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

Support installing requirements from inline script metadata (PEP 723) #13052

Open
wants to merge 15 commits into
base: main
Choose a base branch
from

Conversation

SnoopJ
Copy link
Contributor

@SnoopJ SnoopJ commented Oct 28, 2024

This changeset adds support for installing requirements declared in a script using inline metadata as defined by PEP 723

I'm sure this still needs changes, but I'm at the point where I'm ready for a maintainer to point out to me how much I've missed 😅

Closes #12891

Comment on lines +280 to +304
if options.scripts:
if len(options.scripts) > 1:
raise CommandError("--script can only be given once")

script = options.scripts[0]
script_metadata = pep723_metadata(script)

script_requires_python = script_metadata.get("requires-python", "")

if script_requires_python and not options.ignore_requires_python:
target_python = make_target_python(options)

if not check_requires_python(
requires_python=script_requires_python,
version_info=target_python.py_version_info,
):
raise UnsupportedPythonVersion(
f"Script {script!r} requires a different Python: "
f"{target_python.py_version} not in {script_requires_python!r}"
)

for req in script_metadata.get("dependencies", []):
requirements.append(
InstallRequirement(Requirement(req), comes_from=None)
)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It feels ungraceful to put all of this logic here but I'm not really sure how I would plumb it into a separate function. Suggestions welcome

Comment on lines +301 to +302
for req in script_metadata.get("dependencies", []):
requirements.append(
Copy link
Contributor Author

@SnoopJ SnoopJ Oct 28, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ruff is upset that I wrote a loop with .append() here (PERF401) but I don't know if a comprehension would really be justified here? I can maybe see the case for requirements.extend(...) but it still seems like it'd be harder to read to me. Looking for feedback.

Edit: here's a diff of the extend() version that passes the new tests:

diff --git a/src/pip/_internal/cli/req_command.py b/src/pip/_internal/cli/req_command.py
index 294dc9f40..1f972eba4 100644
--- a/src/pip/_internal/cli/req_command.py
+++ b/src/pip/_internal/cli/req_command.py
@@ -298,10 +298,10 @@ class RequirementCommand(IndexGroupCommand):
                         f"{target_python.py_version} not in {script_requires_python!r}"
                     )

-            for req in script_metadata.get("dependencies", []):
-                requirements.append(
-                    InstallRequirement(Requirement(req), comes_from=None)
-                )
+            requirements.extend(
+                InstallRequirement(Requirement(req), comes_from=None)
+                for req in script_metadata.get("dependencies", [])
+            )

         # If any requirement has hash options, enable hash checking.
         if any(req.has_hash_options for req in requirements):

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

PEP 723 support
1 participant