# 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)?