219 lines
9.4 KiB
ReStructuredText
219 lines
9.4 KiB
ReStructuredText
.. _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
|