Skip to content

PEP 621 Projects

Learn how to use Tombo with modern PEP 621 Python projects. This is the current standard for Python packaging and the format Tombo works best with.

What is PEP 621?

PEP 621 defines how to store project metadata in pyproject.toml files. It's the modern standard that replaces setup.py for most Python projects.

Key benefits:

  • Declarative - Metadata defined in TOML, not Python code
  • Standard - Official Python packaging standard
  • Tool-agnostic - Works with pip, build, twine, and other tools
  • Rich metadata - Supports all PyPI metadata fields

Basic PEP 621 Structure

Here's a typical PEP 621 pyproject.toml file where Tombo provides rich assistance:

pyproject.toml
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

[project]
name = "my-awesome-project"
version = "0.1.0"
description = "An awesome Python project"
readme = "README.md"
license = {text = "MIT"}
authors = [
    {name = "Your Name", email = "you@example.com"},
]
classifiers = [
    "Development Status :: 4 - Beta",
    "Intended Audience :: Developers",
    "Programming Language :: Python :: 3",
    "Programming Language :: Python :: 3.8",
    "Programming Language :: Python :: 3.9",
    "Programming Language :: Python :: 3.10",
    "Programming Language :: Python :: 3.11",
]
requires-python = ">=3.8"
dependencies = [
    "requests>=2.28.0",     # ← Hover here for rich package info
    "click>=8.0.0",         # ← Completion works after >=, ==, ~=, etc.
    "pydantic>=2.0.0",      # ← See latest v2 versions
    "httpx>=0.24.0",        # ← Python compatibility indicators
]

[project.optional-dependencies]
dev = [
    "pytest>=7.0.0",       # ← Testing framework
    "black>=23.0.0",        # ← Code formatter
    "ruff>=0.0.250",        # ← Fast linter
    "mypy>=1.0.0",          # ← Type checker
]
docs = [
    "mkdocs>=1.4.0",        # ← Documentation generator
    "mkdocs-material>=9.0.0", # ← Material theme
]
test = [
    "pytest-cov>=4.0.0",   # ← Coverage plugin
    "pytest-mock>=3.10.0", # ← Mocking plugin
]

[project.urls]
Homepage = "https://github.com/username/my-awesome-project"
Documentation = "https://my-awesome-project.readthedocs.io"
Repository = "https://github.com/username/my-awesome-project.git"
Issues = "https://github.com/username/my-awesome-project/issues"

[project.scripts]
my-cli = "my_awesome_project.cli:main"

[project.gui-scripts]
my-gui = "my_awesome_project.gui:main"

[project.entry-points."my_awesome_project.plugins"]
plugin1 = "my_awesome_project.plugins:plugin1"

Tombo Features in PEP 621

Dependencies Array

The dependencies array is where Tombo shines:

pyproject.toml
[project]
dependencies = [
    "requests",           # Hover: See package description, latest version
    "requests>=",         # Completion: Get version suggestions after >=
    "requests>=2.28.0",   # Hover: See if this specific version exists
    "numpy~=1.24",        # Completion: See compatible ~= versions
    "pandas==2.0.3",      # Hover: Check if this exact version is available
]

What Tombo provides:

  • Rich hover information on package names
  • Version completion after constraint operators
  • Compatibility indicators for Python versions
  • Pre-release version detection
  • Yanked version warnings

Optional Dependencies

Organize development, testing, and documentation dependencies:

pyproject.toml
[project.optional-dependencies]
# Development tools
dev = [
    "black>=23.0.0",        # ← Hover to see latest formatting options
    "ruff>=0.0.250",        # ← Fast linter with many rules
    "pre-commit>=3.0.0",    # ← Git hooks for quality
]

# Testing framework
test = [
    "pytest>=7.0.0",       # ← Core testing framework
    "pytest-cov>=4.0.0",   # ← Coverage reporting
    "pytest-xdist>=3.0.0", # ← Parallel test execution
    "hypothesis>=6.0.0",   # ← Property-based testing
]

# Documentation
docs = [
    "mkdocs>=1.4.0",        # ← Documentation site generator
    "mkdocs-material>=9.0.0", # ← Beautiful theme
    "mkdocstrings[python]>=0.20.0", # ← API documentation
]

# Production extras
postgres = [
    "psycopg2-binary>=2.9.0", # ← PostgreSQL adapter
    "sqlalchemy>=2.0.0",      # ← ORM framework
]

redis = [
    "redis>=4.0.0",         # ← Redis client
    "celery>=5.2.0",        # ← Task queue
]

Installation examples:

# Install base dependencies
pip install .

# Install with development tools
pip install .[dev]

# Install multiple groups
pip install .[dev,test,docs]

# Install all optional dependencies
pip install .[dev,test,docs,postgres,redis]

Real-World Examples

Web API Project

pyproject.toml - FastAPI Web Service
[project]
name = "awesome-api"
version = "1.0.0"
description = "A high-performance web API"
requires-python = ">=3.8"
dependencies = [
    # Web framework
    "fastapi>=0.100.0",      # ← Modern async web framework
    "uvicorn[standard]>=0.20.0", # ← ASGI server with extras

    # Database
    "sqlalchemy>=2.0.0",     # ← Modern ORM with async support
    "alembic>=1.10.0",       # ← Database migrations
    "asyncpg>=0.28.0",       # ← Async PostgreSQL driver

    # Validation & serialization
    "pydantic>=2.0.0",       # ← Data validation with v2 features
    "pydantic-settings>=2.0.0", # ← Settings management

    # HTTP client
    "httpx>=0.24.0",         # ← Async HTTP client

    # Authentication
    "python-jose[cryptography]>=3.3.0", # ← JWT handling
    "passlib[bcrypt]>=1.7.0", # ← Password hashing

    # Monitoring
    "structlog>=23.0.0",     # ← Structured logging
    "prometheus-client>=0.16.0", # ← Metrics collection
]

[project.optional-dependencies]
dev = [
    "pytest>=7.0.0",
    "pytest-asyncio>=0.21.0", # ← Async test support
    "httpx>=0.24.0",          # ← Test client
    "pytest-cov>=4.0.0",
    "black>=23.0.0",
    "ruff>=0.0.250",
    "mypy>=1.0.0",
]

Data Science Project

pyproject.toml - ML/Data Science Project
[project]
name = "data-analysis-toolkit"
version = "0.2.0"
description = "Advanced data analysis and machine learning tools"
requires-python = ">=3.9"
dependencies = [
    # Core data science stack
    "numpy>=1.24.0",         # ← Numerical computing foundation
    "pandas>=2.0.0",         # ← Data manipulation and analysis
    "polars>=0.18.0",        # ← Fast DataFrame library alternative

    # Scientific computing
    "scipy>=1.10.0",         # ← Scientific computing library
    "scikit-learn>=1.3.0",   # ← Machine learning framework
    "statsmodels>=0.14.0",   # ← Statistical modeling

    # Deep learning
    "torch>=2.0.0",          # ← PyTorch deep learning framework
    "torchvision>=0.15.0",   # ← Computer vision models
    "transformers>=4.30.0",  # ← Hugging Face transformers

    # Visualization
    "matplotlib>=3.7.0",     # ← Basic plotting
    "seaborn>=0.12.0",       # ← Statistical visualization
    "plotly>=5.15.0",        # ← Interactive visualizations

    # Jupyter ecosystem
    "jupyter>=1.0.0",        # ← Jupyter metapackage
    "ipykernel>=6.0.0",      # ← Jupyter kernel
    "ipywidgets>=8.0.0",     # ← Interactive widgets
]

[project.optional-dependencies]
gpu = [
    "torch>=2.0.0+cu118",    # ← CUDA-enabled PyTorch
    "cupy>=12.0.0",          # ← GPU arrays
]

CLI Application

pyproject.toml - Command Line Tool
[project]
name = "awesome-cli"
version = "2.1.0"
description = "A powerful command-line tool"
requires-python = ">=3.8"
dependencies = [
    # CLI framework
    "click>=8.1.0",          # ← Command line interface creation
    "rich>=13.0.0",          # ← Rich text and beautiful formatting
    "typer>=0.9.0",          # ← Modern CLI framework (alternative)

    # Configuration
    "pydantic>=2.0.0",       # ← Data validation
    "pydantic-settings>=2.0.0", # ← Settings management
    "toml>=0.10.2",          # ← TOML file parsing

    # File operations
    "pathlib2>=2.3.0",       # ← Enhanced path operations
    "watchdog>=3.0.0",       # ← File system monitoring

    # Network operations
    "requests>=2.31.0",      # ← HTTP requests
    "urllib3>=2.0.0",        # ← HTTP client library

    # Progress and feedback
    "tqdm>=4.65.0",          # ← Progress bars
    "spinners>=0.0.24",      # ← Loading spinners
]

[project.scripts]
awesome = "awesome_cli.main:cli"
awesome-admin = "awesome_cli.admin:admin_cli"

[project.optional-dependencies]
dev = [
    "pytest>=7.0.0",
    "click-testing>=0.4.0",  # ← CLI testing utilities
    "coverage>=7.0.0",
]

Working with Constraints

Version Constraint Types

Tombo understands all PEP 440 version specifiers:

pyproject.toml
[project]
dependencies = [
    # Exact version
    "requests==2.31.0",      # ← Exactly 2.31.0

    # Greater than or equal
    "numpy>=1.24.0",         # ← 1.24.0 or newer

    # Compatible release (tilde)
    "pandas~=2.0.3",         # ← >=2.0.3, <2.1.0

    # Caret (not standard, but Poetry-style)
    "click^=8.1.0",          # ← >=8.1.0, <9.0.0 (if supported)

    # Complex constraints
    "django>=4.0.0,<5.0.0",  # ← Multiple constraints

    # Exclude specific versions
    "sqlalchemy>=1.4.0,!=1.4.5", # ← Exclude buggy version

    # Pre-release inclusion
    "fastapi>=0.100.0rc1",   # ← Include pre-releases explicitly
]

Tombo completion works after:

  • == - Exact version completion
  • >= - Minimum version completion
  • <= - Maximum version completion
  • ~= - Compatible release completion
  • != - Exclusion version completion
  • > - Greater than completion
  • < - Less than completion

Python Version Compatibility

Specify Python version requirements:

pyproject.toml
[project]
requires-python = ">=3.8"    # ← Tombo shows compatibility for this range

dependencies = [
    "typing-extensions>=4.0.0", # ← Hover shows: "Needed for Python <3.10"
    "importlib-metadata>=4.0.0", # ← Hover shows: "Needed for Python <3.8"
]

classifiers = [
    "Programming Language :: Python :: 3",
    "Programming Language :: Python :: 3.8",  # ← Supported versions
    "Programming Language :: Python :: 3.9",
    "Programming Language :: Python :: 3.10",
    "Programming Language :: Python :: 3.11",
    "Programming Language :: Python :: 3.12",
]

Advanced PEP 621 Features

Dynamic Metadata

Some fields can be marked as dynamic:

pyproject.toml
[project]
name = "my-project"
dynamic = ["version", "description"]  # ← Loaded from __init__.py

dependencies = [
    "requests>=2.31.0",     # ← Static dependencies still get Tombo support
]

Entry Points

Define command-line scripts and plugins:

pyproject.toml
[project.scripts]
my-cli = "my_package.cli:main"
my-tool = "my_package.tools:run"

[project.gui-scripts]
my-gui = "my_package.gui:main"

[project.entry-points."console_scripts"]
custom-cmd = "my_package.custom:handler"

# Plugin system entry points
[project.entry-points."my_package.plugins"]
plugin_a = "my_package.plugins.a:PluginA"
plugin_b = "my_package.plugins.b:PluginB"

Best Practices with Tombo

1. Use Semantic Versioning Constraints

Good constraint choices
[project]
dependencies = [
    # Allow patch updates, pin major.minor
    "requests~=2.31.0",      # ← Allows 2.31.x updates

    # Allow minor updates, pin major
    "django>=4.2.0,<5.0.0",  # ← Django 4.x series

    # Pin exactly for very specific needs
    "pillow==10.0.0",        # ← Exact version for reproducibility
]
Logical grouping
[project.optional-dependencies]
# Web-specific dependencies
web = [
    "fastapi>=0.100.0",
    "uvicorn>=0.20.0",
    "jinja2>=3.1.0",
]

# Database dependencies
db = [
    "sqlalchemy>=2.0.0",
    "alembic>=1.10.0",
]

# All database drivers
db-postgres = ["psycopg2-binary>=2.9.0"]
db-mysql = ["pymysql>=1.0.0"]
db-sqlite = ["aiosqlite>=0.19.0"]

3. Use Comments for Context

Documented dependencies
[project]
dependencies = [
    # Core HTTP client - used throughout the application
    "httpx>=0.24.0",         # ← Async support required

    # Data validation - v2 required for performance
    "pydantic>=2.0.0",       # ← Breaking changes from v1

    # Serialization - msgpack faster than JSON for large data
    "msgpack>=1.0.0",        # ← Binary serialization format
]

Migration from setup.py

If you're migrating from setup.py to PEP 621:

Before (setup.py)

from setuptools import setup, find_packages

setup(
    name="my-package",
    version="1.0.0",
    install_requires=[
        "requests>=2.31.0",
        "click>=8.1.0",
    ],
    extras_require={
        "dev": ["pytest>=7.0.0", "black>=23.0.0"],
    },
)

After (pyproject.toml)

[project]
name = "my-package"
version = "1.0.0"
dependencies = [
    "requests>=2.31.0",     # ← Same deps, now with Tombo support!
    "click>=8.1.0",
]

[project.optional-dependencies]
dev = [
    "pytest>=7.0.0",
    "black>=23.0.0",
]

Benefits of migration:

  • Tombo support - Rich hover and completion
  • Standard format - Official Python packaging
  • Tool agnostic - Works with any build backend
  • Better tooling - More editor support

Next Steps

Ready to explore more Tombo features?

Troubleshooting PEP 621

Common Issues

Tombo not working in pyproject.toml?

  1. Check file name - Must be exactly pyproject.toml
  2. Verify section - Dependencies must be in [project] section
  3. Check syntax - Use array format: dependencies = ["package>=1.0"]
  4. Restart VS Code - Reload after major changes

Version completion not triggering?

  1. Use constraint operators - Type >=, ==, ~= to trigger
  2. Check cursor position - Must be after the operator
  3. Manual trigger - Use Ctrl+Space to force completion
  4. Check network - First lookup requires internet connection

Need more help? Check our troubleshooting guide!