What is pyproject.toml in Python

Author:Murphy  |  View: 20874  |  Time: 2025-03-23 18:40:58

Dependency management in Python is tricky, and sometimes frustrating work. Newcomers, are usually tempted to install any dependency (i.e. package) they may find useful, even in a single virtual enviroment. Therefore, this approach increases the chances of having conflicting package dependencies and ending up in the so-called dependency hell.

In a couple of my previous articles, we covered a few different methods for handling dependencies in Python projects, using setup.py, setup.cfg and requirements.txt files. However, as of Python 3.6, a new standard configuration file called pyproject.toml was introduced, and aims to simplify the way users manage dependencies and metadata definitions.

Over the last few years, the pyproject.toml file has become the standard (and most popular) way for managing depdendeices in Python projects. In the next few sections we will explore how dependency management can be achieved using this file. Furthermore, we will also demonstrate how to install a Project with pyproject.toml specification in editable mode.


Subscribe to Data Pipeline, a newsletter dedicated to Data Engineering


Dependency management prior to pyproject.toml

When Python was first released, the defacto package used for building distributions was distutils. Over time, setuptools made its appearence aiming to build additional features on top of distutils. Both tools made use of a setup.py file where users could specify dependencies and metadata used as part of the package build distribution.

This however, has created an issue given that any project that chooses to use setuptools must be import the package in setup.py file. Therefore, setup.py cannot be executed without knowing its dependencies but at the same time, the purpose of the file itself is to determine these dependencies. And this is how we ended up with the so-called chicken and egg problem in Python dependency management.

I hope this information is enough to understand why a new approach was required. If you are interested in learning more about a more detailed explanation of the chicken-and-egg problem with setuptools and pip make sure to read PEP-518.

The new propasal, which is part of PEP-518, aimed to specify a new way for Python projects to list their dependencies upfront, so that tools like pip can make sure they are installed prior to the project build.


The pyproject.toml

The pyproject.tom file was introduced as part of the Python Enhancement Proposal (PEP) 518, that specifies how Python projects must specify build dependencies.

These build dependeencies will be stored in the file that is located at the root directory of the project and follows the TOML (Tom's Obvious, Minimal Language) syntax.

It contains metadata information such as the project name, version, description, author, license, and various other details.

One of the key features of the pyproject.toml file is the ability to define project dependencies. This allows developers to specify the packages and their versions required for the project to run properly. This helps in maintaining the consistency of the project and ensures that the project can be easily reproduced by other developers.

The pyproject.toml file also supports the concept of extras which allows developers to define optional dependencies for a project. This allows users to install only the necessary dependencies in order to run the project. Usually, in the extras section one could specify additional requirements that will be used as part of testing (e.g. pytest).

In addition to the standard metadata and dependencies, pyproject.toml file also supports custom fields that can be used by third-party tools. As an example, you can consider linters, formatters and checkers such as black and mypy. This allows developers to extend the functionality of the file and add custom fields as per their requirements.


Managing dependencies in pyproject.toml

pyprojet.toml can be used with package dependency management tools, such as setuptools and poetry.

Here's an example file for a project using poetry:

[build-system]
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"

[tool.poetry]
name = "my-project"
version = "1.0.0"
description = "My Python project"
authors = ["John Doe <[email protected]>"]
license = "MIT"

[tool.poetry.dependencies]
python = "^3.6"

[tool.poetry.dev-dependencies]
pytest = "^4.6"

[tool.poetry.extras]
docs = ["sphinx"]

And here's an example with setuptools:

[build-system]
requires = ["setuptools"]
build-backend = "setuptools.build_meta"

[project]
name = "my_package"
description = "My package description"
readme = "README.rst"
requires-python = ">=3.7"
keywords = ["one", "two"]
license = {text = "BSD 3-Clause License"}
classifiers = [
    "Framework :: Django",
    "Programming Language :: Python :: 3",
]
dependencies = [
    "requests",
    'importlib-metadata; python_version<"3.8"',
]
dynamic = ["version"]

[project.optional-dependencies]
pdf = ["ReportLab>=1.2", "RXP"]
rest = ["docutils>=0.3", "pack ==1.1, ==1.3"]

[project.scripts]
my-script = "my_package.module:function"

Installing project in editable mode from pyproject.toml

If you are actively developing a project, the chances are you may want to install the project locally in editable mode. When installing a package in editable mode from a specific location, any changes made to the source code will be reflected immediately in the environment (without you having to re-install the "new" version).

Assuming you are using poetry to manage your Python dependencies and in order to install a Python project in editable mode, you need to have the following content in your pyproject.toml file

[build-system]
requires = ["poetry-core>=1.0.8"]
build-backend = "poetry.core.masonry.api"

and from the project's root directory, simply run

$ pip install -e .

Alternatively, a poetry install will also result in editable install. You can find out more on how to manage your Python projects' dependencies with Poetry, in one of my latest articles:

Managing Python Dependencies with Poetry


Final Thoughts

In today's article we discussed about the usage of pyproject.toml in Python when it comes to managing dependencies and distributing projects across the community.

Overall pyproject.toml provides a standard and easy-to-use configuration for Python projects. It simplifies the process of defining metadata and dependencies, and ensures that the project can be easily reproduced by other developers.


Subscribe to Data Pipeline, a newsletter dedicated to Data Engineering


Related articles you may also like

setup.py vs setup.cfg in Python


requirements.txt vs setup.py in Python


Managing Python Dependencies with Poetry

Tags: Data Engineering Data Science Programming Python Software Development

Comment