PEP 723: Finalize (#3297)

Co-authored-by: Adam Turner <9087854+aa-turner@users.noreply.github.com>
This commit is contained in:
Ofek Lev 2023-08-23 10:28:32 -04:00 committed by GitHub
parent b03237ebc8
commit 875160e4d3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 270 additions and 255 deletions

View File

@ -11,6 +11,7 @@ Content-Type: text/x-rst
Created: 04-Aug-2023
Post-History: `04-Aug-2023 <https://discuss.python.org/t/30979>`__,
`06-Aug-2023 <https://discuss.python.org/t/31151>`__,
`23-Aug-2023 <https://discuss.python.org/t/32149>`__,
Replaces: 722
@ -55,23 +56,21 @@ and not in an external file.
We choose to follow the latest developments of other modern packaging
ecosystems (namely `Go`__ and provisionally `Rust`__) by embedding the existing
`metadata standard <pyproject metadata_>`_ that is used to describe
projects.
file used to describe projects, in our case ``pyproject.toml``.
__ https://github.com/erning/gorun
__ https://rust-lang.github.io/rfcs/3424-cargo-script.html
The format is intended to bridge the gap between different types of users
of Python. Knowledge of how to write project metadata will be directly
transferable to all use cases, whether writing a script or maintaining a
project that is distributed via PyPI. Additionally, users will benefit from
seamless interoperability with tools that are already familiar with the format.
of Python. Users will benefit from seamless interoperability with tools that
already work with TOML.
One of the central themes we discovered from the recent
`packaging survey <https://discuss.python.org/t/22420>`__ is that users have
begun getting frustrated with the lack of unification regarding both tooling
and specs. Adding yet another way to define metadata, even for a currently
unsatisfied use case, would further fragment the community.
and specs. Adding yet another metadata format (like :pep:`722` syntax for a
list of dependencies), even for a currently unsatisfied use case, would
further fragment the community.
The following are some of the use cases that this PEP wishes to support:
@ -79,19 +78,15 @@ The following are some of the use cases that this PEP wishes to support:
an example, the interface would be simply
``hatch run /path/to/script.py [args]`` and Hatch will manage the
environment for that script. Such tools could be used as shebang lines on
non-Windows systems e.g. ``#!/usr/bin/env hatch run``. You would also be
able to enter a shell into that environment like other projects by doing
``hatch -p /path/to/script.py shell`` since the project flag would learn
that project metadata could be read from a single file.
non-Windows systems e.g. ``#!/usr/bin/env hatch run``.
* A script that desires to transition to a directory-type project. A user may
be rapidly prototyping locally or in a remote REPL environment and then
decide to transition to a more formal project layout if their idea works
out. This intermediate script stage would be very useful to have fully
reproducible bug reports. By using the same metadata format, the user can
simply copy and paste the metadata into a ``pyproject.toml`` file and
continue working without having to learn a new format. More likely, even, is
that tooling will eventually support this transformation with a single
command.
reproducible bug reports. By using the same format, the user can simply copy
and paste the metadata into a ``pyproject.toml`` file and continue working
without having to learn a new format. More likely, even, is that tooling will
eventually support this transformation with a single command.
* Users that wish to avoid manual dependency management. For example, package
managers that have commands to add/remove dependencies or dependency update
automation in CI that triggers based on new versions or in response to
@ -101,50 +96,68 @@ The following are some of the use cases that this PEP wishes to support:
Specification
=============
Any Python script may assign a variable named ``__pyproject__`` to a multi-line
*double-quoted* string literal (``"""``) containing a valid TOML document. The
variable MUST start at the beginning of the line and the opening of the string
MUST be on the same line as the assignment. The closing of the string MUST be
on a line by itself, and MUST NOT be indented.
This PEP defines a metadata comment block format loosely inspired [2]_ by
`reStructuredText Directives`__.
When there are multiple ``__pyproject__`` variables defined, tools MUST produce
an error.
__ https://docutils.sourceforge.io/docs/ref/rst/directives.html
The TOML document MUST NOT contain multi-line double-quoted strings, as that
would conflict with the Python string containing the document. Single-quoted
multi-line TOML strings may be used instead.
Any Python script may have top-level comment blocks that start with the line
``# /// TYPE`` where ``TYPE`` determines how to process the content, and ends
with the line ``# ///``. Every line between these two lines 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
``#``).
This is the canonical regular expression that MUST be used to parse the
metadata:
.. code:: text
(?ms)^__pyproject__ *= *"""\\?$(.+?)^"""$
In circumstances where there is a discrepancy between the regular expression
and the text specification, the regular expression takes precedence.
When there are multiple comment blocks of the same ``TYPE`` defined, tools MUST
produce an error.
Tools reading embedded metadata MAY respect the standard Python encoding
declaration. If they choose not to do so, they MUST process the file as UTF-8.
This document MAY include the ``[project]``, ``[tool]`` and ``[build-system]``
tables.
This is the canonical regular expression that MAY be used to parse the
metadata:
The ``[project]`` table differs in the following ways:
.. code:: text
* The ``name`` and ``version`` fields are not required and MAY be defined
dynamically by tools if the user does not define them
* These fields do not need to be listed in the ``dynamic`` array
(?m)^# /// (?P<type>[a-zA-Z0-9-]+)$\s(?P<content>(^#(| .*)$\s)+)^# ///$
Non-script running tools MAY choose to alter their behavior based on
configuration that is stored in their expected ``[tool]`` sub-table.
In circumstances where there is a discrepancy between the text specification
and the regular expression, the text specification takes precedence.
Build frontends SHOULD NOT use the backend defined in the ``[build-system]``
table to build scripts with embedded metadata. This requires a new PEP because
the current methods defined in :pep:`517` act upon a directory, not a file.
We use ``SHOULD NOT`` instead of ``MUST NOT`` in order to allow tools to
experiment [2]_ with such functionality before we standardize (indeed this
would be a requirement).
Tools MUST NOT read from metadata blocks with types that have not been
standardized by this PEP or future ones.
pyproject type
--------------
The first type of metadata block is named ``pyproject`` which represents
content similar to [3]_ what one would see in a ``pyproject.toml`` file.
This document MAY include the ``[run]`` and ``[tool]`` tables.
The :pep:`tool table <518#tool-table>` MAY be used by any tool, script runner
or otherwise, to configure behavior.
The ``[run]`` table MAY include the following optional fields:
* ``dependencies``: A list of strings that specifies the runtime dependencies
of the script. Each entry MUST be a valid :pep:`508` dependency.
* ``requires-python``: A string that specifies the Python version(s) with which
the script is compatible. The value of this field MUST be a valid
:pep:`version specifier <440#version-specifiers>`.
* ``version``: A string that specifies the version of the script. The value of
this field MUST be a valid :pep:`440` version.
Any future PEPs that define additional fields for the ``[run]`` table when used
in a ``pyproject.toml`` file MUST include the aforementioned fields exactly as
specified. The fields defined by this PEP are equally as applicable to
full-fledged projects as they are to single-file scripts.
Script runners MUST error if the specified ``dependencies`` cannot be provided.
Script runners SHOULD error if no version of Python that satisfies the specified
``requires-python`` can be provided.
Example
-------
@ -153,14 +166,14 @@ The following is an example of a script with an embedded ``pyproject.toml``:
.. code:: python
__pyproject__ = """
[project]
requires-python = ">=3.11"
dependencies = [
"requests<3",
"rich",
]
"""
# /// pyproject
# [run]
# requires-python = ">=3.11"
# dependencies = [
# "requests<3",
# "rich",
# ]
# ///
import requests
from rich.pretty import pprint
@ -169,9 +182,9 @@ The following is an example of a script with an embedded ``pyproject.toml``:
data = resp.json()
pprint([(k, v["title"]) for k, v in data.items()][:10])
The following is an example of a proposed syntax for single-file Rust project
that embeds their equivalent of ``pyproject.toml``,
which is called ``Cargo.toml``:
The following [4]_ is an example of a proposed syntax for single-file Rust
projects that embeds their equivalent of ``pyproject.toml``, which is called
``Cargo.toml``:
.. code:: rust
@ -187,26 +200,6 @@ which is called ``Cargo.toml``:
println!("Did our date match? {}", re.is_match("2014-01-01"));
}
One important thing to note is that the metadata is embedded in a
`doc-comment`_ (their equivalent of docstrings).
`Other syntaxes <cargo embedded manifest_>`_ are under consideration
within the Rust project,
including using attributes which are somewhat like a
syntactically recognized equivalent of dunder variables,
with the key difference between Rust's choice and this PEP being that
any valid Rust syntax will be allowed,
requiring one of the Rust syntax parsers to work with it, like `syn`__.
__ https://crates.io/crates/syn
We argue that our choice, in comparison to the `doc-comment`_ approach,
is easier to read and provides easier edits for humans by virtue
of the contents starting at the beginning of lines so would precisely match
the contents of a ``pyproject.toml`` file.
It is also is easier for tools to parse and modify this continuous block
of text which was `one of the concerns <cargo embedded manifest_>`_
raised in the Rust pre-RFC.
Reference Implementation
========================
@ -215,34 +208,53 @@ higher.
.. code:: python
import re, tomllib
import re
import tomllib
REGEX = r'(?ms)^__pyproject__ *= *"""\\?$(.+?)^"""$'
REGEX = r'(?m)^# /// (?P<type>[a-zA-Z0-9-]+)$\s(?P<content>(^#(| .*)$\s)+)^# ///$'
def read(script: str) -> dict | None:
matches = list(re.finditer(REGEX, script))
if len(matches) > 1:
raise ValueError('Multiple __pyproject__ definitions found')
elif len(matches) == 1:
return tomllib.loads(matches[0])
else:
return None
def read(script: str) -> dict | None:
name = 'pyproject'
matches = list(
filter(lambda m: m.group('type') == name, re.finditer(REGEX, script))
)
if len(matches) > 1:
raise ValueError(f'Multiple {name} blocks found')
elif len(matches) == 1:
return tomllib.loads(matches[0])
else:
return None
Often tools will edit dependencies like package managers or dependency update
automation in CI. The following is a crude example of modifying the content
using the ``tomlkit`` library.
using the ``tomlkit`` library__.
__ https://tomlkit.readthedocs.io/en/latest/
.. code:: python
import re, tomlkit
import re
def add(script: str, dependency: str) -> str:
match = re.search(r'(?ms)^__pyproject__ *= *"""\\?$(.+?)^"""$', script)
config = tomlkit.parse(match.group(1))
config['project']['dependencies'].append(dependency)
import tomlkit
start, end = match.span(1)
return script[:start] + tomlkit.dumps(config) + script[end:]
REGEX = r'(?m)^# /// (?P<type>[a-zA-Z0-9-]+)$\s(?P<content>(^#(| .*)$\s)+)^# ///$'
def add(script: str, dependency: str) -> str:
match = re.search(REGEX, script)
content = ''.join(
line[2:] if line.startswith('# ') else line[1:]
for line in match.group('content').splitlines(keepends=True)
)
config = tomlkit.parse(content)
config['project']['dependencies'].append(dependency)
new_content = ''.join(
f'# {line}' if line.strip() else f'#{line}'
for line in tomlkit.dumps(config).splitlines(keepends=True)
)
start, end = match.span('content')
return script[:start] + new_content + script[end:]
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"
@ -252,26 +264,11 @@ feature.
Backwards Compatibility
=======================
At the time of writing, the ``__pyproject__`` variable only appears five times
`on GitHub`__ and four of those belong to a user who appears to already be
using this PEP's exact format.
At the time of writing, the ``# /// pyproject`` block comment starter does not
appear `on GitHub`__. Therefore, there is little risk of existing scripts being
broken by this PEP.
__ https://github.com/search?q=__pyproject__&type=code
For example, `this script`__ uses ``matplotlib`` and ``pandas`` to plot a
timeseries. It is a good example of a script that you would see in the wild:
self-contained and short.
__ https://github.com/cjolowicz/scripts/blob/31c61e7dad8d17e0070b080abee68f4f505da211/python/plot_timeseries.py
This user's tooling invokes scripts by creating a project at runtime using the
embedded metadata and then uses an entry point that references the main
function.
This PEP allows this user's tooling to remove that extra step of indirection.
This PEP's author has discovered after writing a draft that this pattern is
used in the wild by others (sent private messages).
__ https://github.com/search?q=%22%23+%2F%2F%2F+pyproject%22&type=code
Security Implications
@ -284,34 +281,69 @@ installed in the user's environment.
The risk here is part of the functionality of the tool being used to run the
script, and as such should already be addressed by the tool itself. The only
additional risk introduced by this PEP is if an untrusted script with a
embedded metadata is run, when a potentially malicious dependency might be
installed.
embedded metadata is run, when a potentially malicious dependency or transitive
dependency might be installed.
This risk is addressed by the normal good practice of reviewing code
before running it. Additionally, tools may be able to provide locking
functionality when configured by their ``[tool]`` sub-table to, for example,
add the resolution result as managed metadata somewhere in the script (this
is what Go's ``gorun`` can do).
before running it. Additionally, tools may be able to provide
`locking functionality <723-tool-configuration_>`__ to ameliorate this risk.
How to Teach This
=================
Since the format chosen is the same as the official metadata standard, we can
have a page that describes how to embed the metadata in scripts and to learn
about metadata itself direct users to the living document that describes
`project metadata <pyproject metadata_>`_.
To embed metadata in a script, define a comment block that starts with the
line ``# /// pyproject`` and ends with the line ``# ///``. Every line between
those two lines must be a comment and the full content is derived by removing
the first two characters. The ``pyproject`` type indicates that the content
is TOML and resembles a ``pyproject.toml`` file.
We will document that the name and version fields in the ``[project]`` table
may be elided for simplicity. Additionally, we will have guidance explaining
that single-file scripts cannot (yet) be built into a wheel via standard means.
.. code:: python
We will explain that it is up to individual tools whether or not their behavior
is altered based on the embedded metadata. For example, every script runner may
not be able to provide an environment for specific Python versions as defined
by the ``requires-python`` field.
# /// pyproject
# [run]
# dependencies = [
# "requests<3",
# "rich",
# ]
# requires-python = ">=3.11"
# version = "0.1.0"
# ///
Finally, we may want to list some tools that support this PEP's format.
The two allowed tables are ``[run]`` and ``[tool]``. The ``[run]`` table may
contain the following fields:
.. list-table::
* - Field
- Description
- Tool behavior
* - ``dependencies``
- A list of strings that specifies the runtime dependencies of the script.
Each entry must be a valid :pep:`508` dependency.
- Tools will error if the specified dependencies cannot be provided.
* - ``requires-python``
- A string that specifies the Python version(s)
with which the script is compatible.
The value of this field must be a valid
:pep:`version specifier <440#version-specifiers>`.
- Tools might error if no version of Python that satisfies
the constraint can be executed.
* - ``version``
- A string that specifies the version of the script.
The value of this field must be a valid :pep:`440` version.
- Tools may use this however they wish, if defined.
It is up to individual tools whether or not their behavior is altered based on
the embedded metadata. For example, every script runner may not be able to
provide an environment for specific Python versions as defined by the
``requires-python`` field.
The :pep:`tool table <518#tool-table>` may be used by any tool, script runner
or otherwise, to configure behavior.
Recommendations
@ -321,28 +353,6 @@ Tools that support managing different versions of Python should attempt to use
the highest available version of Python that is compatible with the script's
``requires-python`` metadata, if defined.
For projects that have large multi-line external metadata to embed like a
README file, it is recommended that they become directories with a
``pyproject.toml`` file. While this is technically allowed, it is strongly
discouraged to have large chunks of multi-line metadata and is indicative
of the fact that a script has graduated to a more traditional layout.
If the content is small, for example in the case of internal packages, it is
recommended that multi-line *single-quoted* TOML strings (``'''``) be used.
For example:
.. code:: python
__pyproject__ = """
[project]
readme.content-type = "text/markdown"
readme.text = '''
# Some Project
Please refer to our corporate docs
for more information.
'''
"""
Tooling buy-in
==============
@ -366,35 +376,6 @@ have committed to implementing support should it be accepted:
Rejected Ideas
==============
Why not limit to specific metadata fields?
------------------------------------------
By limiting the metadata to a specific set of fields, for example just
``dependencies``, we would prevent legitimate use cases both known and unknown.
The following are examples of known use cases:
* ``requires-python``: For tools that support managing Python installations,
this allows users to target specific versions of Python for new syntax
or standard library functionality.
* ``version``: It is quite common to version scripts for persistence even when
using a VCS like Git. When not using a VCS it is even more common to version,
for example the author has been in multiple time sensitive debugging sessions
with customers where due to the airgapped nature of the environment, the only
way to transfer the script was via email or copying and pasting it into a
chat window. In these cases, versioning is invaluable to ensure that the
customer is using the latest (or a specific) version of the script.
* ``description``: For scripts that don't need an argument parser, or if the
author has never used one, tools can treat this as help text which can be
shown to the user.
By not allowing the ``[tool]`` section, we would prevent especially script
runners from allowing users to configure behavior. For example, a script runner
may support configuration instructing to run scripts in containers for
situations in which there is no cross-platform support for a dependency or if
the setup is too complex for the average user like when requiring Nvidia
drivers. Situations like this would allow users to proceed with what they want
to do whereas otherwise they may stop at that point altogether.
.. _723-comment-block:
Why not use a comment block resembling requirements.txt?
@ -436,9 +417,9 @@ would live as single-file scripts:
executable or script runner.
This PEP argues that reusing our TOML-based metadata format is the best for
each category of user and that the block comment is only approachable for
those who have familiarity with ``requirements.txt``, which represents a
small subset of users.
each category of user and that the requirements-like block comment is only
approachable for those who have familiarity with ``requirements.txt``, which
represents a small subset of users.
* For the average person automating a task or the data scientist, they are
already starting with zero context and are unlikely to be familiar with
@ -447,9 +428,9 @@ small subset of users.
of a chat bot or direct code completion software. Searching for Python
metadata formatting will lead them to the TOML-based format that already
exists which they can reuse. The author tested GitHub Copilot with this
PEP and it already supports auto-completion of fields and dependencies.
In contrast, a new format may take years of being trained on the Internet
for models to learn.
PEP and it already supports auto-completion of ``dependencies``. In contrast,
a new format may take years of being trained on the Internet for models to
learn.
Additionally, these users are most susceptible to formatting quirks and
syntax errors. TOML is a well-defined format with existing online
@ -464,7 +445,7 @@ small subset of users.
with TOML since they are used to structured data formats and there would be
less perceived magic in their systems.
Additionally, for maintenance of their systems ``__pyproject__`` would be
Additionally, for maintenance of their systems ``/// pyproject`` would be
much easier to search for from a shell than a block comment with potentially
numerous extensions over time.
* For the SRE types, they are likely to be familiar with TOML already from
@ -490,11 +471,12 @@ small subset of users.
Studio Code would be able to provide TOML syntax highlighting much more
easily than each writing custom logic for this feature.
Additionally, since the original block comment alternative format went against
the recommendation of :pep:`8` and as a result linters and IDE auto-formatters
that respected the recommendation would
Additionally, since the original block comment alternative format (double
``#``) went against the recommendation of :pep:`8` and as a result linters
and IDE auto-formatters that respected the recommendation would
`fail by default <https://discuss.python.org/t/29905/247>`__, the final
proposal uses standard comments starting with a single ``#`` character.
proposal uses standard comments starting with a single ``#`` character without
any obvious start nor end sequence.
The concept of regular comments that do not appear to be intended for machines
(i.e. `encoding declarations`__) affecting behavior would not be customary to
@ -517,47 +499,89 @@ would be multiple ways to achieve the same thing which goes against our
foundational principle of "there should be one - and preferably only one -
obvious way to do it".
Why not consider scripts as projects without wheels?
----------------------------------------------------
Why not use a multi-line string?
--------------------------------
There is `an ongoing discussion <pyproject without wheels_>`_ about how to
use ``pyproject.toml`` for projects that are not intended to be built as
wheels. This PEP considers the discussion only tangentially related.
A previous version of this PEP proposed that the metadata be stored as follows:
The use case described in that thread is primarily talking about projects that
represent applications like a Django app or a Flask app. These projects are
often installed on each server in a virtual environment with strict dependency
pinning e.g. a lock file with some sort of hash checking. Such projects would
never be distributed as a wheel (except for maybe a transient editable one
that is created when doing ``pip install -e .``).
.. code:: python
In contrast, scripts are managed loosely by their runners and would almost
always have relaxed dependency constraints. Additionally, there may be a future
in which there is `a standard way <723-limit-build-backend_>`_ to ship projects
that are in the form of a single file.
__pyproject__ = """
...
"""
.. _723-limit-build-backend:
The most significant problem with this proposal is that the embedded TOML would
be limited in the following ways:
Why not limit build backend behavior?
-------------------------------------
* It would not be possible to use multi-line double-quoted strings in the TOML
as that would conflict with the Python string containing the document. Many
TOML writers do not preserve style and may potentially produce output that
would be malformed.
* The way in which character escaping works in Python strings is not quite the
way it works in TOML strings. It would be possible to preserve a one-to-one
character mapping by enforcing raw strings, but this ``r`` prefix requirement
may be potentially confusing to users.
A previous version of this PEP proposed that the ``[build-system]`` table
mustn't be defined. The rationale was that builds would never occur so it
did not make sense to allow this section.
Why not reuse core metadata fields?
-----------------------------------
We removed that limitation based on
`feedback <https://discuss.python.org/t/31151/9>`__ stating that there
are already tools that exist in the wild that build wheels and source
distributions from single files.
A previous version of this PEP proposed to reuse the existing
`metadata standard <pyproject metadata_>`_ that is used to describe projects.
The author of the Rust RFC for embedding metadata
`mentioned to us <https://discuss.python.org/t/29905/179>`__ that they are
actively looking into that as well based on user feedback saying that there
is unnecessary friction with managing small projects, which we have also
heard in the Python community.
There are two significant problems with this proposal:
There has been `a commitment <https://discuss.python.org/t/31151/15>`__ to
support this by at least one major build system.
* The ``name`` and ``version`` fields are required and changing that would
require its own PEP
* Reusing the data is `fundamentally a misuse of it`__
__ https://snarky.ca/differentiating-between-writing-down-dependencies-to-use-packages-and-for-packages-themselves/
Why not limit to specific metadata fields?
------------------------------------------
By limiting the metadata to a specific set of fields, for example just
``dependencies``, we would prevent legitimate known use cases:
* ``requires-python``: For tools that support managing Python installations,
this allows users to target specific versions of Python for new syntax
or standard library functionality.
* ``version``: It is quite common to version scripts for persistence even when
using a VCS like Git. When not using a VCS it is even more common to version,
for example the author has been in multiple time sensitive debugging sessions
with customers where due to the airgapped nature of the environment, the only
way to transfer the script was via email or copying and pasting it into a
chat window. In these cases, versioning is invaluable to ensure that the
customer is using the latest (or a specific) version of the script.
.. _723-tool-configuration:
Why not limit tool configuration?
---------------------------------
By not allowing the ``[tool]`` table, we would prevent known functionality
that would benefit users. For example:
* A script runner may support injecting of dependency resolution data for an
embedded lock file (this is what Go's ``gorun`` can do).
* A script runner may support configuration instructing to run scripts in
containers for situations in which there is no cross-platform support for a
dependency or if the setup is too complex for the average user like when
requiring Nvidia drivers. Situations like this would allow users to proceed
with what they want to do whereas otherwise they may stop at that point
altogether.
* Tools may wish to experiment with features to ease development burden for
users such as the building of single-file scripts into packages. We received
`feedback <https://discuss.python.org/t/31151/9>`__ stating that there are
already tools that exist in the wild that build wheels and source
distributions from single files.
The author of the Rust RFC for embedding metadata
`mentioned to us <https://discuss.python.org/t/29905/179>`__ that they are
actively looking into that as well based on user feedback saying that there
is unnecessary friction with managing small projects.
There has been `a commitment <https://discuss.python.org/t/31151/15>`__ to
support this by at least one major build system.
Why not limit tool behavior?
----------------------------
@ -574,25 +598,6 @@ from maintainers of tools that this would be undesirable and potentially
confusing to users. Additionally, this may allow for a universally easier
way to configure tools in certain circumstances and solve existing issues.
Why not accept all valid Python expression syntax?
--------------------------------------------------
There has been a suggestion that we should not restrict how the
``__pyproject__`` variable is defined and we should parse the abstract syntax
tree. For example:
.. code:: python
__pyproject__ = (
"""
[project]
dependencies = []
"""
)
We will not be doing this so that every language has the possibility to read
the metadata without dependence on knowledge of every version of Python.
Why not just set up a Python project with a ``pyproject.toml``?
---------------------------------------------------------------
@ -682,7 +687,7 @@ detail.
So in order to make a standard, two things would be required:
1. A standardised replacement for the requirements file format.
2. A standard for how to locate the requiements file for a given script.
2. A standard for how to locate the requirements file for a given script.
The first item is a significant undertaking. It has been discussed on a number
of occasions, but so far no-one has attempted to actually do it. The most
@ -705,7 +710,7 @@ script (for example, publishing it on a text file sharing service like Github's
gist, or a corporate intranet) may not allow for deriving the location of an
associated requirements file from the script's location (tools like ``pipx``
support running a script directly from a URL, so "download and unpack a zip of
the script and itsdependencies" may not be an appropriate requirement).
the script and its dependencies" may not be an appropriate requirement).
Essentially, though, the issue here is that there is an explicitly stated
requirement that the format supports storing dependency data *in the script
@ -765,8 +770,6 @@ References
==========
.. _pyproject metadata: https://packaging.python.org/en/latest/specifications/declaring-project-metadata/
.. _doc-comment: https://doc.rust-lang.org/stable/book/ch14-02-publishing-to-crates-io.html#making-useful-documentation-comments
.. _cargo embedded manifest: https://github.com/epage/cargo-script-mvs/blob/main/0000-cargo-script.md#embedded-manifest-format
.. _pip-run issue: https://github.com/jaraco/pip-run/issues/44
.. _pyproject without wheels: https://discuss.python.org/t/projects-that-arent-meant-to-generate-a-wheel-and-pyproject-toml/29684
@ -779,8 +782,20 @@ Footnotes
projects that require special maintenance like the
`AWS CLI <https://github.com/aws/aws-cli/tree/4393dcdf044a5275000c9c193d1933c07a08fdf1/scripts>`__
or `Calibre <https://github.com/kovidgoyal/calibre/tree/master/setup>`__.
.. [2] For example, projects like Hatch and Poetry have their own backends
and may wish to support this use case only when their backend is used.
.. [2] The syntax is taken directly from the final resolution of the
`Blocks extension`__ to `Python Markdown`__.
__ https://github.com/facelessuser/pymdown-extensions/discussions/1973
__ https://github.com/Python-Markdown/markdown
.. [3] A future PEP that officially introduces the ``[run]`` table to
``pyproject.toml`` files will make this PEP not just similar but a strict
subset.
.. [4] One important thing to note is that the metadata is embedded in a
`doc-comment`__ (their equivalent of docstrings). `Other syntaxes`__ are
under consideration within the Rust project.
__ https://doc.rust-lang.org/stable/book/ch14-02-publishing-to-crates-io.html#making-useful-documentation-comments
__ https://github.com/epage/cargo-script-mvs/blob/main/0000-cargo-script.md#embedded-manifest-format
Copyright