Skip to main content

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)

Download the zipapp here

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_installs is a generator that will yield each python version it discovers
  • list_python_installs will take the python versions discovered by get_python_installs and 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)

Source distribution for ducktools-pythonfinder 0.11.1
File Size Uploaded Provenance
ducktools_pythonfinder-0.11.1.tar.gz 67.5 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for ducktools-pythonfinder 0.11.1
File Interpreter ABI Platform
ducktools_pythonfinder-0.11.1-py3-none-any.whl Python 3 none any Details

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 log

Release 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 log

Security 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.

Select from 2 files

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 log

A 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.

Release history Release notifications | RSS feed

This release

0.11.1 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page