Python Tooling Explained
Background and context articles that explain the why behind Python tools, packaging standards, and ecosystem decisions.
Explanation pages give the context behind Python’s tooling: what concepts mean, why standards exist, how tools compare, and what trade-offs they make. They are for reading, not doing.
To set up a tool, start with a Tutorial. To solve a specific problem, see the How-To guides.
The groups below organize concepts, tool comparisons, PEPs and standards, coming-from-another-language guides, and opinionated philosophy pieces.
Complete Guides
Long-form walkthroughs of uv, Ruff, ty, Claude Code, and Codex
Complete Guide to Claude Code
How to use Claude Code for Python development: setup, testing, debugging, and effective prompting.
Complete Guide to Codex
How to use OpenAI's Codex CLI for Python development: sandbox modes, autonomy levels, project setup, testing, and scripted automation.
Complete Guide to Ruff
A comprehensive guide to Ruff, the fast Python linter and formatter that replaces flake8, Black, isort, and dozens of other tools with a single binary. Learn installation, configuration, core workflows, and migration strategies.
Complete Guide to ty
A comprehensive guide to ty, the fast Python type checker from Astral. Learn installation, configuration, editor setup, and migration from mypy or pyright.
Complete Guide to uv
A comprehensive guide to uv, the fast Python package manager that replaces pip, pyenv, pipx, and virtualenv with a single tool. Learn installation, core workflows, and migration strategies.
Core Concepts
Definitions of virtual environments, lock files, build backends, and packaging vocabulary
Sampling vs deterministic profilers: which should I use?
Sampling profilers peek at a running program on a timer; deterministic profilers hook every call. Each distorts a different kind of program. Here's how to choose.
Understanding dependency groups in uv
How dependency groups, optional dependencies, and extras work in uv and pyproject.toml, and when to use each.
Understanding the Conda/Anaconda Ecosystem
How conda, Miniconda, Anaconda, and conda-forge fit together as a language-agnostic package management ecosystem for scientific computing.
uv init: project types, flags, and examples
uv init creates a new Python project with pyproject.toml, a venv, and a lockfile. Covers --app, --lib, --package, --bare, and --python flags.
What are Optional Dependencies and Dependency Groups?
Optional dependencies provide installable feature extras for end users, while dependency groups organize dev and test requirements.
What is a .python-version file?
A .python-version file specifies which Python version to use for a project, recognized by uv and pyenv.
What is a build backend?
Build backends turn source code into installable Python packages. They exist because PEP 517 split package building into two halves, letting standard frontends invoke any backend through a common hook API.
What is a build frontend?
A build frontend orchestrates the package build process by invoking build backends and managing build environments.
What is a lockfile?
A lockfile records exact dependency versions to guarantee reproducible Python environments across systems and time.
What is a Python application?
A Python application is a self-contained program for end users, unlike a package designed to be imported by other code.
What is a Python Interpreter?
A Python interpreter is the program that reads and executes Python code. Understanding where interpreters live and how tools find them clarifies most Python environment issues.
What is a Python module?
A Python module is any file or extension Python can import. Pure modules are .py source files; extension modules are compiled .so or .pyd binaries. A directory of modules with an __init__.py is an import package, not a module.
What is a Python package?
A Python package is a collection of code modules bundled with metadata, distributed as wheels, sdists, or conda packages.
What is a Virtual Environment?
A virtual environment is an isolated Python runtime that lets each project maintain its own dependencies and Python version.
What Is an Editable Install?
An editable install links a package's source code to the Python environment so code changes take effect without reinstalling.
What is CPython's JIT Compiler?
CPython's experimental JIT compiler translates hot bytecode paths into machine code at runtime using a copy-and-patch technique, aiming to speed up Python without requiring any code changes.
What is PyPA (Python Packaging Authority)?
PyPA is the working group that maintains core Python packaging tools including pip, setuptools, wheel, and twine.
What is PyPI (Python Package Index)?
PyPI is the official repository where Python developers publish and discover installable packages via pip and uv.
What is Python?
Python is a high-level, general-purpose programming language with a rich ecosystem of tools, organizations, and governance.
What is the GIL?
The Global Interpreter Lock is a mutex in CPython that allows only one thread to execute Python bytecode at a time, trading thread parallelism for simple internals and safe C extensions.
What's the difference between a distribution package and an import package?
A distribution package is what you install (the name on PyPI). An import package is what you import in Python (the directory of modules). They don't have to share a name, which is why pip install Pillow gives you import PIL.
When to Use `uv run` vs `uvx`
Use uv run for project code that needs your dependencies; use uvx for standalone tools that run independently.
Tool Comparisons
How uv, Poetry, pip, pixi, and other tools differ in features and workflow
Do you still need tox or nox if you use uv?
uv can run tests across Python versions on its own, but tox and nox still earn their place when you need dependency matrices, parallel execution, or session orchestration.
Do you still need tox or nox if you use uv?
uv handles Python version installs and virtual environments, but tox and nox solve a different problem: orchestrating test matrices.
How do pyenv and uv compare for Python interpreter management?
pyenv focuses on Python version switching via shell shims, while uv integrates version management into a unified development toolkit.
How do Python type checkers compare?
mypy, pyright, ty, Pyrefly, Basedpyright, and Zuban are Python's major type checkers. They differ in speed, typing-spec conformance, default strictness, licensing, and editor integration.
How do Ruff and Pylint compare?
Ruff offers dramatically faster performance and automatic fixes via Rust, while Pylint provides deeper semantic analysis from Python.
How do uv and Poetry compare?
uv and Poetry both manage Python projects and dependencies through pyproject.toml, but they differ in scope, speed, and standards alignment.
src layout vs flat layout: which to use and why
The src layout prevents accidental imports during testing by placing your package under src/. The flat layout is simpler and suits applications you won't publish. Learn which to pick.
uv vs pixi vs conda for Scientific Python
Choosing between uv, pixi, and conda for scientific computing and GPU workloads depends on whether your dependencies live on PyPI, conda-forge, or both.
What's the difference between pip and uv?
pip and uv both install Python packages, but uv offers 10-100x faster performance and integrated environment management.
When should I choose pixi over uv?
Pixi and uv both manage Python projects with lockfiles and fast dependency resolution, but pixi adds access to conda channels for native and non-Python dependencies.
Which Python package manager should I use?
A decision tree for choosing the right Python package manager based on your project type, team needs, and technical requirements.
Standards & PEPs
PEP 8, 517, 621, 723, 735, and the standards that shape modern Python tooling
Versioning Python packages: SemVer, CalVer, and PEP 440
PEP 440 is the grammar every Python package has to follow. SemVer and CalVer are the policies teams lay on top. This page covers how the two map onto PEP 440, how `~=` behaves differently under each, and the caveats that keep catching maintainers.
What Are Wheel Variants?
Wheel variants extend Python's wheel format so packages can ship hardware-specific builds under one name. PEP 817 and PEP 825 specify how installers detect the host and pick the right one.
What is a PEP?
Python Enhancement Proposals (PEPs) are formal documents that propose new features, collect community input, and record design decisions.
What is a version specifier?
A version specifier tells pip, uv, or any PEP 440 resolver which versions of a package are acceptable, using operators like ==, >=, ~=, !=, ===, and the compatible release clause.
What is core metadata?
Core metadata is the standardized set of fields that describes a Python distribution: name, version, dependencies, classifiers, and more. It lives in the METADATA file inside a wheel, PKG-INFO inside an sdist, and is queryable at runtime via importlib.metadata.
What is PEP 503?
PEP 503 defines the Simple Repository API that package indexes like PyPI implement for compatibility with pip and uv.
What is PEP 517/518 compatibility?
PEP 517 and PEP 518 define standard interfaces for Python build systems, moving packaging from setup.py to pyproject.toml.
What is PEP 609?
PEP 609 establishes the governance model for the Python Packaging Authority, formalizing membership, decision making, and project lifecycle.
What is PEP 621 compatibility?
PEP 621 standardizes how Python projects declare core metadata like name, version, and dependencies in pyproject.toml.
What is PEP 660?
PEP 660 standardizes how build backends implement editable installs, replacing the setuptools-only setup.py develop approach.
What is PEP 668?
PEP 668 marks system Python installations as externally managed, causing pip to refuse package installation outside a virtual environment.
What is PEP 703?
PEP 703 adds a build configuration that lets CPython run without the Global Interpreter Lock, producing the free-threaded Python interpreter.
What is PEP 723?
PEP 723 defines a standard for embedding dependency and Python version requirements directly in Python script files.
What is PEP 735?
PEP 735 adds a standard [dependency-groups] table to pyproject.toml so tools like uv, pip, Poetry, and PDM can share one way to declare development dependencies.
What is PEP 751?
PEP 751 introduces pylock.toml, a standardized lockfile format for reproducible Python dependency installation.
What is PEP 772?
PEP 772 establishes the Python Packaging Council, an elected body with authority over packaging standards, replacing PyPA's informal governance under PEP 609.
What is PEP 773?
PEP 773 introduces PyManager, a unified tool for installing and managing Python versions on Windows, replacing the traditional installer and py launcher.
What is PEP 779?
PEP 779 sets the criteria the free-threaded Python build had to meet before Python 3.14 could mark it officially supported.
What is PEP 8?
PEP 8 is Python's official style guide covering naming conventions, whitespace, line length, and code formatting standards.
Why pylock.toml Includes Digital Attestations
The pylock.toml lockfile format records publisher identities alongside package hashes, letting you detect supply chain compromises by diffing your lockfile.
Coming From Another Language
Python tooling for engineers experienced with Go, Rust, TypeScript, Java, or C#
Python Tooling for C# Developers
A guide to Python's development tooling for developers coming from the C# and .NET ecosystem.
Python Tooling for Go Developers
A guide to Python's development tooling for developers coming from the Go ecosystem.
Python Tooling for Java Developers
A guide to Python's development tooling for developers coming from the Java ecosystem.
Python Tooling for Rust Developers
A guide to Python's development tooling for developers coming from the Rust ecosystem.
Python Tooling for TypeScript Developers
A guide to Python's development tooling for developers coming from the TypeScript and JavaScript ecosystem.
uv for Non-Python Teams
Teams whose primary language isn't Python still end up with Python scripts, CI helpers, and CLI tools. uv is the single-tool answer that keeps that work from becoming its own admin job.
Why Python Tooling Looks Like This
Opinionated takes on packaging history, defaults, and recommended choices
Do I need a project to use uv?
You don't. Here are the real options for using uv with a directory of single-file scripts, and when to pick each.
Does Poetry Support Python Standards for Dependency Management?
Poetry 2.0 adopted PEP 621 standard project metadata in pyproject.toml while retaining its own tool.poetry section for advanced features.
Is Conda actually free?
The conda package manager and conda-forge are free and open source, but Anaconda's repository requires a paid license for organizations with more than 200 employees.
Should I run `python setup.py`?
Commands like python setup.py install and python setup.py sdist are deprecated. Use python -m build and pip install instead.
Should I use Homebrew to install Python?
Homebrew's Python exists to support other Homebrew tools and can break unexpectedly on upgrade. Use uv to manage Python instead.
Why are there so many Python packaging tools?
PEP 517 broke setuptools' monopoly on Python packaging, and a dozen alternatives rushed in to fill the gap.
Why did uv originally use Hatch as a build backend?
uv originally defaulted to Hatchling as its build backend because it was modern, standards-compliant, and had minimal dependencies. Since July 2025, uv_build is the default.
Why doesn't Python just fix packaging?
Python's packaging frustrations stem from its decentralized ecosystem: the organizations that could unify it have each chosen not to, for understandable reasons.
Why Doesn't the Authoritative Python Packaging Guide Mention the Best Thing that's Happened to Python Packaging?
The Python Packaging User Guide omits uv because PyPA only documents its own tools, despite uv's widespread adoption.
Why Installing a Python Package Can Run Code
A Python package can execute code at three different moments: once when it installs, and twice at every interpreter startup afterward. Seeing all three explains why supply-chain defenses look the way they do.
Why should I avoid using the system Python?
The system Python is shared with your OS. Installing packages into it risks breaking system tools, creates permission headaches, and locks every project to one Python version.
Why should I choose Conda?
Conda manages non-Python dependencies that pip cannot, making it the right choice when your project depends on compiled libraries across languages.
Why Should I Choose pyproject.toml over requirements.txt for managing dependencies?
pyproject.toml provides standardized metadata, build configuration, and tool settings in one file versus requirements.txt's flat dependency list.
Why should I use a virtual environment?
Virtual environments prevent dependency conflicts, protect system Python, and make projects reproducible across machines.
Why use native uv commands instead of uv pip
uv's native project interface (uv add, uv sync, uv run) provides lockfiles, declarative dependencies, and automatic environments that uv pip cannot.
Why Use Trusted Publishing for PyPI?
Trusted publishing replaces long-lived PyPI API tokens with short-lived OIDC credentials, eliminating the most common way attackers gain unauthorized upload access to PyPI.
Why You Should Try uv if You Use Python
uv consolidates pip, virtualenv, pyenv, and pip-tools into one fast, standards-based tool for Python development.
Topic Deep Dives
Longer explorations of how Python tools work under the hood
Enough Git to Supervise Your AI Coding Agent
The mental model of Git and GitHub you need to understand what your AI coding agent is doing with version control.
How do I ship a Python application to end users?
A practical guide to the 2026 options for distributing Python applications: from uvx one-liners to freezer bundles to ONNX for ML.
How Does Hot Reloading Work in Python?
Python has no universal hot-reload convention. Instead, different tools and frameworks implement their own approaches to reloading code during development.
How Python Package Formats Evolved: From tar.gz to .whl
The 25-year journey from distutils tarballs through eggs to wheels, and how each format solved one problem while creating the next.
How Python tools adopt uv under the hood
Hatch, PDM, pixi, tox, and other tools embed uv's resolver and installer as shared infrastructure, giving their users uv's speed without switching tools.
Modern Python Project Setup Guide for AI Assistants
Standardized instructions for AI assistants to scaffold modern Python projects using uv and pyproject.toml.
What Happens When You Run `uv run`
A step-by-step breakdown of the six stages uv performs before your command executes: project discovery, Python resolution, environment creation, locking, syncing, and execution.
Why Installing GPU Python Packages Is So Complicated
Python's wheel format cannot express GPU hardware requirements, forcing every CUDA package to invent its own installation workaround. Here is how the ecosystem works today and what wheel variants will change.