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

Discover and prefer the parent interpreter when invoked with python -m uv #3736

Merged
merged 2 commits into from
May 22, 2024

Conversation

zanieb
Copy link
Member

@zanieb zanieb commented May 22, 2024

Closes #2222
Closes #2058
Replaces #2338
See also #2649

We use an environment variable (UV_INTERNAL__PARENT_INTERPRETER) to track the invoking interpreter when python -m uv is used. The parent interpreter is preferred over all other sources (though it will be skipped if it does not meet a --python request or if --system is used and it belongs to a virtual environment). We warn if --system is not provided and this interpreter would mutate system packages, but allow it.

@zanieb zanieb added the enhancement New feature or request label May 22, 2024
@zanieb zanieb changed the title Discover and prefer the parent interpreter when invoked with python -m uv ... Discover and prefer the parent interpreter when invoked with python -m uv May 22, 2024
@zanieb zanieb marked this pull request as ready for review May 22, 2024 14:18
@@ -1053,22 +1063,16 @@ impl SourceSelector {
InterpreterSource::SearchPath,
InterpreterSource::PyLauncher,
InterpreterSource::ManagedToolchain,
InterpreterSource::ParentInterpreter,
Copy link
Member Author

Choose a reason for hiding this comment

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

This is in the SystemPython::Required clause. Maybe I should move it out? This may be a bit weird if you do ./.venv/bin/python -m uv pip install --system as we'll still find this Python... but also a bit weird if you do /sys/python -m uv --system and we find a different Python?

Copy link
Member Author

Choose a reason for hiding this comment

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

I think I can fix this with some changes to discovery

Copy link
Member

Choose a reason for hiding this comment

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

Is the ideal behavior that:

  • ./.venv/bin/python -m uv pip install --system does not find .venv/bin/python
  • /sys/python -m uv --system does find /sys/python

?

Copy link
Member Author

Choose a reason for hiding this comment

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

I think so yea. With #3739 this will be possible

Copy link
Member Author

Choose a reason for hiding this comment

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

(rebasing this onto that now)

Copy link
Member Author

Choose a reason for hiding this comment

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

The behavior should be as described now, I'll do some QA.

@@ -31,6 +31,9 @@ def _run() -> None:
if venv:
env.setdefault("VIRTUAL_ENV", venv)

# Let `uv` know that it was spawned by this Python interpreter
env["UV__PARENT_INTERPRETER"] = sys.executable
Copy link
Member

Choose a reason for hiding this comment

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

Can we use something other than the double underscore, like a name that is so long that no one likes to use it outside that script?

Copy link
Member Author

Choose a reason for hiding this comment

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

I feel like the double underscore is sufficient for saying it's not user facing and we're not going to document or support it elsewhere. Idk about making the name arbitrarily longer.... I guess I could do UV_PRIVATE__...?

Copy link
Member Author

Choose a reason for hiding this comment

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

Added more suffix

@zanieb zanieb changed the base branch from main to zb/filter-system-preferences May 22, 2024 16:05
Base automatically changed from zb/filter-system-preferences to main May 22, 2024 16:22
zanieb added a commit that referenced this pull request May 22, 2024
Previously, we enforced `SystemPython` outside of the interpreter
discovery exclusively with source selection. Now, we perform additional
filtering of interpreters depending on if they are a virtual
environment. This should not change any existing behavior, but will make
it much easier to have consistent behavior in ambiguous cases like
#3736 (comment) where a
source could provide either a system interpreter or virtual environment
interpreter.
Comment on lines +65 to 69
/// Only allow a system Python if passed directly i.e. via [`InterpreterSource::ProvidedPath`] or [`InterpreterSource::ParentInterpreter`]
#[default]
Explicit,
/// Do not allow a system Python
Disallowed,
Copy link
Member Author

Choose a reason for hiding this comment

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

I decided to add an Explicit variant to avoid confusing internal behavior where SystemPython::Disallowed could still get a system Python from this environment variable.

# Conflicts:
#	crates/uv-interpreter/src/discovery.rs
@zanieb
Copy link
Member Author

zanieb commented May 22, 2024

e.g.

❯ RUST_LOG=uv=trace ./uv/.venv/bin/python -m uv -v pip install anyio
TRACE Cached interpreter info for Python 3.12.3, skipping probing: uv/.venv/bin/python
TRACE Found Python interpreter cpython 3.12.3 at /Users/zb/workspace/uv/.venv/bin/python from parent interpreter
DEBUG Using Python 3.12.3 environment at uv/.venv/bin/python
DEBUG Trying to lock if free: uv/.venv/.lock
TRACE Comparing installed with source: Registry(InstalledRegistryDist { name: PackageName("anyio"), version: "4.3.0", path: "/Users/zb/workspace/uv/.venv/lib/python3.12/site-packages/anyio-4.3.0.dist-info" }) Registry { specifier: VersionSpecifiers([]), index: None }
TRACE Comparing installed with source: Registry(InstalledRegistryDist { name: PackageName("sniffio"), version: "1.3.1", path: "/Users/zb/workspace/uv/.venv/lib/python3.12/site-packages/sniffio-1.3.1.dist-info" }) Registry { specifier: VersionSpecifiers([VersionSpecifier { operator: GreaterThanEqual, version: "1.1" }]), index: None }
TRACE Comparing installed with source: Registry(InstalledRegistryDist { name: PackageName("idna"), version: "3.7", path: "/Users/zb/workspace/uv/.venv/lib/python3.12/site-packages/idna-3.7.dist-info" }) Registry { specifier: VersionSpecifiers([VersionSpecifier { operator: GreaterThanEqual, version: "2.8" }]), index: None }
DEBUG Requirement satisfied: anyio
DEBUG Requirement satisfied: idna>=2.8
DEBUG Requirement satisfied: sniffio>=1.1
DEBUG All editables satisfied: 
Audited 1 package in 1ms
❯ RUST_LOG=uv=trace ./uv/.venv/bin/python -m uv -v pip install anyio --system
TRACE Searching PATH for executables: python3, python
TRACE Checking `PATH` directory for interpreters: /Users/zb/bin
TRACE Checking `PATH` directory for interpreters: /Users/zb/.local/bin
TRACE Checking `PATH` directory for interpreters: /Users/zb/.cargo/bin
TRACE Checking `PATH` directory for interpreters: /opt/homebrew/bin
TRACE Found possible Python executable: /opt/homebrew/bin/python3
TRACE Cached interpreter info for Python 3.12.3, skipping probing: /opt/homebrew/bin/python3
TRACE Found Python interpreter cpython 3.12.3 at /opt/homebrew/bin/python3 from search path
DEBUG Using Python 3.12.3 environment at /opt/homebrew/opt/[email protected]/bin/python3.12
error: The interpreter at /opt/homebrew/opt/[email protected]/Frameworks/Python.framework/Versions/3.12 is externally managed, and indicates the following:
❯ ./uv/.venv/bin/python -m uv -v pip install anyio --python 3.10
INFO Found active virtual environment (via VIRTUAL_ENV) at: /Users/zb/workspace/uv/.venv
DEBUG Ignoring Python interpreter at `/Users/zb/workspace/uv/bin/cpython-3.10.13-macos-aarch64-none/install/bin/python3`: system intepreter not explicit
DEBUG Ignoring Python interpreter at `/opt/homebrew/opt/[email protected]/bin/python3.12`: system intepreter not explicit
DEBUG Ignoring Python interpreter at `/Library/Developer/CommandLineTools/usr/bin/python3`: system intepreter not explicit
DEBUG Ignoring Python interpreter at `/opt/homebrew/opt/[email protected]/bin/python3.12`: system intepreter not explicit
error: No interpreter found for Python 3.10 in all sources
❯ /opt/homebrew/bin/python3 -m uv -v pip install anyio
DEBUG Allowing system Python interpreter at `/opt/homebrew/opt/[email protected]/bin/python3.12`
DEBUG Using Python 3.12.3 environment at /opt/homebrew/opt/[email protected]/bin/python3.12

@zanieb zanieb merged commit 5fe8910 into main May 22, 2024
44 checks passed
@zanieb zanieb deleted the zb/parent-interp branch May 22, 2024 16:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
3 participants