PEP 723: Mark as Provisional (#3505)

Co-authored-by: Carol Willing <carolcode@willingconsulting.com>
Co-authored-by: Brett Cannon <brett@python.org>
Co-authored-by: David Ellis <ducksual@gmail.com>
This commit is contained in:
Ofek Lev 2023-11-03 15:16:59 -04:00 committed by GitHub
parent 32de30c52e
commit 04b3abd6a7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 57 additions and 10 deletions

View File

@ -4,7 +4,7 @@ Author: Ofek Lev <ofekmeister@gmail.com>
Sponsor: Adam Turner <python@quite.org.uk> Sponsor: Adam Turner <python@quite.org.uk>
PEP-Delegate: Brett Cannon <brett@python.org> PEP-Delegate: Brett Cannon <brett@python.org>
Discussions-To: https://discuss.python.org/t/31151 Discussions-To: https://discuss.python.org/t/31151
Status: Draft Status: Provisional
Type: Standards Track Type: Standards Track
Topic: Packaging Topic: Packaging
Content-Type: text/x-rst Content-Type: text/x-rst
@ -13,6 +13,7 @@ Post-History: `04-Aug-2023 <https://discuss.python.org/t/30979>`__,
`06-Aug-2023 <https://discuss.python.org/t/31151>`__, `06-Aug-2023 <https://discuss.python.org/t/31151>`__,
`23-Aug-2023 <https://discuss.python.org/t/32149>`__, `23-Aug-2023 <https://discuss.python.org/t/32149>`__,
Replaces: 722 Replaces: 722
Resolution: https://discuss.python.org/t/36763
Abstract Abstract
@ -101,14 +102,39 @@ This PEP defines a metadata comment block format loosely inspired [2]_ by
__ https://docutils.sourceforge.io/docs/ref/rst/directives.html __ https://docutils.sourceforge.io/docs/ref/rst/directives.html
Any Python script may have top-level comment blocks that start with the line Any Python script may have top-level comment blocks that MUST start with the
``# /// TYPE`` where ``TYPE`` determines how to process the content, and ends line ``# /// TYPE`` where ``TYPE`` determines how to process the content. That
with the line ``# ///``. Every line between these two lines MUST be a comment is: a single ``#``, followed by a single space, followed by three forward
starting with ``#``. If there are characters after the ``#`` then the first slashes, followed by a single space, followed by the type of metadata. Block
character MUST be a space. The embedded content is formed by taking away the MUST end with the line ``# ///``. That is: a single ``#``, followed by a single
first two characters of each line if the second character is a space, otherwise space, followed by three forward slashes. The ``TYPE`` MUST only consist of
just the first character (which means the line consists of only a single ASCII letters, numbers and hyphens.
``#``).
Every line between these two lines (``# /// TYPE`` and ``# ///``) MUST be a
comment starting with ``#``. If there are characters after the ``#`` then the
first character MUST be a space. The embedded content is formed by taking away
the first two characters of each line if the second character is a space,
otherwise just the first character (which means the line consists of only a
single ``#``).
Precedence for an ending line ``# ///`` is given when the next line is not
a valid embedded content line as described above. For example, the following
is a single fully valid block:
.. code:: python
# /// some-toml
# embedded-csharp = """
# /// <summary>
# /// text
# ///
# /// </summary>
# public class MyClass { }
# """
# ///
A starting line MUST NOT be placed between another starting line and its ending
line. In such cases tools MAY produce an error. Unclosed blocks MUST be ignored.
When there are multiple comment blocks of the same ``TYPE`` defined, tools MUST When there are multiple comment blocks of the same ``TYPE`` defined, tools MUST
produce an error. produce an error.
@ -219,7 +245,11 @@ higher.
if len(matches) > 1: if len(matches) > 1:
raise ValueError(f'Multiple {name} blocks found') raise ValueError(f'Multiple {name} blocks found')
elif len(matches) == 1: elif len(matches) == 1:
return tomllib.loads(matches[0]) content = ''.join(
line[2:] if line.startswith('# ') else line[1:]
for line in matches[0].group('content').splitlines(keepends=True)
)
return tomllib.loads(content)
else: else:
return None return None
@ -258,6 +288,23 @@ Note that this example used a library that preserves TOML formatting. This is
not a requirement for editing by any means but rather is a "nice to have" not a requirement for editing by any means but rather is a "nice to have"
feature. feature.
The following is an example of how to read a stream of arbitrary metadata
blocks.
.. code:: python
import re
from typing import Iterator
REGEX = r'(?m)^# /// (?P<type>[a-zA-Z0-9-]+)$\s(?P<content>(^#(| .*)$\s)+)^# ///$'
def stream(script: str) -> Iterator[tuple[str, str]]:
for match in re.finditer(REGEX, script):
yield match.group('type'), ''.join(
line[2:] if line.startswith('# ') else line[1:]
for line in match.group('content').splitlines(keepends=True)
)
Backwards Compatibility Backwards Compatibility
======================= =======================