From 807ab8aac8a4fd8ccb31d0bd2349415e77e70c90 Mon Sep 17 00:00:00 2001 From: Anderson Bravalheri Date: Wed, 8 Mar 2023 19:00:27 +0000 Subject: [PATCH] Add Requires-Dist to PKG-INFO --- setuptools/_core_metadata.py | 55 ++++++++++++++++++++++++++++++++++-- setuptools/dist.py | 4 +++ 2 files changed, 56 insertions(+), 3 deletions(-) diff --git a/setuptools/_core_metadata.py b/setuptools/_core_metadata.py index aa96fa9d01..bfa7a3374c 100644 --- a/setuptools/_core_metadata.py +++ b/setuptools/_core_metadata.py @@ -10,6 +10,10 @@ from distutils.util import rfc822_escape +from . import _normalization +from ._deprecation_warning import SetuptoolsDeprecationWarning +from .extern.packaging.markers import Marker +from .extern.packaging.requirements import Requirement from .extern.packaging.version import Version from .warnings import SetuptoolsDeprecationWarning @@ -175,14 +179,59 @@ def write_field(key, value): # PEP 566 if self.long_description_content_type: write_field('Description-Content-Type', self.long_description_content_type) - if self.provides_extras: - for extra in self.provides_extras: - write_field('Provides-Extra', extra) self._write_list(file, 'License-File', self.license_files or []) + _write_requirements(self, file) long_description = self.get_long_description() if long_description: file.write("\n%s" % long_description) if not long_description.endswith("\n"): file.write("\n") + + +def _write_requirements(self, file): + for req in self.install_requires: + file.write(f"Requires-Dist: {req}\n") + + processed_extras = {} + for augmented_extra, reqs in self.extras_require.items(): + # Historically, setuptools allows "augmented extras": `:` + unsafe_extra, _, condition = augmented_extra.partition(":") + unsafe_extra = unsafe_extra.strip() + extra = _normalization.safe_extra(unsafe_extra) + + if extra: + _write_provides_extra(file, processed_extras, extra, unsafe_extra) + for req in reqs: + r = _include_extra(req, extra, condition.strip()) + file.write(f"Requires-Dist: {r}\n") + + return processed_extras + + +def _include_extra(req: str, extra: str, condition: str) -> Requirement: + r = Requirement(req) + parts = ( + f"({r.marker})" if r.marker else None, + f"({condition})" if condition else None, + f"extra == {extra!r}" if extra else None, + ) + r.marker = Marker(" and ".join(x for x in parts if x)) + return r + + +def _write_provides_extra(file, processed_extras, safe, unsafe): + previous = processed_extras.get(safe) + if previous == unsafe: + msg = f"""Ambiguity during "extra" normalization for dependencies.\n\n + ******************************************************************** + {previous!r} and {unsafe!r} normalize to the same value:\n + {safe!r}\n + In future versions, setuptools might halt the build process. + ********************************************************************\n\n + """ + warnings.warn(msg, SetuptoolsDeprecationWarning, stacklevel=3) + else: + processed_extras[safe] = unsafe + file.write(f"Provides-Extra: {safe}\n") diff --git a/setuptools/dist.py b/setuptools/dist.py index fd2543febd..445c3a6856 100644 --- a/setuptools/dist.py +++ b/setuptools/dist.py @@ -263,6 +263,8 @@ class Distribution(_Distribution): 'provides_extras': OrderedSet, 'license_file': lambda: None, 'license_files': lambda: None, + 'install_requires': list, + 'extras_require': dict, } _patched_dist = None @@ -389,6 +391,8 @@ def _finalize_requires(self): self.metadata.python_requires = self.python_requires self._normalize_requires() + self.metadata.install_requires = self.install_requires + self.metadata.extras_require = self.extras_require if self.extras_require: for extra in self.extras_require.keys():