Issue #2562: Fix distutils PKG-INFO writing logic to allow having
non-ascii characters and Unicode in setup.py meta-data.
This commit is contained in:
parent
6a2fd81316
commit
b339b2aa6f
|
@ -23,6 +23,9 @@ from distutils.util import check_environ, strtobool, rfc822_escape
|
||||||
from distutils import log
|
from distutils import log
|
||||||
from distutils.debug import DEBUG
|
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*
|
# 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
|
# 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
|
# that they're very similar is no coincidence; the default naming scheme is
|
||||||
|
@ -1084,23 +1087,23 @@ class DistributionMetadata:
|
||||||
if self.provides or self.requires or self.obsoletes:
|
if self.provides or self.requires or self.obsoletes:
|
||||||
version = '1.1'
|
version = '1.1'
|
||||||
|
|
||||||
file.write('Metadata-Version: %s\n' % version)
|
self._write_field(file, 'Metadata-Version', version)
|
||||||
file.write('Name: %s\n' % self.get_name() )
|
self._write_field(file, 'Name', self.get_name())
|
||||||
file.write('Version: %s\n' % self.get_version() )
|
self._write_field(file, 'Version', self.get_version())
|
||||||
file.write('Summary: %s\n' % self.get_description() )
|
self._write_field(file, 'Summary', self.get_description())
|
||||||
file.write('Home-page: %s\n' % self.get_url() )
|
self._write_field(file, 'Home-page', self.get_url())
|
||||||
file.write('Author: %s\n' % self.get_contact() )
|
self._write_field(file, 'Author', self.get_contact())
|
||||||
file.write('Author-email: %s\n' % self.get_contact_email() )
|
self._write_field(file, 'Author-email', self.get_contact_email())
|
||||||
file.write('License: %s\n' % self.get_license() )
|
self._write_field(file, 'License', self.get_license())
|
||||||
if self.download_url:
|
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() )
|
long_desc = rfc822_escape( self.get_long_description())
|
||||||
file.write('Description: %s\n' % long_desc)
|
self._write_field(file, 'Description', long_desc)
|
||||||
|
|
||||||
keywords = string.join( self.get_keywords(), ',')
|
keywords = string.join( self.get_keywords(), ',')
|
||||||
if 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, 'Platform', self.get_platforms())
|
||||||
self._write_list(file, 'Classifier', self.get_classifiers())
|
self._write_list(file, 'Classifier', self.get_classifiers())
|
||||||
|
@ -1110,10 +1113,19 @@ class DistributionMetadata:
|
||||||
self._write_list(file, 'Provides', self.get_provides())
|
self._write_list(file, 'Provides', self.get_provides())
|
||||||
self._write_list(file, 'Obsoletes', self.get_obsoletes())
|
self._write_list(file, 'Obsoletes', self.get_obsoletes())
|
||||||
|
|
||||||
def _write_list (self, file, name, values):
|
def _write_field(self, file, name, value):
|
||||||
for value in values:
|
|
||||||
|
if isinstance(value, unicode):
|
||||||
|
value = value.encode(PKG_INFO_ENCODING)
|
||||||
|
else:
|
||||||
|
value = str(value)
|
||||||
file.write('%s: %s\n' % (name, value))
|
file.write('%s: %s\n' % (name, value))
|
||||||
|
|
||||||
|
def _write_list (self, file, name, values):
|
||||||
|
|
||||||
|
for value in values:
|
||||||
|
self._write_field(file, name, value)
|
||||||
|
|
||||||
# -- Metadata query methods ----------------------------------------
|
# -- Metadata query methods ----------------------------------------
|
||||||
|
|
||||||
def get_name (self):
|
def get_name (self):
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
# -*- coding: latin-1 -*-
|
||||||
|
|
||||||
"""Tests for distutils.dist."""
|
"""Tests for distutils.dist."""
|
||||||
|
|
||||||
import distutils.cmd
|
import distutils.cmd
|
||||||
|
@ -95,6 +97,39 @@ class DistributionTestCase(unittest.TestCase):
|
||||||
finally:
|
finally:
|
||||||
os.unlink(TESTFN)
|
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):
|
class MetadataTestCase(unittest.TestCase):
|
||||||
|
|
||||||
|
|
|
@ -56,7 +56,10 @@ C-API
|
||||||
Library
|
Library
|
||||||
-------
|
-------
|
||||||
|
|
||||||
- Issue #3726: Allowed spaces in separators in logging configuration files.
|
- Issue #2562: Fix distutils PKG-INFO writing logic to allow having
|
||||||
|
non-ascii characters and Unicode in setup.py meta-data.
|
||||||
|
|
||||||
|
- Issue #3726: Allow spaces in separators in logging configuration files.
|
||||||
|
|
||||||
- Issue #3719: platform.architecture() fails if there are spaces in the
|
- Issue #3719: platform.architecture() fails if there are spaces in the
|
||||||
path to the Python binary.
|
path to the Python binary.
|
||||||
|
|
Loading…
Reference in New Issue