ducktools: pythonfinder
Find local python installs on Windows/Linux/MacOS and find the latest installers from python.org for Windows and MacOS or sources for Linux (as python.org does not provide linux installers).
Requires Python >= 3.10 (but will discover older Python installs)
It is also available as an application and library on PyPI. The simplest way to install this is with uv.
With uv:
- Install it as an application with
uv tool install ducktools-pythonfinder - Run once with
uvx ducktools-pythonfinder - Add it as a library to a project with
uv add ducktools-pythonfinder - Add it as a library for a script with
uv add --script scriptname.py ducktools-pythonfinder - test it in a repl with
uv run --isolated --with ducktools-pythonfinder python
If you do not wish to use uv, you can also install as an application with
pipx, or manually manage dependencies in pyproject.toml,
inline script metadata
or in virtual environments using pip.
Command Line Usage
ducktools-pythonfinder can be used as a module or as a bundled zipapp (as pythonfinder.pyz).
python pythonfinder.pyz or python -m ducktools.pythonfinder
will provide a table of installed python versions
and their respective folders. It will also indicate the python running the
command if it is found, or the python that is the base for the venv running the command.
Python versions listed can be restricted by using the --max, --min and
--compatible options to the command. These roughly translate to >= for min, < for max
and ~= for compatible in python version specifiers.
Library Usage
Local installs
The module provides two main functions for searching for local python installs:
get_python_installsis a generator that will yield each python version it discoverslist_python_installswill take the python versions discovered byget_python_installsand return a sorted list from newest to oldest python version discovered.- For the purposes of sorting, prerelease versions are considered older than any released version.
On Windows these methods will search the registry for PEP514 recorded python installs
before checking for any pyenv-win installs that have not been registered. Finally, if
uv is available it will try to find Python installs managed by uv.
On Linux and MacOS this will search for pyenv installs first,
if uv is available it will then try to find uv managed python installs.
Finally it will search PATH for any other python* binaries that might be available.
If a python install is found twice (for instance a pyenv install in the windows registry) it will only be returned the first time it is found.
The python installs will be returned as instances of PythonInstall which will
contain version info and executable path along with some other useful metadata.
Example:
import os.path
from ducktools.pythonfinder import list_python_installs
user_path = os.path.expanduser("~")
for install in list_python_installs():
install.executable = install.executable.replace(user_path, "~")
print(install)
Example Windows Output:
PythonInstall(version=(3, 12, 5, 'final', 0), executable='~\\.pyenv\\pyenv-win\\versions\\3.12.5\\python.exe', architecture='64bit', implementation='cpython', metadata={'DiplayName': 'Python 3.12 (64-bit)', 'SupportUrl': 'https://github.com/pyenv-win/pyenv-win/issues', 'SysArchitecture': '64bit', 'SysVersion': '3.12', 'Version': '3.12.5', 'InWindowsRegistry': True}, shadowed=False)
PythonInstall(version=(3, 12, 3, 'final', 0), executable='~\\.pyenv\\pyenv-win\\versions\\3.12.3\\python.exe', architecture='64bit', implementation='cpython', metadata={}, shadowed=False)
PythonInstall(version=(3, 11, 9, 'final', 0), executable='~\\.pyenv\\pyenv-win\\versions\\3.11.9\\python.exe', architecture='64bit', implementation='cpython', metadata={'DiplayName': 'Python 3.11 (64-bit)', 'SupportUrl': 'https://github.com/pyenv-win/pyenv-win/issues', 'SysArchitecture': '64bit', 'SysVersion': '3.11', 'Version': '3.11.9', 'InWindowsRegistry': True}, shadowed=False)
PythonInstall(version=(3, 10, 11, 'final', 0), executable='~\\.pyenv\\pyenv-win\\versions\\3.10.11\\python.exe', architecture='64bit', implementation='cpython', metadata={'DiplayName': 'Python 3.10 (64-bit)', 'SupportUrl': 'https://github.com/pyenv-win/pyenv-win/issues', 'SysArchitecture': '64bit', 'SysVersion': '3.10', 'Version': '3.10.11', 'InWindowsRegistry': True}, shadowed=False)
PythonInstall(version=(3, 9, 13, 'final', 0), executable='~\\.pyenv\\pyenv-win\\versions\\3.9.13\\python.exe', architecture='64bit', implementation='cpython', metadata={'DiplayName': 'Python 3.9 (64-bit)', 'SupportUrl': 'https://github.com/pyenv-win/pyenv-win/issues', 'SysArchitecture': '64bit', 'SysVersion': '3.9', 'Version': '3.9.13', 'InWindowsRegistry': True}, shadowed=False)
PythonInstall(version=(3, 8, 10, 'final', 0), executable='~\\.pyenv\\pyenv-win\\versions\\3.8.10\\python.exe', architecture='64bit', implementation='cpython', metadata={'DiplayName': 'Python 3.8 (64-bit)', 'SupportUrl': 'https://github.com/pyenv-win/pyenv-win/issues', 'SysArchitecture': '64bit', 'SysVersion': '3.8', 'Version': '3.8.10', 'InWindowsRegistry': True}, shadowed=False)
PythonInstall(version=(3, 13, 0, 'candidate', 1), executable='~\\.pyenv\\pyenv-win\\versions\\3.13.0rc1\\python.exe', architecture='64bit', implementation='cpython', metadata={}, shadowed=False)```
Finding venvs
There is now a submodule to search for virtual environments.
import os
from ducktools.pythonfinder.venv import list_python_venvs
for venv in list_python_venvs(recursive=False, search_parent_folders=True):
print(venv.executable)
Why?
For the purposes of PEP723 script dependencies and other releated tools
it may be useful to find another version of python other than the one currently running
in order to satisfy the requires-python field.
This tool is intended to search for potential python installs to attempt to
satisfy such a requirement.
Isn't there already a 'pythonfinder' module?
That module appears to require searching for a specific version and will find venv pythons.
In contrast ducktools.pythonfinder simply yields python installs as they are discovered
and will attempt to avoid returning virtualenv python installs (unless you are searching for venvs)
Metadata
Release files for ducktools-pythonfinder 0.11.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| ducktools_pythonfinder-0.11.1.tar.gz | 67.5 kB | With provenance | Details for ducktools_pythonfinder-0.11.1.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| ducktools_pythonfinder-0.11.1-py3-none-any.whl | Python 3 | none | any | Details for ducktools_pythonfinder-0.11.1-py3-none-any.whl |
Total release size: 101.8 kB
Release files / ducktools_pythonfinder-0.11.1.tar.gz
| Download URL | ducktools_pythonfinder-0.11.1.tar.gz |
|---|---|
| Size | 67.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c9da91f0a254f2b2a2640148f87a43765b37f99b65012735483a15d1ebff6b13
|
|
BLAKE2b-256 checksum How to use checksums |
0601340ecce84ef6581dcbfca87ac62e105caf5f81d434dc8dfdd04bece7d4aa
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 21, 2026.
Transparency logRelease files / ducktools_pythonfinder-0.11.1-py3-none-any.whl
| Download URL | ducktools_pythonfinder-0.11.1-py3-none-any.whl |
|---|---|
| Size | 34.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
6929b84e88691fcb4f842322dec10596f89becd55eee135387a904b3b64c9e42
|
|
BLAKE2b-256 checksum How to use checksums |
036da46573c7588e6beac0ad8c2d13ce1549844cbe5dfd13e5cd168755d13c2d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 21, 2026.
Transparency logSecurity for ducktools-pythonfinder 0.11.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for ducktools_pythonfinder-0.11.1.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 21, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.