Index: Lib/distutils/tests/test_dist.py =================================================================== --- Lib/distutils/tests/test_dist.py (revision 66031) +++ Lib/distutils/tests/test_dist.py (working copy) @@ -1,3 +1,5 @@ +# -*- coding: latin-1 -*- + """Tests for distutils.dist.""" import distutils.cmd @@ -95,6 +97,39 @@ finally: os.unlink(TESTFN) + def test_write_pkg_file(self): + # Check DistributionMetadata handling of Unicode fields + my_file = os.path.join(os.path.dirname(__file__), 'f') + klass = distutils.dist.Distribution + + dist = klass(attrs={'author': u'Mister Café', + 'name': 'my.package', + 'maintainer': u'Café Junior', + 'description': u'Café torréfié', + 'long_description': u'Héhéhé'}) + + + # let's make sure the file can be written + # with Unicode fields. they are encoded with + # PKG_INFO_ENCODING + try: + dist.metadata.write_pkg_file(open(my_file, 'w')) + finally: + if os.path.exists(my_file): + os.remove(my_file) + + # regular ascii is of course always usable + dist = klass(attrs={'author': 'Mister Cafe', + 'name': 'my.package', + 'maintainer': 'Cafe Junior', + 'description': 'Cafe torrefie', + 'long_description': 'Hehehe'}) + + try: + dist.metadata.write_pkg_file(open(my_file, 'w')) + finally: + if os.path.exists(my_file): + os.remove(my_file) class MetadataTestCase(unittest.TestCase): Index: Lib/distutils/dist.py =================================================================== --- Lib/distutils/dist.py (revision 66031) +++ Lib/distutils/dist.py (working copy) @@ -23,6 +23,9 @@ from distutils import log from distutils.debug import DEBUG +# Encoding used for the PKG-INFO files +PKG_INFO_ENCODING = 'utf-8' + # Regex to define acceptable Distutils command names. This is not *quite* # the same as a Python NAME -- I don't allow leading underscores. The fact # that they're very similar is no coincidence; the default naming scheme is @@ -1084,23 +1087,23 @@ if self.provides or self.requires or self.obsoletes: version = '1.1' - file.write('Metadata-Version: %s\n' % version) - file.write('Name: %s\n' % self.get_name() ) - file.write('Version: %s\n' % self.get_version() ) - file.write('Summary: %s\n' % self.get_description() ) - file.write('Home-page: %s\n' % self.get_url() ) - file.write('Author: %s\n' % self.get_contact() ) - file.write('Author-email: %s\n' % self.get_contact_email() ) - file.write('License: %s\n' % self.get_license() ) + self._write_field(file, 'Metadata-Version', version) + self._write_field(file, 'Name', self.get_name()) + self._write_field(file, 'Version', self.get_version()) + self._write_field(file, 'Summary', self.get_description()) + self._write_field(file, 'Home-page', self.get_url()) + self._write_field(file, 'Author', self.get_contact()) + self._write_field(file, 'Author-email', self.get_contact_email()) + self._write_field(file, 'License', self.get_license()) if self.download_url: - file.write('Download-URL: %s\n' % self.download_url) + self._write_field(file, 'Download-URL', self.download_url) - long_desc = rfc822_escape( self.get_long_description() ) - file.write('Description: %s\n' % long_desc) + long_desc = rfc822_escape( self.get_long_description()) + self._write_field(file, 'Description', long_desc) keywords = string.join( self.get_keywords(), ',') if keywords: - file.write('Keywords: %s\n' % keywords ) + self._write_field(file, 'Keywords', keywords) self._write_list(file, 'Platform', self.get_platforms()) self._write_list(file, 'Classifier', self.get_classifiers()) @@ -1110,9 +1113,18 @@ self._write_list(file, 'Provides', self.get_provides()) self._write_list(file, 'Obsoletes', self.get_obsoletes()) + def _write_field(self, file, name, value): + + if isinstance(value, unicode): + value = value.encode(PKG_INFO_ENCODING) + else: + value = str(value) + file.write('%s: %s\n' % (name, value)) + def _write_list (self, file, name, values): + for value in values: - file.write('%s: %s\n' % (name, value)) + self._write_field(file, name, value) # -- Metadata query methods ----------------------------------------