From 11e33dbad2fc20b93561e0e2270d7f066909f2fb Mon Sep 17 00:00:00 2001 From: Greg Roodt Date: Mon, 11 Mar 2024 14:33:56 +1100 Subject: [PATCH 1/5] . --- flit/upload.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flit/upload.py b/flit/upload.py index afd5f798..4a9697c8 100644 --- a/flit/upload.py +++ b/flit/upload.py @@ -226,7 +226,7 @@ def build_post_data(action, metadata:Metadata): "version": metadata.version, # additional meta-data - "metadata_version": '2.1', + "metadata_version": '2.3', "summary": metadata.summary, "home_page": metadata.home_page, "author": metadata.author, From d7d1839275ec278d01faa95c68b74f18c984957b Mon Sep 17 00:00:00 2001 From: Greg Roodt Date: Mon, 11 Mar 2024 14:35:25 +1100 Subject: [PATCH 2/5] . --- flit_core/flit_core/common.py | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/flit_core/flit_core/common.py b/flit_core/flit_core/common.py index 9f2b9204..327d0bff 100644 --- a/flit_core/flit_core/common.py +++ b/flit_core/flit_core/common.py @@ -348,7 +348,7 @@ class Metadata(object): requires_external = () provides_extra = () - metadata_version = "2.1" + metadata_version = "2.3" def __init__(self, data): data = data.copy() @@ -359,9 +359,13 @@ def __init__(self, data): assert hasattr(self, k), "data does not have attribute '{}'".format(k) setattr(self, k, v) - def _normalise_name(self, n): + def _normalise_field_name(self, n): return n.lower().replace('-', '_') + def _normalise_core_metadata_name(self, name): + # Normalized Names (PEP 503) + return re.sub(r"[-_.]+", "-", name).lower() + def write_metadata_file(self, fp): """Write out metadata in the email headers format""" fields = [ @@ -383,11 +387,11 @@ def write_metadata_file(self, fp): ] for field in fields: - value = getattr(self, self._normalise_name(field)) + value = getattr(self, self._normalise_field_name(field)) fp.write(u"{}: {}\n".format(field, value)) for field in optional_fields: - value = getattr(self, self._normalise_name(field)) + value = getattr(self, self._normalise_field_name(field)) if value is not None: # TODO: verify which fields can be multiline # The spec has multiline examples for Author, Maintainer & @@ -400,13 +404,15 @@ def write_metadata_file(self, fp): fp.write(u'Classifier: {}\n'.format(clsfr)) for req in self.requires_dist: - fp.write(u'Requires-Dist: {}\n'.format(req)) + normalised_req = self._normalise_core_metadata_name(req) + fp.write(u'Requires-Dist: {}\n'.format(normalised_req)) for url in self.project_urls: fp.write(u'Project-URL: {}\n'.format(url)) for extra in self.provides_extra: - fp.write(u'Provides-Extra: {}\n'.format(extra)) + normalised_extra = self._normalise_core_metadata_name(extra) + fp.write(u'Provides-Extra: {}\n'.format(normalised_extra)) if self.description is not None: fp.write(u'\n' + self.description + u'\n') From 547cd61f46c1cfd855ee2b45ef7135f9e636bdae Mon Sep 17 00:00:00 2001 From: Greg Roodt Date: Wed, 13 Mar 2024 21:11:15 +1100 Subject: [PATCH 3/5] . --- flit_core/flit_core/common.py | 20 ++++++++++- flit_core/flit_core/tests/test_common.py | 45 ++++++++++++++++++++++++ 2 files changed, 64 insertions(+), 1 deletion(-) diff --git a/flit_core/flit_core/common.py b/flit_core/flit_core/common.py index 327d0bff..0adafc06 100644 --- a/flit_core/flit_core/common.py +++ b/flit_core/flit_core/common.py @@ -366,6 +366,24 @@ def _normalise_core_metadata_name(self, name): # Normalized Names (PEP 503) return re.sub(r"[-_.]+", "-", name).lower() + def _extract_extras(self, req): + match = re.search(r'\[([^]]*)\]', req) + if match: + list_str = match.group(1) + return [item.strip() for item in list_str.split(',')] + else: + return None + + def _normalise_requires_dist(self, req): + extras = self._extract_extras(req) + if extras: + normalised_extras = [self._normalise_core_metadata_name(extra) for extra in extras] + normalised_extras_str = ', '.join(normalised_extras) + normalised_req = re.sub(r'\[([^]]*)\]', f"[{normalised_extras_str}]", req) + return normalised_req + else: + return req + def write_metadata_file(self, fp): """Write out metadata in the email headers format""" fields = [ @@ -404,7 +422,7 @@ def write_metadata_file(self, fp): fp.write(u'Classifier: {}\n'.format(clsfr)) for req in self.requires_dist: - normalised_req = self._normalise_core_metadata_name(req) + normalised_req = self._normalise_requires_dist(req) fp.write(u'Requires-Dist: {}\n'.format(normalised_req)) for url in self.project_urls: diff --git a/flit_core/flit_core/tests/test_common.py b/flit_core/flit_core/tests/test_common.py index b6d62905..87ba0f83 100644 --- a/flit_core/flit_core/tests/test_common.py +++ b/flit_core/flit_core/tests/test_common.py @@ -156,3 +156,48 @@ def test_metadata_multiline(tmp_path): assert msg['Version'] == d['version'] assert [l.lstrip() for l in msg['Author'].splitlines()] == d['author'].splitlines() assert not msg.defects + +@pytest.mark.parametrize( + ("requires_dist", "expected_result"), + [ + ('foo [extra_1, extra.2, extra-3, extra__4, extra..5, extra--6]', 'foo [extra-1, extra-2, extra-3, extra-4, extra-5, extra-6]'), + ('foo', 'foo'), + ('foo[bar]', 'foo[bar]'), + ], +) +def test_metadata_2_3_requires_dist(requires_dist, expected_result): + d = { + 'name': 'foo', + 'version': '1.0', + 'requires_dist': [requires_dist], + } + md = Metadata(d) + sio = StringIO() + md.write_metadata_file(sio) + sio.seek(0) + + msg = email.parser.Parser(policy=email.policy.compat32).parse(sio) + assert msg['Requires-Dist'] == expected_result + assert not msg.defects + +@pytest.mark.parametrize( + ("provides_extra", "expected_result"), + [ + ('foo', 'foo'), + ('foo__bar..baz', 'foo-bar-baz'), + ], +) +def test_metadata_2_3_provides_extra(provides_extra, expected_result): + d = { + 'name': 'foo', + 'version': '1.0', + 'provides_extra': [provides_extra], + } + md = Metadata(d) + sio = StringIO() + md.write_metadata_file(sio) + sio.seek(0) + + msg = email.parser.Parser(policy=email.policy.compat32).parse(sio) + assert msg['Provides-Extra'] == expected_result + assert not msg.defects \ No newline at end of file From 0dceb805ed1c744287344a73f327764e2ce6b5dc Mon Sep 17 00:00:00 2001 From: Greg Roodt Date: Wed, 13 Mar 2024 21:18:53 +1100 Subject: [PATCH 4/5] . --- flit_core/flit_core/tests/test_common.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/flit_core/flit_core/tests/test_common.py b/flit_core/flit_core/tests/test_common.py index 87ba0f83..824fa5de 100644 --- a/flit_core/flit_core/tests/test_common.py +++ b/flit_core/flit_core/tests/test_common.py @@ -163,6 +163,10 @@ def test_metadata_multiline(tmp_path): ('foo [extra_1, extra.2, extra-3, extra__4, extra..5, extra--6]', 'foo [extra-1, extra-2, extra-3, extra-4, extra-5, extra-6]'), ('foo', 'foo'), ('foo[bar]', 'foo[bar]'), + # https://packaging.python.org/en/latest/specifications/core-metadata/#requires-dist-multiple-use + ('pkginfo', 'pkginfo'), + ('zope.interface (>3.5.0)', 'zope.interface (>3.5.0)'), + ("pywin32 >1.0; sys_platform == 'win32'", "pywin32 >1.0; sys_platform == 'win32'"), ], ) def test_metadata_2_3_requires_dist(requires_dist, expected_result): @@ -200,4 +204,4 @@ def test_metadata_2_3_provides_extra(provides_extra, expected_result): msg = email.parser.Parser(policy=email.policy.compat32).parse(sio) assert msg['Provides-Extra'] == expected_result - assert not msg.defects \ No newline at end of file + assert not msg.defects From fcdfafd80b837229727a729ec19de269a649ff9d Mon Sep 17 00:00:00 2001 From: Thomas Kluyver Date: Tue, 30 Apr 2024 20:09:00 +0100 Subject: [PATCH 5/5] Add dynamic field to Metadata class --- flit_core/flit_core/common.py | 1 + 1 file changed, 1 insertion(+) diff --git a/flit_core/flit_core/common.py b/flit_core/flit_core/common.py index 0adafc06..6625224b 100644 --- a/flit_core/flit_core/common.py +++ b/flit_core/flit_core/common.py @@ -347,6 +347,7 @@ class Metadata(object): obsoletes_dist = () requires_external = () provides_extra = () + dynamic = () metadata_version = "2.3"