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

Cross-platform third-party stubs requirements install script #13482

Conversation

Avasam
Copy link
Collaborator

@Avasam Avasam commented Feb 9, 2025

I got tired of translating the bash script to powershell, so there you go.

As further steps it's probably possible to obsolete the get_external_stub_requirements and get_stubtest_system_requirements scripts entirely with a few modifications (like cli flags for "system vs local" install, "uv vs pip", and specifying third-party stubs to install from) to run such install scripts directly on the CI.

Copy link
Member

@AlexWaygood AlexWaygood left a comment

Choose a reason for hiding this comment

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

Nice

from ts_utils.requirements import get_external_stub_requirements

requirements = get_external_stub_requirements()
subprocess.check_call(("pip", "install", *[str(requirement) for requirement in requirements]))
Copy link
Member

@AlexWaygood AlexWaygood Feb 9, 2025

Choose a reason for hiding this comment

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

nit: we have uv as a dependency in requirements-tests.txt. I think the prior steps in the README would already have failed if you hadn't installed those dependencies, by the time you get to the instructions about this script on line 30

Suggested change
subprocess.check_call(("pip", "install", *[str(requirement) for requirement in requirements]))
subprocess.check_call(("uv", "pip", "install", *map(str,requirements)))

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I initially considered it. But we still have a handful of places where we use pip directly instead of uv. And last I checked, uv doesn't tend to respect the activated environment (or lack thereof if contributor wants to install to system Python). Which feels like a speedbump to newer contributors or those using custom venvs.

From our contributing guidelines:

$ python3 -m venv .venv
$ source .venv/bin/activate
(.venv)$ pip install -U pip
(.venv)$ pip install -r requirements-tests.txt

The current places where uv pip is used in tests is where temporary venvs are created anyway.

Copy link
Member

Choose a reason for hiding this comment

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

Hmm, I'm pretty sure it does respect the activated environment — if you have an example where it doesn't, that definitely sounds like a bug you should report! 😃 but you're right that some of the external requirements might not be PEP-517-compliant. So, probably best to stick with pip for now 👍

Copy link
Member

Choose a reason for hiding this comment

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

(FWIW it does seem like all the packages installed by this script are PEP-517 compliant and installable by uv)

Copy link
Collaborator Author

@Avasam Avasam Feb 9, 2025

Choose a reason for hiding this comment

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

Hmm, I'm pretty sure it does respect the activated environment — if you have an example where it doesn't, that definitely sounds like a bug you should report!

Looks like that may have just changed in 0.5.29. This is what I used to get: astral-sh/uv#1495 (comment)

So, probably best to stick with pip for now 👍

That being said, I wouldn't mind having a follow-up that updates all python -m pip, python3 -m pip, and pip usages in docs and scripts for uv pip. (except for pip install -r requirements-tests.txt because that's a bit of a catch-22)

Copy link
Member

Choose a reason for hiding this comment

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

Looks like that may have just changed in 0.5.29. This is what I used to get: astral-sh/uv#1495 (comment)

Oh, right. Yeah, it might not respect the activated environment for the "project API" commands like uv sync. It should always respect it for any uv pip commands though, I think?

Comment on lines +10 to +13
if __name__ == "__main__":
distributions = sys.argv[1:]
for requirement in sorted(get_external_stub_requirements(distributions), key=str):
print(requirement)
Copy link
Member

Choose a reason for hiding this comment

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

I think we could get rid of the mapfile usage in our workflows if we made a couple of tweaks here:

diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
index 32cd27c49..8e222aebf 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -47,7 +47,7 @@ jobs:
       - run: uv pip install -r requirements-tests.txt --system
       - name: Install external dependencies for 3rd-party stubs
         run: |
-          mapfile -t DEPENDENCIES < <( python tests/get_external_stub_requirements.py )
+          DEPENDENCIES=$( python tests/get_external_stub_requirements.py )
           if [ -n "$DEPENDENCIES" ]; then
               echo "Installing packages:"
               for DEP in "${DEPENDENCIES[@]}"; do echo "  ${DEP}"; done
@@ -108,7 +108,7 @@ jobs:
         run: uv venv .venv
       - name: Install 3rd-party stub dependencies
         run: |
-          mapfile -t DEPENDENCIES < <( python tests/get_external_stub_requirements.py )
+          DEPENDENCIES=$( python tests/get_external_stub_requirements.py )
           if [ -n "$DEPENDENCIES" ]; then
               echo "Installing packages:"
               for DEP in "${DEPENDENCIES[@]}"; do echo "  ${DEP}"; done
diff --git a/tests/get_external_stub_requirements.py b/tests/get_external_stub_requirements.py
index 177da48ab..144fd8478 100755
--- a/tests/get_external_stub_requirements.py
+++ b/tests/get_external_stub_requirements.py
@@ -8,6 +8,4 @@ import sys
 from ts_utils.requirements import get_external_stub_requirements
 
 if __name__ == "__main__":
-    distributions = sys.argv[1:]
-    for requirement in sorted(get_external_stub_requirements(distributions), key=str):
-        print(requirement)
+    print(" ".join(sorted(map(str, get_external_stub_requirements(sys.argv[1:])))))

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Sure, that's in line with where my changes are going. As mentioned in the PR description. I think the entire run code block could be replaced by a reusable python script.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

ugh, maybe getting rid of the mapfile usage isn't quite as easy as I thought. Sorry for the bother -- maybe just revert the last commit :-)

I figured it out ^^

@AlexWaygood
Copy link
Member

ugh, maybe getting rid of the mapfile usage isn't quite as easy as I thought. Sorry for the bother -- maybe just revert the last commit :-)

@AlexWaygood AlexWaygood merged commit c99e54d into python:main Feb 9, 2025
58 checks passed
@Avasam Avasam deleted the Cross-platform-third-party-stubs-requirements-install-script branch February 9, 2025 21:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants