diff --git a/aptsources/sourceslist.py b/aptsources/sourceslist.py index 91ce8ef..36e276d 100644 --- a/aptsources/sourceslist.py +++ b/aptsources/sourceslist.py @@ -83,6 +83,17 @@ def uniq(s): return list(set(s)) +def _open_decoded_in_py3(path, mode): + """Hardcode UTF-8 in Python 3. We do it everywhere else as well.""" + import sys + import io + + if sys.version_info.major >= 3: + return io.open(path, mode, encoding="utf-8") + else: + return open(path, mode) + + class SourceEntry(object): """ single sources.list entry """ @@ -230,6 +241,14 @@ class SourceEntry(object): """ debug helper """ return self.str().strip() + def __bytes__(self): + """python3 debug helper """ + return self.str().strip().encode("utf-8") + + def __unicode__(self): + """python2 debug helper """ + return self.str().strip().decode("utf-8") + def str(self): """ return the current line as string """ if self.invalid: @@ -387,7 +406,7 @@ class SourcesList(object): def load(self, file): """ (re)load the current sources """ try: - with open(file, "r") as f: + with _open_decoded_in_py3(file, "r") as f: for line in f: source = SourceEntry(line, file) self.list.append(source) @@ -405,14 +424,14 @@ class SourcesList(object): "# Remember that you can only use http, ftp or file URIs\n" "# CDROMs are managed through the apt-cdrom tool.\n") - with open(path, "w") as f: + with _open_decoded_in_py3(path, "w") as f: f.write(header) return try: for source in self.list: if source.file not in files: - files[source.file] = open(source.file, "w") + files[source.file] = _open_decoded_in_py3(source.file, "w") files[source.file].write(source.str()) finally: for f in files: diff --git a/tests/data/aptsources/sources.list b/tests/data/aptsources/sources.list index 8ca6807..9a3b836 100644 --- a/tests/data/aptsources/sources.list +++ b/tests/data/aptsources/sources.list @@ -1,5 +1,5 @@ # comment 1 -deb http://de.archive.ubuntu.com/ubuntu/ edgy main +deb http://de.archive.ubuntu.com/ubuntu/ edgy main # Unicode: Äffchen # comment 2 deb http://de.archive.ubuntu.com/ubuntu/ edgy restricted # comment 3 diff --git a/tests/test_aptsources.py b/tests/test_aptsources.py index f955205..5779e8e 100644 --- a/tests/test_aptsources.py +++ b/tests/test_aptsources.py @@ -1,5 +1,7 @@ #!/usr/bin/env python +# This Python file uses the following encoding: utf-8 +import sys import unittest import os import copy @@ -41,6 +43,12 @@ class TestAptSources(unittest.TestCase): "sources.list") sources = aptsources.sourceslist.SourcesList(True, self.templates) self.assertEqual(len(sources.list), 10) + if sys.version_info.major < 3: + self.assertRegexpMatches(str(sources.list[1]), '\xc3\x84ffchen$') + self.assertRegexpMatches(unicode(sources.list[1]), u'Äffchen$') + else: + self.assertRegex(bytes(sources.list[1]), b'\xc3\x84ffchen$') + self.assertRegex(str(sources.list[1]), 'Äffchen$') # test load sources.list = [] sources.load("data/aptsources/sources.list")