Skip to content

Commit 696e136

Browse files
authored
Merge pull request #1611 from woodruffw-forks/ww/pep-753
guides, specifications: update for PEP 753
2 parents 55995ee + 0441f5a commit 696e136

File tree

5 files changed

+249
-28
lines changed

5 files changed

+249
-28
lines changed

source/guides/writing-pyproject-toml.rst

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -399,13 +399,21 @@ To prevent a package from being uploaded to PyPI, use the special ``Private ::
399399
Do Not Upload`` classifier. PyPI will always reject packages with classifiers
400400
beginning with ``Private ::``.
401401

402+
.. _writing-pyproject-toml-urls:
402403

403404
``urls``
404405
--------
405406

406407
A list of URLs associated with your project, displayed on the left
407408
sidebar of your PyPI project page.
408409

410+
.. note::
411+
412+
See :ref:`well-known-labels` for a listing
413+
of labels that PyPI and other packaging tools are specifically aware of,
414+
and `PyPI's project metadata docs <https://docs.pypi.org/project_metadata/#project-urls>`_
415+
for PyPI-specific URL processing.
416+
409417
.. code-block:: toml
410418
411419
[project.urls]
@@ -415,11 +423,34 @@ sidebar of your PyPI project page.
415423
Issues = "https://github.com/me/spam/issues"
416424
Changelog = "https://github.com/me/spam/blob/master/CHANGELOG.md"
417425
418-
Note that if the key contains spaces, it needs to be quoted, e.g.,
426+
Note that if the label contains spaces, it needs to be quoted, e.g.,
419427
``Website = "https://example.com"`` but
420428
``"Official Website" = "https://example.com"``.
421429

430+
Users are advised to use :ref:`well-known-labels` for their project URLs
431+
where appropriate, since consumers of metadata (like package indices) can
432+
specialize their presentation.
433+
434+
For example in the following metadata, neither ``MyHomepage`` nor
435+
``"Download Link"`` is a well-known label, so they will be rendered verbatim:
422436

437+
.. code-block:: toml
438+
439+
[project.urls]
440+
MyHomepage = "https://example.com"
441+
"Download Link" = "https://example.com/abc.tar.gz"
442+
443+
444+
Whereas in this metadata ``HomePage`` and ``DOWNLOAD`` both have
445+
well-known equivalents (``homepage`` and ``download``), and can be presented
446+
with those semantics in mind (the project's home page and its external
447+
download location, respectively).
448+
449+
.. code-block:: toml
450+
451+
[project.urls]
452+
HomePage = "https://example.com"
453+
DOWNLOAD = "https://example.com/abc.tar.gz"
423454
424455
Advanced plugins
425456
================

source/specifications/core-metadata.rst

Lines changed: 38 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -341,32 +341,6 @@ Example::
341341
These tools have been very widely used for many years, so it was
342342
easier to update the specification to match the de facto standard.
343343

344-
.. _home-page-optional:
345-
.. _core-metadata-home-page:
346-
347-
Home-page
348-
=========
349-
350-
.. versionadded:: 1.0
351-
352-
A string containing the URL for the distribution's home page.
353-
354-
Example::
355-
356-
Home-page: http://www.example.com/~cschultz/bvote/
357-
358-
.. _core-metadata-download-url:
359-
360-
Download-URL
361-
============
362-
363-
.. versionadded:: 1.1
364-
365-
A string containing the URL from which this version of the distribution
366-
can be downloaded. (This means that the URL can't be something like
367-
".../BeagleVote-latest.tgz", but instead must be ".../BeagleVote-0.45.tgz".)
368-
369-
370344
.. _author-optional:
371345
.. _core-metadata-author:
372346

@@ -669,6 +643,10 @@ Example::
669643

670644
The label is free text limited to 32 characters.
671645

646+
Starting with :pep:`753`, project metadata consumers (such as the Python
647+
Package Index) can use a standard normalization process to discover "well-known"
648+
labels, which can then be given special presentations when being rendered
649+
for human consumption. See :ref:`well-known-project-urls`.
672650

673651
.. _metadata_provides_extra:
674652
.. _core-metadata-provides-extra:
@@ -819,6 +797,40 @@ Examples::
819797
Deprecated Fields
820798
=================
821799

800+
.. _home-page-optional:
801+
.. _core-metadata-home-page:
802+
803+
Home-page
804+
---------
805+
806+
.. versionadded:: 1.0
807+
808+
.. deprecated:: 1.2
809+
810+
Per :pep:`753`, use :ref:`core-metadata-project-url` instead.
811+
812+
A string containing the URL for the distribution's home page.
813+
814+
Example::
815+
816+
Home-page: http://www.example.com/~cschultz/bvote/
817+
818+
.. _core-metadata-download-url:
819+
820+
Download-URL
821+
------------
822+
823+
.. versionadded:: 1.1
824+
825+
.. deprecated:: 1.2
826+
827+
Per :pep:`753`, use :ref:`core-metadata-project-url` instead.
828+
829+
A string containing the URL from which this version of the distribution
830+
can be downloaded. (This means that the URL can't be something like
831+
"``.../BeagleVote-latest.tgz``", but instead must be
832+
"``.../BeagleVote-0.45.tgz``".)
833+
822834
Requires
823835
--------
824836

source/specifications/pyproject-toml.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,8 @@ Trove classifiers which apply to the project.
318318
:ref:`Project-URL <core-metadata-project-url>`
319319

320320
A table of URLs where the key is the URL label and the value is the
321-
URL itself.
321+
URL itself. See :ref:`well-known-project-urls` for normalization rules
322+
and well-known rules when processing metadata for presentation.
322323

323324

324325
Entry points

source/specifications/section-distribution-metadata.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,4 @@ Package Distribution Metadata
1212
pyproject-toml
1313
inline-script-metadata
1414
platform-compatibility-tags
15+
well-known-project-urls
Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
.. _`well-known-project-urls`:
2+
3+
===================================
4+
Well-known Project URLs in Metadata
5+
===================================
6+
7+
.. important::
8+
9+
This document is primarily of interest to metadata *consumers*,
10+
who should use the normalization rules and well-known list below
11+
to make their presentation of project URLs consistent across the
12+
Python ecosystem.
13+
14+
Metadata *producers* (such as build tools and individual package
15+
maintainers) may continue to use any labels they please, within the
16+
overall ``Project-URL`` length restrictions. However, when possible, users are
17+
*encouraged* to pick meaningful labels that normalize to well-known
18+
labels.
19+
20+
.. note::
21+
22+
See :ref:`Writing your pyproject.toml - urls <writing-pyproject-toml-urls>`
23+
for user-oriented guidance on choosing project URL labels in your package's
24+
metadata.
25+
26+
.. note:: This specification was originally defined in :pep:`753`.
27+
28+
:pep:`753` deprecates the :ref:`core-metadata-home-page` and
29+
:ref:`core-metadata-download-url` metadata fields in favor of
30+
:ref:`core-metadata-project-url`, and defines a normalization and
31+
lookup procedure for determining whether a ``Project-URL`` is
32+
"well-known," i.e. has the semantics assigned to ``Home-page``,
33+
``Download-URL``, or other common project URLs.
34+
35+
This allows indices (such as the Python Package Index) and other downstream
36+
metadata consumers to present project URLs in a
37+
consistent manner.
38+
39+
.. _project-url-label-normalization:
40+
41+
Label normalization
42+
===================
43+
44+
.. note::
45+
46+
Label normalization is performed by metadata *consumers*, not metadata
47+
producers.
48+
49+
To determine whether a ``Project-URL`` label is "well-known," metadata
50+
consumers should normalize the label before comparing it to the
51+
:ref:`list of well-known labels <well-known-labels>`.
52+
53+
The normalization procedure for ``Project-URL`` labels is defined
54+
by the following Python function:
55+
56+
.. code-block:: python
57+
58+
import string
59+
60+
def normalize_label(label: str) -> str:
61+
chars_to_remove = string.punctuation + string.whitespace
62+
removal_map = str.maketrans("", "", chars_to_remove)
63+
return label.translate(removal_map).lower()
64+
65+
In plain language: a label is *normalized* by deleting all ASCII punctuation
66+
and whitespace, and then converting the result to lowercase.
67+
68+
The following table shows examples of labels before (raw) and after
69+
normalization:
70+
71+
.. list-table::
72+
:header-rows: 1
73+
74+
* - Raw
75+
- Normalized
76+
* - ``Homepage``
77+
- ``homepage``
78+
* - ``Home-page``
79+
- ``homepage``
80+
* - ``Home page``
81+
- ``homepage``
82+
* - ``Change_Log``
83+
- ``changelog``
84+
* - ``What's New?``
85+
- ``whatsnew``
86+
* - ``github``
87+
- ``github``
88+
89+
.. _well-known-labels:
90+
91+
Well-known labels
92+
=================
93+
94+
.. note::
95+
96+
The list of well-known labels is a living standard, maintained as part of
97+
this document.
98+
99+
The following table lists labels that are well-known for the purpose of
100+
specializing the presentation of ``Project-URL`` metadata:
101+
102+
.. list-table::
103+
:header-rows: 1
104+
105+
* - Label (Human-readable equivalent)
106+
- Description
107+
- Aliases
108+
* - ``homepage`` (Homepage)
109+
- The project's home page
110+
- *(none)*
111+
* - ``source`` (Source Code)
112+
- The project's hosted source code or repository
113+
- ``repository``, ``sourcecode``, ``github``
114+
* - ``download`` (Download)
115+
- A download URL for the current distribution, equivalent to ``Download-URL``
116+
- *(none)*
117+
* - ``changelog`` (Changelog)
118+
- The project's comprehensive changelog
119+
- ``changes``, ``whatsnew``, ``history``
120+
* - ``releasenotes`` (Release Notes)
121+
- The project's curated release notes
122+
- *(none)*
123+
* - ``documentation`` (Documentation)
124+
- The project's online documentation
125+
- ``docs``
126+
* - ``issues`` (Issue Tracker)
127+
- The project's bug tracker
128+
- ``bugs``, ``issue``, ``tracker``, ``issuetracker``, ``bugtracker``
129+
* - ``funding`` (Funding)
130+
- Funding Information
131+
- ``sponsor``, ``donate``, ``donation``
132+
133+
Package metadata consumers may choose to render aliased labels the same as
134+
their "parent" well known label, or further specialize them.
135+
136+
Example behavior
137+
================
138+
139+
The following shows the flow of project URL metadata from
140+
``pyproject.toml`` to core metadata to a potential index presentation:
141+
142+
.. code-block:: toml
143+
:caption: Example project URLs in standard configuration
144+
145+
[project.urls]
146+
"Home Page" = "https://example.com"
147+
DOCUMENTATION = "https://readthedocs.org"
148+
Repository = "https://upstream.example.com/me/spam.git"
149+
GitHub = "https://github.com/example/spam"
150+
151+
.. code-block:: email
152+
:caption: Core metadata representation
153+
154+
Project-URL: Home page, https://example.com
155+
Project-URL: DOCUMENTATION, https://readthedocs.org
156+
Project-URL: Repository, https://upstream.example.com/me/spam.git
157+
Project-URL: GitHub, https://github.com/example/spam
158+
159+
.. code-block:: text
160+
:caption: Potential rendering
161+
162+
Homepage: https://example.com
163+
Documentation: https://readthedocs.org
164+
Source Code: https://upstream.example.com/me/spam.git
165+
Source Code (GitHub): https://github.com/example/spam
166+
167+
Observe that the core metadata appears in the form provided by the user
168+
(since metadata *producers* do not perform normalization), but the
169+
metadata *consumer* normalizes and identifies appropriate
170+
human-readable equivalents based on the normalized form:
171+
172+
* ``Home page`` becomes ``homepage``, which is rendered as ``Homepage``
173+
* ``DOCUMENTATION`` becomes ``documentation``, which is rendered as ``Documentation``
174+
* ``Repository`` becomes ``repository``, which is rendered as ``Source Code``
175+
* ``GitHub`` becomes ``github``, which is rendered as ``Source Code (GitHub)``
176+
(as a specialization of ``Source Code``)

0 commit comments

Comments
 (0)