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

Include environment variables in interpreter info caching #11601

Merged
merged 2 commits into from
Feb 19, 2025

Conversation

konstin
Copy link
Member

@konstin konstin commented Feb 18, 2025

We want to use sys.path for package discovery (#2500, #9849). For that, we need to know the correct value of sys.path. sys.path is a runtime-changeable value, which gets influenced from a lot of different sources: Environment variables, CLI arguments, .pth files with scripting, sys.path.append() at runtime, a distributor patching Python, etc. We cannot capture them all accurately, especially since it's possible to change sys.path mid-execution. Instead, we do a best effort attempt at matching the user's expectation.

The assumption is that package installation generally happens in venv site-packages, system/user site-packages (including pypy shipping packages with std), and PYTHONPATH. Specifically, we reuse PYTHONPATH as dedicated way for users to tell uv to include specific directories in package discovery.

A common way to influence sys.path that is not using venvs is setting PYTHONPATH. To support this we're capturing PYTHONPATH as part of the cache invalidation, i.e. we refresh the interpreter metadata if it changed. For completeness, we're also capturing other environment variables documented as influencing sys.path or other fields in the interpreter info.

This PR does not include reading registry values for sys.path additions on Windows as documented in https://docs.python.org/3.11/using/windows.html#finding-modules. It notably also does not include parsing of python CLI arguments, we only consider their environment variable versions for package installation and listing. We could try parsing CLI flags in uv run python, but we'd still miss them when Python is launched indirectly through a script, and it's more consistent to only consider uv's own arguments and environment variables, similar to uv's behavior in other places.

@konstin konstin added the enhancement New feature or improvement to existing functionality label Feb 18, 2025
Comment on lines 740 to 748
Self {
pythonhome: env::var_os("PYTHONHOME"),
pythonpath: env::var_os("PYTHONPATH"),
pythonsafepath: env::var_os("PYTHONSAFEPATH"),
pythonplatlibdir: env::var_os("PYTHONPLATLIBDIR"),
pythonnousersite: env::var_os("PYTHONNOUSERSITE"),
pythonuserbase: env::var_os("PYTHONUSERBASE"),
appdata: env::var_os("APPDATA"),
home: env::var_os("HOME"),
Copy link
Member

@zanieb zanieb Feb 18, 2025

Choose a reason for hiding this comment

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

Technically, we should add all these to the static EnvVars declarations so we can document what we read these for. Could you do that please?

Copy link
Member Author

Choose a reason for hiding this comment

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

oops, good catch!

We want to use `sys.path` for package discovery (#2500, #9849). For that, we need to know the correct value of `sys.path`. `sys.path` is a runtime-changeable value, which gets influenced from a lot of different sources: Environment variables, CLI arguments, `.pth` files with scripting, `sys.path.append()` at runtime, etc. We cannot capture them all accurately, especially since it's possible to change `sys.path` mid-execution. Instead, we do a best effort attempt at matching the user's expectation.

A common way to influence `sys.path` that is not using venvs is setting `PYTHONPATH`. To support this we're capturing `PYTHONPATH` as part of the cache invalidation, i.e. we refresh the interpreter metadata if it changed. For completeness, we're also capturing other environment variables documented as influencing `sys.path` or other fields in the interpreter info.

This PR does not include reading registry values for `sys.path` additions on Windows as documented in https://docs.python.org/3.11/using/windows.html#finding-modules. It notably also does not include parsing of python CLI arguments, we only consider their environment variable versions for package installation and listing. We could try parsing CLI flags in `uv run python`, but we'd still miss them when Python is launched indirectly through a script, and it's more consistent to only consider uv's own arguments and environment variables, similar to uv's behavior in other places.
@konstin konstin force-pushed the konsti/cache-python-interpreter-by-env-vars branch from 02a8350 to 07be9ce Compare February 19, 2025 10:01
@konstin konstin enabled auto-merge (squash) February 19, 2025 10:03
@konstin konstin merged commit da30cc4 into main Feb 19, 2025
70 of 72 checks passed
@konstin konstin deleted the konsti/cache-python-interpreter-by-env-vars branch February 19, 2025 10:10
konstin added a commit that referenced this pull request Feb 19, 2025
konstin added a commit that referenced this pull request Feb 19, 2025
zanieb pushed a commit that referenced this pull request Feb 19, 2025
…1622)

Revert #11601 for now

We run Python interpreter discovery with `-I` (#2500) which means these
environments variables are ignored when determining `sys.path`. Unless
we decide to remove the `-I` flag from the `sys.path` query, we
shouldn't release these changes to interpreter discovery caching.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or improvement to existing functionality
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants