From 26297b95f7bd4eac0cd90a872717b4e140c5c209 Mon Sep 17 00:00:00 2001 From: Paul Ganssle Date: Tue, 13 Mar 2018 11:17:44 -0400 Subject: [PATCH] Add Maintainer and Maintainer-Email fields Per PEP 345, Author, Author-Email, Maintainer and Maintainer-Email are all optional fields, this patch implements reading and writing them properly into PKG-INFO. See bpo-33069 --- Lib/distutils/dist.py | 19 ++++-- Lib/distutils/tests/test_dist.py | 62 +++++++++++++++++++ .../2018-03-13-11-23-54.bpo-33069.cP5Km-.rst | 1 + 3 files changed, 78 insertions(+), 4 deletions(-) create mode 100644 Misc/NEWS.d/next/Build/2018-03-13-11-23-54.bpo-33069.cP5Km-.rst diff --git a/Lib/distutils/dist.py b/Lib/distutils/dist.py index 6cf0a0d6632dc7..fe47b71545051f 100644 --- a/Lib/distutils/dist.py +++ b/Lib/distutils/dist.py @@ -1079,9 +1079,9 @@ def _read_list(name): self.description = _read_field('summary') # we are filling author only. self.author = _read_field('author') - self.maintainer = None + self.maintainer = _read_field('maintainer') self.author_email = _read_field('author-email') - self.maintainer_email = None + self.maintainer_email = _read_field('maintainer-email') self.url = _read_field('home-page') self.license = _read_field('license') @@ -1129,8 +1129,19 @@ def write_pkg_file(self, file): 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()) + + 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) diff --git a/Lib/distutils/tests/test_dist.py b/Lib/distutils/tests/test_dist.py index 0a19f0fb6274cb..28f941aed209d9 100644 --- a/Lib/distutils/tests/test_dist.py +++ b/Lib/distutils/tests/test_dist.py @@ -518,6 +518,68 @@ def test_read_metadata(self): self.assertEqual(metadata.obsoletes, None) self.assertEqual(metadata.requires, ['foo']) + def test_author_maintainer(self): + attrs = {"name": "package", + "version": "1.0", + "description": "xxx"} + + def roundtrip_tofile(attr_dict): + dist = Distribution(attr_dict) + + PKG_INFO = io.StringIO() + dist.metadata.write_pkg_file(PKG_INFO) + PKG_INFO.seek(0) + + metadata_out = DistributionMetadata() + metadata_out.read_pkg_file(PKG_INFO) + + return metadata_out + + 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'})), + ] + + tested_keys = ['author', 'author_email', + 'maintainer', 'maintainer_email'] + for case_name, cattrs in test_cases: + with self.subTest(case_name): + metadata = roundtrip_tofile(cattrs) + + for key in tested_keys: + val = getattr(metadata, key) + self.assertEqual(val, cattrs.get(key, None)) + def test_suite(): suite = unittest.TestSuite() suite.addTest(unittest.makeSuite(DistributionTestCase)) diff --git a/Misc/NEWS.d/next/Build/2018-03-13-11-23-54.bpo-33069.cP5Km-.rst b/Misc/NEWS.d/next/Build/2018-03-13-11-23-54.bpo-33069.cP5Km-.rst new file mode 100644 index 00000000000000..441c98cf9c30d6 --- /dev/null +++ b/Misc/NEWS.d/next/Build/2018-03-13-11-23-54.bpo-33069.cP5Km-.rst @@ -0,0 +1 @@ +Add support for maintainer= and maintainer_email= into distutils.