# How to Manage Multiple Python Versions with mise: Core Plugin Guide

> Easily manage multiple Python versions with mise. Install runtimes, set project defaults, and switch contexts instantly using simple commands. Boost your Python workflow.

- Repository: [jdx/mise](https://github.com/jdx/mise)
- Tags: how-to-guide
- Published: 2026-08-09

---

**To manage multiple Python versions with mise, install specific runtimes with `mise install`, declare project defaults in `.python-version` or [`mise.toml`](https://github.com/jdx/mise/blob/main/mise.toml), and switch contexts instantly using `mise use` or automatic shims.**

Managing multiple Python versions with mise provides a declarative alternative to traditional version managers. The tool treats Python as a core plugin—implemented in [`src/plugins/core/python.rs`](https://github.com/jdx/mise/blob/main/src/plugins/core/python.rs)—that implements the generic `Backend` trait to handle version resolution, installation, and environment activation. This architecture allows you to maintain several Python interpreters simultaneously while ensuring the correct binary appears in your PATH based on project context.

## How mise Handles Python Version Resolution

The Python core plugin in [`src/plugins/core/python.rs`](https://github.com/jdx/mise/blob/main/src/plugins/core/python.rs) orchestrates the entire lifecycle of Python runtime management. When you execute a command like `mise use python@3.14`, the backend converts each `python@X.Y` specifier into a **ToolRequest** object that resolves against available versions from python-build-standalone or compiled binaries.

### Version Discovery and Installation

Unlike tools that rely solely on semantic versioning assumptions, the mise Python backend queries exact build metadata to interpret specifiers like "latest", "3.14", or flavor tags such as `anaconda`. Once resolved, the backend invokes `python-build` or downloads pre-compiled binaries into `$HOME/.local/share/mise/installs/python/<version>` according to the documentation in [`docs/lang/python.md`](https://github.com/jdx/mise/blob/main/docs/lang/python.md).

After installation, each Python binary registers with mise's internal **Toolset**, enabling the `mise which` and `mise where` commands to resolve to the correct shim path immediately.

## Installing Multiple Python Versions

To install several Python versions side-by-side, specify multiple version constraints in a single command. The mise registry (defined in [`registry/python.toml`](https://github.com/jdx/mise/blob/main/registry/python.toml)) maps the `python` tool name to its backend configuration, allowing simultaneous management of disparate releases.

Install specific versions globally:

```bash
mise install python@3.14 python@3.15

```

This creates distinct installations in `$HOME/.local/share/mise/installs/python/3.14` and `$HOME/.local/share/mise/installs/python/3.15`, each with isolated standard libraries and site-packages.

## Configuring Version Selection

Mise supports two primary methods for declaring which Python version a project should use: legacy `.python-version` files and the modern [`mise.toml`](https://github.com/jdx/mise/blob/main/mise.toml) configuration.

### Using mise.toml

Add the following to your project's [`mise.toml`](https://github.com/jdx/mise/blob/main/mise.toml) to set a default Python version:

```toml
[tools]
python = "3.15"

```

### Using .python-version Files

For compatibility with existing workflows, mise automatically detects `.python-version` files containing a single version string:

```

3.14

```

When present in a directory, this file overrides global defaults but yields to explicit [`mise.toml`](https://github.com/jdx/mise/blob/main/mise.toml) configurations in the same project.

## Activating and Switching Versions

The `mise use` command, documented in [`docs/cli/use.md`](https://github.com/jdx/mise/blob/main/docs/cli/use.md), provides granular control over which Python interpreter is active for a specific shell session or project.

### Temporary Version Switching

Activate a specific version for the current shell only:

```bash
mise use python@3.14
python -V  # → Python 3.14.x

```

### Global Default Management

Set multiple global defaults simultaneously while maintaining explicit binary access:

```bash
mise use -g python@3.14 python@3.15
python -V      # → Python 3.14.x (primary global)

python3.15 -V  # → Python 3.15.x (explicit binary)

```

When you spawn a shell with `mise activate`, the shim directory prepends the selected Python binary to your `$PATH`. Because each request can specify a different version, you can have several shims active simultaneously, enabling per-project or per-command version selection.

## Virtual Environment Integration

Mise provides two distinct mechanisms for virtual environment management that integrate with its Python version handling.

### Custom Virtual Environments

The `_.python.venv` setting in [`mise.toml`](https://github.com/jdx/mise/blob/main/mise.toml) creates or activates a custom virtual environment using `python -m venv` or `uv`:

```toml
_.python.venv = { path = ".venv", create = true, python = "3.14" }

```

When you run `mise activate`, this configuration automatically creates the virtual environment if it does not exist and sources it, shadowing the global shim with the venv's interpreter.

### Automatic uv Integration

For projects using the uv package manager, enable `python.uv_venv_auto` in your settings:

```toml
[settings]
python.uv_venv_auto = "create|source"

```

This setting triggers when a `uv.lock` file is present, automatically sourcing or creating a uv-managed virtual environment without manual configuration. As noted in [`docs/mise-cookbook/python.md`](https://github.com/jdx/mise/blob/main/docs/mise-cookbook/python.md), this mechanism maintains a single source of truth for the interpreter version while leveraging uv's performance benefits.

## Practical Configuration Examples

The following patterns demonstrate common workflows for managing multiple Python versions with mise:

**Global configuration with local overrides:**

```toml

# ~/.config/mise/config.toml

[tools]
python = "3.15"

```

```toml

# ~/legacy-project/mise.toml

[tools]
python = "3.14"

```

**Automatic virtual environment activation:**

```toml

# mise.toml

[tools]
python = "3.15"

_.python.venv = {
  path = ".venv",
  create = true,
  python = "3.15"
}

```

**Multiple versions for testing:**

```bash

# Install both versions

mise install python@3.14 python@3.15

# Use 3.14 for current shell

mise use python@3.14

# Verify isolation

which python    # → ~/.local/share/mise/installs/python/3.14/bin/python

```

## Summary

- The Python core plugin in [`src/plugins/core/python.rs`](https://github.com/jdx/mise/blob/main/src/plugins/core/python.rs) implements the `Backend` trait to resolve, install, and register Python versions without relying on external version managers.
- Versions install to `$HOME/.local/share/mise/installs/python/<version>` and register with mise's `Toolset` for immediate shim availability.
- Use `mise use` to switch between versions globally, per-project, or per-shell session while maintaining access to explicit binaries like `python3.15`.
- Configure project defaults via [`mise.toml`](https://github.com/jdx/mise/blob/main/mise.toml) or `.python-version` files, with the former taking precedence.
- Integrate virtual environments using `_.python.venv` for standard venv/uv workflows or `python.uv_venv_auto` for zero-configuration uv projects.

## Frequently Asked Questions

### How does mise resolve ambiguous Python version requests?

The Python backend in [`src/plugins/core/python.rs`](https://github.com/jdx/mise/blob/main/src/plugins/core/python.rs) converts version strings like "3.14" or "latest" into exact `ToolRequest` objects by consulting metadata from python-build-standalone or compiled binary manifests. This ensures that "3.14" resolves to the latest patch release available in the build registry rather than relying on semantic versioning assumptions.

### Can I use multiple Python versions simultaneously in the same shell?

Yes. When you run `mise use -g python@3.14 python@3.15`, mise registers both versions in the `Toolset`. The first specified version becomes the default `python` binary, while additional versions remain accessible via versioned binaries like `python3.15`. Both shims appear in your PATH, allowing you to invoke specific interpreters explicitly.

### What is the difference between `_.python.venv` and `python.uv_venv_auto`?

`_.python.venv` is a general-purpose configuration that works with any Python project, using `python -m venv` or `uv` to create and activate virtual environments based on your specified path and Python version. In contrast, `python.uv_venv_auto` is a setting that only activates when a `uv.lock` file exists, automatically managing uv-specific virtual environments without explicit path configuration.

### Where does mise store downloaded Python interpreters?

Installed Python versions reside in `$HOME/.local/share/mise/installs/python/<version>` according to the source code in [`docs/lang/python.md`](https://github.com/jdx/mise/blob/main/docs/lang/python.md). This centralized location allows mise to maintain multiple versions independently while exposing them through shims in `$HOME/.local/share/mise/shims` that adjust dynamically based on your current `Toolset`.