python-discovery 1.4.4__tar.gz → 1.5.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {python_discovery-1.4.4 → python_discovery-1.5.3}/.github/dependabot.yaml +6 -1
- {python_discovery-1.4.4 → python_discovery-1.5.3}/.github/workflows/check.yaml +27 -5
- {python_discovery-1.4.4 → python_discovery-1.5.3}/.github/workflows/prepare-release.yaml +2 -11
- {python_discovery-1.4.4 → python_discovery-1.5.3}/.github/workflows/release.yaml +3 -7
- {python_discovery-1.4.4 → python_discovery-1.5.3}/.pre-commit-config.yaml +17 -10
- {python_discovery-1.4.4 → python_discovery-1.5.3}/PKG-INFO +6 -16
- {python_discovery-1.4.4 → python_discovery-1.5.3}/README.md +3 -0
- {python_discovery-1.4.4 → python_discovery-1.5.3}/docs/changelog.rst +43 -0
- {python_discovery-1.4.4 → python_discovery-1.5.3}/docs/conf.py +5 -1
- {python_discovery-1.4.4 → python_discovery-1.5.3}/docs/explanation.rst +79 -34
- {python_discovery-1.4.4 → python_discovery-1.5.3}/pyproject.toml +63 -50
- {python_discovery-1.4.4 → python_discovery-1.5.3}/src/python_discovery/_cache.py +5 -5
- {python_discovery-1.4.4 → python_discovery-1.5.3}/src/python_discovery/_cached_py_info.py +69 -33
- {python_discovery-1.4.4 → python_discovery-1.5.3}/src/python_discovery/_discovery.py +149 -22
- {python_discovery-1.4.4 → python_discovery-1.5.3}/src/python_discovery/_py_info.py +60 -304
- python_discovery-1.5.3/src/python_discovery/_py_info_collect.py +370 -0
- {python_discovery-1.4.4 → python_discovery-1.5.3}/src/python_discovery/_py_spec.py +3 -3
- {python_discovery-1.4.4 → python_discovery-1.5.3}/src/python_discovery/_specifier.py +9 -6
- {python_discovery-1.4.4 → python_discovery-1.5.3}/src/python_discovery/_windows/_pep514.py +11 -11
- python_discovery-1.5.3/tasks/old_target_check.py +45 -0
- python_discovery-1.5.3/tasks/old_target_check.sh +8 -0
- {python_discovery-1.4.4 → python_discovery-1.5.3}/tasks/release.py +35 -35
- {python_discovery-1.4.4 → python_discovery-1.5.3}/tests/py_info/test_py_info.py +17 -21
- {python_discovery-1.4.4 → python_discovery-1.5.3}/tests/test_cached_py_info.py +97 -1
- {python_discovery-1.4.4 → python_discovery-1.5.3}/tests/test_discovery.py +134 -62
- python_discovery-1.5.3/tests/test_iter_interpreters.py +423 -0
- python_discovery-1.5.3/tests/test_py_info_collect.py +333 -0
- {python_discovery-1.4.4 → python_discovery-1.5.3}/tests/test_py_info_extra.py +4 -222
- {python_discovery-1.4.4 → python_discovery-1.5.3}/tests/test_specifier.py +5 -5
- {python_discovery-1.4.4 → python_discovery-1.5.3}/tests/windows/conftest.py +1 -1
- {python_discovery-1.4.4 → python_discovery-1.5.3}/tox.toml +4 -4
- python_discovery-1.4.4/tests/test_iter_interpreters.py +0 -218
- {python_discovery-1.4.4 → python_discovery-1.5.3}/.github/FUNDING.yaml +0 -0
- {python_discovery-1.4.4 → python_discovery-1.5.3}/.github/SECURITY.md +0 -0
- {python_discovery-1.4.4 → python_discovery-1.5.3}/.github/release.yaml +0 -0
- {python_discovery-1.4.4 → python_discovery-1.5.3}/.gitignore +0 -0
- {python_discovery-1.4.4 → python_discovery-1.5.3}/.readthedocs.yaml +0 -0
- {python_discovery-1.4.4 → python_discovery-1.5.3}/.readthedocs.yml +0 -0
- {python_discovery-1.4.4 → python_discovery-1.5.3}/CODE_OF_CONDUCT.md +0 -0
- {python_discovery-1.4.4 → python_discovery-1.5.3}/LICENSE +0 -0
- {python_discovery-1.4.4 → python_discovery-1.5.3}/docs/_static/custom.css +0 -0
- {python_discovery-1.4.4 → python_discovery-1.5.3}/docs/_static/logo.svg +0 -0
- {python_discovery-1.4.4 → python_discovery-1.5.3}/docs/changelog/template.jinja2 +0 -0
- {python_discovery-1.4.4 → python_discovery-1.5.3}/docs/how-to/standalone-usage.rst +0 -0
- {python_discovery-1.4.4 → python_discovery-1.5.3}/docs/index.rst +0 -0
- {python_discovery-1.4.4 → python_discovery-1.5.3}/docs/reference/api.rst +0 -0
- {python_discovery-1.4.4 → python_discovery-1.5.3}/docs/reference/environment-variables.rst +0 -0
- {python_discovery-1.4.4 → python_discovery-1.5.3}/docs/tutorial/getting-started.rst +0 -0
- {python_discovery-1.4.4 → python_discovery-1.5.3}/src/python_discovery/__init__.py +0 -0
- {python_discovery-1.4.4 → python_discovery-1.5.3}/src/python_discovery/_compat.py +0 -0
- {python_discovery-1.4.4 → python_discovery-1.5.3}/src/python_discovery/_windows/__init__.py +0 -0
- {python_discovery-1.4.4 → python_discovery-1.5.3}/src/python_discovery/_windows/_propose.py +0 -0
- {python_discovery-1.4.4 → python_discovery-1.5.3}/src/python_discovery/py.typed +0 -0
- {python_discovery-1.4.4 → python_discovery-1.5.3}/tests/conftest.py +0 -0
- {python_discovery-1.4.4 → python_discovery-1.5.3}/tests/py_info/test_py_info_exe_based_of.py +0 -0
- {python_discovery-1.4.4 → python_discovery-1.5.3}/tests/test_cache.py +0 -0
- {python_discovery-1.4.4 → python_discovery-1.5.3}/tests/test_discovery_extra.py +0 -0
- {python_discovery-1.4.4 → python_discovery-1.5.3}/tests/test_py_spec.py +0 -0
- {python_discovery-1.4.4 → python_discovery-1.5.3}/tests/test_py_spec_extra.py +0 -0
- {python_discovery-1.4.4 → python_discovery-1.5.3}/tests/windows/test_windows.py +0 -0
- {python_discovery-1.4.4 → python_discovery-1.5.3}/tests/windows/test_windows_pep514.py +0 -0
- {python_discovery-1.4.4 → python_discovery-1.5.3}/tests/windows/winreg_mock_values.py +0 -0
|
@@ -7,14 +7,11 @@ on:
|
|
|
7
7
|
pull_request:
|
|
8
8
|
schedule:
|
|
9
9
|
- cron: "0 8 * * *"
|
|
10
|
-
|
|
11
10
|
concurrency:
|
|
12
11
|
group: check-${{ github.ref }}
|
|
13
12
|
cancel-in-progress: true
|
|
14
|
-
|
|
15
13
|
permissions:
|
|
16
14
|
contents: read
|
|
17
|
-
|
|
18
15
|
jobs:
|
|
19
16
|
test:
|
|
20
17
|
runs-on: ubuntu-latest
|
|
@@ -22,6 +19,8 @@ jobs:
|
|
|
22
19
|
fail-fast: false
|
|
23
20
|
matrix:
|
|
24
21
|
env:
|
|
22
|
+
- "3.15"
|
|
23
|
+
- "3.15t"
|
|
25
24
|
- "3.14"
|
|
26
25
|
- "3.13"
|
|
27
26
|
- "3.12"
|
|
@@ -34,12 +33,12 @@ jobs:
|
|
|
34
33
|
- dev
|
|
35
34
|
- pkg_meta
|
|
36
35
|
steps:
|
|
37
|
-
- uses: actions/checkout@
|
|
36
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
38
37
|
with:
|
|
39
38
|
fetch-depth: 0
|
|
40
39
|
persist-credentials: false
|
|
41
40
|
- name: Install the latest version of uv
|
|
42
|
-
uses: astral-sh/setup-uv@
|
|
41
|
+
uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
|
|
43
42
|
with:
|
|
44
43
|
enable-cache: false
|
|
45
44
|
cache-dependency-glob: "pyproject.toml"
|
|
@@ -56,3 +55,26 @@ jobs:
|
|
|
56
55
|
env:
|
|
57
56
|
PYTEST_ADDOPTS: "-vv --durations=20"
|
|
58
57
|
DIFF_AGAINST: HEAD
|
|
58
|
+
old-target:
|
|
59
|
+
runs-on: ubuntu-latest
|
|
60
|
+
steps:
|
|
61
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
62
|
+
with:
|
|
63
|
+
fetch-depth: 0
|
|
64
|
+
persist-credentials: false
|
|
65
|
+
- name: Install the latest version of uv
|
|
66
|
+
uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
|
|
67
|
+
with:
|
|
68
|
+
enable-cache: false
|
|
69
|
+
cache-dependency-glob: "pyproject.toml"
|
|
70
|
+
github-token: ${{ secrets.GITHUB_TOKEN }}
|
|
71
|
+
- name: Build the wheel
|
|
72
|
+
run: uv build --wheel --out-dir dist .
|
|
73
|
+
- name: Discover Python 3.6
|
|
74
|
+
run: tasks/old_target_check.sh 3.6 discover
|
|
75
|
+
- name: Discover Python 3.7
|
|
76
|
+
run: tasks/old_target_check.sh 3.7 discover
|
|
77
|
+
- name: Reject Python 3.5
|
|
78
|
+
run: tasks/old_target_check.sh 3.5 rejected
|
|
79
|
+
- name: Reject Python 2.7
|
|
80
|
+
run: tasks/old_target_check.sh 2.7 rejected
|
|
@@ -12,13 +12,10 @@ on:
|
|
|
12
12
|
- minor
|
|
13
13
|
- patch
|
|
14
14
|
default: auto
|
|
15
|
-
|
|
16
15
|
permissions:
|
|
17
16
|
contents: read
|
|
18
|
-
|
|
19
17
|
env:
|
|
20
18
|
FORCE_COLOR: 1
|
|
21
|
-
|
|
22
19
|
jobs:
|
|
23
20
|
prepare-release:
|
|
24
21
|
runs-on: ubuntu-24.04
|
|
@@ -26,24 +23,21 @@ jobs:
|
|
|
26
23
|
permissions:
|
|
27
24
|
contents: write
|
|
28
25
|
steps:
|
|
29
|
-
- uses: actions/checkout@
|
|
26
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
30
27
|
with:
|
|
31
28
|
fetch-depth: 0
|
|
32
29
|
token: ${{ secrets.RELEASE_PAT }}
|
|
33
30
|
persist-credentials: true
|
|
34
|
-
|
|
35
31
|
- name: Install the latest version of uv
|
|
36
|
-
uses: astral-sh/setup-uv@
|
|
32
|
+
uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
|
|
37
33
|
with:
|
|
38
34
|
enable-cache: true
|
|
39
35
|
cache-dependency-glob: "pyproject.toml"
|
|
40
36
|
github-token: ${{ secrets.GITHUB_TOKEN }}
|
|
41
|
-
|
|
42
37
|
- name: Configure git
|
|
43
38
|
run: |
|
|
44
39
|
git config user.name "${GITHUB_ACTOR}"
|
|
45
40
|
git config user.email "${GITHUB_ACTOR}@users.noreply.github.com"
|
|
46
|
-
|
|
47
41
|
- name: Calculate next version
|
|
48
42
|
id: version
|
|
49
43
|
env:
|
|
@@ -84,16 +78,13 @@ jobs:
|
|
|
84
78
|
|
|
85
79
|
echo "Next version: $next"
|
|
86
80
|
echo "version=$next" >> $GITHUB_OUTPUT
|
|
87
|
-
|
|
88
81
|
- name: Install tox
|
|
89
82
|
run: uv tool install --python-preference only-managed --python 3.14 tox@latest --with tox-uv
|
|
90
|
-
|
|
91
83
|
- name: Run release process
|
|
92
84
|
run: tox run -e release -- ${STEPS_VERSION_OUTPUTS_VERSION}
|
|
93
85
|
env:
|
|
94
86
|
GH_TOKEN: ${{ secrets.RELEASE_PAT }}
|
|
95
87
|
STEPS_VERSION_OUTPUTS_VERSION: ${{ steps.version.outputs.version }}
|
|
96
|
-
|
|
97
88
|
- name: Display completion message
|
|
98
89
|
run: echo "Release ${STEPS_VERSION_OUTPUTS_VERSION} prepared and pushed successfully!"
|
|
99
90
|
env:
|
|
@@ -2,23 +2,20 @@ name: Release to PyPI
|
|
|
2
2
|
on:
|
|
3
3
|
push:
|
|
4
4
|
tags: ["*"]
|
|
5
|
-
|
|
6
5
|
permissions:
|
|
7
6
|
contents: read
|
|
8
|
-
|
|
9
7
|
env:
|
|
10
8
|
dists-artifact-name: python-package-distributions
|
|
11
|
-
|
|
12
9
|
jobs:
|
|
13
10
|
build:
|
|
14
11
|
runs-on: ubuntu-latest
|
|
15
12
|
steps:
|
|
16
|
-
- uses: actions/checkout@
|
|
13
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
17
14
|
with:
|
|
18
15
|
fetch-depth: 0
|
|
19
16
|
persist-credentials: false
|
|
20
17
|
- name: Install the latest version of uv
|
|
21
|
-
uses: astral-sh/setup-uv@
|
|
18
|
+
uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
|
|
22
19
|
with:
|
|
23
20
|
enable-cache: false
|
|
24
21
|
cache-dependency-glob: "pyproject.toml"
|
|
@@ -30,7 +27,6 @@ jobs:
|
|
|
30
27
|
with:
|
|
31
28
|
name: ${{ env.dists-artifact-name }}
|
|
32
29
|
path: dist/*
|
|
33
|
-
|
|
34
30
|
release:
|
|
35
31
|
needs:
|
|
36
32
|
- build
|
|
@@ -47,6 +43,6 @@ jobs:
|
|
|
47
43
|
name: ${{ env.dists-artifact-name }}
|
|
48
44
|
path: dist/
|
|
49
45
|
- name: Publish to PyPI
|
|
50
|
-
uses: pypa/gh-action-pypi-publish@
|
|
46
|
+
uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # v1.14.2
|
|
51
47
|
with:
|
|
52
48
|
attestations: true
|
|
@@ -5,34 +5,41 @@ repos:
|
|
|
5
5
|
- id: end-of-file-fixer
|
|
6
6
|
- id: trailing-whitespace
|
|
7
7
|
- repo: https://github.com/python-jsonschema/check-jsonschema
|
|
8
|
-
rev: 0.
|
|
8
|
+
rev: 0.38.0
|
|
9
9
|
hooks:
|
|
10
10
|
- id: check-github-workflows
|
|
11
11
|
args: ["--verbose"]
|
|
12
12
|
- repo: https://github.com/codespell-project/codespell
|
|
13
|
-
rev: v2.4.
|
|
13
|
+
rev: v2.4.3
|
|
14
14
|
hooks:
|
|
15
15
|
- id: codespell
|
|
16
16
|
additional_dependencies: ["tomli>=2.4"]
|
|
17
17
|
- repo: https://github.com/tox-dev/pyproject-fmt
|
|
18
|
-
rev: "v2.
|
|
18
|
+
rev: "v2.28.0"
|
|
19
19
|
hooks:
|
|
20
20
|
- id: pyproject-fmt
|
|
21
21
|
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
22
|
-
rev: "v0.
|
|
22
|
+
rev: "v0.16.3"
|
|
23
23
|
hooks:
|
|
24
24
|
- id: ruff-format
|
|
25
25
|
- id: ruff
|
|
26
26
|
args: ["--fix", "--unsafe-fixes", "--exit-non-zero-on-fix"]
|
|
27
|
-
- repo: https://github.com/
|
|
28
|
-
rev: "
|
|
27
|
+
- repo: https://github.com/google/yamlfmt
|
|
28
|
+
rev: "v0.21.0"
|
|
29
29
|
hooks:
|
|
30
|
-
- id:
|
|
30
|
+
- id: yamlfmt
|
|
31
|
+
- repo: local
|
|
32
|
+
hooks:
|
|
33
|
+
- id: mdformat
|
|
34
|
+
name: mdformat
|
|
35
|
+
entry: mdformat --wrap 120
|
|
36
|
+
language: python
|
|
37
|
+
types: [markdown]
|
|
31
38
|
additional_dependencies:
|
|
32
|
-
-
|
|
33
|
-
-
|
|
39
|
+
- mdformat-gfm>=1
|
|
40
|
+
- mdformat-ruff>=0.1.3
|
|
34
41
|
- repo: https://github.com/zizmorcore/zizmor-pre-commit
|
|
35
|
-
rev: v1.
|
|
42
|
+
rev: v1.29.0
|
|
36
43
|
hooks:
|
|
37
44
|
- id: zizmor
|
|
38
45
|
- repo: meta
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
2
|
Name: python-discovery
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.5.3
|
|
4
4
|
Summary: Python interpreter discovery
|
|
5
5
|
Project-URL: Changelog, https://github.com/tox-dev/python-discovery/releases
|
|
6
6
|
Project-URL: Documentation, https://python-discovery.readthedocs.io
|
|
@@ -42,25 +42,12 @@ Classifier: Programming Language :: Python :: 3.11
|
|
|
42
42
|
Classifier: Programming Language :: Python :: 3.12
|
|
43
43
|
Classifier: Programming Language :: Python :: 3.13
|
|
44
44
|
Classifier: Programming Language :: Python :: 3.14
|
|
45
|
+
Classifier: Programming Language :: Python :: 3.15
|
|
45
46
|
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
46
47
|
Classifier: Topic :: Software Development :: Libraries
|
|
47
48
|
Classifier: Topic :: Utilities
|
|
48
49
|
Requires-Python: >=3.8
|
|
49
50
|
Requires-Dist: filelock>=3.15.4
|
|
50
|
-
Requires-Dist: platformdirs<5,>=4.3.6
|
|
51
|
-
Provides-Extra: docs
|
|
52
|
-
Requires-Dist: furo>=2025.12.19; extra == 'docs'
|
|
53
|
-
Requires-Dist: sphinx-autodoc-typehints>=3.6.3; extra == 'docs'
|
|
54
|
-
Requires-Dist: sphinx>=9.1; extra == 'docs'
|
|
55
|
-
Requires-Dist: sphinxcontrib-mermaid>=2; extra == 'docs'
|
|
56
|
-
Requires-Dist: sphinxcontrib-towncrier>=0.4; extra == 'docs'
|
|
57
|
-
Requires-Dist: towncrier>=25.8; extra == 'docs'
|
|
58
|
-
Provides-Extra: testing
|
|
59
|
-
Requires-Dist: covdefaults>=2.3; extra == 'testing'
|
|
60
|
-
Requires-Dist: coverage>=7.5.4; extra == 'testing'
|
|
61
|
-
Requires-Dist: pytest-mock>=3.14; extra == 'testing'
|
|
62
|
-
Requires-Dist: pytest>=8.3.5; extra == 'testing'
|
|
63
|
-
Requires-Dist: setuptools>=75.1; extra == 'testing'
|
|
64
51
|
Description-Content-Type: text/markdown
|
|
65
52
|
|
|
66
53
|
# [`python-discovery`](https://python-discovery.readthedocs.io/en/latest/)
|
|
@@ -81,6 +68,9 @@ the right one for you.
|
|
|
81
68
|
Give it a requirement like `python3.12` or `>=3.11,<3.13`, and it searches all known locations, verifies each candidate,
|
|
82
69
|
and returns detailed metadata about the match. Results are cached to disk so repeated lookups are fast.
|
|
83
70
|
|
|
71
|
+
The library runs on Python 3.8+ and discovers interpreters as old as Python 3.6; anything older is skipped with a
|
|
72
|
+
warning naming the version it found.
|
|
73
|
+
|
|
84
74
|
## Usage
|
|
85
75
|
|
|
86
76
|
```python
|
|
@@ -16,6 +16,9 @@ the right one for you.
|
|
|
16
16
|
Give it a requirement like `python3.12` or `>=3.11,<3.13`, and it searches all known locations, verifies each candidate,
|
|
17
17
|
and returns detailed metadata about the match. Results are cached to disk so repeated lookups are fast.
|
|
18
18
|
|
|
19
|
+
The library runs on Python 3.8+ and discovers interpreters as old as Python 3.6; anything older is skipped with a
|
|
20
|
+
warning naming the version it found.
|
|
21
|
+
|
|
19
22
|
## Usage
|
|
20
23
|
|
|
21
24
|
```python
|
|
@@ -6,6 +6,49 @@
|
|
|
6
6
|
|
|
7
7
|
.. towncrier release notes start
|
|
8
8
|
|
|
9
|
+
********************
|
|
10
|
+
v1.5.3 (2026-08-24)
|
|
11
|
+
********************
|
|
12
|
+
|
|
13
|
+
Bug fixes - 1.5.3
|
|
14
|
+
=================
|
|
15
|
+
- Restore discovery of Python 3.6 and 3.7 interpreters: the interrogation script had grown 3.8-only syntax and is now
|
|
16
|
+
kept to Python 3.6. Candidates below 3.6 log one warning naming the version found instead of two debug-level query
|
|
17
|
+
attempts, and the verdict is cached so they are queried only once; an absolute-path spec for one raises
|
|
18
|
+
``RuntimeError`` with the same message - by :user:`gaborbernat`. (:issue:`116`)
|
|
19
|
+
- Prefer the version-matched system executable when CPython reports an existing generic executable for a copied POSIX
|
|
20
|
+
virtual environment. (:issue:`124`)
|
|
21
|
+
|
|
22
|
+
Improved documentation - 1.5.3
|
|
23
|
+
==============================
|
|
24
|
+
- Document the version floors: runs on Python 3.8+, discovers interpreters down to 3.6 - by :user:`gaborbernat`. (:issue:`116`)
|
|
25
|
+
|
|
26
|
+
********************
|
|
27
|
+
v1.5.1 (2026-07-31)
|
|
28
|
+
********************
|
|
29
|
+
|
|
30
|
+
Bug fixes - 1.5.1
|
|
31
|
+
=================
|
|
32
|
+
- Locate uv's interpreter store the way uv does, using XDG on macOS (``~/.local/share/uv/python``) and roaming
|
|
33
|
+
``%APPDATA%\uv\python`` on Windows, neither of which ``platformdirs`` reported. The uv variables now come from the
|
|
34
|
+
``env`` mapping rather than ``os.environ`` - by :user:`gaborbernat`. (:issue:`109`)
|
|
35
|
+
- Pick uv-managed interpreters by install directory name instead of globbing the store. A bare ``3.8`` now means
|
|
36
|
+
CPython, the way uv resolves it, rather than whichever implementation the filesystem happened to list first, and
|
|
37
|
+
probing runs newest version first - by :user:`gaborbernat`. (:issue:`110`)
|
|
38
|
+
|
|
39
|
+
Packaging updates and notes for downstreams - 1.5.1
|
|
40
|
+
===================================================
|
|
41
|
+
- Drop the ``platformdirs`` runtime dependency; locating uv's store was the only thing it did - by
|
|
42
|
+
:user:`gaborbernat`. (:issue:`109`)
|
|
43
|
+
|
|
44
|
+
********************
|
|
45
|
+
v1.5.0 (2026-07-21)
|
|
46
|
+
********************
|
|
47
|
+
|
|
48
|
+
Packaging updates and notes for downstreams - 1.5.0
|
|
49
|
+
===================================================
|
|
50
|
+
- Declare support for Python 3.15 and run the test suite against it, currently in beta. (:issue:`104`)
|
|
51
|
+
|
|
9
52
|
********************
|
|
10
53
|
v1.4.4 (2026-07-08)
|
|
11
54
|
********************
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
+
import os
|
|
5
6
|
from datetime import datetime, timezone
|
|
6
7
|
from pathlib import Path
|
|
7
8
|
|
|
@@ -11,9 +12,10 @@ company = "tox-dev"
|
|
|
11
12
|
name = "python-discovery"
|
|
12
13
|
version = ".".join(__version__.split(".")[:2])
|
|
13
14
|
release = __version__
|
|
14
|
-
copyright = f"2026-{datetime.now(tz=timezone.utc).year}, {company}" #
|
|
15
|
+
copyright = f"2026-{datetime.now(tz=timezone.utc).year}, {company}" # ruff:ignore[builtin-variable-shadowing]
|
|
15
16
|
|
|
16
17
|
extensions = [
|
|
18
|
+
"sphinx_llm.txt",
|
|
17
19
|
"sphinx.ext.autodoc",
|
|
18
20
|
"sphinx.ext.autosectionlabel",
|
|
19
21
|
"sphinx.ext.extlinks",
|
|
@@ -58,3 +60,5 @@ html_theme_options = {
|
|
|
58
60
|
"sidebar_hide_name": True,
|
|
59
61
|
}
|
|
60
62
|
html_css_files = ["custom.css"]
|
|
63
|
+
|
|
64
|
+
markdown_http_base = os.environ.get("READTHEDOCS_CANONICAL_URL", "")
|
|
@@ -68,9 +68,33 @@ detects these shims and resolves them to the actual binary.
|
|
|
68
68
|
How uv-managed Pythons are discovered
|
|
69
69
|
---------------------------------------
|
|
70
70
|
|
|
71
|
-
`uv <https://docs.astral.sh/uv/>`_ installs Python interpreters under a single root directory
|
|
72
|
-
|
|
73
|
-
|
|
71
|
+
`uv <https://docs.astral.sh/uv/>`_ installs Python interpreters under a single root directory. ``UV_PYTHON_INSTALL_DIR``
|
|
72
|
+
overrides it; otherwise the store is the ``python`` bucket of uv's state directory, which uv derives as follows:
|
|
73
|
+
|
|
74
|
+
.. list-table::
|
|
75
|
+
:header-rows: 1
|
|
76
|
+
:widths: 20 40 40
|
|
77
|
+
|
|
78
|
+
* - Platform
|
|
79
|
+
- Legacy state directory
|
|
80
|
+
- Current state directory
|
|
81
|
+
* - Windows
|
|
82
|
+
- ``%APPDATA%\uv\data``
|
|
83
|
+
- ``%APPDATA%\uv`` (roaming, not local)
|
|
84
|
+
* - macOS
|
|
85
|
+
- ``~/Library/Application Support/uv``
|
|
86
|
+
- ``$XDG_DATA_HOME/uv`` or ``~/.local/share/uv``
|
|
87
|
+
* - Other
|
|
88
|
+
- same as current
|
|
89
|
+
- ``$XDG_DATA_HOME/uv`` or ``~/.local/share/uv``
|
|
90
|
+
|
|
91
|
+
uv follows the XDG convention on macOS too, and falls back to the legacy directory only when that directory already
|
|
92
|
+
exists. python-discovery searches both, in the same order, so a leftover legacy directory cannot hide the store uv
|
|
93
|
+
installs into. A relative ``XDG_DATA_HOME`` does not count, as the XDG specification requires, and Windows ignores it
|
|
94
|
+
outright. Every one of these variables comes from the ``env`` mapping passed to
|
|
95
|
+
:func:`~python_discovery.get_interpreter`, rather than from the process environment.
|
|
96
|
+
|
|
97
|
+
Each install lives in its own subdirectory, but the actual binary location varies by OS and implementation:
|
|
74
98
|
|
|
75
99
|
.. list-table::
|
|
76
100
|
:header-rows: 1
|
|
@@ -89,42 +113,51 @@ install lives in its own subdirectory, but the actual binary location varies by
|
|
|
89
113
|
- ``<root>/<key>/bin/graalpy``
|
|
90
114
|
- ``<root>/<key>/bin/graalpy.exe``
|
|
91
115
|
|
|
116
|
+
GraalPy keeps its ``bin/`` segment on Windows (an upstream choice in uv); PyPy and CPython do not. python-discovery
|
|
117
|
+
globs all of these patterns regardless of the host OS, because globs that do not match anything are essentially
|
|
118
|
+
free, and the cross-platform list is short. Symlinked aliases inside an install (``bin/python``,
|
|
119
|
+
``bin/python3``, ``bin/python3.14`` all pointing at the same real file) are deduplicated by resolved path before
|
|
120
|
+
the subprocess interrogation, so each install is interrogated once. python-discovery also follows the ``install``
|
|
121
|
+
subdirectory some distributions unpack into, as uv does.
|
|
122
|
+
|
|
123
|
+
Which uv installs get interrogated
|
|
124
|
+
------------------------------------
|
|
125
|
+
|
|
126
|
+
Interrogating an interpreter costs a subprocess, and a uv install directory announces what it holds in its own name:
|
|
127
|
+
``<implementation>-<version>[+<variant>]-<os>-<arch>-<libc>``, for example
|
|
128
|
+
``cpython-3.14.6+freethreaded-macos-aarch64-none``. python-discovery reads that name and skips the installs the spec
|
|
129
|
+
already rules out, then probes what is left in uv's preference order:
|
|
130
|
+
|
|
92
131
|
.. mermaid::
|
|
93
132
|
|
|
94
133
|
flowchart LR
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
W2 --> Dedup
|
|
107
|
-
W3 --> Dedup
|
|
108
|
-
W4 --> Dedup
|
|
109
|
-
|
|
110
|
-
Dedup --> Interrogate(["subprocess interrogation"])
|
|
111
|
-
|
|
112
|
-
style Call fill:#4a90d9,stroke:#2a5f8f,color:#fff
|
|
113
|
-
style Mode fill:#d9904a,stroke:#8f5f2a,color:#fff
|
|
114
|
-
style N1 fill:#3a7fc2,stroke:#1f4d7a,color:#fff
|
|
115
|
-
style N2 fill:#3a7fc2,stroke:#1f4d7a,color:#fff
|
|
116
|
-
style W1 fill:#9f4ad9,stroke:#5f2a8f,color:#fff
|
|
117
|
-
style W2 fill:#9f4ad9,stroke:#5f2a8f,color:#fff
|
|
118
|
-
style W3 fill:#9f4ad9,stroke:#5f2a8f,color:#fff
|
|
119
|
-
style W4 fill:#9f4ad9,stroke:#5f2a8f,color:#fff
|
|
120
|
-
style Dedup fill:#c2873a,stroke:#7a4c1f,color:#fff
|
|
134
|
+
Dirs[/"store subdirectories"/] --> Parse{"name is a uv key?"}
|
|
135
|
+
Parse -->|"no"| Last["probe last"]
|
|
136
|
+
Parse -->|"yes"| Filter["drop what the spec rules out:<br>implementation, version, free-threaded, debug"]
|
|
137
|
+
Filter --> Sort["CPython → PyPy → GraalPy,<br>newest version first,<br>default build before variants"]
|
|
138
|
+
Sort --> Interrogate(["subprocess interrogation"])
|
|
139
|
+
Last --> Interrogate
|
|
140
|
+
|
|
141
|
+
style Dirs fill:#4a90d9,stroke:#2a5f8f,color:#fff
|
|
142
|
+
style Parse fill:#d9904a,stroke:#8f5f2a,color:#fff
|
|
143
|
+
style Filter fill:#9f4ad9,stroke:#5f2a8f,color:#fff
|
|
144
|
+
style Sort fill:#c2873a,stroke:#7a4c1f,color:#fff
|
|
121
145
|
style Interrogate fill:#4a9f4a,stroke:#2a6f2a,color:#fff
|
|
122
146
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
147
|
+
python-discovery reads the variant suffix the same way :class:`~python_discovery.PythonSpec` does: ``3.14t`` wants
|
|
148
|
+
``+freethreaded``, ``3.14d`` wants ``+debug``. A spec that says nothing about a variant leaves it unconstrained, so
|
|
149
|
+
``3.14`` still reaches a ``+debug`` install, after the default build rather than instead of it.
|
|
150
|
+
|
|
151
|
+
A bare version spec such as ``3.8`` matches CPython only, which is what uv resolves it to and what the equivalent
|
|
152
|
+
``python3.8`` probe on ``PATH`` finds in practice. Ask for ``pypy3.8`` or enumerate with
|
|
153
|
+
:func:`~python_discovery.iter_interpreters` to reach the other implementations - PyPy ships a ``bin/python`` symlink,
|
|
154
|
+
so a store-wide glob would otherwise hand back PyPy for ``3.8`` whenever the filesystem listed it first.
|
|
155
|
+
|
|
156
|
+
Two names carry less information than they appear to. GraalPy keys named after the GraalVM release
|
|
157
|
+
(``graalpy-24.1.1``, from older uv versions) do not constrain the version, and uv's minor version links
|
|
158
|
+
(``cpython-3.15`` pointing at ``cpython-3.15.0b3``) move on the next patch release, so the concrete install ranks
|
|
159
|
+
ahead of the link. Anything that is not a uv key - a hand-made ``UV_PYTHON_INSTALL_DIR`` layout, say - stays in
|
|
160
|
+
the running, at the back of the queue.
|
|
128
161
|
|
|
129
162
|
Selecting one interpreter vs. enumerating all of them
|
|
130
163
|
-------------------------------------------------------
|
|
@@ -210,6 +243,18 @@ The timeout applies to each individual interpreter being queried. If you set a v
|
|
|
210
243
|
legitimate interpreters may be skipped; if too high, the discovery process may take longer to fail
|
|
211
244
|
when encountering problematic interpreters.
|
|
212
245
|
|
|
246
|
+
Supported Python versions
|
|
247
|
+
-------------------------
|
|
248
|
+
|
|
249
|
+
Two floors apply: python-discovery itself runs on Python 3.8+ (``requires-python``), while discovery
|
|
250
|
+
reaches down to Python 3.6 - old enough to cover RHEL 8's system Python.
|
|
251
|
+
|
|
252
|
+
python-discovery skips candidates below 3.6 with one warning naming the executable, the version
|
|
253
|
+
found, and the floor; the verdict is cached, so the interpreter is not queried again. Candidates too
|
|
254
|
+
old to run the version check at all (before Python 2.7) fail as a generic query error. An
|
|
255
|
+
absolute-path spec for a below-floor interpreter raises :class:`RuntimeError` with the same message.
|
|
256
|
+
The floor moves only in a major release.
|
|
257
|
+
|
|
213
258
|
Spec format reference
|
|
214
259
|
-----------------------
|
|
215
260
|
|