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 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354
|
.. _declarative config:
------------------------------------------------
Configuring setuptools 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 (for example, :file:`setup.cfg`)
to define a package’s metadata and other options (declarative config).
This approach allows automation scenarios and can reduce boilerplate code.
.. _example-setup-config:
.. code-block:: ini
[metadata]
name = my_package
version = attr: my_package.VERSION
author = Josiah Carberry
author_email = josiah_carberry@brown.edu
description = My package description
long_description = file: README.rst, CHANGELOG.rst, LICENSE.rst
keywords = one, two
license = BSD-3-Clause
classifiers =
Framework :: Django
Programming Language :: Python :: 3
[options]
zip_safe = False
include_package_data = True
packages = find:
python_requires = >=3.8
install_requires =
requests
importlib-metadata; python_version<"3.10"
[options.package_data]
* = *.txt, *.rst
hello = *.msg
[options.entry_points]
console_scripts =
executable-name = my_package.module:function
[options.extras_require]
pdf = ReportLab>=1.2; RXP
rest = docutils>=0.3; pack ==1.1, ==1.3
[options.packages.find]
exclude =
examples*
tools*
docs*
my_package.tests*
Metadata and options are set in the config sections of the same name.
* Keys are the same as the :doc:`keyword arguments </references/keywords>` 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 configuration has all the Python 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, using :ref:`package_dir <keyword/package_dir>`, 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
In this example, the value for the :ref:`package_dir <keyword/package_dir>`
configuration (i.e. ``=src``) is parsed as ``{"": "src"}``.
The ``""`` key has a special meaning in this context, and indicates that all the
packages are contained inside the given directory.
Also note that the value for ``[options.packages.find] where`` matches the
value associated with ``""`` in the ``package_dir`` dictionary.
..
TODO: Add the following tip once the auto-discovery is no longer experimental:
Starting in version 61, ``setuptools`` can automatically infer the
configurations for both ``packages`` and ``package_dir`` for projects using
a ``src/`` layout (as long as no value is specified for ``py_modules``).
Please see :doc:`package discovery </userguide/package_discovery>` for more
details.
Interpolation
=============
Config files are parsed using :mod:`configparser` with
`interpolation <https://docs.python.org/3/library/configparser.html#interpolation-of-values>`_
enabled. As a result, one config value may reference another. This
feature may be used, for example, in defining extras:
.. code-block:: ini
[options.extras_require]
tester =
pytest==3.3.2
pytest-sugar
dev =
pytest-xdist
%(tester)s
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 each entry corresponds to a key/value pair,
with keys separated from values by ``=``.
If an entry starts with ``=``, the key is assumed to be an empty string
(e.g. ``=src`` is parsed as ``{"": "src"}``).
* ``section`` - values are read from a dedicated (sub)section
Special directives:
* ``attr:`` - Value is read from a module attribute.
It is advisable to use literal values together with ``attr:`` (e.g. ``str``,
``tuple[str]``, see :func:`ast.literal_eval`). This is recommend
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,
using :func:`importlib.util.spec_from_file_location` recommended recipe
(see :ref:`example on Python docs <python:importlib-examples>`
about "Importing a source file directly").
Note however that importing the module is error prone since your package is
not installed yet. You may also need to manually add the project directory to
``sys.path`` (via ``setup.py``) in order to be able to do that.
When the module is imported, ``attr:`` supports
callables and iterables; unsupported types are cast using ``str()``.
* ``file:`` - Value is read from a list of files and then concatenated
.. important::
The ``file:`` directive is sandboxed and won't reach anything outside the
project directory (i.e. the directory containing ``setup.cfg``/``pyproject.toml``).
.. note::
If you are using an old version of ``setuptools``, you might need to ensure
that all files referenced by the ``file:`` directive are included in the ``sdist``
(you can do that via ``MANIFEST.in`` or using plugins such as ``setuptools-scm``,
please have a look on :doc:`/userguide/miscellaneous` for more information).
.. versionchanged:: 66.1.0
Newer versions of ``setuptools`` will automatically add these files to the ``sdist``.
Metadata
--------
.. attention::
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 [#meta-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_files license_file 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
============================== ================= ================= =============== ==========
**Notes**:
.. [#meta-1] The ``version`` file attribute has only been supported since 39.2.0.
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.
Options
-------
======================= =================================== =============== ====================
Key Type Minimum Version Notes
======================= =================================== =============== ====================
zip_safe bool
setup_requires list-semi 36.7.0
install_requires file:, list-semi **BETA** [#opt-2]_, [#opt-6]_
extras_require file:, section **BETA** [#opt-2]_, [#opt-6]_
python_requires str 34.4.0
entry_points file:, section 51.0.0
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 [#opt-3]_
package_dir dict
package_data section [#opt-1]_
exclude_package_data section
namespace_packages list-comma [#opt-5]_
py_modules list-comma 34.4.0
data_files section 40.6.0 [#opt-4]_
======================= =================================== =============== ====================
**Notes**:
.. [#opt-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``.
.. [#opt-2] In ``install_requires`` and ``extras_require``, values are parsed as ``list-semi``.
This implies that in order to include markers, each requirement **must** be *dangling*
in a new line:
.. code-block:: ini
[options]
install_requires =
importlib-metadata; python_version<"3.10"
[options.extras_require]
all =
importlib-metadata; python_version<"3.10"
.. [#opt-3] 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``.
The ``find_namespace:`` directive is supported since Python >=3.3.
.. [#opt-4] ``data_files`` is deprecated and should be avoided.
Please check :doc:`/userguide/datafiles` for more information.
.. [#opt-5] ``namespace_packages`` is deprecated in favour of native/implicit
namespaces (:pep:`420`). Check :doc:`the Python Packaging User Guide
<PyPUG:guides/packaging-namespace-packages>` for more information.
.. [#opt-6] ``file:`` directives for reading requirements are supported since version 62.6.
The format for the file resembles a ``requirements.txt`` file,
however please keep in mind that all non-comment lines must conform with :pep:`508`
(``pip``-specify syntaxes, e.g. ``-c/-r/-e`` flags, are not supported).
Library developers should avoid tightly pinning their dependencies to a specific
version (e.g. via a "locked" requirements file).
Compatibility with other tools
==============================
Historically, several tools explored declarative package configuration
in parallel. And several of them chose to place the packaging
configuration within the project's :file:`setup.cfg` file.
One of the first was ``distutils2``, which development has stopped in
2013. Other include ``pbr`` which is still under active development or
``d2to1``, which was a plug-in that backports declarative configuration
to ``distutils``, but has had no release since Oct. 2015.
As a way to harmonize packaging tools, ``setuptools``, having held the
position of *de facto* standard, has gradually integrated those
features as part of its core features.
Still this has lead to some confusion and feature incompatibilities:
- some tools support features others don't;
- some have similar features but the declarative syntax differs;
The table below tries to summarize the differences. But, please, refer
to each tool documentation for up-to-date information.
=========================== ========== ========== ===== ===
feature setuptools distutils2 d2to1 pbr
=========================== ========== ========== ===== ===
[metadata] description-file S Y Y Y
[files] S Y Y Y
entry_points Y Y Y S
[backwards_compat] N Y Y Y
=========================== ========== ========== ===== ===
Y: supported, N: unsupported, S: syntax differs (see
:ref:`above example<example-setup-config>`).
Also note that some features were only recently added to ``setuptools``.
Please refer to the previous sections to find out when.
|