0

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?

Dimitris Fasarakis Hilliard
  • 150,925
  • 31
  • 268
  • 253
J. C.
  • 109
  • 2
  • 11
  • 2
    You should probably escape the backslashes or use raw strings: `"C:\\Users..."` or `r"C:\Users..."` – tobias_k Feb 10 '17 at 14:41
  • 1
    ... or use forward slashes. – cdarke Feb 10 '17 at 14:42
  • Possible duplicate of [(unicode error) 'unicodeescape' codec can't decode bytes in position 2-3: truncated \UXXXXXXXX escape](http://stackoverflow.com/questions/37400974/unicode-error-unicodeescape-codec-cant-decode-bytes-in-position-2-3-trunca) – Josh Lee Feb 10 '17 at 18:14

2 Answers2

3

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.

tobias_k
  • 81,265
  • 12
  • 120
  • 179
1

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)
Eric Leschinski
  • 146,994
  • 96
  • 417
  • 335
WhatsThePoint
  • 3,395
  • 8
  • 31
  • 53