Merge branch 'main' into pep-667-exec-impact
This commit is contained in:
commit
544de0fbf8
|
@ -5,13 +5,24 @@ Author: Philippe Ombredanne <pombredanne@nexb.com>,
|
|||
Karolina Surma <karolina.surma@gazeta.pl>,
|
||||
PEP-Delegate: Brett Cannon <brett@python.org>
|
||||
Discussions-To: https://discuss.python.org/t/53020
|
||||
Status: Draft
|
||||
Status: Provisional
|
||||
Type: Standards Track
|
||||
Topic: Packaging
|
||||
Created: 15-Aug-2019
|
||||
Post-History: `15-Aug-2019 <https://discuss.python.org/t/2154>`__,
|
||||
`17-Dec-2021 <https://discuss.python.org/t/12622>`__,
|
||||
`10-May-2024 <https://discuss.python.org/t/53020>`__,
|
||||
Resolution: https://discuss.python.org/t/53020/106
|
||||
|
||||
|
||||
Provisional Acceptance
|
||||
======================
|
||||
|
||||
This PEP has been **provisionally accepted**,
|
||||
with the following required conditions before the PEP is made Final:
|
||||
|
||||
1. An implementation of the PEP in two build back-ends.
|
||||
2. An implementation of the PEP in PyPI.
|
||||
|
||||
|
||||
.. _639-abstract:
|
||||
|
@ -540,7 +551,7 @@ as specified below:
|
|||
|
||||
Any characters or character sequences not covered by this specification are
|
||||
invalid. Projects MUST NOT use such values.
|
||||
Tools consuming this field MAY reject invalid values with an error.
|
||||
Tools consuming this field SHOULD reject invalid values with an error.
|
||||
|
||||
Tools MUST assume that license file content is valid UTF-8 encoded text,
|
||||
and SHOULD validate this and raise an error if it is not.
|
||||
|
|
|
@ -61,10 +61,10 @@ Actual:
|
|||
- 3.12.2: Tuesday, 2024-02-06
|
||||
- 3.12.3: Tuesday, 2024-04-09
|
||||
- 3.12.4: Thursday, 2024-06-06
|
||||
- 3.12.5: Tuesday, 2024-08-06
|
||||
|
||||
Expected:
|
||||
|
||||
- 3.12.5: Tuesday, 2024-08-06
|
||||
- 3.12.6: Tuesday, 2024-10-01
|
||||
- 3.12.7: Tuesday, 2024-12-03
|
||||
- 3.12.8: Tuesday, 2025-02-04
|
||||
|
|
|
@ -3,16 +3,18 @@ Title: Type Defaults for Type Parameters
|
|||
Author: James Hilton-Balfe <gobot1234yt@gmail.com>
|
||||
Sponsor: Jelle Zijlstra <jelle.zijlstra@gmail.com>
|
||||
Discussions-To: https://discuss.python.org/t/pep-696-type-defaults-for-typevarlikes/22569
|
||||
Status: Accepted
|
||||
Status: Final
|
||||
Type: Standards Track
|
||||
Topic: Typing
|
||||
Content-Type: text/x-rst
|
||||
Created: 14-Jul-2022
|
||||
Python-Version: 3.13
|
||||
Post-History: `22-Mar-2022 <https://mail.python.org/archives/list/typing-sig@python.org/thread/7VWBZWXTCX6RAJO6GG67BAXUPFZ24NTC/>`__,
|
||||
`08-Jan-2023 <https://discuss.python.org/t/pep-696-type-defaults-for-typevarlikes/22569/>`__,
|
||||
Resolution: https://discuss.python.org/t/pep-696-type-defaults-for-typevarlikes/22569/34
|
||||
|
||||
.. canonical-typing-spec:: :ref:`typing:type_parameter_defaults` and
|
||||
:external+py3.13:ref:`type-params`
|
||||
|
||||
Abstract
|
||||
--------
|
||||
|
||||
|
|
|
@ -2,16 +2,17 @@ PEP: 702
|
|||
Title: Marking deprecations using the type system
|
||||
Author: Jelle Zijlstra <jelle.zijlstra@gmail.com>
|
||||
Discussions-To: https://discuss.python.org/t/pep-702-marking-deprecations-using-the-type-system/23036
|
||||
Status: Accepted
|
||||
Status: Final
|
||||
Type: Standards Track
|
||||
Topic: Typing
|
||||
Content-Type: text/x-rst
|
||||
Created: 30-Dec-2022
|
||||
Python-Version: 3.13
|
||||
Post-History: `01-Jan-2023 <https://mail.python.org/archives/list/typing-sig@python.org/thread/AKTFUYW3WDT7R7PGRIJQZMYHMDJNE4QH/>`__,
|
||||
`22-Jan-2023 <https://discuss.python.org/t/pep-702-marking-deprecations-using-the-type-system/23036>`__
|
||||
Resolution: https://discuss.python.org/t/pep-702-marking-deprecations-using-the-type-system/23036/61
|
||||
|
||||
.. canonical-typing-spec:: :ref:`typing:deprecated` and
|
||||
:external+py3.13:func:`@warnings.deprecated<warnings.deprecated>`
|
||||
|
||||
Abstract
|
||||
========
|
||||
|
|
|
@ -3,10 +3,9 @@ Title: TypedDict: Read-only items
|
|||
Author: Alice Purcell <alicederyn@gmail.com>
|
||||
Sponsor: Pablo Galindo <pablogsal@gmail.com>
|
||||
Discussions-To: https://discuss.python.org/t/pep-705-read-only-typeddict-items/37867
|
||||
Status: Accepted
|
||||
Status: Final
|
||||
Type: Standards Track
|
||||
Topic: Typing
|
||||
Content-Type: text/x-rst
|
||||
Created: 07-Nov-2022
|
||||
Python-Version: 3.13
|
||||
Post-History: `30-Sep-2022 <https://mail.python.org/archives/list/typing-sig@python.org/thread/6FR6RKNUZU4UY6B6RXC2H4IAHKBU3UKV/>`__,
|
||||
|
@ -16,6 +15,8 @@ Post-History: `30-Sep-2022 <https://mail.python.org/archives/list/typing-sig@pyt
|
|||
`04-Nov-2023 <https://discuss.python.org/t/pep-705-read-only-typeddict-items/37867>`__,
|
||||
Resolution: https://discuss.python.org/t/pep-705-read-only-typeddict-items/37867/39
|
||||
|
||||
.. canonical-typing-spec:: :ref:`typing:readonly` and
|
||||
:external+py3.13:data:`typing.ReadOnly`
|
||||
|
||||
Abstract
|
||||
========
|
||||
|
@ -353,7 +354,7 @@ Keyword argument typing
|
|||
class Function(Protocol):
|
||||
def __call__(self, **kwargs: Unpack[Args]) -> None: ...
|
||||
|
||||
def impl(self, **kwargs: Unpack[ReadOnlyArgs]) -> None:
|
||||
def impl(**kwargs: Unpack[ReadOnlyArgs]) -> None:
|
||||
kwargs["key1"] = 3 # Type check error: key1 is readonly
|
||||
|
||||
fn: Function = impl # Accepted by type checker: function signatures are identical
|
||||
|
|
|
@ -2,12 +2,13 @@ PEP: 741
|
|||
Title: Python Configuration C API
|
||||
Author: Victor Stinner <vstinner@python.org>
|
||||
Discussions-To: https://discuss.python.org/t/pep-741-python-configuration-c-api-second-version/45403
|
||||
Status: Draft
|
||||
Status: Final
|
||||
Type: Standards Track
|
||||
Created: 18-Jan-2024
|
||||
Python-Version: 3.14
|
||||
Post-History: `19-Jan-2024 <https://discuss.python.org/t/pep-741-python-configuration-c-api/43637>`__,
|
||||
`08-Feb-2024 <https://discuss.python.org/t/pep-741-python-configuration-c-api-second-version/45403>`__,
|
||||
Resolution: https://discuss.python.org/t/pep-741-python-configuration-c-api-second-version/45403/88
|
||||
|
||||
Abstract
|
||||
========
|
||||
|
@ -29,9 +30,6 @@ configuration of the Python **preinitialization** and the Python
|
|||
single choice to embed Python, instead of having two "Python" and
|
||||
"Isolated" choices (:pep:`587`), to simplify the API further.
|
||||
|
||||
This new API replaces the deprecated and incomplete legacy API which is
|
||||
scheduled for removal between Python 3.13 and Python 3.15.
|
||||
|
||||
The lower level :pep:`587` ``PyConfig`` API remains available for use
|
||||
cases with an intentionally higher level of coupling to CPython
|
||||
implementation details (such as emulating the full functionality of
|
||||
|
@ -71,7 +69,7 @@ Security fix
|
|||
|
||||
To fix `CVE-2020-10735
|
||||
<https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-10735>`_,
|
||||
a denial-of-service when converting very a large string to an integer (in base
|
||||
a denial-of-service when converting a very large string to an integer (in base
|
||||
10), it was discussed to add a new ``PyConfig`` member to stable
|
||||
branches which affects the ABI.
|
||||
|
||||
|
@ -233,7 +231,7 @@ These C API functions are excluded from the limited C API.
|
|||
PyInitConfig structure
|
||||
----------------------
|
||||
|
||||
The ``PyInitConfig`` structure is implemented by combining the four
|
||||
The ``PyInitConfig`` structure is implemented by combining the three
|
||||
structures of the ``PyConfig`` API and has an ``inittab`` member as
|
||||
well:
|
||||
|
||||
|
@ -279,7 +277,7 @@ Following options can be get by ``PyConfig_Get()`` and set and
|
|||
- API: ``sys.base_exec_prefix``.
|
||||
* - ``base_executable``
|
||||
- ``str``
|
||||
- API: ``sys.base_executable``.
|
||||
- API: ``sys._base_executable``.
|
||||
* - ``base_prefix``
|
||||
- ``str``
|
||||
- API: ``sys.base_prefix``.
|
||||
|
@ -288,7 +286,7 @@ Following options can be get by ``PyConfig_Get()`` and set and
|
|||
- API: ``sys.flags.bytes_warning``.
|
||||
* - ``exec_prefix``
|
||||
- ``str``
|
||||
- API: ``sys.base_prefix``.
|
||||
- API: ``sys.exec_prefix``.
|
||||
* - ``executable``
|
||||
- ``str``
|
||||
- API: ``sys.executable``.
|
||||
|
@ -355,7 +353,7 @@ dictionary (``key: str`` → ``value: str | True``).
|
|||
Read-only configuration options
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Following options can be get ``PyConfig_Get()``, but cannot be set by
|
||||
Following options can be get by ``PyConfig_Get()``, but cannot be set by
|
||||
``PyConfig_Set()``.
|
||||
|
||||
.. list-table::
|
||||
|
@ -373,7 +371,7 @@ Following options can be get ``PyConfig_Get()``, but cannot be set by
|
|||
-
|
||||
* - ``check_hash_pycs_mode``
|
||||
- ``str``
|
||||
- API: ``imp.check_hash_pycs_mode``.
|
||||
-
|
||||
* - ``code_debug_ranges``
|
||||
- ``bool``
|
||||
-
|
||||
|
@ -427,23 +425,20 @@ Following options can be get ``PyConfig_Get()``, but cannot be set by
|
|||
- API: ``sys.flags.isolated`` (``int``).
|
||||
* - ``legacy_windows_fs_encoding``
|
||||
- ``bool``
|
||||
-
|
||||
- Windows only.
|
||||
* - ``legacy_windows_stdio``
|
||||
- ``bool``
|
||||
- Windows only
|
||||
- Windows only.
|
||||
* - ``malloc_stats``
|
||||
- ``bool``
|
||||
-
|
||||
* - ``module_search_paths_set``
|
||||
- ``bool``
|
||||
-
|
||||
* - ``orig_argv``
|
||||
- ``list[str]``
|
||||
- API: ``sys.orig_argv``.
|
||||
* - ``pathconfig_warnings``
|
||||
* - ``parse_argv``
|
||||
- ``bool``
|
||||
-
|
||||
* - ``parse_argv``
|
||||
* - ``pathconfig_warnings``
|
||||
- ``bool``
|
||||
-
|
||||
* - ``perf_profiling``
|
||||
|
@ -452,9 +447,6 @@ Following options can be get ``PyConfig_Get()``, but cannot be set by
|
|||
* - ``program_name``
|
||||
- ``str``
|
||||
-
|
||||
* - ``pythonpath_env``
|
||||
- ``str``
|
||||
-
|
||||
* - ``run_command``
|
||||
- ``str``
|
||||
-
|
||||
|
@ -487,9 +479,6 @@ Following options can be get ``PyConfig_Get()``, but cannot be set by
|
|||
- ``str``
|
||||
- API: ``sys.stdin.errors``, ``sys.stdout.errors`` and
|
||||
``sys.stderr.errors``.
|
||||
* - ``sys_path_0``
|
||||
- ``str``
|
||||
-
|
||||
* - ``tracemalloc``
|
||||
- ``int``
|
||||
- API: ``tracemalloc.is_tracing()`` (``bool``).
|
||||
|
@ -499,24 +488,15 @@ Following options can be get ``PyConfig_Get()``, but cannot be set by
|
|||
* - ``use_hash_seed``
|
||||
- ``bool``
|
||||
-
|
||||
* - ``utf8_mode``
|
||||
- ``bool``
|
||||
-
|
||||
* - ``user_site_directory``
|
||||
- ``bool``
|
||||
- API: ``sys.flags.no_user_site`` (``int``).
|
||||
* - ``utf8_mode``
|
||||
- ``bool``
|
||||
-
|
||||
* - ``warn_default_encoding``
|
||||
- ``bool``
|
||||
-
|
||||
* - ``_install_importlib``
|
||||
- ``bool``
|
||||
-
|
||||
* - ``_init_main``
|
||||
- ``bool``
|
||||
-
|
||||
* - ``_is_python_build``
|
||||
- ``bool``
|
||||
-
|
||||
* - ``_pystats``
|
||||
- ``bool``
|
||||
- API: ``sys._stats_on()``, ``sys._stats_off()``.
|
||||
|
@ -670,9 +650,7 @@ Error Handling
|
|||
* Return ``0`` if *config* has no exit code set.
|
||||
|
||||
Only the ``Py_InitializeFromInitConfig()`` function can set an exit
|
||||
code if the ``parse_argv`` option is non-zero. For example, an
|
||||
isolated configuration cannot set an exit code by default, since
|
||||
``parse_argv`` is zero by default.
|
||||
code if the ``parse_argv`` option is non-zero.
|
||||
|
||||
An exit code can be set when parsing the command line failed (exit
|
||||
code 2) or when a command line option asks to display the command
|
||||
|
@ -761,8 +739,8 @@ Examples
|
|||
Initialize Python
|
||||
-----------------
|
||||
|
||||
Example initializing Python, set configuration options of different types,
|
||||
return -1 on error:
|
||||
Example initializing Python, set configuration options of various types,
|
||||
return ``-1`` on error:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
|
@ -780,7 +758,6 @@ return -1 on error:
|
|||
}
|
||||
|
||||
// Set a list of UTF-8 strings (argv)
|
||||
// Preinitialize implicitly Python to decode the bytes string.
|
||||
char *argv[] = {"my_program", "-c", "pass"};
|
||||
if (PyInitConfig_SetStrList(config, "argv",
|
||||
Py_ARRAY_LENGTH(argv), argv) < 0) {
|
||||
|
@ -792,13 +769,6 @@ return -1 on error:
|
|||
goto error;
|
||||
}
|
||||
|
||||
// Set a list of UTF-8 strings (xoptions).
|
||||
char* xoptions[] = {"faulthandler"};
|
||||
if (PyInitConfig_SetStrList(config, "xoptions",
|
||||
Py_ARRAY_LENGTH(xoptions), xoptions) < 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
// Initialize Python with the configuration
|
||||
if (Py_InitializeFromInitConfig(config) < 0) {
|
||||
goto error;
|
||||
|
@ -827,7 +797,7 @@ configuration:
|
|||
|
||||
int config_bytes_warning(PyInitConfig *config)
|
||||
{
|
||||
int bytes_warning;
|
||||
int64_t bytes_warning;
|
||||
if (PyInitConfig_GetInt(config, "bytes_warning", &bytes_warning)) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -866,12 +836,13 @@ Python version removes the option.
|
|||
Implementation
|
||||
==============
|
||||
|
||||
* Issue: `No limited C API to customize Python initialization
|
||||
* Issue: `[C API] PEP 741: Add PyInitConfig C API to customize
|
||||
the Python initialization
|
||||
<https://github.com/python/cpython/issues/107954>`_
|
||||
* PR: `Add PyInitConfig C API
|
||||
<https://github.com/python/cpython/pull/110176>`_
|
||||
* PR: `Add PyConfig_Get() function
|
||||
<https://github.com/python/cpython/pull/112609>`_
|
||||
<https://github.com/python/cpython/pull/123472>`_
|
||||
* PR: `Add PyInitConfig C API
|
||||
<https://github.com/python/cpython/pull/123502>`_
|
||||
|
||||
|
||||
Backwards Compatibility
|
||||
|
|
|
@ -2,7 +2,7 @@ PEP: 742
|
|||
Title: Narrowing types with TypeIs
|
||||
Author: Jelle Zijlstra <jelle.zijlstra@gmail.com>
|
||||
Discussions-To: https://discuss.python.org/t/pep-742-narrowing-types-with-typenarrower/45613
|
||||
Status: Accepted
|
||||
Status: Final
|
||||
Type: Standards Track
|
||||
Topic: Typing
|
||||
Created: 07-Feb-2024
|
||||
|
@ -11,6 +11,8 @@ Post-History: `11-Feb-2024 <https://discuss.python.org/t/pep-742-narrowing-types
|
|||
Replaces: 724
|
||||
Resolution: https://discuss.python.org/t/pep-742-narrowing-types-with-typeis/45613/35
|
||||
|
||||
.. canonical-typing-spec:: :ref:`typing:typeis` and
|
||||
:external+py3.13:data:`typing.TypeIs`
|
||||
|
||||
Abstract
|
||||
========
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
PEP: 752
|
||||
Title: Package repository namespaces
|
||||
Title: Implicit namespaces for package repositories
|
||||
Author: Ofek Lev <ofekmeister@gmail.com>
|
||||
Sponsor: Barry Warsaw <barry@python.org>
|
||||
PEP-Delegate: Donald Stufft <donald@stufft.io>
|
||||
PEP-Delegate: Dustin Ingram <di@python.org>
|
||||
Discussions-To: https://discuss.python.org/t/61227
|
||||
Status: Draft
|
||||
Type: Standards Track
|
||||
|
@ -47,7 +47,10 @@ verified pattern of ownership. Some examples:
|
|||
|
||||
__ https://docs.datadoghq.com/developers/integrations/agent_integration/
|
||||
|
||||
Such projects are uniquely vulnerable to `dependency confusion`__ attacks.
|
||||
Such projects are uniquely vulnerable to name-squatting attacks
|
||||
which can ultimately result in `dependency confusion`__.
|
||||
|
||||
__ https://www.activestate.com/resources/quick-reads/dependency-confusion/
|
||||
|
||||
For example, say a new product is released for which monitoring would be
|
||||
valuable. It would be reasonable to assume that Datadog would eventually
|
||||
|
@ -59,8 +62,6 @@ appears legitimate which would execute malicious code at runtime. Not only are
|
|||
users more likely to install such packages but doing so taints the perception
|
||||
of the entire project.
|
||||
|
||||
__ https://www.activestate.com/resources/quick-reads/dependency-confusion/
|
||||
|
||||
Although :pep:`708` attempts to address this attack vector, it is specifically
|
||||
about the case of multiple repositories being considered during dependency
|
||||
resolution and does not offer any protection to the aforementioned use cases.
|
||||
|
@ -74,9 +75,6 @@ because typos would have to be in the prefix itself which is
|
|||
Rationale
|
||||
=========
|
||||
|
||||
Tolerance for Disruption
|
||||
------------------------
|
||||
|
||||
Other package ecosystems have generally solved this problem by taking one of
|
||||
two approaches: either minimizing or maximizing backwards compatibility.
|
||||
|
||||
|
@ -110,61 +108,50 @@ __ https://learn.microsoft.com/en-us/nuget/nuget-org/id-prefix-reservation
|
|||
__ https://devblogs.microsoft.com/nuget/Package-identity-and-trust/
|
||||
|
||||
This PEP specifies the NuGet approach of authorized reservation across a flat
|
||||
namespace for the following reasons:
|
||||
|
||||
* Causing churn for the community is a hard blocker.
|
||||
* The NPM approach has the potential to cause confusion for users if we allow
|
||||
unscoped names. Our community has chosen to normalize separator characters
|
||||
and so ``@aws/s3`` would likely be confused with ``@aws-s3``.
|
||||
|
||||
Approval Process
|
||||
----------------
|
||||
|
||||
PyPI has been understaffed, receiving the first `dedicated specialist`__ in
|
||||
July 2024. Due to lack of resources, user support has been lacking for
|
||||
`package name claims <https://discuss.python.org/t/27436/19>`__,
|
||||
`organization requests <https://discuss.python.org/t/33764/15>`__,
|
||||
`storage limit increases <https://discuss.python.org/t/54035>`__,
|
||||
and even `account recovery <https://discuss.python.org/t/43422/122>`__.
|
||||
|
||||
__ https://pyfound.blogspot.com/2024/07/announcing-our-new-pypi-support.html
|
||||
|
||||
The `default policy <grant-approval-criteria_>`_ of only allowing
|
||||
`corporate organizations <corp-orgs_>`_ to reserve namespaces (except in
|
||||
specific scenarios) provides the following benefits:
|
||||
|
||||
* PyPI would have a constant source of funding for support specialists,
|
||||
infrastructure maintenance and new features.
|
||||
* Although each application would require independent review, less human
|
||||
feedback would be required because the process to approve a paid organization
|
||||
already bestows a certain amount of trust.
|
||||
namespace. Any solution that requires new package syntax must be built atop the
|
||||
existing flat namespace and therefore implicit namespaces acquired via a
|
||||
reservation mechanism would be a prerequisite to such explicit namespaces.
|
||||
|
||||
Terminology
|
||||
===========
|
||||
|
||||
The keywords "MUST", "MUST NOT", "REQUIRED", "SHOULD", "SHOULD NOT",
|
||||
"RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as
|
||||
described in :rfc:`2119`.
|
||||
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD",
|
||||
"SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be
|
||||
interpreted as described in :rfc:`2119`.
|
||||
|
||||
Organization
|
||||
`Organizations <orgs_>`_ are entities that own projects and have various
|
||||
users associated with them. Only organizations have access to the namespace
|
||||
application form.
|
||||
Corporate Organization
|
||||
`Corporate organizations <corp-orgs_>`_ are organizations that have paid
|
||||
for special functionality on PyPI.
|
||||
Public Namespace
|
||||
A `public <public-namespaces_>`_ namespace allows for uploads from any
|
||||
project owner.
|
||||
Private Namespace
|
||||
A private namespace only allows uploads from an owner of the namespace.
|
||||
users associated with them.
|
||||
Grant
|
||||
A grant is a reservation of a namespace for a package repository.
|
||||
Open Namespace
|
||||
An `open <open-namespaces_>`_ namespace allows for uploads from any project
|
||||
owner.
|
||||
Restricted Namespace
|
||||
A restricted namespace only allows uploads from an owner of the namespace.
|
||||
Parent Namespace
|
||||
A namespace's parent refers to the namespace without the trailing
|
||||
hyphenated component e.g. the parent of ``foo-bar`` is ``foo``.
|
||||
Child Namespace
|
||||
A namespace's child refers to the namespace with an additional trailing
|
||||
hyphenated component e.g. the child of ``foo`` is ``foo-bar``.
|
||||
|
||||
Specification
|
||||
=============
|
||||
|
||||
`Organizations <orgs_>`_ (NOT regular users) MAY reserve one or more
|
||||
namespaces. Such reservations neither confer ownership nor grant special
|
||||
privileges to existing projects.
|
||||
.. _orgs:
|
||||
|
||||
Organizations
|
||||
-------------
|
||||
|
||||
Any package repository that allows for the creation of projects (e.g.
|
||||
non-mirrors) MAY offer the concept of `organizations`__. Organizations
|
||||
are entities that own projects and have various users associated with them.
|
||||
|
||||
__ https://blog.pypi.org/posts/2023-04-23-introducing-pypi-organizations/
|
||||
|
||||
Organizations MAY reserve one or more namespaces. Such reservations neither
|
||||
confer ownership nor grant special privileges to existing projects.
|
||||
|
||||
.. _naming:
|
||||
|
||||
|
@ -172,15 +159,13 @@ Naming
|
|||
------
|
||||
|
||||
A namespace MUST be a `valid`__ project name and `normalized`__ internally e.g.
|
||||
``foo.bar`` would become ``foo-bar``. The user facing namespace (e.g. in UI
|
||||
tooltips) MUST preserve the original pre-normalized text as defined during
|
||||
reservation.
|
||||
``foo.bar`` would become ``foo-bar``.
|
||||
|
||||
__ https://packaging.python.org/en/latest/specifications/name-normalization/#name-format
|
||||
__ https://packaging.python.org/en/latest/specifications/name-normalization/#name-normalization
|
||||
|
||||
Grant Semantics
|
||||
---------------
|
||||
Semantics
|
||||
---------
|
||||
|
||||
A namespace grant bestows ownership over the following:
|
||||
|
||||
|
@ -193,46 +178,16 @@ A namespace grant bestows ownership over the following:
|
|||
Package name matching acts upon the `normalized <naming_>`_ namespace.
|
||||
|
||||
Namespaces are per-package repository and SHALL NOT be shared between
|
||||
repositories.
|
||||
repositories. For example, if PyPI has a namespace ``microsoft`` that is owned
|
||||
by the company Microsoft, packages starting with ``microsoft-`` that come from
|
||||
other non-PyPI mirror repositories do not confer the same level of trust.
|
||||
|
||||
Grant Types
|
||||
-----------
|
||||
|
||||
There are two types of grants.
|
||||
|
||||
.. _root-grant:
|
||||
|
||||
Root Grant
|
||||
''''''''''
|
||||
|
||||
Only `organizations <orgs_>`_ have the ability to submit requests for namespace
|
||||
grants. An organization gets a root grant for every accepted request. This
|
||||
grant may produce any number of `child grants <child-grant_>`_.
|
||||
|
||||
.. _child-grant:
|
||||
|
||||
Child Grant
|
||||
'''''''''''
|
||||
|
||||
A child grant is created by the owner of a `root grant <root-grant_>`_. The
|
||||
child namespace MUST be prefixed by the root grant namespace followed by a
|
||||
hyphen. For example, ``google-cloud`` would be a valid child of the root
|
||||
namespace ``google``.
|
||||
|
||||
Child grants cannot have their own child grants.
|
||||
|
||||
.. _grant-ownership:
|
||||
|
||||
Grant Ownership
|
||||
---------------
|
||||
|
||||
The owner of a grant may allow any number of other organizations to use the
|
||||
grant. The grants behave as if they were owned by the organization. The owner
|
||||
may revoke this permission at any time.
|
||||
|
||||
The owner may transfer ownership to another organization. If the organization
|
||||
is a corporate organization, the target for transfer must also be. Settings for
|
||||
permitted organizations are transferred as well.
|
||||
Grants MUST NOT overlap. For example, if there is an existing grant
|
||||
for ``foo-bar`` then a new grant for ``foo`` would be forbidden. An overlap is
|
||||
determined by comparing the `normalized <naming_>`_ proposed namespace with the
|
||||
normalized namespace of every existing root grant. Every comparison must append
|
||||
a hyphen to the end of the proposed and existing namespace. An overlap is
|
||||
detected when any existing namespace starts with the proposed namespace.
|
||||
|
||||
.. _uploads:
|
||||
|
||||
|
@ -248,123 +203,84 @@ If the following criteria are all true for a given upload:
|
|||
|
||||
Then the upload MUST fail with a 403 HTTP status code.
|
||||
|
||||
.. _user-interface:
|
||||
.. _open-namespaces:
|
||||
|
||||
User Interface
|
||||
--------------
|
||||
|
||||
Every page for a particular release
|
||||
(`example <https://pypi.org/project/google-cloud-compute/1.19.2/>`__)
|
||||
that both matches an active namespace grant and is tied to an
|
||||
`owner <grant-ownership_>`_
|
||||
MUST receive a special indicator that signifies this tie.
|
||||
|
||||
The UI also MUST indicate what the prefix is (NuGet does not do this) and this
|
||||
value MUST match the ``namespace`` key in the `API <repository-metadata_>`_.
|
||||
|
||||
Repositories SHOULD have a dedicated page that enumerates every active
|
||||
namespace grant and which organization(s) own it.
|
||||
|
||||
.. _public-namespaces:
|
||||
|
||||
Public Namespaces
|
||||
Open Namespaces
|
||||
-----------------
|
||||
|
||||
The owner of a grant may choose to allow others the ability to release new
|
||||
projects with the associated namespace. Doing so MUST allow
|
||||
`uploads <uploads_>`_ for new projects matching the namespace from any user
|
||||
but such releases MUST NOT have the `visual indicator <user-interface_>`_.
|
||||
`uploads <uploads_>`_ for new projects matching the namespace from any user.
|
||||
|
||||
It is possible for the `owner <grant-ownership_>`_ of a namespace to both make
|
||||
it public and allow other organizations to use it. In this case, the permitted
|
||||
organizations have no special permissions and are essentially only public.
|
||||
|
||||
Root grants given to `community projects <grant-approval-criteria_>`_ SHALL
|
||||
always be public.
|
||||
|
||||
When a `child grant <child-grant_>`_ is created, its public status SHALL be
|
||||
inherited from the `root grant <root-grant_>`_. Owners of child grants MAY
|
||||
make them public at any time. If a grant is public, it MUST NOT be made private
|
||||
unless the owner of the grant is the owner of every project that matches the
|
||||
namespace.
|
||||
It is possible for the owner of a namespace to both make it open and allow
|
||||
other organizations to use the grant. In this case, the authorized
|
||||
organizations have no special permissions and are equivalent to an open grant
|
||||
without ownership.
|
||||
|
||||
.. _repository-metadata:
|
||||
|
||||
Repository Metadata
|
||||
-------------------
|
||||
|
||||
To allow installers and other tooling insight into this project-level metadata
|
||||
of a namespaced project, the :pep:`JSON API <691>` version will be incremented
|
||||
and support new keys for the project endpoint.
|
||||
The :pep:`JSON API <691>` version will be incremented from ``1.0`` to ``1.1``.
|
||||
The following API changes MUST be implemented by repositories that support
|
||||
this PEP. Repositories that do not support this PEP MUST NOT implement these
|
||||
changes so that consumers of the API are able to determine whether the
|
||||
repository supports this PEP.
|
||||
|
||||
The ``owner`` key SHOULD be added and refer to the owner of the project,
|
||||
whether an organization or a user.
|
||||
.. _project-detail:
|
||||
|
||||
The ``namespace`` key MAY be added and MUST be ``null`` if the project does not
|
||||
match an active namespace grant. If the project does match a namespace grant,
|
||||
the value MUST be a mapping with the following keys:
|
||||
Project Detail
|
||||
''''''''''''''
|
||||
|
||||
* ``name``: This is the associated `normalized <naming_>`_ namespace e.g.
|
||||
The :pep:`project detail <691#project-detail>` response will be modified as
|
||||
follows.
|
||||
|
||||
The ``namespace`` key MUST be ``null`` if the project does not match an active
|
||||
namespace grant. If the project does match a namespace grant, the value MUST be
|
||||
a mapping with the following keys:
|
||||
|
||||
* ``prefix``: This is the associated `normalized <naming_>`_ namespace e.g.
|
||||
``foo-bar``. If the owner of the project owns multiple matching grants then
|
||||
this MUST be the namespace with the most number of characters. For example,
|
||||
if the project name matched both ``foo-bar`` and ``foo-bar-baz`` then this
|
||||
key would be the latter.
|
||||
* ``owners``: This is an array of organizations that
|
||||
`own <grant-ownership_>`_ the grant. This is useful for tools that wish to
|
||||
make a distinction between official and community packages by checking if
|
||||
the array contains the project ``owner``.
|
||||
* ``public``: This is a boolean indicating whether the namespace is
|
||||
`public <public-namespaces_>`_.
|
||||
* ``authorized``: This is a boolean and will be true if the project owner
|
||||
is an organization and is one of the current owners of the grant. This is
|
||||
useful for tools that wish to make a distinction between official and
|
||||
community packages.
|
||||
* ``open``: This is a boolean indicating whether the namespace is
|
||||
`open <open-namespaces_>`_.
|
||||
|
||||
The presence of the ``namespace`` key indicates support for this PEP.
|
||||
Namespace Detail
|
||||
''''''''''''''''
|
||||
|
||||
The format of this URL is ``/namespace/<namespace>`` where ``<namespace>`` is
|
||||
the `normalized <naming_>`_ namespace. For example, the URL for the namespace
|
||||
``foo.bar`` would be ``/namespace/foo-bar``.
|
||||
|
||||
The response will be a mapping with the following keys:
|
||||
|
||||
* ``prefix``: This is the `normalized <naming_>`_ version of the namespace e.g.
|
||||
``foo-bar``.
|
||||
* ``owner``: This is the organization that is responsible for the namespace.
|
||||
* ``open``: This is a boolean indicating whether the namespace is
|
||||
`open <open-namespaces_>`_.
|
||||
* ``parent``: This is the parent namespace if it exists. For example, if the
|
||||
namespace is ``foo-bar`` and there is an active grant for ``foo``, then this
|
||||
would be ``"foo"``. If there is no parent then this key will be ``null``.
|
||||
* ``children``: This is an array of any child namespaces. For example, if the
|
||||
namespace is ``foo`` and there are active grants for ``foo-bar`` and
|
||||
``foo-bar-baz`` then this would be ``["foo-bar", "foo-bar-baz"]``.
|
||||
|
||||
Grant Removal
|
||||
-------------
|
||||
|
||||
If a grant is shared with other organizations, the owner organization MUST
|
||||
initiate a transfer as a prerequisite for organization deletion.
|
||||
When a reserved namespace becomes unclaimed, repositories MUST set the
|
||||
``namespace`` key to ``null`` in the `API <project-detail_>`_.
|
||||
|
||||
If a grant is not shared, the owner may unclaim the namespace in either of the
|
||||
following circumstances:
|
||||
|
||||
* The organization manually removes themselves as the owner.
|
||||
* The organization is deleted.
|
||||
|
||||
When a reserved namespace becomes unclaimed, repositories:
|
||||
|
||||
1. MUST remove the `visual indicator <user-interface_>`_
|
||||
2. MUST remove the ``namespace`` key in the `API <repository-metadata_>`_
|
||||
|
||||
Grant Applications
|
||||
------------------
|
||||
|
||||
Submission
|
||||
''''''''''
|
||||
|
||||
Only `organizations <orgs_>`_ have access to the page for submitting grant
|
||||
applications. Reviews of `corporate organizations <corp-orgs_>`_ applications
|
||||
are prioritized.
|
||||
|
||||
.. _grant-approval-criteria:
|
||||
|
||||
Approval Criteria
|
||||
'''''''''''''''''
|
||||
|
||||
1. The namespace MUST NOT be something common like ``tool`` or ``apps``.
|
||||
2. The namespace SHOULD be greater than three characters.
|
||||
3. The namespace SHOULD properly and clearly identify the reservation owner.
|
||||
4. The organization SHOULD be actively using the namespace.
|
||||
5. There SHOULD be evidence that *not* reserving the namespace may cause
|
||||
ambiguity, confusion, or other harm to the community.
|
||||
|
||||
Organizations that are not `corporate organizations <corp-orgs_>`_ MUST
|
||||
represent one of the following:
|
||||
|
||||
* Large, popular open-source projects with many packages [2]_
|
||||
* Universities that actively publish packages
|
||||
* Government organizations that actively publish packages
|
||||
* NPOs/NGOs that actively publish packages like
|
||||
`Our World in Data <https://github.com/owid>`__
|
||||
Namespaces that were previously claimed but are now not SHOULD be eligible for
|
||||
claiming again by any organization.
|
||||
|
||||
Backwards Compatibility
|
||||
=======================
|
||||
|
@ -378,10 +294,6 @@ __ https://github.com/python/typeshed/issues/2491#issuecomment-578456045
|
|||
Security Implications
|
||||
=====================
|
||||
|
||||
* Although users will no longer see the visual indicator when a namespace
|
||||
becomes unclaimed, external consumers of metadata may have difficulty
|
||||
scraping the user facing
|
||||
`enumeration <user-interface_>`_ of grants to verify current ownership.
|
||||
* There is an opportunity to build on top of :pep:`740` and :pep:`480` so that
|
||||
one could prove cryptographically that a specific release came from an owner
|
||||
of the associated namespace. This PEP makes no effort to describe how this
|
||||
|
@ -390,13 +302,10 @@ Security Implications
|
|||
How to Teach This
|
||||
=================
|
||||
|
||||
For organizations, we will document how to reserve namespaces, what the
|
||||
benefits are and pricing.
|
||||
|
||||
For consumers of packages we will document the indicator on release pages, how
|
||||
metadata is exposed in the `API <repository-metadata_>`_ and potentially in
|
||||
future note tooling that supports utilizing namespaces to provide extra
|
||||
security guarantees during installation.
|
||||
For consumers of packages we will document how metadata is exposed in the
|
||||
`API <repository-metadata_>`_ and potentially in future note tooling that
|
||||
supports utilizing namespaces to provide extra security guarantees during
|
||||
installation.
|
||||
|
||||
Reference Implementation
|
||||
========================
|
||||
|
@ -430,43 +339,12 @@ shuffling, an acquisition, or any other reason. Whenever this happens every
|
|||
project they own would in effect be renamed which would cause unnecessary
|
||||
confusion for users, frequently.
|
||||
|
||||
Users have come to expect that package names may be typed without worry of
|
||||
conflicting shell syntax and any namespace solution would pose challenges:
|
||||
|
||||
* Copying NPM's syntax (e.g. ``@foo/bar``) would alienate a large number of
|
||||
Windows users because the ``@`` character is considered special in
|
||||
`PowerShell`__.
|
||||
* Starting names with a ``/`` would conflict with the common installer
|
||||
capability of accepting paths without URI ``file://`` syntax.
|
||||
* Starting names with a ``//`` like Bazel
|
||||
`target patterns <https://bazel.build/run/build#specifying-build-targets>`__
|
||||
would be confusing to users because the current normalization standard
|
||||
eliminates consecutive separator characters.
|
||||
|
||||
__ https://learn.microsoft.com/en-us/powershell/scripting/lang-spec/chapter-07?view=powershell-7.4#717--operator
|
||||
|
||||
Finally, the disruption to the community would be massive because it would
|
||||
require an update from every package manager, security scanner, IDE, etc. New
|
||||
packages released with the scoping would be incompatible with older tools and
|
||||
would cause confusion for users along with frustration from maintainers having
|
||||
to triage such complaints.
|
||||
|
||||
Allow Non-Public Namespaces for Community Projects
|
||||
--------------------------------------------------
|
||||
|
||||
This PEP enforces that the discretionary namespace grants for community
|
||||
projects are `public <public-namespaces_>`_. This is almost always desired by
|
||||
such projects and prevents the following situations:
|
||||
|
||||
* A perceived reduction in openness of community projects, for example if a
|
||||
project was taken over by a business entity there may be a desire for it to
|
||||
prevent the creation of new packages matching the namespace.
|
||||
* When an existing community project with plugins (such as MkDocs) chooses to
|
||||
reserve a namespace, future plugins that are officially adopted would have to
|
||||
change their name. This would cause a massive disruption to users and reset
|
||||
usage statistics. The workaround is to have a new package that is advertised
|
||||
which would depend on the real package but this is suboptimal.
|
||||
|
||||
Open Issues
|
||||
===========
|
||||
|
||||
|
@ -526,9 +404,6 @@ __ https://github.com/open-telemetry/opentelemetry-python-contrib
|
|||
__ https://airflow.apache.org/docs/apache-airflow/stable/authoring-and-scheduling/plugins.html
|
||||
__ https://airflow.apache.org/docs/apache-airflow-providers/index.html
|
||||
|
||||
.. _orgs: https://blog.pypi.org/posts/2023-04-23-introducing-pypi-organizations/
|
||||
.. _corp-orgs: https://docs.pypi.org/organization-accounts/pricing-and-payments/#corporate-organizations
|
||||
|
||||
Copyright
|
||||
=========
|
||||
|
||||
|
|
Loading…
Reference in New Issue