# Python toolchain

> What Elide's Python toolchain covers in 1.6.0: the optional Python component, running scripts and modules, pyproject.toml entry points, virtual environments, tests, and what is not available.

Python support is experimental. Elide runs Python 3.13 with its standard library and optional package tooling.
Python formatting and test discovery under `elide test` remain unavailable.

| Task | Command | Status |
| --- | --- | --- |
| Add Python to an install | `elide setup python` | Available |
| Run a script, `-c` or `-m` | `elide python ...`, `elide run app.py` | Available |
| Run a `pyproject.toml` entry point | `elide run NAME` | Available |
| Use packages from a virtual environment | `VIRTUAL_ENV=.venv elide python app.py` | Available |
| Run unittest or pytest | `elide python -m unittest`, `elide python -m pytest` | Available |
| Install PyPI packages | `elide install --ecosystems=pypi`, `elide uv install` | Requires the Python component and pytools |
| Discover Python tests | `elide test` | Not available |
| Format, LSP, `elide init` template | | Not available |

## Add Python

Python is an optional component:

```bash
elide setup python
```

Without it, Python commands print `Python support is not installed. Run 'elide setup python' to add it.` and exit `2`.
See [Python with Elide](https://elide.help/docs/python) for channels and package-manager installs.

## Run Python

`elide python` takes the same arguments as `python`; `elide run` and a bare `elide app.py` run `.py` files too:

```bash
elide python app.py --name Elide
elide python -m json.tool input.json
elide run app.py
```

Interpreter flags (`-I`, `-B`, `-u`, `-W`, ...) are listed in [Python with Elide](https://elide.help/docs/python#interpreter-options).

## Run project scripts

`elide run NAME` runs a `[project.scripts]` entry point from the `pyproject.toml` in the current directory. No
`elide.pkl` is needed.

```toml
# pyproject.toml
[project]
name = "greet"
version = "0.1.0"
requires-python = ">=3.13"

[project.scripts]
greet = "greet.cli:main"
```

```python
# greet/cli.py
import sys


def greeting(name: str) -> str:
    return f"Hello, {name}!"


def main() -> int:
    print(greeting(sys.argv[1] if len(sys.argv) > 1 else "world"))
    return 0
```

```bash
elide run greet Elide
```

```terminaloutput
Hello, Elide!
```

`elide greet Elide` does the same. Arguments after the name go to `sys.argv`, and the function's integer return value
is the exit code. A file named `greet`, an `elide.pkl` script or a `package.json` script of the same name wins; see
[Project setup](https://elide.help/docs/projects#add-a-script).

## Packages

Use `elide install --ecosystems=pypi` for declared dependencies, or `elide uv install PACKAGE`.
Packages go into the project's automatic environment with no activation. See
[Packages and virtual environments](https://elide.help/docs/python-packages).

## Tests

Run unittest or pytest through `elide python -m`; see [Python tests](https://elide.help/docs/python-testing). `elide test` runs JavaScript,
TypeScript and JUnit tests only.

## Samples

- [Python calling JavaScript](https://elide.help/docs/code-samples#python-calling-javascript)
- [JavaScript importing Python](https://elide.help/docs/code-samples#javascript-importing-python)
- [Python script](https://elide.help/docs/code-samples#python-script)

`elide init` has no Python template.

## Known limitations

- **C extensions**: some C extension modules do not load.
- **pip**: not bundled; `elide python -m pip` fails with `No module named pip`.
- More: [Python with Elide](https://elide.help/docs/python#known-limitations).
