diff --git a/tests/tools/wheelmaker_test.py b/tests/tools/wheelmaker_test.py index 288dde720a..85094af9b8 100644 --- a/tests/tools/wheelmaker_test.py +++ b/tests/tools/wheelmaker_test.py @@ -71,5 +71,41 @@ def test_arcname_from(self) -> None: self.assertEqual(got, want) +class GetNewRequirementLineTest(unittest.TestCase): + def test_requirement(self): + result = wheelmaker.get_new_requirement_line("requests>=2.0", "") + self.assertEqual(result, "Requires-Dist: requests>=2.0") + + def test_requirement_and_extra(self): + result = wheelmaker.get_new_requirement_line("requests>=2.0", "extra=='dev'") + self.assertEqual(result, "Requires-Dist: requests>=2.0; extra=='dev'") + + def test_requirement_with_url(self): + result = wheelmaker.get_new_requirement_line( + "requests @ git+https://github.com/psf/requests.git@3aa6386c3", "" + ) + self.assertEqual( + result, + "Requires-Dist: requests @ git+https://github.com/psf/requests.git@3aa6386c3", + ) + + def test_requirement_with_marker(self): + result = wheelmaker.get_new_requirement_line( + "requests>=2.0; python_version>='3.6'", "" + ) + self.assertEqual( + result, 'Requires-Dist: requests>=2.0; python_version >= "3.6"' + ) + + def test_requirement_with_marker_and_extra(self): + result = wheelmaker.get_new_requirement_line( + "requests>=2.0; python_version>='3.6'", "extra=='dev'" + ) + self.assertEqual( + result, + "Requires-Dist: requests>=2.0; (python_version >= \"3.6\") and extra=='dev'", + ) + + if __name__ == "__main__": unittest.main() diff --git a/tools/wheelmaker.py b/tools/wheelmaker.py index 4390df3445..7124ae7c9d 100644 --- a/tools/wheelmaker.py +++ b/tools/wheelmaker.py @@ -330,9 +330,7 @@ def add_wheelfile(self): Wheel-Version: 1.0 Generator: bazel-wheelmaker 1.0 Root-Is-Purelib: {} -""".format( - "true" if self._platform == "any" else "false" - ) +""".format("true" if self._platform == "any" else "false") for tag in self.disttags(): wheel_contents += "Tag: %s\n" % tag self._whlfile.add_string(self.distinfo_path("WHEEL"), wheel_contents) @@ -365,6 +363,32 @@ def get_files_to_package(input_files): return files +def get_new_requirement_line(reqs_text: str, extra: str) -> str: + """Formats a requirement text into a Requires-Dist metadata line.""" + from packaging.requirements import Requirement + + req = Requirement(reqs_text.strip()) + req_extra_deps = f"[{','.join(req.extras)}]" if req.extras else "" + + # Handle URL requirements (PEP 508) + if req.url: + req_spec = f" @ {req.url}" + else: + req_spec = str(req.specifier) + + base = f"Requires-Dist: {req.name}{req_extra_deps}{req_spec}" + + if req.marker: + if extra: + return f"{base}; ({req.marker}) and {extra}" + else: + return f"{base}; {req.marker}" + elif extra: + return f"{base}; {extra}" + else: + return base + + def resolve_argument_stamp( argument: str, volatile_status_stamp: Path, stable_status_stamp: Path ) -> str: @@ -430,7 +454,7 @@ def parse_args() -> argparse.Namespace: output_group.add_argument( "--name_file", type=Path, - help="A file where the canonical name of the " "wheel will be written", + help="A file where the canonical name of the wheel will be written", ) output_group.add_argument( @@ -578,19 +602,6 @@ def main() -> None: # Search for any `Requires-Dist` entries that refer to other files and # expand them. - def get_new_requirement_line(reqs_text, extra): - req = Requirement(reqs_text.strip()) - req_extra_deps = f"[{','.join(req.extras)}]" if req.extras else "" - if req.marker: - if extra: - return f"Requires-Dist: {req.name}{req_extra_deps}{req.specifier}; ({req.marker}) and {extra}" - else: - return f"Requires-Dist: {req.name}{req_extra_deps}{req.specifier}; {req.marker}" - else: - return f"Requires-Dist: {req.name}{req_extra_deps}{req.specifier}; {extra}".strip( - " ;" - ) - for meta_line in metadata.splitlines(): if not meta_line.startswith("Requires-Dist: "): continue