1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
|
.. _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, you still might require a ``setup.py`` file containing
a *arg-less* ``setup()`` function call to support
:doc:`editable installs <pip:cli/pip_install>`.
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 bellow 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) and can be set via the ``tool.setuptools`` table.
They are equivalent to the :doc:`/references/keywords` used by the ``setup.py`` file:
========================= =========================== =========================
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 bellow
``packages`` array or ``find`` directive See tip bellow
``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**
========================= =========================== =========================
In the table above, 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 them, 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 <src-layout>` and :ref:`flat <flat-layout>` layouts.
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 as shown bellow:
.. 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 calculated during the build by either
``setuptools`` itself or the selected plugins (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 used dynamically: ``version``,
``classifiers``, ``description``, ``entry-points``, ``scripts``,
``gui-scripts`` and ``readme``.
When these fields are expected to be directly 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 will read an attribute from
the given module [#attr]_, while ``file`` will read all the 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>`.
.. [#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
|