Configuration¶
whey
is configured in the pyproject.toml
file defined in PEP 517 and PEP 518.
Note
whey
only supports TOML v0.5.0.
pyproject.toml
files using features of newer TOML versions may not parse correctly.
[build-system]
¶
whey
must be set as the build-backend
in the [build-system]
table.
Example:
[build-system]
requires = [ "whey",]
build-backend = "whey"
[project]
¶
The metadata used by whey
is defined in the [project]
table, per PEP 621.
As a minimum, the table MUST contain the keys name
and version
1.
- 1
Other tools, such as flit and trampolim, may support determining
project.version
dynamically without specifying a value inpyproject.toml
.
-
name
¶ - Type: StringRequired:
True
The name of the project.
Ideally, the name should be normalised to lowercase, with underscores replaced by hyphens. The name may only contain ASCII letters, numbers, and the following symbols:
._-
. It must start and end with a letter or number.This key is required, and MUST be defined statically.
Example:
[project] name = "spam"
-
version
¶ - Type: String
The version of the project as supported by PEP 440.
With
whey
this key is required, and must be defined statically. Other backends may support determining this value automatically if it is listed inproject.dynamic
.Example:
[project] version = "2020.0.0"
-
description
¶ - Type: String
A short summary description of the project.
PyPI will display this towards the top of the project page. A longer description can be provided as
readme
.Example:
[project] description = "Lovely Spam! Wonderful Spam!"
-
readme
¶ -
The full description of the project (i.e. the README).
The field accepts either a string or a table. If it is a string then it is the relative path to a text file containing the full description. The file’s encoding MUST be UTF-8, and have one of the following content types:
text/markdown
, with a a case-insensitive.md
suffix.text/x-rst
, with a a case-insensitive.rst
suffix.text/plain
, with a a case-insensitive.txt
suffix.
The readme field may instead be a table with the following keys:
file
– a string value representing a relative path to a file containing the full description.text
– a string value which is the full description.content-type
– (required) a string specifying the content-type of the full description.charset
– (optional, default UTF-8) the encoding of thefile
.
The
file
andtext
keys are mutually exclusive, but one must be provided in the table.PyPI will display this on the project page
Examples:
[project] readme = "README.rst"
[project] readme = {file = "README.md", content-type = "text/markdown", encoding = "UTF-8"}
[project.readme] text = "Spam is a brand of canned cooked pork made by Hormel Foods Corporation." content-type = "text/x-rst"
-
requires-python
¶ - Type: String
The Python version requirements of the project, as a PEP 508 specifier.
Example:
[project] requires-python = ">=3.6"
-
license
¶ - Type: Table
The table may have one of two keys:
file
– a string value that is a relative file path to the file which contains the license for the project. The file’s encoding MUST be UTF-8.text
– string value which is the license of the project.
These keys are mutually exclusive.
Examples:
[project] license = {file = "LICENSE.rst"}
[project.license] file = "COPYING"
[project.license] text = """ This software may only be obtained by sending the author a postcard, and then the user promises not to redistribute it. """
-
The tables list the people or organizations considered to be the “authors” of the project.
Each table has 2 keys:
name
andemail
. Both keys are optional, and both values must be strings.The
name
value MUST be a valid email name (i.e. whatever can be put as a name, before an email, in RFC 822) and not contain commas.The
email
value MUST be a valid email address.
Examples:
[project] authors = [ {name = "Dominic Davis-Foster", email = "dominic@davis-foster.co.uk"}, {name = "The pip developers", email = "distutils-sig@python.org"} ]
[[project.authors]] name = "Tzu-ping Chung" [[project.authors]] email = "hi@pradyunsg.me"
-
maintainers
¶ -
The tables list the people or organizations considered to be the “maintainers” of the project.
This field otherwise functions the same as
authors
.Example:
[project] authors = [ {email = "hi@pradyunsg.me"}, {name = "Tzu-ping Chung"} ] maintainers = [ {name = "Brett Cannon", email = "brett@python.org"} ]
-
keywords
¶ -
The keywords for the project.
These can be used by community members to find projects based on their desired criteria.
Example:
[project] keywords = [ "egg", "bacon", "sausage", "tomatoes", "Lobster Thermidor",]
-
classifiers
¶ -
The trove classifiers which apply to the project.
Classifiers describe who the project is for, what systems it can run on, and how mature it is. These can then be used by community members to find projects based on their desired criteria.
Example:
[project] classifiers = [ "Development Status :: 4 - Beta", "Programming Language :: Python" ]
-
urls
¶ -
A table of URLs where the key is the URL label and the value is the URL itself.
The URL labels are free text, but may not exceed 32 characters.
Example:
[project.urls] homepage = "https://example.com" documentation = "https://readthedocs.org" repository = "https://github.com" changelog = "https://github.com/me/spam/blob/master/CHANGELOG.md"
-
scripts
¶ -
The console scripts provided by the project.
The keys are the names of the scripts and the values are the object references in the form
module.submodule:object
.See the entry point specification for more details.
Example:
[project.scripts] spam-cli = "spam:main_cli" # One which depends on extras: foobar = "foomod:main_bar [bar,baz]"
-
gui-scripts
¶ -
The graphical application scripts provided by the project.
The keys are the names of the scripts, and the values are the object references in the form
module.submodule:object
.See the entry point specification for more details.
Example:
[project.gui-scripts] spam-gui = "spam.gui:main_gui"
-
entry-points
¶ -
Each sub-table’s name is an entry point group.
Users MUST NOT create nested sub-tables but instead keep the entry point groups to only one level deep.
Users MUST NOT create sub-tables for
console_scripts
orgui_scripts
. Use[project.scripts]
and[project.gui-scripts]
instead.See the entry point specification for more details.
Example:
[project.entry-points."spam.magical"] tomatoes = "spam:main_tomatoes" # pytest plugins refer to a module, so there is no ':obj' [project.entry-points.pytest11] nbval = "nbval.plugin"
-
dependencies
¶ -
The dependencies of the project.
Each string MUST be formatted as a valid PEP 508 string.
Example:
[project] dependencies = [ "httpx", "gidgethub[httpx]>4.0.0", "django>2.1; os_name != 'nt'", "django>2.0; os_name == 'nt'" ]
-
optional-dependencies
¶ -
The optional dependencies of the project.
The keys specify an extra, and must be valid Python identifiers.
The values are arrays of strings, which must be valid PEP 508 strings.
Example:
[project.optional-dependencies] test = [ "pytest < 5.0.0", "pytest-cov[all]" ]
-
dynamic
¶ -
Specifies which fields listed by PEP 621 were intentionally unspecified so
whey
can provide such metadata dynamically.Whey currently only supports
classifiers
,dependencies
, andrequires-python
as dynamic fields. Other tools may support different dynamic fields.Example:
[project] dynamic = [ "classifiers",] [tool.whey] base-classifiers = [ "Development Status :: 3 - Alpha", "Typing :: Typed", ]
[tool.whey]
¶
-
package
¶ - Type: String
The path to the package to distribute, relative to the directory containing
pyproject.toml
. This defaults toproject.name
if unspecified.Example:
[project] name = "domdf-python-tools" [tool.whey] package = "domdf_python_tools"
-
source-dir
¶ - Type: String
The name of the directory containing the project’s source. This defaults to
'.'
if unspecified.Examples:
[project] name = "flake8"
[tool.whey] source-dir = "src/flake8"
-
additional-files
¶ -
A list of MANIFEST.in-style entries for additional files to include in distributions.
The supported commands are:
Command
Description
include pat1 pat2 ...
Add all files matching any of the listed patterns
exclude pat1 pat2 ...
Remove all files matching any of the listed patterns
recursive-include dir-pattern pat1 pat2 ...
Add all files under directories matching
dir-pattern
that match any of the listed patternsrecursive-exclude dir-pattern pat1 pat2 ...
Remove all files under directories matching
dir-pattern
that match any of the listed patternswhey
was built with type hints in mind, so it will automatically include anypy.typed
files and*.pyi
stub files automatically.Note
If using
tool.whey.source-dir
, the entries for files within the package must start with the value ofsource-dir
.For example, if
source-dir
is'src'
and the package is atsrc/spam
an entry might beinclude src/spam/template.scss
.Examples:
[tool.whey] additional-files = [ "include domdf_python_tools/google-10000-english-no-swears.txt", "recursive-exclude domdf_python_tools *.json", ]
[tool.whey] source-dir = "src" additional-files = [ "include src/domdf_python_tools/google-10000-english-no-swears.txt", "recursive-exclude src/domdf_python_tools *.json", ]
-
license-key
¶ - Type: String
An identifier giving the project’s license.
This is used for the License field in the Core Metadata, and to add the appropriate trove classifier.
It is recommended to use an SPDX Identifier, but note that not all map to classifiers.
Example:
[tool.whey] license-key = "MIT"
-
base-classifiers
¶ -
A list of trove classifiers.
This list will be extended with the appropriate classifiers for the
license-key
and the supportedplatforms
,python-implementations
andpython-versions
.This field is ignored if
classifiers
is not listed inproject.dynamic
Example:
[project] dynamic = [ "classifiers", ] [tool.whey] base-classifiers = [ "Development Status :: 3 - Alpha", "Typing :: Typed", ]
-
platforms
¶ -
A list of supported platforms. This is used to add appropriate trove classifiers and is listed under Platform in the Core Metadata.
Example:
[tool.whey] platforms = [ "Windows", "Linux",]
-
python-implementations
¶ -
A list of supported Python implementations. This can be used to add appropriate trove classifiers.
Example:
[tool.whey] python-implementations = [ "CPython", "PyPy",]
-
python-versions
¶ -
A list of supported Python versions. This can be used to add appropriate trove classifiers and dynamically determine the minimum required Python version for
project.requires-python
.Example:
[tool.whey] python-versions = [ "3.6", "3.7", ]
Environment Variables¶
-
CHECK_README
¶ Setting this to
0
disables the optional README validation feature, which checks the README will render correctly on PyPI.
-
SOURCE_DATE_EPOCH
¶ To make reproducible builds, set this to a timestamp as a number of seconds since 1970-01-01 UTC, and document the value you used. On Unix systems, you can get a value for the current time by running:
date +%s
Note
The timestamp cannot be before 1980-01-01 or after 2107-12-31.
See also
-
WHEY_VERBOSE
¶ Run whey in verbose mode. This includes printing the names of the files being added to the sdist or wheel.
If using whey’s command-line interface, this option defaults to
0
. Setting it to1
has the same meaning as the-v / --verbose
option.If using whey’s PEP 517 backend, this option defaults to
1
. Setting it to0
disables the verbose output.
-
WHEY_TRACEBACK
¶ Show the complete traceback on error.
This option defaults to
0
. Setting it to1
has the same meaning as the-T / --traceback
option, both for the command-line interface and the PEP 517 backend.
Complete Example¶
This is an example of a complete pyproject.toml
file for PEP 621.
For an explanation of each field, see the Configuration section.
[build-system]
requires = [ "whey",]
build-backend = "whey"
[project]
name = "spam"
version = "2020.0.0"
description = "Lovely Spam! Wonderful Spam!"
readme = "README.rst"
requires-python = ">=3.8"
license = {file = "LICENSE.txt"}
keywords = [ "egg", "bacon", "sausage", "tomatoes", "Lobster Thermidor",]
authors = [
{name = "Dominic Davis-Foster", email = "dominic@davis-foster.co.uk"},
{name = "The pip developers", email = "distutils-sig@python.org"}
]
maintainers = [
{name = "Brett Cannon", email = "brett@python.org"}
]
classifiers = [
"Development Status :: 4 - Beta",
"Programming Language :: Python"
]
dependencies = [
"httpx",
"gidgethub[httpx]>4.0.0",
"django>2.1; os_name != 'nt'",
"django>2.0; os_name == 'nt'"
]
[project.optional-dependencies]
test = [
"pytest < 5.0.0",
"pytest-cov[all]"
]
[project.urls]
homepage = "https://example.com"
documentation = "https://readthedocs.org"
repository = "https://github.com"
changelog = "https://github.com/me/spam/blob/master/CHANGELOG.md"
[project.scripts]
spam-cli = "spam:main_cli"
# One which depends on extras:
foobar = "foomod:main_bar [bar,baz]"
[project.gui-scripts]
spam-gui = "spam:main_gui"
[project.entry-points."spam.magical"]
tomatoes = "spam:main_tomatoes"
# pytest plugins refer to a module, so there is no ':obj'
[project.entry-points.pytest11]
nbval = "nbval.plugin"