Skip to content

Commit 91b599b

Browse files
Add an example and list of keys to the project metadata spec (#1168)
* Add an example to the project metadata spec Copied from PEP 621 and then slightly updated. * Fix indentation * Add an anchor for `Dynamic` * Add a list of acceptable keys (and start using the term "key" instead of "field") Co-authored-by: Brian Rutledge <[email protected]>
1 parent 12b38c4 commit 91b599b

File tree

2 files changed

+125
-38
lines changed

2 files changed

+125
-38
lines changed

source/specifications/core-metadata.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ a single ``-`` character. This can be done using the following snippet of code
9191

9292
re.sub(r"[-_.]+", "-", name).lower()
9393

94+
9495
.. _core-metadata-version:
9596

9697
Version
@@ -106,6 +107,8 @@ Example::
106107
Version: 1.0a2
107108

108109

110+
.. _core-metadata-dynamic:
111+
109112
Dynamic (multiple use)
110113
======================
111114

source/specifications/declaring-project-metadata.rst

Lines changed: 122 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -9,36 +9,60 @@ Declaring project metadata
99
packaging-related tools to consume. It defines the following
1010
specification as the canonical source for the format used.
1111

12+
13+
Specification
14+
=============
15+
1216
There are two kinds of metadata: *static* and *dynamic*. Static
1317
metadata is specified in the ``pyproject.toml`` file directly and
1418
cannot be specified or changed by a tool. Dynamic metadata is listed
15-
via the ``dynamic`` field (defined later in this specification) and
19+
via the ``dynamic`` key (defined later in this specification) and
1620
represents metadata that a tool will later provide.
1721

18-
The fields defined in this specification MUST be in a table named
19-
``[project]`` in ``pyproject.toml``. No tools may add fields to this
22+
The keys defined in this specification MUST be in a table named
23+
``[project]`` in ``pyproject.toml``. No tools may add keys to this
2024
table which are not defined by this specification. For tools wishing
2125
to store their own settings in ``pyproject.toml``, they may use the
2226
``[tool]`` table as defined in the
2327
:ref:`build dependency declaration specification <declaring-build-dependencies>`.
2428
The lack of a ``[project]`` table implicitly means the build back-end
25-
will dynamically provide all fields.
29+
will dynamically provide all keys.
2630

27-
The only fields required to be statically defined are:
31+
The only keys required to be statically defined are:
2832

2933
- ``name``
3034

31-
The fields which are required but may be specified *either* statically
35+
The keys which are required but may be specified *either* statically
3236
or listed as dynamic are:
3337

3438
- ``version``
3539

36-
All other fields are considered optional and may be specified
40+
All other keys are considered optional and may be specified
3741
statically, listed as dynamic, or left unspecified.
3842

43+
The complete list of keys allowed in the ``[project]`` table are:
44+
45+
- ``authors``
46+
- ``classifiers``
47+
- ``dependencies``
48+
- ``description``
49+
- ``dynamic``
50+
- ``entry-points``
51+
- ``gui-scripts``
52+
- ``keywords``
53+
- ``license``
54+
- ``maintainers``
55+
- ``name``
56+
- ``optional-dependencies``
57+
- ``readme``
58+
- ``requires-python``
59+
- ``scripts``
60+
- ``urls``
61+
- ``version``
62+
3963

4064
``name``
41-
========
65+
--------
4266

4367
- TOML_ type: string
4468
- Corresponding :ref:`core metadata <core-metadata>` field:
@@ -51,7 +75,7 @@ as it is read for internal consistency.
5175

5276

5377
``version``
54-
===========
78+
-----------
5579

5680
- TOML_ type: string
5781
- Corresponding :ref:`core metadata <core-metadata>` field:
@@ -63,7 +87,7 @@ Users SHOULD prefer to specify already-normalized versions.
6387

6488

6589
``description``
66-
===============
90+
---------------
6791

6892
- TOML_ type: string
6993
- Corresponding :ref:`core metadata <core-metadata>` field:
@@ -73,7 +97,7 @@ The summary description of the project.
7397

7498

7599
``readme``
76-
==========
100+
----------
77101

78102
- TOML_ type: string or table
79103
- Corresponding :ref:`core metadata <core-metadata>` field:
@@ -82,28 +106,28 @@ The summary description of the project.
82106

83107
The full description of the project (i.e. the README).
84108

85-
The field accepts either a string or a table. If it is a string then
109+
The key accepts either a string or a table. If it is a string then
86110
it is a path relative to ``pyproject.toml`` to a text file containing
87111
the full description. Tools MUST assume the file's encoding is UTF-8.
88112
If the file path ends in a case-insensitive ``.md`` suffix, then tools
89113
MUST assume the content-type is ``text/markdown``. If the file path
90114
ends in a case-insensitive ``.rst``, then tools MUST assume the
91115
content-type is ``text/x-rst``. If a tool recognizes more extensions
92116
than this PEP, they MAY infer the content-type for the user without
93-
specifying this field as ``dynamic``. For all unrecognized suffixes
117+
specifying this key as ``dynamic``. For all unrecognized suffixes
94118
when a content-type is not provided, tools MUST raise an error.
95119

96-
The ``readme`` field may also take a table. The ``file`` key has a
120+
The ``readme`` key may also take a table. The ``file`` key has a
97121
string value representing a path relative to ``pyproject.toml`` to a
98122
file containing the full description. The ``text`` key has a string
99123
value which is the full description. These keys are
100124
mutually-exclusive, thus tools MUST raise an error if the metadata
101125
specifies both keys.
102126

103-
A table specified in the ``readme`` field also has a ``content-type``
104-
field which takes a string specifying the content-type of the full
127+
A table specified in the ``readme`` key also has a ``content-type``
128+
key which takes a string specifying the content-type of the full
105129
description. A tool MUST raise an error if the metadata does not
106-
specify this field in the table. If the metadata does not specify the
130+
specify this key in the table. If the metadata does not specify the
107131
``charset`` parameter, then it is assumed to be UTF-8. Tools MAY
108132
support other encodings if they choose to. Tools MAY support
109133
alternative content-types which they can transform to a content-type
@@ -112,7 +136,7 @@ tools MUST raise an error for unsupported content-types.
112136

113137

114138
``requires-python``
115-
===================
139+
-------------------
116140

117141
- TOML_ type: string
118142
- Corresponding :ref:`core metadata <core-metadata>` field:
@@ -122,7 +146,7 @@ The Python version requirements of the project.
122146

123147

124148
``license``
125-
===========
149+
-----------
126150

127151
- TOML_ type: table
128152
- Corresponding :ref:`core metadata <core-metadata>` field:
@@ -137,7 +161,7 @@ tool MUST raise an error if the metadata specifies both keys.
137161

138162

139163
``authors``/``maintainers``
140-
===========================
164+
---------------------------
141165

142166
- TOML_ type: Array of inline tables with string keys and values
143167
- Corresponding :ref:`core metadata <core-metadata>` field:
@@ -151,10 +175,10 @@ project. The exact meaning is open to interpretation — it may list the
151175
original or primary authors, current maintainers, or owners of the
152176
package.
153177

154-
The "maintainers" field is similar to "authors" in that its exact
178+
The "maintainers" key is similar to "authors" in that its exact
155179
meaning is open to interpretation.
156180

157-
These fields accept an array of tables with 2 keys: ``name`` and
181+
These keys accept an array of tables with 2 keys: ``name`` and
158182
``email``. Both values must be strings. The ``name`` value MUST be a
159183
valid email name (i.e. whatever can be put as a name, before an email,
160184
in :rfc:`822`) and not contain commas. The ``email`` value MUST be a
@@ -179,7 +203,7 @@ follows:
179203

180204

181205
``keywords``
182-
============
206+
------------
183207

184208
- TOML_ type: array of strings
185209
- Corresponding :ref:`core metadata <core-metadata>` field:
@@ -189,7 +213,7 @@ The keywords for the project.
189213

190214

191215
``classifiers``
192-
===============
216+
---------------
193217

194218
- TOML_ type: array of strings
195219
- Corresponding :ref:`core metadata <core-metadata>` field:
@@ -199,7 +223,7 @@ Trove classifiers which apply to the project.
199223

200224

201225
``urls``
202-
========
226+
--------
203227

204228
- TOML_ type: table with keys and values of strings
205229
- Corresponding :ref:`core metadata <core-metadata>` field:
@@ -210,7 +234,7 @@ URL itself.
210234

211235

212236
Entry points
213-
============
237+
------------
214238

215239
- TOML_ type: table (``[project.scripts]``, ``[project.gui-scripts]``,
216240
and ``[project.entry-points]``)
@@ -240,7 +264,7 @@ be ambiguous in the face of ``[project.scripts]`` and
240264

241265

242266
``dependencies``/``optional-dependencies``
243-
==========================================
267+
------------------------------------------
244268

245269
- TOML_ type: Array of :pep:`508` strings (``dependencies``), and a
246270
table with values of arrays of :pep:`508` strings
@@ -267,41 +291,101 @@ metadata.
267291

268292

269293
``dynamic``
270-
===========
294+
-----------
271295

272296
- TOML_ type: array of string
273-
- A corresponding :ref:`core metadata <core-metadata>` field does not
274-
exist
297+
- Corresponding :ref:`core metadata <core-metadata>` field:
298+
:ref:`Dynamic <core-metadata-dynamic>`
275299

276-
Specifies which fields listed by this PEP were intentionally
300+
Specifies which keys listed by this PEP were intentionally
277301
unspecified so another tool can/will provide such metadata
278302
dynamically. This clearly delineates which metadata is purposefully
279303
unspecified and expected to stay unspecified compared to being
280304
provided via tooling later on.
281305

282306
- A build back-end MUST honour statically-specified metadata (which
283-
means the metadata did not list the field in ``dynamic``).
307+
means the metadata did not list the key in ``dynamic``).
284308
- A build back-end MUST raise an error if the metadata specifies
285309
``name`` in ``dynamic``.
286310
- If the :ref:`core metadata <core-metadata>` specification lists a
287-
field as "Required", then the metadata MUST specify the field
311+
field as "Required", then the metadata MUST specify the key
288312
statically or list it in ``dynamic`` (build back-ends MUST raise an
289-
error otherwise, i.e. it should not be possible for a required field
313+
error otherwise, i.e. it should not be possible for a required key
290314
to not be listed somehow in the ``[project]`` table).
291315
- If the :ref:`core metadata <core-metadata>` specification lists a
292316
field as "Optional", the metadata MAY list it in ``dynamic`` if the
293-
expectation is a build back-end will provide the data for the field
317+
expectation is a build back-end will provide the data for the key
294318
later.
295319
- Build back-ends MUST raise an error if the metadata specifies a
296-
field statically as well as being listed in ``dynamic``.
297-
- If the metadata does not list a field in ``dynamic``, then a build
320+
key statically as well as being listed in ``dynamic``.
321+
- If the metadata does not list a key in ``dynamic``, then a build
298322
back-end CANNOT fill in the requisite metadata on behalf of the user
299323
(i.e. ``dynamic`` is the only way to allow a tool to fill in
300324
metadata and the user must opt into the filling in).
301325
- Build back-ends MUST raise an error if the metadata specifies a
302-
field in ``dynamic`` but the build back-end was unable to determine
326+
key in ``dynamic`` but the build back-end was unable to determine
303327
the data for it (omitting the data, if determined to be the accurate
304328
value, is acceptable).
305329

306330

331+
Example
332+
=======
333+
334+
.. code-block:: toml
335+
336+
[project]
337+
name = "spam"
338+
version = "2020.0.0"
339+
description = "Lovely Spam! Wonderful Spam!"
340+
readme = "README.rst"
341+
requires-python = ">=3.8"
342+
license = {file = "LICENSE.txt"}
343+
keywords = ["egg", "bacon", "sausage", "tomatoes", "Lobster Thermidor"]
344+
authors = [
345+
{email = "[email protected]"},
346+
{name = "Tzu-Ping Chung"}
347+
]
348+
maintainers = [
349+
{name = "Brett Cannon", email = "[email protected]"}
350+
]
351+
classifiers = [
352+
"Development Status :: 4 - Beta",
353+
"Programming Language :: Python"
354+
]
355+
356+
dependencies = [
357+
"httpx",
358+
"gidgethub[httpx]>4.0.0",
359+
"django>2.1; os_name != 'nt'",
360+
"django>2.0; os_name == 'nt'"
361+
]
362+
363+
# dynamic = ["version", "description"]
364+
365+
[project.optional-dependencies]
366+
test = [
367+
"pytest > 5.0.0",
368+
"pytest-cov[all]"
369+
]
370+
doc = [
371+
"sphinx",
372+
"furo"
373+
]
374+
375+
[project.urls]
376+
homepage = "https://example.com"
377+
documentation = "https://readthedocs.org"
378+
repository = "https://github.com/me/spam.git"
379+
changelog = "https://github.com/me/spam/blob/master/CHANGELOG.md"
380+
381+
[project.scripts]
382+
spam-cli = "spam:main_cli"
383+
384+
[project.gui-scripts]
385+
spam-gui = "spam:main_gui"
386+
387+
[project.entry-points."spam.magical"]
388+
tomatoes = "spam:main_tomatoes"
389+
390+
307391
.. _TOML: https://toml.io

0 commit comments

Comments
 (0)