Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for maintainer in PKG-INFO #1294

Merged
merged 3 commits into from Mar 17, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGES.rst
@@ -1,3 +1,8 @@
v38.7.0
-------

* #1288: Add support for maintainer in PKG-INFO.

v38.6.1
-------

Expand Down
48 changes: 36 additions & 12 deletions setuptools/dist.py
Expand Up @@ -14,6 +14,7 @@
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
Expand All @@ -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)
Expand All @@ -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
Expand Down
78 changes: 78 additions & 0 deletions setuptools/tests/test_dist.py
@@ -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):
"""
Expand Down Expand Up @@ -45,3 +48,78 @@ def sdist_with_index(distname, version):
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