# Inspiration PEP 723 support | Tool | Date added | Version | | ------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | [`pipx run`](https://pipx.pypa.io/latest/docs/#pipx-run) | [2024-01-12](https://github.com/pypa/pipx/releases/tag/1.4.2) | [1.4.2](https://pipx.pypa.io/latest/changelog/#:~:text=Update%20pipx%20run%20on%20scripts%20using%20///%20script%20and%20no%20run%20table%20following%20the%20updated%20version%20of%20PEP%20723) | | [`pip-run`](https://github.com/jaraco/pip-run) | [2024-01-20](https://pip-run.readthedocs.io/en/latest/history.html#v12-5-0) | [12.5.0](https://pip-run.readthedocs.io/en/latest/history.html#v12-5-0) | | [`hatch env run`](https://hatch.pypa.io/latest/cli/reference/#hatch-run) | [2024-05-02](https://hatch.pypa.io/latest/history/hatch/#hatch-v1.10.0:~:text=The%20run%20command%20can%20now%20execute%20scripts%20that%20define%20inline%20metadata%20for%20dependencies%20and%20Python%20version%20constraints) | [1.10.0](https://hatch.pypa.io/latest/history/hatch/#hatch-v1.10.0:~:text=The%20run%20command%20can%20now%20execute%20scripts%20that%20define%20inline%20metadata%20for%20dependencies%20and%20Python%20version%20constraints) | | [`pdm run`](https://pdm-project.org/en/latest/reference/cli/#run) | [2024-06-26](https://pipx.pypa.io/latest/changelog/#:~:text=Update%20pipx%20run%20on%20scripts%20using%20///%20script%20and%20no%20run%20table%20following%20the%20updated%20version%20of%20PEP%20723) | [2.16.0](https://pipx.pypa.io/latest/changelog/#:~:text=Update%20pipx%20run%20on%20scripts%20using%20///%20script%20and%20no%20run%20table%20following%20the%20updated%20version%20of%20PEP%20723) | | [`uv run`](https://docs.astral.sh/uv/reference/cli/#uv-run) | [2024-08-24](https://astral.sh/blog/uv-unified-python-packaging) | [0.3](https://astral.sh/blog/uv-unified-python-packaging) | [`poetry run`](https://python-poetry.org/docs/cli/#run) is only for entry points. ## pipx ``` usage: pipx run [-h] [--quiet] [--verbose] [--global] [--no-cache] [--path] [--pypackages] [--spec SPEC] [--python PYTHON] [--fetch-missing-python] [--system-site-packages] [--index-url INDEX_URL] [--editable] [--pip-args PIP_ARGS] app ... ``` ### pip-run ``` usage: Arguments to pip-run prior to `--` are used to specify the requirements to make available, just as arguments to pip install. For example: pip-run -r requirements.txt "requests>=2.0" That will launch python after installing the deps in requirements.txt and also a late requests. Packages are always installed to a temporary location and cleaned up when the process exits. Arguments after `--` are passed to the Python interpreter. So to launch `script.py`: pip-run -- script.py For simplicity, the `--` may be omitted and Python arguments will be inferred starting with the first Python file that exists: pip-run script.py To invoke another executable instead of Python, prefix the argument with a `!`: pip-run cowsay -- !cowsay "hello!" If the `--` is omitted or nothing is passed, the python interpreter will be launched in interactive mode: pip-run >>> For more examples and details, see https://pypi.org/project/pip-run. options: -h, --help show this help message and exit ``` ## Hatch ``` Usage: hatch env run [OPTIONS] ARGS... Options: Name Type Description Default --env, -e text The environments to target Sentinel.UNSET --include, -i text The matrix variables to include Sentinel.UNSET --exclude, -x text The matrix variables to exclude Sentinel.UNSET --filter, -f text The JSON data used to select environments None --force-continue boolean Run every command and if there were any errors exit with the first code False --ignore-compat boolean Ignore incompatibility when selecting specific environments False --help boolean Show this message and exit. False ``` ## PDM ``` Options: -h, --help: Show this help message and exit. -v, --verbose: Use -v for detailed output and -vv for more detailed -q, --quiet: Suppress output -g, --global: Use the global project, supply the project root with -p option -p, --project: Specify another path as the project root, which changes the base ofpyproject.toml and __pypackages__ [env var: PDM_PROJECT] -k, --skip: Skip some tasks and/or hooks by their comma-separated names. Can be supplied multiple times. Use:all to skip all hooks. Use:pre and:post to skip all pre or post hooks. --venv NAME: Run the command in the virtual environment with the given key. [env var: PDM_IN_VENV] -l, --list: Show all available scripts defined inpyproject.toml -j, --json: Output all scripts infos in JSON Execution Parameters: -s, --site-packages: Load site-packages from the selected interpreter --recreate: Recreate the script environment for self-contained scripts script: The command to run args: Arguments that will be passed to the command ``` ## uv ``` Run a command or script Usage: uv run [OPTIONS] [COMMAND] Options: --extra <EXTRA> Include optional dependencies from the specified extra name --all-extras Include all optional dependencies --no-extra <NO_EXTRA> Exclude the specified optional dependencies, if `--all-extras` is supplied --no-dev Disable the development dependency group [env: UV_NO_DEV=] --group <GROUP> Include dependencies from the specified dependency group --no-group <NO_GROUP> Disable the specified dependency group [env: UV_NO_GROUP=] --no-default-groups Ignore the default dependency groups [env: UV_NO_DEFAULT_GROUPS=] --only-group <ONLY_GROUP> Only include dependencies from the specified dependency group --all-groups Include dependencies from all dependency groups -m, --module Run a Python module --only-dev Only include the development dependency group --no-editable Install any editable dependencies, including the project and any workspace members, as non-editable [env: UV_NO_EDITABLE=] --exact Perform an exact sync, removing extraneous packages --env-file <ENV_FILE> Load environment variables from a `.env` file [env: UV_ENV_FILE=] --no-env-file Avoid reading environment variables from a `.env` file [env: UV_NO_ENV_FILE=] -w, --with <WITH> Run with the given packages installed --with-editable <WITH_EDITABLE> Run with the given packages installed in editable mode --with-requirements <WITH_REQUIREMENTS> Run with the packages listed in the given files --isolated Run the command in an isolated virtual environment [env: UV_ISOLATED=] --active Prefer the active virtual environment over the project's virtual environment --no-sync Avoid syncing the virtual environment [env: UV_NO_SYNC=] --locked Assert that the `uv.lock` will remain unchanged [env: UV_LOCKED=] --frozen Run without updating the `uv.lock` file [env: UV_FROZEN=] -s, --script Run the given path as a Python script --gui-script Run the given path as a Python GUI script --all-packages Run the command with all workspace members installed --package <PACKAGE> Run the command in a specific package in the workspace --no-project Avoid discovering the project or workspace --python-platform <PYTHON_PLATFORM> The platform for which requirements should be installed [possible values: windows, linux, macos, x86_64-pc-windows-msvc, aarch64-pc-windows-msvc, i686-pc-windows-msvc, x86_64-unknown-linux-gnu, aarch64-apple-darwin, x86_64-apple-darwin, aarch64-unknown-linux-gnu, aarch64-unknown-linux-musl, x86_64-unknown-linux-musl, riscv64-unknown-linux, x86_64-manylinux2014, x86_64-manylinux_2_17, x86_64-manylinux_2_28, x86_64-manylinux_2_31, x86_64-manylinux_2_32, x86_64-manylinux_2_33, x86_64-manylinux_2_34, x86_64-manylinux_2_35, x86_64-manylinux_2_36, x86_64-manylinux_2_37, x86_64-manylinux_2_38, x86_64-manylinux_2_39, x86_64-manylinux_2_40, aarch64-manylinux2014, aarch64-manylinux_2_17, aarch64-manylinux_2_28, aarch64-manylinux_2_31, aarch64-manylinux_2_32, aarch64-manylinux_2_33, aarch64-manylinux_2_34, aarch64-manylinux_2_35, aarch64-manylinux_2_36, aarch64-manylinux_2_37, aarch64-manylinux_2_38, aarch64-manylinux_2_39, aarch64-manylinux_2_40, aarch64-linux-android, x86_64-linux-android, wasm32-pyodide2024, arm64-apple-ios, arm64-apple-ios-simulator, x86_64-apple-ios-simulator] Index options: --index <INDEX> The URLs to use when resolving dependencies, in addition to the default index [env: UV_INDEX=] --default-index <DEFAULT_INDEX> The URL of the default package index (by default: <https://pypi.org/simple>) [env: UV_DEFAULT_INDEX=] -i, --index-url <INDEX_URL> (Deprecated: use `--default-index` instead) The URL of the Python package index (by default: <https://pypi.org/simple>) [env: UV_INDEX_URL=] --extra-index-url <EXTRA_INDEX_URL> (Deprecated: use `--index` instead) Extra URLs of package indexes to use, in addition to `--index-url` [env: UV_EXTRA_INDEX_URL=] -f, --find-links <FIND_LINKS> Locations to search for candidate distributions, in addition to those found in the registry indexes [env: UV_FIND_LINKS=] --no-index Ignore the registry index (e.g., PyPI), instead relying on direct URL dependencies and those provided via `--find-links` --index-strategy <INDEX_STRATEGY> The strategy to use when resolving against multiple index URLs [env: UV_INDEX_STRATEGY=] [possible values: first-index, unsafe-first-match, unsafe-best-match] --keyring-provider <KEYRING_PROVIDER> Attempt to use `keyring` for authentication for index URLs [env: UV_KEYRING_PROVIDER=] [possible values: disabled, subprocess] Resolver options: -U, --upgrade Allow package upgrades, ignoring pinned versions in any existing output file. Implies `--refresh` -P, --upgrade-package <UPGRADE_PACKAGE> Allow upgrades for a specific package, ignoring pinned versions in any existing output file. Implies `--refresh-package` --resolution <RESOLUTION> The strategy to use when selecting between the different compatible versions for a given package requirement [env: UV_RESOLUTION=] [possible values: highest, lowest, lowest-direct] --prerelease <PRERELEASE> The strategy to use when considering pre-release versions [env: UV_PRERELEASE=] [possible values: disallow, allow, if-necessary, explicit, if-necessary-or-explicit] --fork-strategy <FORK_STRATEGY> The strategy to use when selecting multiple versions of a given package across Python versions and platforms [env: UV_FORK_STRATEGY=] [possible values: fewest, requires-python] --exclude-newer <EXCLUDE_NEWER> Limit candidate packages to those that were uploaded prior to the given date [env: UV_EXCLUDE_NEWER=] --exclude-newer-package <EXCLUDE_NEWER_PACKAGE> Limit candidate packages for specific packages to those that were uploaded prior to the given date --no-sources Ignore the `tool.uv.sources` table when resolving dependencies. Used to lock against the standards-compliant, publishable package metadata, as opposed to using any workspace, Git, URL, or local path sources [env: UV_NO_SOURCES=] Installer options: --reinstall Reinstall all packages, regardless of whether they're already installed. Implies `--refresh` --reinstall-package <REINSTALL_PACKAGE> Reinstall a specific package, regardless of whether it's already installed. Implies `--refresh-package` --link-mode <LINK_MODE> The method to use when installing packages from the global cache [env: UV_LINK_MODE=] [possible values: clone, copy, hardlink, symlink] --compile-bytecode Compile Python files to bytecode after installation [env: UV_COMPILE_BYTECODE=] Build options: -C, --config-setting <CONFIG_SETTING> Settings to pass to the PEP 517 build backend, specified as `KEY=VALUE` pairs --config-settings-package <CONFIG_SETTINGS_PACKAGE> Settings to pass to the PEP 517 build backend for a specific package, specified as `PACKAGE:KEY=VALUE` pairs --no-build-isolation Disable isolation when building source distributions [env: UV_NO_BUILD_ISOLATION=] --no-build-isolation-package <NO_BUILD_ISOLATION_PACKAGE> Disable isolation when building source distributions for a specific package --no-build Don't build source distributions [env: UV_NO_BUILD=] --no-build-package <NO_BUILD_PACKAGE> Don't build source distributions for a specific package [env: UV_NO_BUILD_PACKAGE=] --no-binary Don't install pre-built wheels [env: UV_NO_BINARY=] --no-binary-package <NO_BINARY_PACKAGE> Don't install pre-built wheels for a specific package [env: UV_NO_BINARY_PACKAGE=] Cache options: -n, --no-cache Avoid reading from or writing to the cache, instead using a temporary directory for the duration of the operation [env: UV_NO_CACHE=] --cache-dir <CACHE_DIR> Path to the cache directory [env: UV_CACHE_DIR=] --refresh Refresh all cached data --refresh-package <REFRESH_PACKAGE> Refresh cached data for a specific package Python options: -p, --python <PYTHON> The Python interpreter to use for the run environment. [env: UV_PYTHON=] --managed-python Require use of uv-managed Python versions [env: UV_MANAGED_PYTHON=] --no-managed-python Disable use of uv-managed Python versions [env: UV_NO_MANAGED_PYTHON=] --no-python-downloads Disable automatic downloads of Python. [env: "UV_PYTHON_DOWNLOADS=never"] Global options: -q, --quiet... Use quiet output -v, --verbose... Use verbose output --color <COLOR_CHOICE> Control the use of color in output [possible values: auto, always, never] --native-tls Whether to load TLS certificates from the platform's native certificate store [env: UV_NATIVE_TLS=] --offline Disable network access [env: UV_OFFLINE=] --allow-insecure-host <ALLOW_INSECURE_HOST> Allow insecure connections to a host [env: UV_INSECURE_HOST=] --no-progress Hide all progress outputs [env: UV_NO_PROGRESS=] --directory <DIRECTORY> Change to the given directory prior to running the command [env: UV_WORKING_DIR=] --project <PROJECT> Discover a project in the given directory [env: UV_PROJECT=] --config-file <CONFIG_FILE> The path to a `uv.toml` file to use for configuration [env: UV_CONFIG_FILE=] --no-config Avoid discovering configuration files (`pyproject.toml`, `uv.toml`) [env: UV_NO_CONFIG=] -h, --help Display the concise help for this command Use `uv help run` for more details. ``` # Purpose For simplest way to execute code in an implicit, ephemeral virtual environment (i.e. the Python interpreter is an implementation detail). This could be limited to just inline script metadata if that would help with acceptance. # Ideas Need to consider [[Caching app files while being ignored by backup apps]] for the implicit virtual environments. - Supporting `pyproject.toml` - `--group`/`--with`: Specifies the dependency group to use (only applicable when a directory path is specified, maybe zip file if it ships with a `pyproject.toml`) - Care about extras, e.g. `--extra` or implicitly specified via `--group`/`--with`? - `uv` uses `--extra` - Making it the same name as for dependency groups helps transition from an extra to a group when a project makes such a move - Execute what's in `bin/` for the virtual environment if command name is specified? - Fall back to `-m` if nothing found in `bin/` matching the name (and it wasn't a valid path)? - Automatically do an editable install? - Basically run [[sync]] ? - What happens when there is inline script metadata and `pyproject.toml`? - If a file path is specified: - If the file is a zip file, do anything special like look for inline script metadata in `__main__.py`? A lock file? - If [inline script metadata](https://packaging.python.org/en/latest/specifications/inline-script-metadata/) is specified, use that - Otherwise assume metadata of no dependencies and any Python version - If a directory path is specified: - For convenience when a [directory contains a `__main__.py` file](https://docs.python.org/3/using/cmdline.html) - Use inline script metadata, `pyproject.toml`, or `pylock.toml`? - Provide a way to specify whether `launch` or `run` are the default when no subcommand specified? - Don't read the shebang; only rely on the metadata to limit the Python version