summaryrefslogtreecommitdiff
path: root/docs/userguide/declarative_config.rst
blob: 7c97ca1cfa040d67df45aa191fd494b8e5694e83 (plain)
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
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
.. _declarative config:

-----------------------------------------
Configuring setup() using setup.cfg files
-----------------------------------------

.. note:: New in 30.3.0 (8 Dec 2016).

.. important::
    If compatibility with legacy builds (i.e. those not using the :pep:`517`
    build API) is desired, a ``setup.py`` file containing a ``setup()`` function
    call is still required even if your configuration resides in ``setup.cfg``.

``Setuptools`` allows using configuration files (usually :file:`setup.cfg`)
to define a package’s metadata and other options that are normally supplied
to the ``setup()`` function (declarative config).

This approach not only allows automation scenarios but also reduces
boilerplate code in some cases.

.. note::

    This implementation has limited compatibility with the distutils2-like
    ``setup.cfg`` sections used by the ``pbr`` and ``d2to1`` packages.

    Namely: only metadata-related keys from ``metadata`` section are supported
    (except for ``description-file``); keys from ``files``, ``entry_points``
    and ``backwards_compat`` are not supported.


.. code-block:: ini

    [metadata]
    name = my_package
    version = attr: src.VERSION
    description = My package description
    long_description = file: README.rst, CHANGELOG.rst, LICENSE.rst
    keywords = one, two
    license = BSD 3-Clause License
    classifiers =
        Framework :: Django
        License :: OSI Approved :: BSD License
        Programming Language :: Python :: 3
        Programming Language :: Python :: 3.5

    [options]
    zip_safe = False
    include_package_data = True
    packages = find:
    scripts =
        bin/first.py
        bin/second.py
    install_requires =
        requests
        importlib; python_version == "2.6"

    [options.package_data]
    * = *.txt, *.rst
    hello = *.msg

    [options.extras_require]
    pdf = ReportLab>=1.2; RXP
    rest = docutils>=0.3; pack ==1.1, ==1.3

    [options.packages.find]
    exclude =
        src.subpackage1
        src.subpackage2

    [options.data_files]
    /etc/my_package =
        site.d/00_default.conf
        host.d/00_default.conf
    data = data/img/logo.png, data/svg/icon.svg

Metadata and options are set in the config sections of the same name.

* Keys are the same as the keyword arguments one provides to the ``setup()``
  function.

* Complex values can be written comma-separated or placed one per line
  in *dangling* config values. The following are equivalent:

  .. code-block:: ini

      [metadata]
      keywords = one, two

      [metadata]
      keywords =
          one
          two

* In some cases, complex values can be provided in dedicated subsections for
  clarity.

* Some keys allow ``file:``, ``attr:``, ``find:``, and ``find_namespace:`` directives in
  order to cover common usecases.

* Unknown keys are ignored.


Using a ``src/`` layout
=======================

One commonly used package configuration has all the module source code in a
subdirectory (often called the ``src/`` layout), like this::

    ├── src
    │   └── mypackage
    │       ├── __init__.py
    │       └── mod1.py
    ├── setup.py
    └── setup.cfg

You can set up your ``setup.cfg`` to automatically find all your packages in
the subdirectory like this:

.. code-block:: ini

    # This example contains just the necessary options for a src-layout, set up
    # the rest of the file as described above.

    [options]
    package_dir=
        =src
    packages=find:

    [options.packages.find]
    where=src

Specifying values
=================

Some values are treated as simple strings, some allow more logic.

Type names used below:

* ``str`` - simple string
* ``list-comma`` - dangling list or string of comma-separated values
* ``list-semi`` - dangling list or string of semicolon-separated values
* ``bool`` - ``True`` is 1, yes, true
* ``dict`` - list-comma where keys are separated from values by ``=``
* ``section`` - values are read from a dedicated (sub)section


Special directives:

* ``attr:`` - Value is read from a module attribute.  ``attr:`` supports
  callables and iterables; unsupported types are cast using ``str()``.

  In order to support the common case of a literal value assigned to a variable
  in a module containing (directly or indirectly) third-party imports,
  ``attr:`` first tries to read the value from the module by examining the
  module's AST.  If that fails, ``attr:`` falls back to importing the module.

* ``file:`` - Value is read from a list of files and then concatenated


.. note::
    The ``file:`` directive is sandboxed and won't reach anything outside
    the directory containing ``setup.py``.


Metadata
--------

.. note::
    The aliases given below are supported for compatibility reasons,
    but their use is not advised.

==============================  =================  =================  =============== =====
Key                             Aliases            Type               Minimum Version Notes
==============================  =================  =================  =============== =====
name                                               str
version                                            attr:, file:, str  39.2.0          (1)
url                             home-page          str
download_url                    download-url       str
project_urls                                       dict               38.3.0
author                                             str
author_email                    author-email       str
maintainer                                         str
maintainer_email                maintainer-email   str
classifiers                     classifier         file:, list-comma
license                                            str
license_file                                       str
license_files                                      list-comma         42.0.0
description                     summary            file:, str
long_description                long-description   file:, str
long_description_content_type                      str                38.6.0
keywords                                           list-comma
platforms                       platform           list-comma
provides                                           list-comma
requires                                           list-comma
obsoletes                                          list-comma
==============================  =================  =================  =============== =====

.. note::
    A version loaded using the ``file:`` directive must comply with PEP 440.
    It is easy to accidentally put something other than a valid version
    string in such a file, so validation is stricter in this case.

Notes:
1. The ``version`` file attribute has only been supported since 39.2.0.

Options
-------

=======================  ===================================  =============== =====
Key                      Type                                 Minimum Version Notes
=======================  ===================================  =============== =====
zip_safe                 bool
setup_requires           list-semi
install_requires         list-semi
extras_require           section
python_requires          str
entry_points             file:, section
use_2to3                 bool
use_2to3_fixers          list-comma
use_2to3_exclude_fixers  list-comma
convert_2to3_doctests    list-comma
scripts                  list-comma
eager_resources          list-comma
dependency_links         list-comma
tests_require            list-semi
include_package_data     bool
packages                 find:, find_namespace:, list-comma
package_dir              dict
package_data             section                                              (1)
exclude_package_data     section
namespace_packages       list-comma
py_modules               list-comma
data_files               dict                                 40.6.0
=======================  ===================================  =============== =====

.. note::

    **packages** - The ``find:`` and ``find_namespace:`` directive can be further configured
    in a dedicated subsection ``options.packages.find``. This subsection
    accepts the same keys as the ``setuptools.find_packages`` and the
    ``setuptools.find_namespace_packages`` function:
    ``where``, ``include``, and ``exclude``.

    **find_namespace directive** - The ``find_namespace:`` directive is supported since Python >=3.3.


Notes:
1. In the ``package_data`` section, a key named with a single asterisk (``*``)
refers to all packages, in lieu of the empty string used in ``setup.py``.

2. In the ``extras_require`` section, values are parsed as ``list-semi``. This implies that in
order to include markers, they **must** be *dangling*:

.. code-block:: ini

    [options.extras_require]
    rest = docutils>=0.3; pack ==1.1, ==1.3
    pdf =
      ReportLab>=1.2
      RXP
      importlib-metadata; python_version < "3.8"