Python Packaging

A 'controversial' opinion

Using `setup.py` to pack and distribute your python packages can be quite challenging every so often. Modern tools like Poetry and UV make not only the packaging a lot easier, but also help you to manage your dependencies in a very convenient way. UV is particularly notable for being 10-100x faster than traditional tools.

If you want more information about Poetry you can read the following articles:

For a comprehensive guide to UV, the lightning-fast Python package manager, read: UV: The Lightning-Fast Python Package Manager.

Introduction

Python packaging is the process of preparing your Python project for distribution and installation. There are two main approaches: the traditional setup.py method and the modern pyproject.toml approach (defined in PEP-517, PEP-518, and PEP-660).

For a comprehensive guide on handling file and directory paths, which is essential for managing project structures, see the File and directory Paths page.

Traditional Approach: setup.py

The setup.py file is at the heart of a traditional Python project. It describes all the metadata about your project. There are quite a few fields you can add to a project to give it a rich set of metadata describing the project. However, there are only three required fields: name, version, and packages. The name field must be unique if you wish to publish your package on the Python Package Index (PyPI). The version field keeps track of different releases of the project. The package’s field describes where you’ve put the Python source code within your project.

This allows you to easily install Python packages. Often it’s enough to write:

python setup.py install

and module will install itself.

Example: setup.py

Our initial setup.py will also include information about the license and will re-use the README.txt file for the long_description field. This will look like:

# setup.py: define package metadata for distribution
from distutils.core import setup
setup(
   name='pythonCheatsheet',  # Package name (must be unique on PyPI)
   version='0.1',  # Version number
   packages=['pipenv',],  # List of packages to include
   license='MIT',  # License type
   long_description=open('README.txt').read(),  # Read description from file
)
Quiz

Sign in to answer this quiz and track your learning progress

What are the three required fields in a setup.py file?
A. name, author, license
B. name, description, packages
C. name, version, packages
D. name, version, license

Modern Approach: pyproject.toml

The pyproject.toml file is the modern standard for Python project configuration (PEP-517, PEP-518, PEP-660). It provides a unified way to specify build system requirements and project metadata in a single, declarative file format.

Benefits of pyproject.toml

  • Declarative: All project metadata in one place
  • Build system agnostic: Works with setuptools, poetry, flit, and other build backends
  • No code execution: Safer and more predictable than setup.py
  • Standardized: Follows PEP standards for better tooling support

Example: pyproject.toml

Here’s a basic pyproject.toml example using setuptools:

[build-system]
requires = ["setuptools>=61.0", "wheel"]
build-backend = "setuptools.build_meta"

[project]
name = "pythonCheatsheet"
version = "0.1"
description = "A Python cheatsheet package"
readme = "README.txt"
requires-python = ">=3.8"
license = {text = "MIT"}
authors = [
    {name = "Your Name", email = "your.email@example.com"}
]
classifiers = [
    "Programming Language :: Python :: 3",
    "License :: OSI Approved :: MIT License",
]

[project.optional-dependencies]
dev = [
    "pytest>=7.0",
    "black>=22.0",
]

Installing from pyproject.toml

With pyproject.toml, you can install your package using pip:

pip install .

Or in editable mode:

pip install -e .
Quiz

Sign in to answer this quiz and track your learning progress

What is the main advantage of pyproject.toml over setup.py?
A. It's faster to execute
B. It's declarative, safer (no code execution), and follows PEP standards
C. It requires less configuration
D. It only works with Python 3.10+

Choosing the Right Approach

  • Use setup.py: If you’re working with legacy projects or need fine-grained control
  • Use pyproject.toml: For new projects (recommended), as it’s the modern standard and provides better tooling support

Find more information visit the official documentation.

Morty Proxy This is a proxified and sanitized view of the page, visit original site.