diff --git a/Lib/packaging/config.py b/Lib/packaging/config.py --- a/Lib/packaging/config.py +++ b/Lib/packaging/config.py @@ -282,7 +282,7 @@ class Config: for filename in filenames: logger.debug(" reading %s", filename) - parser.read(filename) + parser.read(filename, encoding='utf-8') if os.path.split(filename)[-1] == 'setup.cfg': self._read_setup_cfg(parser, filename) diff --git a/Lib/packaging/create.py b/Lib/packaging/create.py --- a/Lib/packaging/create.py +++ b/Lib/packaging/create.py @@ -276,7 +276,7 @@ class MainProgram: return shutil.move(_FILENAME, '%s.old' % _FILENAME) - with open(_FILENAME, 'w') as fp: + with open(_FILENAME, 'w', encoding='utf-8') as fp: fp.write('[metadata]\n') # simple string entries for name in ('name', 'version', 'summary', 'download_url'): diff --git a/Lib/packaging/metadata.py b/Lib/packaging/metadata.py --- a/Lib/packaging/metadata.py +++ b/Lib/packaging/metadata.py @@ -3,6 +3,7 @@ Supports all metadata formats (1.0, 1.1, 1.2). """ +import codecs import re import logging @@ -330,11 +331,16 @@ class Metadata: def write(self, filepath): """Write the metadata fields to filepath.""" - with open(filepath, 'w') as fp: + with open(filepath, 'w', encoding='utf-8') as fp: self.write_file(fp) def write_file(self, fileobject): """Write the PKG-INFO format data to a file object.""" + if not isinstance(fileobject, StringIO): + encoding = codecs.lookup(fileobject.encoding).name + if encoding != 'utf-8': + raise ValueError("Output file should be a UTF-8 text file, not %s encoding" % encoding) + self._set_best_version() for field in _version2fieldlist(self['Metadata-Version']): values = self.get(field) diff --git a/Lib/packaging/tests/support.py b/Lib/packaging/tests/support.py --- a/Lib/packaging/tests/support.py +++ b/Lib/packaging/tests/support.py @@ -146,7 +146,7 @@ class TempdirManager: """ if isinstance(path, (list, tuple)): path = os.path.join(*path) - f = open(path, 'w') + f = open(path, 'w', encoding='utf8') try: f.write(content) finally: diff --git a/Lib/packaging/tests/test_create.py b/Lib/packaging/tests/test_create.py --- a/Lib/packaging/tests/test_create.py +++ b/Lib/packaging/tests/test_create.py @@ -129,7 +129,7 @@ class CreateTestCase(support.TempdirMana sys.stdin.seek(0) main() - with open(os.path.join(self.wdir, 'setup.cfg')) as fp: + with open(os.path.join(self.wdir, 'setup.cfg'), encoding='utf-8') as fp: lines = set(line.rstrip() for line in fp) # FIXME don't use sets @@ -205,7 +205,7 @@ ho, baby! sys.stdin.seek(0) # FIXME Out of memory error. main() - with open(os.path.join(self.wdir, 'setup.cfg')) as fp: + with open(os.path.join(self.wdir, 'setup.cfg'), encoding='utf-8') as fp: lines = set(line.rstrip() for line in fp) self.assertEqual(lines, set(['', diff --git a/Lib/packaging/tests/test_dist.py b/Lib/packaging/tests/test_dist.py --- a/Lib/packaging/tests/test_dist.py +++ b/Lib/packaging/tests/test_dist.py @@ -78,7 +78,7 @@ class DistributionTestCase(support.Tempd # let's make sure the file can be written # with Unicode fields. they are encoded with # PKG_INFO_ENCODING - with open(my_file, 'w') as fp: + with open(my_file, 'w', encoding='utf-8') as fp: dist.metadata.write_file(fp) # regular ascii is of course always usable @@ -88,7 +88,7 @@ class DistributionTestCase(support.Tempd 'summary': 'Cafe torrefie', 'description': 'Hehehe'}) - with open(my_file, 'w') as fp: + with open(my_file, 'w', encoding='utf-8') as fp: dist.metadata.write_file(fp) def test_bad_attr(self):