Imported Upstream version 38.7.0 upstream/38.7.0
authorDongHun Kwak <dh0128.kwak@samsung.com>
Mon, 14 Jan 2019 01:41:41 +0000 (10:41 +0900)
committerDongHun Kwak <dh0128.kwak@samsung.com>
Mon, 14 Jan 2019 01:41:41 +0000 (10:41 +0900)
CHANGES.rst
setup.cfg
setup.py
setuptools/dist.py
setuptools/tests/test_dist.py

index 01fb448ccf4a7f9b020d031e1ca6d7a721cf7600..cabddaf6615f5f72e27219c9e8d3db2a3c4275b4 100644 (file)
@@ -1,3 +1,8 @@
+v38.7.0
+-------
+
+* #1288: Add support for maintainer in PKG-INFO.
+
 v38.6.1
 -------
 
index 5a9a875ced45c397f7122aa373f7cd24b4ba5fd3..1d8dd5ad4ef6280f4ba35feddb815a144f754255 100755 (executable)
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,5 +1,5 @@
 [bumpversion]
-current_version = 38.6.1
+current_version = 38.7.0
 commit = True
 tag = True
 
index a59ba44b91dd2d080ef9926b9a57cf50411ee6a2..c25ade00c2e6d8dc57ab609b760164353cb9d4e2 100755 (executable)
--- a/setup.py
+++ b/setup.py
@@ -89,7 +89,7 @@ def pypi_link(pkg_filename):
 
 setup_params = dict(
     name="setuptools",
-    version="38.6.1",
+    version="38.7.0",
     description="Easily download, build, install, upgrade, and uninstall "
         "Python packages",
     author="Python Packaging Authority",
index d24958daaeec691da98752b521599224cb752890..b74dd0f51a2a49f6f24862a210a4f577ebbc1d47 100644 (file)
@@ -14,6 +14,7 @@ from distutils.errors import (
     DistutilsOptionError, DistutilsPlatformError, DistutilsSetupError,
 )
 from distutils.util import rfc822_escape
+from distutils.version import StrictVersion
 
 from setuptools.extern import six
 from setuptools.extern.six.moves import map, filter, filterfalse
@@ -34,28 +35,46 @@ def _get_unpatched(cls):
     warnings.warn("Do not call this function", DeprecationWarning)
     return get_unpatched(cls)
 
+def get_metadata_version(dist_md):
+    if dist_md.long_description_content_type or dist_md.provides_extras:
+        return StrictVersion('2.1')
+    elif getattr(dist_md, 'python_requires', None) is not None:
+        return StrictVersion('1.2')
+    elif (dist_md.provides or dist_md.requires or dist_md.obsoletes or
+            dist_md.classifiers or dist_md.download_url):
+        return StrictVersion('1.1')
+
+    return StrictVersion('1.0')
+
 
 # Based on Python 3.5 version
 def write_pkg_file(self, file):
     """Write the PKG-INFO format data to a file object.
     """
-    version = '1.0'
-    if (self.provides or self.requires or self.obsoletes or
-            self.classifiers or self.download_url):
-        version = '1.1'
-    # Setuptools specific for PEP 345
-    if hasattr(self, 'python_requires') or self.project_urls:
-        version = '1.2'
-    if self.long_description_content_type or self.provides_extras:
-        version = '2.1'
+    version = get_metadata_version(self)
 
     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())
+
+    if version == '1.2':
+        file.write('Author: %s\n' % self.get_contact())
+        file.write('Author-email: %s\n' % self.get_contact_email())
+    else:
+        optional_fields = (
+            ('Author', 'author'),
+            ('Author-email', 'author_email'),
+            ('Maintainer', 'maintainer'),
+            ('Maintainer-email', 'maintainer_email'),
+        )
+
+        for field, attr in optional_fields:
+            attr_val = getattr(self, attr)
+            if attr_val is not None:
+                file.write('%s: %s\n' % (field, attr_val))
+
     file.write('License: %s\n' % self.get_license())
     if self.download_url:
         file.write('Download-URL: %s\n' % self.download_url)
@@ -69,7 +88,12 @@ def write_pkg_file(self, file):
     if keywords:
         file.write('Keywords: %s\n' % keywords)
 
-    self._write_list(file, 'Platform', self.get_platforms())
+    if version == '1.2':
+        for platform in self.get_platforms():
+            file.write('Platform: %s\n' % platform)
+    else:
+        self._write_list(file, 'Platform', self.get_platforms())
+
     self._write_list(file, 'Classifier', self.get_classifiers())
 
     # PEP 314
index c4c9bd0388e93cbc3d6527c66b4c382e40ca42ee..0c10f05bc1fc2fac3658ac326e82c46ca8401077 100644 (file)
@@ -1,10 +1,13 @@
+# -*- coding: utf-8 -*-
 from setuptools import Distribution
 from setuptools.extern.six.moves.urllib.request import pathname2url
 from setuptools.extern.six.moves.urllib_parse import urljoin
+from setuptools.extern.six import StringIO
 
 from .textwrap import DALS
 from .test_easy_install import make_nspkg_sdist
 
+import pytest
 
 def test_dist_fetch_build_egg(tmpdir):
     """
@@ -45,3 +48,78 @@ def test_dist_fetch_build_egg(tmpdir):
             for r in reqs
         ]
     assert [dist.key for dist in resolved_dists if dist] == reqs
+
+
+def __maintainer_test_cases():
+    attrs = {"name": "package",
+             "version": "1.0",
+             "description": "xxx"}
+
+    def merge_dicts(d1, d2):
+        d1 = d1.copy()
+        d1.update(d2)
+
+        return d1
+
+    test_cases = [
+        ('No author, no maintainer', attrs.copy()),
+        ('Author (no e-mail), no maintainer', merge_dicts(attrs,
+            {'author': 'Author Name'})),
+        ('Author (e-mail), no maintainer', merge_dicts(attrs,
+            {'author': 'Author Name',
+             'author_email': 'author@name.com'})),
+        ('No author, maintainer (no e-mail)', merge_dicts(attrs,
+            {'maintainer': 'Maintainer Name'})),
+        ('No author, maintainer (e-mail)', merge_dicts(attrs,
+            {'maintainer': 'Maintainer Name',
+             'maintainer_email': 'maintainer@name.com'})),
+        ('Author (no e-mail), Maintainer (no-email)', merge_dicts(attrs,
+            {'author': 'Author Name',
+             'maintainer': 'Maintainer Name'})),
+        ('Author (e-mail), Maintainer (e-mail)', merge_dicts(attrs,
+            {'author': 'Author Name',
+             'author_email': 'author@name.com',
+             'maintainer': 'Maintainer Name',
+             'maintainer_email': 'maintainer@name.com'})),
+        ('No author (e-mail), no maintainer (e-mail)', merge_dicts(attrs,
+            {'author_email': 'author@name.com',
+             'maintainer_email': 'maintainer@name.com'})),
+        ('Author unicode', merge_dicts(attrs,
+            {'author': '鉄沢寛'})),
+        ('Maintainer unicode', merge_dicts(attrs,
+            {'maintainer': 'Jan Łukasiewicz'})),
+    ]
+
+    return test_cases
+
+@pytest.mark.parametrize('name,attrs', __maintainer_test_cases())
+def test_maintainer_author(name, attrs):
+    tested_keys = {
+        'author': 'Author',
+        'author_email': 'Author-email',
+        'maintainer': 'Maintainer',
+        'maintainer_email': 'Maintainer-email',
+    }
+
+    # Generate a PKG-INFO file
+    dist = Distribution(attrs)
+    PKG_INFO = StringIO()
+    dist.metadata.write_pkg_file(PKG_INFO)
+    PKG_INFO.seek(0)
+
+    pkg_lines = PKG_INFO.readlines()
+    pkg_lines = [_ for _ in pkg_lines if _]   # Drop blank lines
+    pkg_lines_set = set(pkg_lines)
+
+    # Duplicate lines should not be generated
+    assert len(pkg_lines) == len(pkg_lines_set)
+
+    for fkey, dkey in tested_keys.items():
+        val = attrs.get(dkey, None)
+        if val is None:
+            for line in pkg_lines:
+                assert not line.startswith(fkey + ':')
+        else:
+            line = '%s: %s' % (fkey, val)
+            assert line in pkg_lines_set
+