# Inspiration - [`pipx run`](https://pipx.pypa.io/latest/docs/#pipx-run) ([0.11.0.0](https://pipx.pypa.io/latest/changelog/#:~:text=Replace%20pipx%20BINARY%20with%20pipx%20run%20BINARY%20to%20run%20a%20binary%20in%20an%20ephemeral%20environment.) [on 2019-01-27](https://github.com/pypa/pipx/releases/tag/0.11.0.0) for the concept, [1.4.2 for inline script metadata](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) [on 2024-01-12](https://github.com/pypa/pipx/releases/tag/1.4.2)) - [`hatch env run`](https://hatch.pypa.io/latest/cli/reference/#hatch-run) ([inline script metadata in 1.10.0 on 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)) - [`pdm run`](https://pdm-project.org/en/latest/reference/cli/#run) ([inline script metadata in 2.16.0 on 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)) - [`uv run`](https://docs.astral.sh/uv/reference/cli/#uv-run) ([0.3](https://astral.sh/blog/uv-unified-python-packaging) [on 2024-08-24](https://astral.sh/blog/uv-unified-python-packaging)) - [`poetry run`](https://python-poetry.org/docs/cli/#run) (but 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 ... ``` ## 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). # Ideas Need to consider [[Caching app files while being ignored by backup apps]] for the implicit virtual environments. - `--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 - 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 - 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)?