# 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 in 1.6.0. Elide runs Python 3.13 with its standard library; it does not install PyPI
packages, format Python, or run Python tests under `elide test`.

| 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` | Not available; use a virtual environment |
| 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

`elide install` installs no PyPI packages, and `elide install --ecosystems=pypi` exits `2`. Install packages into a
Python 3.13 virtual environment with another tool and point Elide at it with `VIRTUAL_ENV`; 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).
