Skip to content

Latest commit

 

History

History
218 lines (172 loc) · 9.4 KB

pyproject_config.rst

File metadata and controls

218 lines (172 loc) · 9.4 KB

Configuring setuptools using pyproject.toml files

Note

New in 61.0.0 (experimental)

Warning

Support for declaring 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 editable installs <pip:cli/pip_install>.

A simple script will suffice, for example:

from setuptools import setup

setup()

Starting with 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. build or 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 PyPUG:specifications/declaring-project-metadata guide.

[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-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 /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

eager-resources

boolean

array

If not specified, setuptools will try to guess a reasonable default for the package

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 Deprecated - Use implicit namespaces instead (420)
package-data table/inline-table See /userguide/datafiles

include-package-data exclude-package-data

boolean table/inline-table

True by default

license-files

array of glob patterns

Provisional - likely to change with 639 (by default: ['LICEN[CS]E*', 'COPYING*', 'NOTICE*', 'AUTHORS*'])

data-files table/inline-table Deprecated - check /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 dict and 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 auto-discovery, which should cover most popular project directory organization techniques, such as the src-layout and the 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 directive1 as shown below:

[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:

[tool.setuptools]
packages = ["my_package"]

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 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 2. For example:

# ...
[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 directive3 will read an attribute from the given module4, while file will read the contents of all given files and concatenate them in a single string.

Key Directive Notes

version readme

attr, file file

description file One-line text
classifiers file Multi-line text with one classifier per line

entry-points

file

INI format following PyPUG:specifications/entry-points (console_scripts and gui_scripts can be included)


Notes


  1. 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.

  2. 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 entry-point groups <PyPUG:specifications/entry-points>.

  3. 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.

  4. 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 ast.literal_eval, and should not be modified or re-assigned.