Skip to main content

Cross platform tool to find available python installations

Project description

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.

If you wish to find the latest binaries available from python.org for your platform (or sources on Linux) there is the additional online command with some extra flags.

By default it will fetch the latest patches for each Python release (eg: 2.7.18 for 2.7) for the hardware you're on. The filters for local versions also work.

  • --all-binaries will get you all binary releases that match the restrictions.
  • --system and --machine allow you to specify a platform other than the one you are using (the values you give should match platform.system() and platform.machine() return values).
  • --prerelease includes prerelease versions in the search.

Example: python pythonfinder.pyz online --min 3.10 --system Windows --machine AMD64

| Python Version | URL                                                                |
| -------------- | ------------------------------------------------------------------ |
|         3.12.5 | https://www.python.org/ftp/python/3.12.5/python-3.12.5-amd64.exe   |
|         3.11.9 | https://www.python.org/ftp/python/3.11.9/python-3.11.9-amd64.exe   |
|        3.10.11 | https://www.python.org/ftp/python/3.10.11/python-3.10.11-amd64.exe |

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.

from ducktools.pythonfinder.venv import list_python_venvs

for venv in list_python_venvs():
    print(venv.executable)

Python.org search

Python.org searches are handled by the ducktools.pythonfinder.pythonorg_search module.

from packaging.specifiers import SpecifierSet
from ducktools.pythonfinder.pythonorg_search import PythonOrgSearch

# If system and machine are not provided this uses platform.system() and platform.machine()
searcher = PythonOrgSearch(system="Windows", machine="AMD64")

all_releases = searcher.releases
all_release_files = searcher.release_files
all_312_releases = searcher.matching_versions(SpecifierSet("~=3.12.0"))
all_312_downloads = searcher.matching_versions(SpecifierSet("~=3.12.0"))
all_312_311_win_binaries = searcher.all_matching_binaries(SpecifierSet(">=3.11.0, <3.13"))
latest_312_311_win_binaries = searcher.latest_minor_binaries(SpecifierSet(">=3.11.0, <3.13"))
latest_matching_win_binary = searcher.latest_binary_match(SpecifierSet(">=3.10"))
latest_prerelease_binary = searcher.latest_binary_match(SpecifierSet(">=3.10"), prereleases=True)

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

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ducktools_pythonfinder-0.10.4.tar.gz (223.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

ducktools_pythonfinder-0.10.4-py3-none-any.whl (37.5 kB view details)

Uploaded Python 3

File details

Details for the file ducktools_pythonfinder-0.10.4.tar.gz.

File metadata

  • Download URL: ducktools_pythonfinder-0.10.4.tar.gz
  • Upload date:
  • Size: 223.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for ducktools_pythonfinder-0.10.4.tar.gz
Algorithm Hash digest
SHA256 4bbcd5167581b78392d9a358fa12c3de9e3fbef8b51d54d835c33143566e34b1
MD5 ff0546b0953e6de3b268778b7379b752
BLAKE2b-256 705ff59741510b64f51c52bb76787f3f016a552513a833e30c1d722edee71e60

See more details on using hashes here.

Provenance

The following attestation bundles were made for ducktools_pythonfinder-0.10.4.tar.gz:

Publisher: publish_to_pypi.yml on DavidCEllis/ducktools-pythonfinder

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file ducktools_pythonfinder-0.10.4-py3-none-any.whl.

File metadata

File hashes

Hashes for ducktools_pythonfinder-0.10.4-py3-none-any.whl
Algorithm Hash digest
SHA256 9af72d67afd3d95c4baf8c470c6250c2c16d971acecde23bb44059a4c340a42d
MD5 1772f99c7e8f40f5d1ee88658af44167
BLAKE2b-256 af74785c698e5c3e81e08bf8d6a453e4008bececb1437f7b3bb623b33e2d9ae5

See more details on using hashes here.

Provenance

The following attestation bundles were made for ducktools_pythonfinder-0.10.4-py3-none-any.whl:

Publisher: publish_to_pypi.yml on DavidCEllis/ducktools-pythonfinder

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page