From 875160e4d3aabd821d73ec08564b4ef62f444878 Mon Sep 17 00:00:00 2001 From: Ofek Lev Date: Wed, 23 Aug 2023 10:28:32 -0400 Subject: [PATCH] PEP 723: Finalize (#3297) Co-authored-by: Adam Turner <9087854+aa-turner@users.noreply.github.com> --- pep-0723.rst | 525 ++++++++++++++++++++++++++------------------------- 1 file changed, 270 insertions(+), 255 deletions(-) diff --git a/pep-0723.rst b/pep-0723.rst index ae36e5ba3..fa77dd595 100644 --- a/pep-0723.rst +++ b/pep-0723.rst @@ -11,6 +11,7 @@ Content-Type: text/x-rst Created: 04-Aug-2023 Post-History: `04-Aug-2023 `__, `06-Aug-2023 `__, + `23-Aug-2023 `__, 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 `_ 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 `__ 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[a-zA-Z0-9-]+)$\s(?P(^#(| .*)$\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 `_ 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 `_ -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[a-zA-Z0-9-]+)$\s(?P(^#(| .*)$\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[a-zA-Z0-9-]+)$\s(?P(^#(| .*)$\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 `_. +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 `__, 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 `_ 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 `__ 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 `_ that is used to describe projects. -The author of the Rust RFC for embedding metadata -`mentioned to us `__ 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 `__ 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 `__ 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 `__ 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 `__ 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 `__ or `Calibre `__. -.. [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