mirror of https://github.com/python/cpython
Fixed #7748: now upload and register commands don't need to force the encoding anymore : DistributionMetada returns utf8 strings
This commit is contained in:
parent
aa98058cc4
commit
f14c7fc33d
|
@ -266,7 +266,6 @@ Your selection [default 1]: ''', log.INFO)
|
||||||
if type(value) not in (type([]), type( () )):
|
if type(value) not in (type([]), type( () )):
|
||||||
value = [value]
|
value = [value]
|
||||||
for value in value:
|
for value in value:
|
||||||
value = unicode(value).encode("utf-8")
|
|
||||||
body.write(sep_boundary)
|
body.write(sep_boundary)
|
||||||
body.write('\nContent-Disposition: form-data; name="%s"'%key)
|
body.write('\nContent-Disposition: form-data; name="%s"'%key)
|
||||||
body.write("\n\n")
|
body.write("\n\n")
|
||||||
|
|
|
@ -145,7 +145,7 @@ class upload(PyPIRCCommand):
|
||||||
value = value[1]
|
value = value[1]
|
||||||
else:
|
else:
|
||||||
fn = ""
|
fn = ""
|
||||||
value = str(value)
|
|
||||||
body.write(sep_boundary)
|
body.write(sep_boundary)
|
||||||
body.write('\nContent-Disposition: form-data; name="%s"'%key)
|
body.write('\nContent-Disposition: form-data; name="%s"'%key)
|
||||||
body.write(fn)
|
body.write(fn)
|
||||||
|
|
|
@ -1139,16 +1139,19 @@ class DistributionMetadata:
|
||||||
self._write_list(file, 'Obsoletes', self.get_obsoletes())
|
self._write_list(file, 'Obsoletes', self.get_obsoletes())
|
||||||
|
|
||||||
def _write_field(self, file, name, value):
|
def _write_field(self, file, name, value):
|
||||||
if isinstance(value, unicode):
|
file.write('%s: %s\n' % (name, self._encode_field(value)))
|
||||||
value = value.encode(PKG_INFO_ENCODING)
|
|
||||||
else:
|
|
||||||
value = str(value)
|
|
||||||
file.write('%s: %s\n' % (name, value))
|
|
||||||
|
|
||||||
def _write_list (self, file, name, values):
|
def _write_list (self, file, name, values):
|
||||||
for value in values:
|
for value in values:
|
||||||
self._write_field(file, name, value)
|
self._write_field(file, name, value)
|
||||||
|
|
||||||
|
def _encode_field(self, value):
|
||||||
|
if value is None:
|
||||||
|
return None
|
||||||
|
if isinstance(value, unicode):
|
||||||
|
return value.encode(PKG_INFO_ENCODING)
|
||||||
|
return str(value)
|
||||||
|
|
||||||
# -- Metadata query methods ----------------------------------------
|
# -- Metadata query methods ----------------------------------------
|
||||||
|
|
||||||
def get_name(self):
|
def get_name(self):
|
||||||
|
@ -1161,19 +1164,20 @@ class DistributionMetadata:
|
||||||
return "%s-%s" % (self.get_name(), self.get_version())
|
return "%s-%s" % (self.get_name(), self.get_version())
|
||||||
|
|
||||||
def get_author(self):
|
def get_author(self):
|
||||||
return self.author or "UNKNOWN"
|
return self._encode_field(self.author) or "UNKNOWN"
|
||||||
|
|
||||||
def get_author_email(self):
|
def get_author_email(self):
|
||||||
return self.author_email or "UNKNOWN"
|
return self.author_email or "UNKNOWN"
|
||||||
|
|
||||||
def get_maintainer(self):
|
def get_maintainer(self):
|
||||||
return self.maintainer or "UNKNOWN"
|
return self._encode_field(self.maintainer) or "UNKNOWN"
|
||||||
|
|
||||||
def get_maintainer_email(self):
|
def get_maintainer_email(self):
|
||||||
return self.maintainer_email or "UNKNOWN"
|
return self.maintainer_email or "UNKNOWN"
|
||||||
|
|
||||||
def get_contact(self):
|
def get_contact(self):
|
||||||
return self.maintainer or self.author or "UNKNOWN"
|
return (self._encode_field(self.maintainer) or
|
||||||
|
self._encode_field(self.author) or "UNKNOWN")
|
||||||
|
|
||||||
def get_contact_email(self):
|
def get_contact_email(self):
|
||||||
return self.maintainer_email or self.author_email or "UNKNOWN"
|
return self.maintainer_email or self.author_email or "UNKNOWN"
|
||||||
|
@ -1186,10 +1190,10 @@ class DistributionMetadata:
|
||||||
get_licence = get_license
|
get_licence = get_license
|
||||||
|
|
||||||
def get_description(self):
|
def get_description(self):
|
||||||
return self.description or "UNKNOWN"
|
return self._encode_field(self.description) or "UNKNOWN"
|
||||||
|
|
||||||
def get_long_description(self):
|
def get_long_description(self):
|
||||||
return self.long_description or "UNKNOWN"
|
return self._encode_field(self.long_description) or "UNKNOWN"
|
||||||
|
|
||||||
def get_keywords(self):
|
def get_keywords(self):
|
||||||
return self.keywords or []
|
return self.keywords or []
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
"""Tests for distutils.command.register."""
|
"""Tests for distutils.command.register."""
|
||||||
|
# -*- encoding: utf8 -*-
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
import unittest
|
import unittest
|
||||||
|
@ -136,9 +137,7 @@ class RegisterTestCase(PyPIRCCommandTestCase):
|
||||||
self.assertTrue(self.conn.reqs, 2)
|
self.assertTrue(self.conn.reqs, 2)
|
||||||
req1 = dict(self.conn.reqs[0].headers)
|
req1 = dict(self.conn.reqs[0].headers)
|
||||||
req2 = dict(self.conn.reqs[1].headers)
|
req2 = dict(self.conn.reqs[1].headers)
|
||||||
|
self.assertEquals(req2['Content-length'], req1['Content-length'])
|
||||||
self.assertEquals(req1['Content-length'], '1374')
|
|
||||||
self.assertEquals(req2['Content-length'], '1374')
|
|
||||||
self.assertTrue('xxx' in self.conn.reqs[1].data)
|
self.assertTrue('xxx' in self.conn.reqs[1].data)
|
||||||
|
|
||||||
def test_password_not_in_file(self):
|
def test_password_not_in_file(self):
|
||||||
|
@ -210,7 +209,7 @@ class RegisterTestCase(PyPIRCCommandTestCase):
|
||||||
|
|
||||||
# metadata are OK but long_description is broken
|
# metadata are OK but long_description is broken
|
||||||
metadata = {'url': 'xxx', 'author': 'xxx',
|
metadata = {'url': 'xxx', 'author': 'xxx',
|
||||||
'author_email': 'xxx',
|
'author_email': u'éxéxé',
|
||||||
'name': 'xxx', 'version': 'xxx',
|
'name': 'xxx', 'version': 'xxx',
|
||||||
'long_description': 'title\n==\n\ntext'}
|
'long_description': 'title\n==\n\ntext'}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
"""Tests for distutils.command.upload."""
|
"""Tests for distutils.command.upload."""
|
||||||
|
# -*- encoding: utf8 -*-
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
import unittest
|
import unittest
|
||||||
|
@ -107,14 +108,15 @@ class uploadTestCase(PyPIRCCommandTestCase):
|
||||||
self.write_file(self.rc, PYPIRC_LONG_PASSWORD)
|
self.write_file(self.rc, PYPIRC_LONG_PASSWORD)
|
||||||
|
|
||||||
# lets run it
|
# lets run it
|
||||||
pkg_dir, dist = self.create_dist(dist_files=dist_files)
|
pkg_dir, dist = self.create_dist(dist_files=dist_files, author=u'dédé')
|
||||||
cmd = upload(dist)
|
cmd = upload(dist)
|
||||||
cmd.ensure_finalized()
|
cmd.ensure_finalized()
|
||||||
cmd.run()
|
cmd.run()
|
||||||
|
|
||||||
# what did we send ?
|
# what did we send ?
|
||||||
|
self.assertIn('dédé', self.last_open.req.data)
|
||||||
headers = dict(self.last_open.req.headers)
|
headers = dict(self.last_open.req.headers)
|
||||||
self.assertEquals(headers['Content-length'], '2086')
|
self.assertEquals(headers['Content-length'], '2085')
|
||||||
self.assertTrue(headers['Content-type'].startswith('multipart/form-data'))
|
self.assertTrue(headers['Content-type'].startswith('multipart/form-data'))
|
||||||
self.assertEquals(self.last_open.req.get_method(), 'POST')
|
self.assertEquals(self.last_open.req.get_method(), 'POST')
|
||||||
self.assertEquals(self.last_open.req.get_full_url(),
|
self.assertEquals(self.last_open.req.get_full_url(),
|
||||||
|
|
|
@ -42,6 +42,11 @@ Core and Builtins
|
||||||
Library
|
Library
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
- Issue #7748: Since unicode values are supported for some metadata options
|
||||||
|
in Distutils, the DistributionMetadata get_* methods will now return an utf-8
|
||||||
|
encoded string for them. This ensure that the upload and register commands
|
||||||
|
send the right values to PyPI without any error.
|
||||||
|
|
||||||
- Issue #1670765: Prevent email.generator.Generator from re-wrapping
|
- Issue #1670765: Prevent email.generator.Generator from re-wrapping
|
||||||
headers in multipart/signed MIME parts, which fixes one of the sources of
|
headers in multipart/signed MIME parts, which fixes one of the sources of
|
||||||
invalid modifications to such parts by Generator.
|
invalid modifications to such parts by Generator.
|
||||||
|
@ -186,7 +191,7 @@ Library
|
||||||
- Distutils now correctly identifies the build architecture as "x86_64"
|
- Distutils now correctly identifies the build architecture as "x86_64"
|
||||||
when building on OSX 10.6 without "-arch" flags.
|
when building on OSX 10.6 without "-arch" flags.
|
||||||
|
|
||||||
- Issue #7556: Distutils' msvc9compiler now opens the MSVC Manifest
|
- Issue #7556: Distutils' msvc9compiler now opens the MSVC Manifest
|
||||||
file in text mode.
|
file in text mode.
|
||||||
|
|
||||||
- Issue #7552: Removed line feed in the base64 Authorization header in
|
- Issue #7552: Removed line feed in the base64 Authorization header in
|
||||||
|
|
Loading…
Reference in New Issue