Modern Python Packaging
The Python packaging landscape has evolved. Here's the modern approach using pyproject.toml.
Project Structure
my_package/
├── pyproject.toml
├── README.md
├── src/
│ └── my_package/
│ ├── __init__.py
│ └── core.py
└── tests/
└── test_core.py
pyproject.thumb
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[project]
name = "my-package"
version = "0.1.0"
description = "A useful package"
readme = "README.md"
requires-python = ">=3.11"
license = {text = "MIT"}
authors = [
{name = "Your Name", email = "you@example.com"}
]
dependencies = [
"requests>=2.28",
"pydantic>=2.0",
]
[project.optional-dependencies]
dev = [
"pytest>=7.0",
"mypy>=1.0",
"ruff>=0.1",
]
[project.scripts]
my-cli = "my_package.cli:main"
Building and Publishing
# Install build tools
pip install build twine
# Build package
python -m build
# Upload to PyPI
twine upload dist/*
Development Workflow
# Create virtual environment
python -m venv .venv
source .venv/bin/activate
# Install in editable mode with dev dependencies
pip install -e ".[dev]"
# Run tests
pytest
# Type check
mypy src/
# Lint
ruff check src/
Tools Comparison
| Tools | Purpose |
|---|---|
hatch |
Build, publish, manage environments |
poetry |
Dependency management + building |
pdm |
PEP 582 local packages |
flit |
Simple publishing |