Procházet zdrojové kódy

Fix UnicodeEncodeError on verbose output of unicode paths

We can't assume that the stdout encoding is not less restrictive
than the filesystem encoding.
Jonas Borgström před 11 roky
rodič
revize
fd2f3ea634
1 změnil soubory, kde provedl 10 přidání a 5 odebrání
  1. 10 5
      attic/archiver.py

+ 10 - 5
attic/archiver.py

@@ -2,6 +2,7 @@ import argparse
 from binascii import hexlify
 from datetime import datetime
 from operator import attrgetter
+import io
 import os
 import stat
 import sys
@@ -351,19 +352,19 @@ Type "Yes I am sure" if you understand this and want to continue.\n""")
         matching is attempted.  Thus, if a given pattern ends in a path separator, a
         '*' is appended before matching is attempted.  Patterns with wildcards should
         be quoted to protect them from shell expansion.
-        
+
         Examples:
-        
+
         # Exclude '/home/user/file.o' but not '/home/user/file.odt':
         $ attic create -e '*.o' repo.attic /
-        
+
         # Exclude '/home/user/junk' and '/home/user/subdir/junk' but
         # not '/home/user/importantjunk' or '/etc/junk':
         $ attic create -e '/home/*/junk' repo.attic /
-        
+
         # Exclude the contents of '/home/user/cache' but not the directory itself:
         $ attic create -e /home/user/cache/ repo.attic /
-        
+
         # The file '/home/user/cache/important' is *not* backed up:
         $ attic create -e /home/user/cache/ repo.attic / /home/user/cache/important
         '''
@@ -598,6 +599,10 @@ Type "Yes I am sure" if you understand this and want to continue.\n""")
 
 
 def main():
+    # Make sure stdout and stderr have errors='replace') to avoid unicode
+    # issues when print()-ing unicode file names
+    sys.stdout = io.TextIOWrapper(sys.stdout.buffer, sys.stdout.encoding, 'replace', line_buffering=sys.stdout.line_buffering)
+    sys.stderr = io.TextIOWrapper(sys.stderr.buffer, sys.stderr.encoding, 'replace', line_buffering=sys.stderr.line_buffering)
     archiver = Archiver()
     try:
         exit_code = archiver.run(sys.argv[1:])