J. C.
J. C.

Reputation: 109

Copying files raises a SyntaxError can't decode bytes

I'm trying to code a short program that makes backups of a folder whenever I run it. Currently it's like this:

import time
import shutil
import os

date = time.strftime("%d-%m-%Y")
print(date)

shutil.copy2("C:\Users\joaop\Desktop\VanillaServer\world","C:\Users\joaop\Desktop\VanillaServer\Backups")

for filename in os.listdir("C:\Users\joaop\Desktop\VanillaServer\Backups"):
    if filename == world:
        os.rename(filename, "Backup " + date)

However I get an error:

SyntaxError: (unicode error) 'unicodeescape' codec can't decode bytes in position 2-3: truncated \UXXXXXXXX escape 

and I can't figure out why (according to documentation, I think my code is properly written)

How can I fix this/do it in a better way?

Upvotes: 0

Views: 856

Answers (2)

WhatsThePoint
WhatsThePoint

Reputation: 3635

Backslashes are used for escape characters so when the interpreter sees the \ in your file path string it attempts to use them as an escape character (which are things like \n for new line and \t for tabs).

There are 2 ways around this, using raw strings or double slashing your file path so the interpeter ignores the escape sequence. Use a r to specify a raw string or \\. Now the choice in which you use is up to you but personally I prefer raw strings.

#with raw strings
shutil.copy2(r"C:\Users\joaop\Desktop\VanillaServer\world",r"C:\Users\joaop\Desktop\VanillaServer\Backups")

for filename in os.listdir(r"C:\Users\joaop\Desktop\VanillaServer\Backups"):
    if filename == world:
        os.rename(filename, "Backup " + date)

#with double slashes
shutil.copy2("C:\\Users\\joaop\\Desktop\\VanillaServer\\world","C:\\Users\\joaop\\Desktop\\VanillaServer\\Backups")

for filename in os.listdir("C:\\Users\\joaop\\Desktop\\VanillaServer\\Backups"):
    if filename == world:
        os.rename(filename, "Backup " + date)

Upvotes: 1

tobias_k
tobias_k

Reputation: 82949

In Python, \u... denotes a Unicode sequence, so your \Users directory is interpreted as a Unicode character -- not with very much success.

>>> "\u0061"
'a'
>>> "\users"
  File "<stdin>", line 1
SyntaxError: (unicode error) 'unicodeescape' codec can't decode bytes in position 0-1: truncated \uXXXX escape

To fix it, you should escape the different \ as \\, or use r"..." to make it a raw string.

>>> "C:\\Users\\joaop\\Desktop\\VanillaServer\\world"
'C:\\Users\\joaop\\Desktop\\VanillaServer\\world'
>>> r"C:\Users\joaop\Desktop\VanillaServer\world"
'C:\\Users\\joaop\\Desktop\\VanillaServer\\world'

Don't do both, though, or else they will be escaped twice:

>>> r"C:\\Users\\joaop\\Desktop\\VanillaServer\\world"
'C:\\\\Users\\\\joaop\\\\Desktop\\\\VanillaServer\\\\world'

You only have to escape them when entering the paths directly in your source; if you read those paths from a file, from user input, or from some library function, they will automatically be escaped.

Upvotes: 3

Related Questions