Browse Source

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 11 years ago
parent
commit
fd2f3ea634
1 changed files with 10 additions and 5 deletions
  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:])