How to write a minimally working pyproject.toml file that can install packages?

my question differ because I ask for a human-written pyproject.toml

First, the pyproject.toml file is always “human-writable“.

Then, it is important to know that in this context setuptools and Poetry take the role of what are called “build back-ends” (in a “PEP 517” sense), and there are many such build back-ends available today, setuptools and Poetry (technically poetry-core) are just two examples of them.

As of today, it seems like most (if not all) of the build back-ends I know of expect their configuration (including dependencies) to be written in pyproject.toml. It is also known as “PEP 621“.


[project]

There is a standard specifying how a project’s packaging metadata, including dependencies, should be laid out in the pyproject.toml file under a [project] section: “Declaring project metadata“.

Here is a list of build back-ends I know of that follow this [project] standard:

  • enscons
  • flit_core (see flit)
  • hatchling (see hatch)
  • maturin
  • meson-python
  • pdm-backend (see pdm)
  • scikit-build-core
  • setuptools (experimental support since version 61.0.0)
  • trampolim
  • whey

I have a comparison table here.

For all [project]-compatible build back-ends, the dependencies should be written in the pyproject.toml file at the root of the project’s source code directory like in the following example:

[project]
name = "Thing"
version = "1.2.3"
# ...
dependencies = [
    "SomeLibrary >= 2.2",
    "AnotherLibrary >= 4.5.6",
]

References:

  • PyPA specification “Declaring project metadata
  • PEP 621 – Storing project metadata in pyproject.toml
  • setuptools documentation: “Configuring setuptools using pyproject.toml files

setuptools (before version 61.0.0)

In setuptools before version 61.0.0 there is no support for writing the project’s packaging metadata in pyproject.toml. You have to either write a setup.cfg, or a setup.py, or a combination of both.

My recommendation is to write as much as possible in setup.cfg. Such a setup.cfg could look like this:

[metadata]
name = Thing
version = 1.2.3

[options]
install_requires =
    SomeLibrary >= 2.2
    AnotherLibrary >= 4.5.6
packages = find:

and in most cases the setup.py can be omitted completely or it can be as short as:

import setuptools
setuptools.setup()

References about the dependencies specifically:

  • Dependencies Management in Setuptools
  • PEP 508 – Dependency specification for Python Software Packages
  • PEP 440 – Version Identification and Dependency Specification

Again, note that in most cases it is possible to omit the setup.py file entirely, one of the conditions is that the setup.cfg file and a pyproject.toml file are present and contain all the necessary information. Here is an example of pyproject.toml that works well for a setuptools build back-end:

[build-system]
build-backend = 'setuptools.build_meta'
requires = [
    'setuptools',
]

Poetry

In Poetry everything is defined in pyproject.toml, but it uses Poetry-specific sections [tool.poetry] instead of the standardized [project] section. There are some plans to add support for this standard in Poetry in the future.

This file can be hand-written. As far as I can tell, there is no strict need to ever explicitly install poetry itself (commands such as pip install and pip wheel can get you far enough).

The pyproject.toml file can be as simple as:

[tool.poetry]
name="Thing"
version = '1.2.3'

[tool.poetry.dependencies]
python = '^3.6'
SomeLibrary = '>= 2.2'
AnotherLibrary >= '4.5.6'

[build-system]
requires = ['poetry-core~=1.0']
build-backend = 'poetry.core.masonry.api'

References:

  • Poetry documentation: “The pyproject.toml file
  • Poetry documentation: “Dependency specification

Leave a Comment

Hata!: SQLSTATE[HY000] [1045] Access denied for user 'divattrend_liink'@'localhost' (using password: YES)