blob: 47c4511ebb4809f42a913cc7187b7c89e791e0d7 [file] [log] [blame] [edit]
.. _pyproject.toml config:
-----------------------------------------------------
Configuring setuptools using ``pyproject.toml`` files
-----------------------------------------------------
.. note:: New in 61.0.0 (**experimental**)
.. warning::
Support for declaring :doc:`project metadata
<PyPUG:specifications/declaring-project-metadata>` or configuring
``setuptools`` via ``pyproject.toml`` files is still experimental and might
change (or be removed) in future releases.
.. important::
For the time being, ``pip`` still might require a ``setup.py`` file
to support :doc:`editable installs <pip:cli/pip_install>`.
A simple script will suffice, for example:
.. code-block:: python
from setuptools import setup
setup()
Starting with :pep:`621`, the Python community selected ``pyproject.toml`` as
a standard way of specifying *project metadata*.
``Setuptools`` has adopted this standard and will use the information contained
in this file as an input in the build process.
The example below illustrates how to write a ``pyproject.toml`` file that can
be used with ``setuptools``. It contains two TOML tables (identified by the
``[table-header]`` syntax): ``build-system`` and ``project``.
The ``build-system`` table is used to tell the build frontend (e.g.
:pypi:`build` or :pypi:`pip`) to use ``setuptools`` and any other plugins (e.g.
``setuptools-scm``) to build the package.
The ``project`` table contains metadata fields as described by
:doc:`PyPUG:specifications/declaring-project-metadata` guide.
.. _example-pyproject-config:
.. code-block:: toml
[build-system]
requires = ["setuptools", "setuptools-scm"]
build-backend = "setuptools.build_meta"
[project]
name = "my_package"
description = "My package description"
readme = "README.rst"
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"
.. _setuptools-table:
Setuptools-specific configuration
=================================
While the standard ``project`` table in the ``pyproject.toml`` file covers most
of the metadata used during the packaging process, there are still some
``setuptools``-specific configurations that can be set by users that require
customization.
These configurations are completely optional and probably can be skipped when
creating simple packages.
They are equivalent to the :doc:`/references/keywords` used by the ``setup.py``
file, and can be set via the ``tool.setuptools`` table:
========================= =========================== =========================
Key Value Type (TOML) Notes
========================= =========================== =========================
``platforms`` array
``zip-safe`` boolean If not specified, ``setuptools`` will try to guess
a reasonable default for the package
``eager-resources`` array
``py-modules`` array See tip below
``packages`` array or ``find`` directive See tip below
``package-dir`` table/inline-table Used when explicitly listing ``packages``
``namespace-packages`` array Not necessary if you use :pep:`420`
``package-data`` table/inline-table See :doc:`/userguide/datafiles`
``include-package-data`` boolean ``True`` by default
``exclude-package-data`` table/inline-table
``license-files`` array of glob patterns **Provisional** - likely to change with :pep:`639`
(by default: ``['LICEN[CS]E*', 'COPYING*', 'NOTICE*', 'AUTHORS*']``)
``data-files`` table/inline-table **Deprecated** - check :doc:`/userguide/datafiles`
``script-files`` array **Deprecated** - equivalent to the ``script`` keyword in ``setup.py``
(should be avoided in favour of ``project.scripts``)
``provides`` array **Ignored by pip**
``obsoletes`` array **Ignored by pip**
========================= =========================== =========================
.. note::
The `TOML value types`_ ``array`` and ``table/inline-table`` are roughly
equivalent to the Python's :obj:`dict` and :obj:`list` data types.
Please note that some of these configurations are deprecated or at least
discouraged, but they are made available to ensure portability.
New packages should avoid relying on deprecated/discouraged fields, and
existing packages should consider alternatives.
.. tip::
When both ``py-modules`` and ``packages`` are left unspecified,
``setuptools`` will attempt to perform :ref:`auto-discovery`, which should
cover most popular project directory organization techniques, such as the
:ref:`src-layout` and the :ref:`flat-layout`.
However if your project does not follow these conventional layouts
(e.g. you want to use a ``flat-layout`` but at the same time have custom
directories at the root of your project), you might need to use the ``find``
directive [#directives]_ as shown below:
.. code-block:: toml
[tool.setuptools.packages.find]
where = ["src"] # list of folders that contain the packages (["."] by default)
include = ["my_package*"] # package names should match these glob patterns (["*"] by default)
exclude = ["my_package.tests*"] # exclude packages matching these glob patterns (empty by default)
namespaces = false # to disable scanning PEP 420 namespaces (true by default)
Note that the glob patterns in the example above need to be matched
by the **entire** package name. This means that if you specify ``exclude = ["tests"]``,
modules like ``tests.my_package.test1`` will still be included in the distribution
(to remove them, add a wildcard to the end of the pattern: ``"tests*"``).
Alternatively, you can explicitly list the packages in modules:
.. code-block:: toml
[tool.setuptools]
packages = ["my_package"]
.. _dynamic-pyproject-config:
Dynamic Metadata
================
Note that in the first example of this page we use ``dynamic`` to identify
which metadata fields are dynamically computed during the build by either
``setuptools`` itself or the plugins installed via ``build-system.requires``
(e.g. ``setuptools-scm`` is capable of deriving the current project version
directly from the ``git`` :wiki:`version control` system).
Currently the following fields can be listed as dynamic: ``version``,
``classifiers``, ``description``, ``entry-points``, ``scripts``,
``gui-scripts`` and ``readme``.
When these fields are expected to be provided by ``setuptools`` a
corresponding entry is required in the ``tool.setuptools.dynamic`` table
[#entry-points]_. For example:
.. code-block:: toml
# ...
[project]
name = "my_package"
dynamic = ["version", "readme"]
# ...
[tool.setuptools.dynamic]
version = {attr = "my_package.VERSION"}
readme = {file = ["README.rst", "USAGE.rst"]}
In the ``dynamic`` table, the ``attr`` directive [#directives]_ will read an
attribute from the given module [#attr]_, while ``file`` will read the contents
of all given files and concatenate them in a single string.
================= =================== =========================
Key Directive Notes
================= =================== =========================
``version`` ``attr``, ``file``
``readme`` ``file``
``description`` ``file`` One-line text
``classifiers`` ``file`` Multi-line text with one classifier per line
``entry-points`` ``file`` INI format following :doc:`PyPUG:specifications/entry-points`
(``console_scripts`` and ``gui_scripts`` can be included)
================= =================== =========================
----
.. rubric:: Notes
.. [#entry-points] Dynamic ``scripts`` and ``gui-scripts`` are a special case.
When resolving these metadata keys, ``setuptools`` will look for
``tool.setuptool.dynamic.entry-points``, and use the values of the
``console_scripts`` and ``gui_scripts`` :doc:`entry-point groups
<PyPUG:specifications/entry-points>`.
.. [#directives] In the context of this document, *directives* are special TOML
values that are interpreted differently by ``setuptools`` (usually triggering an
associated function). Most of the times they correspond to a special TOML table
(or inline-table) with a single top-level key.
For example, you can have the ``{find = {where = ["src"], exclude=["tests*"]}}``
directive for ``tool.setuptools.packages``, or ``{attr = "mymodule.attr"}``
directive for ``tool.setuptools.dynamic.version``.
.. [#attr] ``attr`` is meant to be used when the module attribute is statically
specified (e.g. as a string, list or tuple). As a rule of thumb, the
attribute should be able to be parsed with :func:`ast.literal_eval`, and
should not be modified or re-assigned.
.. _TOML value types: https://toml.io/en/v1.0.0