diff --git a/CHANGES b/CHANGES index f703b9b12..5828de634 100644 --- a/CHANGES +++ b/CHANGES @@ -7,6 +7,7 @@ Version 0.16 ------------ (bugfix release, released on X) +- Improve handling of systems with improperly configured file system encoding (#289) - Fix "All archives" output for attic info. (#183) - More user friendly error message when repository key file is not found (#236) - Fix parsing of iso 8601 timestamps with zero microseconds (#282) diff --git a/attic/archive.py b/attic/archive.py index 1b3818bc8..6778bed13 100644 --- a/attic/archive.py +++ b/attic/archive.py @@ -119,6 +119,10 @@ class Archive: class AlreadyExists(Error): """Archive {} already exists""" + class IncompatibleFilesystemEncodingError(Error): + """Failed to encode filename "{}" into file system encoding "{}". Consider configuring the LANG environment variable.""" + + def __init__(self, repository, key, manifest, name, cache=None, create=False, checkpoint_interval=300, numeric_owner=False): self.cwd = os.getcwd() @@ -247,6 +251,8 @@ class Archive: os.rmdir(path) else: os.unlink(path) + except UnicodeEncodeError: + raise self.IncompatibleFilesystemEncodingError(path, sys.getfilesystemencoding()) except OSError: pass mode = item[b'mode'] diff --git a/attic/archiver.py b/attic/archiver.py index 7295ac06e..5731ffb4c 100644 --- a/attic/archiver.py +++ b/attic/archiver.py @@ -188,6 +188,8 @@ Type "Yes I am sure" if you understand this and want to continue.\n""") def do_extract(self, args): """Extract archive contents""" # be restrictive when restoring files, restore permissions later + if sys.getfilesystemencoding() == 'ascii': + print('Warning: File system encoding is "ascii", extracting non-ascii filenames will not be supported.') os.umask(0o077) repository = self.open_repository(args.archive) manifest, key = Manifest.load(repository)