@@ -10,42 +10,56 @@ to a uv-managed python consistent with your project’s `.python-version`
1010
1111This project provides:
1212
13- * ` python ` — a shim script that intercepts ` python ` /` python3.* ` invocations
13+ - ` python ` — a shim script that intercepts ` python ` /` python3.* ` invocations
1414 and resolves an appropriate interpreter using ` uv python find ` .
15- * ` install.bash ` — an installer that copies the shim to ` ~/.local/uv-python-shims/ `
15+ - ` install.bash ` — an installer that copies the shim to ` ~/.local/uv-python-shims/ `
1616 and creates symlinks for ` python3 ` and a set of ` python3.X ` names.
17- * ` tests/ ` — a lightweight bash test harness with mock ` uv ` + mock “python”
17+ - ` tests/ ` — a lightweight bash test harness with mock ` uv ` + mock “python”
1818 executables.
1919
2020References:
2121
22- * ` pyenv `
22+ - ` pyenv `
2323 https://github.com/pyenv/pyenv
2424
25- * ` uv python find `
25+ - ` uv python find `
2626 https://docs.astral.sh/uv/concepts/python-versions/#finding-a-python-executable
2727
2828
2929## The main shim (` ./python ` )
3030
3131** Requires:** ` bash ` and ` uv ` installed and on your ` PATH `
3232
33- * Runs ` uv python find ` to locate the best Python interpreter for the current
34- working directory (uv walks upward looking for project metadata, including
35- ` .python-version ` ).
33+ The shim runs ` uv python find ` to locate the best Python interpreter for the current
34+ working directory:
35+
36+ * The find operation first looks for any python version constraints defined
37+ within a ` .python-version ` file or a project/workspace ` pyproject.toml ` file
38+ within the current directory or any parent directories.
3639
37- * If the shim is invoked via a symlink with a versioned name like ` python3.10 `
38- or ` python3.14 ` , it enforces that ** major.minor** :
40+ * It then searches the following locations ** in order** until it finds the
41+ first available python that satisfies the version constraints (or the first
42+ one found if there are no constraints):
43+ 1 . Closest non-activated virtual environment (activated environments bypass
44+ the shim entirely so they are always selected with no version constraints).
45+ 2 . UV-managed python installations in order from newest to oldest versions.
46+ 3 . The first suitable python found on the ` PATH ` .
3947
40- * It checks what ` uv ` would pick by default .
41- * If the resolved interpreter does not match the requested ` 3.X ` , it reruns
42- ` uv python find 3.X ` and uses that interpreter instead .
48+ * If a suitable python is found, that python is executed via its absolute path .
49+ If a suitable python can NOT be found, the script will exit and display the
50+ error message given by uv .
4351
44- * Avoids recursion:
52+ If the shim is invoked via a symlink with a versioned name like ` python3.10 `
53+ or ` python3.14 ` , it enforces that ** major.minor** . It does this by first checking
54+ what ` uv ` would pick by default and if the resolved interpreter does not match
55+ the requested ` 3.X ` , it reruns ` uv python find 3.X ` and uses that interpreter instead.
4556
46- * Removes the shim directory from ` PATH ` when invoking ` uv ` so ` uv ` won’t
47- discover and re-run the shim as a candidate interpreter.
48- * Executes the resolved interpreter via an absolute path.
57+ When invoking ` uv ` and executing the resolved python interpreter, the shim avoids
58+ recursion by removing the shim directory from ` PATH ` .
59+
60+ There are a number of possible configuration flags that can modify the behavior
61+ of ` uv python find ` . See the commented-out section near the top of the shim script
62+ and uncomment the flags desired to control python discovery.
4963
5064
5165## Install main shim and symlinks
@@ -72,8 +86,8 @@ export PATH="$HOME/.local/uv-python-shims:$PATH"
7286
7387Common locations:
7488
75- * bash: ` ~/.bashrc ` (and/or ` ~/.bash_profile ` )
76- * zsh: ` ~/.zshrc `
89+ - bash: ` ~/.bashrc ` (and/or ` ~/.bash_profile ` )
90+ - zsh: ` ~/.zshrc `
7791
7892Then restart your shell, or run the export line once in your current session.
7993
@@ -86,12 +100,22 @@ python --version
86100python3.11 --version
87101```
88102
89- If you have a ` .python-version ` in a directory, try running from inside it and
90- from a subdirectory to confirm uv project discovery behaves as expected.
103+ If you have a ` .python-version ` in a directory, try running from inside that
104+ directory and from a subdirectory to confirm *** .python-version discovery***
105+ behaves as expected.
106+
107+ If you have a project or workspace defined with a ` pyproject.toml ` that includes
108+ a ` requires-python ` field, try running within that project directory or from a
109+ subdirectory to confirm *** project/workspace discovery*** behaves as expected.
110+
111+ If you have a non-activated virtual environment installed in a ` .venv ` subdirectory
112+ of a project, try running within the project directory or a subdirectory of that
113+ project to confirm *** virtual environment discovery*** behaves as expected.
114+
91115
92116### Installer knobs
93117
94- You can override the install destination or UI pacing:
118+ You can override the install destination or pacing:
95119
96120``` bash
97121DEST_DIR=" $HOME /.local/uv-python-shims" bash ./install.bash
@@ -112,9 +136,9 @@ The tests are written in bash and do **not** require a real `uv` install.
112136
113137They work by:
114138
115- * copying the shim under test into a temp directory
116- * placing mock stubs on ` PATH ` (` tests/bin/uv ` , plus fake interpreters)
117- * asserting calls/behavior via logs and captured output
139+ - copying the shim under test into a temp directory
140+ - placing mock stubs on ` PATH ` (` tests/bin/uv ` , plus fake interpreters)
141+ - asserting calls/behavior via logs and captured output
118142
119143From the project root:
120144
@@ -162,14 +186,23 @@ python version switching to be less coupled from project management.
162186
163187## Notes and caveats
164188
165- * This shim delegates nearly all “what Python should I use?” logic to ` uv ` .
189+ - ** Caution:** ` uv-python-shim ` should NOT be used as a solution for auto-activating
190+ a project's virtual environment. It's not suitable for that task. This shim will
191+ only auto-discover the environment's python interpreter and will not directly
192+ expose any other executables within that environment. Either manually activate
193+ using the mechanism recommended for your environment manager, or possibly auto-activate
194+ the environment with a solution like ` direnv ` or ` mise ` .
195+
196+ - This shim delegates nearly all “what Python should I use?” logic to ` uv ` .
166197 If ` uv ` changes discovery rules or output formats, the shim may need tweaks.
167198
168- * The ` python3.X ` behavior is intentionally “major.minor enforcement” (not micro/patch).
199+ - The ` python3.X ` behavior is intentionally “major.minor enforcement” (not micro/patch).
169200
170- * If you also want shims for other tools (` pip ` , ` pytest ` , etc.), it should be
201+ - If you also want shims for other tools (` pip ` , ` pytest ` , etc.), it should be
171202 straightforward to add siblings that run ` "$resolved_python" -m pip ... ` or similar.
172- I don't need this so I didn't bother adding it.
203+ I don't need this so I didn't bother adding it. Also check the "Caution"
204+ note above. If you need more than just a python shim, you probably would do better
205+ with a different solution.
173206
174207## License
175208
0 commit comments