# Packages and virtual environments

> Install Python packages into an Elide project's automatic environment.

The native Elide launcher uses pytools, Elide's optional Python package tooling library. Install it with
`elide setup python`; use `elide setup python --force` to repair an older or incomplete installation.

Each project has an automatic package environment at `.dev/dependencies/pypi/site-packages`.
Elide adds it to Python's import path without activation or `VIRTUAL_ENV`.

```bash
elide uv install attrs
elide python -c 'import attrs; print(attrs.__version__)'
```

To install dependencies declared in `pyproject.toml`, `requirements.txt`, or `elide.pkl`:

```bash
elide install --ecosystems=pypi
```

`elide install --workspace` includes all declared ecosystems. A plain `elide install` retains
its Maven default.

## Package operations

`elide uv` accepts `install`, `sync`, `compile`, `check`, `list`, `freeze`, and `show`. The optional
`pip` namespace is also accepted, for example `elide uv pip install attrs`.

```bash
elide uv compile requirements.in --generate-hashes --output-file requirements.txt
elide uv sync requirements.txt
elide uv list
elide uv check
```

`compile` locks requirements; this surface does not yet expose uv's project `lock`,
`run`, runtime download, or runtime management commands. `sync` removes packages absent from the
requirements file. Clearing an environment with an empty file requires uv's explicit
`--allow-empty-requirements` option.

`check` validates the project package directory using uv’s dependency, Python-version, and wheel
compatibility diagnostics. It returns 1 for incompatible or missing dependencies.

Use `elide --project PATH uv ...` to select a project. Elide owns the interpreter and destination;
uv's interpreter and target settings do not redirect installation to another environment.
Index, offline, hash-verification, and cache options remain available. Source builds are disabled;
only compatible wheels can be installed. Native CPython wheels cannot substitute for GraalPy wheels.

## Isolated tools

Run a Python console script without installing its dependencies into your project:

```bash
elide uv tool run --from 'httpie==3.2.4' http --help
elide uv tool run --from PACKAGE --with EXTRA_PACKAGE COMMAND ARGS...
elide uv tool list
elide uv tool uninstall ENVIRONMENT_KEY
elide uv tool prune
elide uv tool prune --all
elide uv tool dir
```

Tool options precede `COMMAND`; everything after it is passed through to the tool. `--from` defaults
to the command name. Only compatible wheels are supported; tools requiring unsupported native
extensions or source builds will fail explicitly. This is an Elide-managed tool runner, not the
unrestricted upstream uv tool interface.

Elide runs console entrypoints with its own Python interpreter and preserves your working directory,
arguments, and exit status. Tool dependencies are isolated from project packages, `PYTHONPATH`, and
external virtual environments, including interpreter re-execution. Tools still have normal user
permissions; dependency isolation is not a security sandbox.

Environments live under `$ELIDE_HOME/python/tools`, or the existing Elide user data directory
(`$XDG_DATA_HOME/elide`, falling back to `~/.local/share/elide`). Cache keys include the Elide runtime
identity, package requirements, and index options. Pin requirements for reproducibility; use
`tool run --refresh` to resolve again, including after changing a local wheel at the same path.
`--offline`, `--no-index`, `--index-url`, and `--find-links` are supported.

The cache defaults to **2 GiB** and **30 days since last use**. Each run evicts expired entries and
least-recently-used inactive environments as needed. Set `ELIDE_PYTHON_TOOLS_MAX_BYTES` to adjust the
size limit. Oversized installs are discarded; active environments are protected, so a full cache of
running tools can reject a new install. Size is checked during cache operations, not enforced as a
filesystem quota while arbitrary tool code runs.

`tool list` shows environment keys, byte sizes, and requirements. `tool uninstall KEY` removes one
inactive environment. `tool prune` applies expiry and size limits; `tool prune --all` purges every
inactive environment. The runner avoids a second persistent uv download cache and removes incomplete
staging data on the next cache operation. Cleanup never touches project environments.

## External virtual environments

`VIRTUAL_ENV` remains supported for importing compatible Python 3.13 packages from an external
virtual environment. The project's own packages take precedence over that environment. This is
optional; it is not needed for packages installed through Elide.

Python support remains experimental. The LLVM-driven GraalPy native-extension builder is not yet
implemented. pip is not bundled; use the package commands above.
