Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package python-packaging for
openSUSE:Factory checked in at 2024-03-20 21:09:31
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-packaging (Old)
and /work/SRC/openSUSE:Factory/.python-packaging.new.1905 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-packaging"
Wed Mar 20 21:09:31 2024 rev:33 rq:1158406 version:24.0
Changes:
--------
--- /work/SRC/openSUSE:Factory/python-packaging/python-packaging.changes
2023-11-13 22:15:43.236125174 +0100
+++
/work/SRC/openSUSE:Factory/.python-packaging.new.1905/python-packaging.changes
2024-03-20 21:09:33.055379098 +0100
@@ -1,0 +2,18 @@
+Sat Mar 16 09:28:29 UTC 2024 - Dirk Müller <[email protected]>
+
+- update to 24.0:
+ * Do specifier matching correctly when the specifier contains
+ an epoch number and has more components than the version
+ (:issue:`683`)
+ * Support the experimental --disable-gil builds in
+ packaging.tags (:issue:`727`)
+ * BREAKING: Make optional metadata.Metadata attributes default
+ to None (:issue:`733`)
+ * Fix errors when trying to access the
+ description_content_type, keywords, and requires_python
+ attributes on metadata.Metadata when those values have not
+ been provided (:issue:`733`)
+ * Fix a bug preventing the use of the built in ExceptionGroup
+ on versions of Python that support it (:issue:`725`)
+
+-------------------------------------------------------------------
Old:
----
packaging-23.2.tar.gz
New:
----
packaging-24.0.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-packaging.spec ++++++
--- /var/tmp/diff_new_pack.DVMlvt/_old 2024-03-20 21:09:33.867408938 +0100
+++ /var/tmp/diff_new_pack.DVMlvt/_new 2024-03-20 21:09:33.871409085 +0100
@@ -1,7 +1,7 @@
#
-# spec file
+# spec file for package python-packaging
#
-# Copyright (c) 2023 SUSE LLC
+# Copyright (c) 2024 SUSE LLC
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -53,7 +53,7 @@
%endif
Name: %{pprefix}-packaging%{?psuffix}
-Version: 23.2
+Version: 24.0
Release: 0
Summary: Core utilities for Python packages
License: Apache-2.0 AND BSD-2-Clause
++++++ packaging-23.2.tar.gz -> packaging-24.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/packaging-23.2/CHANGELOG.rst
new/packaging-24.0/CHANGELOG.rst
--- old/packaging-23.2/CHANGELOG.rst 2023-10-01 15:49:25.447660000 +0200
+++ new/packaging-24.0/CHANGELOG.rst 2024-03-10 10:38:57.045243300 +0100
@@ -1,6 +1,20 @@
Changelog
---------
+24.0 - 2024-03-10
+~~~~~~~~~~~~~~~~~
+
+* Do specifier matching correctly when the specifier contains an epoch number
+ and has more components than the version (:issue:`683`)
+* Support the experimental ``--disable-gil`` builds in packaging.tags
+ (:issue:`727`)
+* BREAKING: Make optional ``metadata.Metadata`` attributes default to ``None``
(:issue:`733`)
+* Fix errors when trying to access the ``description_content_type``,
``keywords``,
+ and ``requires_python`` attributes on ``metadata.Metadata`` when those values
+ have not been provided (:issue:`733`)
+* Fix a bug preventing the use of the built in ``ExceptionGroup`` on versions
of
+ Python that support it (:issue:`725`)
+
23.2 - 2023-10-01
~~~~~~~~~~~~~~~~~
@@ -9,7 +23,7 @@
* Requirement parsing no longer automatically validates the URL (:issue:`120`)
* Canonicalize names for requirements comparison (:issue:`644`)
* Introduce ``metadata.Metadata`` (along with ``metadata.ExceptionGroup`` and
``metadata.InvalidMetadata``; :issue:`570`)
-* Introduce the ``validate`` keyword parameter to ``utils.validate_name()``
(:issue:`570`)
+* Introduce the ``validate`` keyword parameter to ``utils.normalize_name()``
(:issue:`570`)
* Introduce ``utils.is_normalized_name()`` (:issue:`570`)
* Make ``utils.parse_sdist_filename()`` and ``utils.parse_wheel_filename()``
raise ``InvalidSdistFilename`` and ``InvalidWheelFilename``, respectively,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/packaging-23.2/PKG-INFO new/packaging-24.0/PKG-INFO
--- old/packaging-23.2/PKG-INFO 1970-01-01 01:00:00.000000000 +0100
+++ new/packaging-24.0/PKG-INFO 1970-01-01 01:00:00.000000000 +0100
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: packaging
-Version: 23.2
+Version: 24.0
Summary: Core utilities for Python packages
Author-email: Donald Stufft <[email protected]>
Requires-Python: >=3.7
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/packaging-23.2/docs/development/getting-started.rst
new/packaging-24.0/docs/development/getting-started.rst
--- old/packaging-23.2/docs/development/getting-started.rst 2023-01-30
16:24:13.025143900 +0100
+++ new/packaging-24.0/docs/development/getting-started.rst 2024-03-10
10:34:41.955998400 +0100
@@ -73,5 +73,5 @@
.. _`virtualenv`: https://pypi.org/project/virtualenv/
.. _`pip`: https://pypi.org/project/pip/
.. _`sphinx`: https://pypi.org/project/Sphinx/
-.. _`reStructured Text`: http://sphinx-doc.org/rest.html
+.. _`reStructured Text`:
https://www.sphinx-doc.org/en/master/usage/restructuredtext/
.. _`pre-commit`: https://pre-commit.com
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/packaging-23.2/docs/development/index.rst
new/packaging-24.0/docs/development/index.rst
--- old/packaging-23.2/docs/development/index.rst 2021-07-23
09:28:26.383909700 +0200
+++ new/packaging-24.0/docs/development/index.rst 2024-03-10
10:34:41.956156300 +0100
@@ -16,4 +16,4 @@
release-process
.. _`GitHub`: https://github.com/pypa/packaging
-.. _`what to put in your bug report`:
http://www.contribution-guide.org/#what-to-put-in-your-bug-report
+.. _`what to put in your bug report`:
https://www.contribution-guide.org/#what-to-put-in-your-bug-report
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/packaging-23.2/docs/development/submitting-patches.rst
new/packaging-24.0/docs/development/submitting-patches.rst
--- old/packaging-23.2/docs/development/submitting-patches.rst 2022-04-02
15:23:31.358636600 +0200
+++ new/packaging-24.0/docs/development/submitting-patches.rst 2024-03-10
10:34:41.956318600 +0100
@@ -70,5 +70,5 @@
.. |black| replace:: ``black``
.. _black: https://pypi.org/project/black/
.. _`Write comments as complete sentences.`:
https://nedbatchelder.com/blog/201401/comments_should_be_sentences.html
-.. _`syntax`: http://sphinx-doc.org/domains.html#info-field-lists
-.. _`Studies have shown`:
http://www.ibm.com/developerworks/rational/library/11-proven-practices-for-peer-review/
+.. _`syntax`:
https://www.sphinx-doc.org/en/master/usage/restructuredtext/field-lists.html
+.. _`Studies have shown`:
https://www.microsoft.com/en-us/research/publication/characteristics-of-useful-code-reviews-an-empirical-study-at-microsoft/
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/packaging-23.2/docs/markers.rst
new/packaging-24.0/docs/markers.rst
--- old/packaging-23.2/docs/markers.rst 2023-01-30 16:24:13.025342500 +0100
+++ new/packaging-24.0/docs/markers.rst 2024-01-06 21:39:23.974311800 +0100
@@ -5,7 +5,8 @@
One extra requirement of dealing with dependencies is the ability to specify
if it is required depending on the operating system or Python version in use.
-`PEP 508`_ defines the scheme which has been implemented by this module.
+The :ref:`specification of dependency specifiers <pypug:dependency-specifiers>`
+defines the scheme which has been implemented by this module.
Usage
-----
@@ -51,7 +52,7 @@
This class abstracts handling markers for dependencies of a project. It can
be passed a single marker or multiple markers that are ANDed or ORed
- together. Each marker will be parsed according to PEP 508.
+ together. Each marker will be parsed according to the specification.
:param str markers: The string representation of a marker or markers.
:raises InvalidMarker: If the given ``markers`` are not parseable, then
@@ -63,8 +64,10 @@
:param dict environment: A dictionary containing keys and values to
override the detected environment.
- :raises: UndefinedComparison: If the marker uses a PEP 440 comparison on
- strings which are not valid PEP 440 versions.
+ :raises: UndefinedComparison: If the marker uses a comparison on strings
+ which are not valid versions per the
+ :ref:`specification of version specifiers
+ <pypug:version-specifiers>`.
:raises: UndefinedEnvironmentName: If the marker accesses a value that
isn't present inside of the environment
dictionary.
@@ -72,19 +75,18 @@
.. exception:: InvalidMarker
Raised when attempting to create a :class:`Marker` with a string that
- does not conform to PEP 508.
+ does not conform to the specification.
.. exception:: UndefinedComparison
- Raised when attempting to evaluate a :class:`Marker` with a PEP 440
- comparison operator against values that are not valid PEP 440 versions.
+ Raised when attempting to evaluate a :class:`Marker` with a
+ comparison operator against values that are not valid
+ versions per the :ref:`specification of version specifiers
+ <pypug:version-specifiers>`.
.. exception:: UndefinedEnvironmentName
Raised when attempting to evaluate a :class:`Marker` with a value that is
missing from the evaluation environment.
-
-
-.. _`PEP 508`: https://www.python.org/dev/peps/pep-0508/
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/packaging-23.2/docs/requirements.rst
new/packaging-24.0/docs/requirements.rst
--- old/packaging-23.2/docs/requirements.rst 2023-10-01 14:58:59.369405300
+0200
+++ new/packaging-24.0/docs/requirements.rst 2024-01-06 21:39:23.974455600
+0100
@@ -4,8 +4,9 @@
.. currentmodule:: packaging.requirements
Parse a given requirements line for specifying dependencies of a Python
-project, using `PEP 508`_ which defines the scheme that has been implemented
-by this module.
+project, using the :ref:`specification of dependency specifiers
+<pypug:dependency-specifiers>`, which defines the scheme that has been
+implemented by this module.
Usage
-----
@@ -60,8 +61,8 @@
When a requirement is specified with a URL, the :class:`Requirement` class
used to check the URL and reject values containing invalid scheme and
- netloc combinations. This is no longer performed since PEP 508 does not
- specify such rules, and the check incorrectly disallows valid requirement
+ netloc combinations. This is no longer performed since the specification
does
+ not have such rules, and the check incorrectly disallows valid requirement
strings from being parsed.
Reference
@@ -70,7 +71,7 @@
.. class:: Requirement(requirement)
This class abstracts handling the details of a requirement for a project.
- Each requirement will be parsed according to PEP 508.
+ Each requirement will be parsed according to the specification.
:param str requirement: The string representation of a requirement.
:raises InvalidRequirement: If the given ``requirement`` is not parseable,
@@ -99,6 +100,4 @@
.. exception:: InvalidRequirement
Raised when attempting to create a :class:`Requirement` with a string that
- does not conform to PEP 508.
-
-.. _`PEP 508`: https://www.python.org/dev/peps/pep-0508/
+ does not conform to the specification.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/packaging-23.2/docs/utils.rst
new/packaging-24.0/docs/utils.rst
--- old/packaging-23.2/docs/utils.rst 2023-10-01 14:58:59.369609600 +0200
+++ new/packaging-24.0/docs/utils.rst 2024-01-06 21:39:23.974585000 +0100
@@ -85,7 +85,8 @@
:param str filename: The name of the wheel file.
:raises InvalidWheelFilename: If the filename in question
- does not follow conventions outlined in `PEP 427`_.
+ does not follow the :ref:`wheel specification
+ <pypug:binary-distribution-format>`.
.. doctest::
@@ -137,4 +138,3 @@
Raised when a source distribution file name is considered invalid.
.. _Source distribution format:
https://packaging.python.org/specifications/source-distribution-format/#source-distribution-file-name
-.. _`PEP 427`: https://peps.python.org/pep-0427/#file-name-convention
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/packaging-23.2/pyproject.toml
new/packaging-24.0/pyproject.toml
--- old/packaging-23.2/pyproject.toml 2023-10-01 14:58:59.370197300 +0200
+++ new/packaging-24.0/pyproject.toml 2024-01-06 21:39:23.974710700 +0100
@@ -42,7 +42,6 @@
[tool.coverage.run]
branch = true
-omit = ["packaging/_compat.py"]
[tool.coverage.report]
exclude_lines = ["pragma: no cover", "@abc.abstractmethod",
"@abc.abstractproperty"]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/packaging-23.2/src/packaging/__init__.py
new/packaging-24.0/src/packaging/__init__.py
--- old/packaging-23.2/src/packaging/__init__.py 2023-10-01
15:49:25.447881500 +0200
+++ new/packaging-24.0/src/packaging/__init__.py 2024-03-10
10:38:57.045582800 +0100
@@ -6,7 +6,7 @@
__summary__ = "Core utilities for Python packages"
__uri__ = "https://github.com/pypa/packaging"
-__version__ = "23.2"
+__version__ = "24.0"
__author__ = "Donald Stufft and individual contributors"
__email__ = "[email protected]"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/packaging-23.2/src/packaging/_manylinux.py
new/packaging-24.0/src/packaging/_manylinux.py
--- old/packaging-23.2/src/packaging/_manylinux.py 2023-10-01
14:58:59.370645000 +0200
+++ new/packaging-24.0/src/packaging/_manylinux.py 2024-03-10
10:34:41.956493400 +0100
@@ -55,7 +55,15 @@
return _is_linux_armhf(executable)
if "i686" in archs:
return _is_linux_i686(executable)
- allowed_archs = {"x86_64", "aarch64", "ppc64", "ppc64le", "s390x",
"loongarch64"}
+ allowed_archs = {
+ "x86_64",
+ "aarch64",
+ "ppc64",
+ "ppc64le",
+ "s390x",
+ "loongarch64",
+ "riscv64",
+ }
return any(arch in allowed_archs for arch in archs)
@@ -82,7 +90,7 @@
#
https://github.com/python/cpython/blob/fcf1d003bf4f0100c/Lib/platform.py#L175-L183
try:
# Should be a string like "glibc 2.17".
- version_string: str = getattr(os, "confstr")("CS_GNU_LIBC_VERSION")
+ version_string: Optional[str] = os.confstr("CS_GNU_LIBC_VERSION")
assert version_string is not None
_, version = version_string.rsplit()
except (AssertionError, AttributeError, OSError, ValueError):
@@ -174,7 +182,7 @@
return False
# Check for presence of _manylinux module.
try:
- import _manylinux # noqa
+ import _manylinux
except ImportError:
return True
if hasattr(_manylinux, "manylinux_compatible"):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/packaging-23.2/src/packaging/_parser.py
new/packaging-24.0/src/packaging/_parser.py
--- old/packaging-23.2/src/packaging/_parser.py 2023-04-21 00:00:17.821521300
+0200
+++ new/packaging-24.0/src/packaging/_parser.py 2024-03-10 10:34:41.956662700
+0100
@@ -324,10 +324,7 @@
def process_env_var(env_var: str) -> Variable:
- if (
- env_var == "platform_python_implementation"
- or env_var == "python_implementation"
- ):
+ if env_var in ("platform_python_implementation", "python_implementation"):
return Variable("platform_python_implementation")
else:
return Variable(env_var)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/packaging-23.2/src/packaging/metadata.py
new/packaging-24.0/src/packaging/metadata.py
--- old/packaging-23.2/src/packaging/metadata.py 2023-10-01
14:58:59.371100400 +0200
+++ new/packaging-24.0/src/packaging/metadata.py 2024-01-06
21:39:23.974911200 +0100
@@ -41,10 +41,10 @@
try:
- ExceptionGroup = __builtins__.ExceptionGroup # type: ignore[attr-defined]
-except AttributeError:
+ ExceptionGroup
+except NameError: # pragma: no cover
- class ExceptionGroup(Exception): # type: ignore[no-redef] # noqa: N818
+ class ExceptionGroup(Exception): # noqa: N818
"""A minimal implementation of :external:exc:`ExceptionGroup` from
Python 3.11.
If :external:exc:`ExceptionGroup` is already defined by Python itself,
@@ -61,6 +61,9 @@
def __repr__(self) -> str:
return f"{self.__class__.__name__}({self.message!r},
{self.exceptions!r})"
+else: # pragma: no cover
+ ExceptionGroup = ExceptionGroup
+
class InvalidMetadata(ValueError):
"""A metadata field contains invalid data."""
@@ -505,24 +508,19 @@
# No need to check the cache as attribute lookup will resolve into the
# instance's __dict__ before __get__ is called.
cache = instance.__dict__
- try:
- value = instance._raw[self.name] # type: ignore[literal-required]
- except KeyError:
- if self.name in _STRING_FIELDS:
- value = ""
- elif self.name in _LIST_FIELDS:
- value = []
- elif self.name in _DICT_FIELDS:
- value = {}
- else: # pragma: no cover
- assert False
+ value = instance._raw.get(self.name)
- try:
- converter: Callable[[Any], T] = getattr(self,
f"_process_{self.name}")
- except AttributeError:
- pass
- else:
- value = converter(value)
+ # To make the _process_* methods easier, we'll check if the value is
None
+ # and if this field is NOT a required attribute, and if both of those
+ # things are true, we'll skip the the converter. This will mean that
the
+ # converters never have to deal with the None union.
+ if self.name in _REQUIRED_ATTRS or value is not None:
+ try:
+ converter: Callable[[Any], T] = getattr(self,
f"_process_{self.name}")
+ except AttributeError:
+ pass
+ else:
+ value = converter(value)
cache[self.name] = value
try:
@@ -677,7 +675,7 @@
ins._raw = data.copy() # Mutations occur due to caching enriched
values.
if validate:
- exceptions: List[InvalidMetadata] = []
+ exceptions: List[Exception] = []
try:
metadata_version = ins.metadata_version
metadata_age = _VALID_METADATA_VERSIONS.index(metadata_version)
@@ -732,10 +730,10 @@
If *validate* is true, the metadata will be validated. All exceptions
related to validation will be gathered and raised as an
:class:`ExceptionGroup`.
"""
- exceptions: list[InvalidMetadata] = []
raw, unparsed = parse_email(data)
if validate:
+ exceptions: list[Exception] = []
for unparsed_key in unparsed:
if unparsed_key in _EMAIL_TO_RAW_MAPPING:
message = f"{unparsed_key!r} has invalid data"
@@ -749,8 +747,9 @@
try:
return cls.from_raw(raw, validate=validate)
except ExceptionGroup as exc_group:
- exceptions.extend(exc_group.exceptions)
- raise ExceptionGroup("invalid or unparsed metadata", exceptions)
from None
+ raise ExceptionGroup(
+ "invalid or unparsed metadata", exc_group.exceptions
+ ) from None
metadata_version: _Validator[_MetadataVersion] = _Validator()
""":external:ref:`core-metadata-metadata-version`
@@ -761,62 +760,66 @@
*validate* parameter)"""
version: _Validator[version_module.Version] = _Validator()
""":external:ref:`core-metadata-version` (required)"""
- dynamic: _Validator[List[str]] = _Validator(
+ dynamic: _Validator[Optional[List[str]]] = _Validator(
added="2.2",
)
""":external:ref:`core-metadata-dynamic`
(validated against core metadata field names and lowercased)"""
- platforms: _Validator[List[str]] = _Validator()
+ platforms: _Validator[Optional[List[str]]] = _Validator()
""":external:ref:`core-metadata-platform`"""
- supported_platforms: _Validator[List[str]] = _Validator(added="1.1")
+ supported_platforms: _Validator[Optional[List[str]]] =
_Validator(added="1.1")
""":external:ref:`core-metadata-supported-platform`"""
- summary: _Validator[str] = _Validator()
+ summary: _Validator[Optional[str]] = _Validator()
""":external:ref:`core-metadata-summary` (validated to contain no
newlines)"""
- description: _Validator[str] = _Validator() # TODO 2.1: can be in body
+ description: _Validator[Optional[str]] = _Validator() # TODO 2.1: can be
in body
""":external:ref:`core-metadata-description`"""
- description_content_type: _Validator[str] = _Validator(added="2.1")
+ description_content_type: _Validator[Optional[str]] =
_Validator(added="2.1")
""":external:ref:`core-metadata-description-content-type` (validated)"""
- keywords: _Validator[List[str]] = _Validator()
+ keywords: _Validator[Optional[List[str]]] = _Validator()
""":external:ref:`core-metadata-keywords`"""
- home_page: _Validator[str] = _Validator()
+ home_page: _Validator[Optional[str]] = _Validator()
""":external:ref:`core-metadata-home-page`"""
- download_url: _Validator[str] = _Validator(added="1.1")
+ download_url: _Validator[Optional[str]] = _Validator(added="1.1")
""":external:ref:`core-metadata-download-url`"""
- author: _Validator[str] = _Validator()
+ author: _Validator[Optional[str]] = _Validator()
""":external:ref:`core-metadata-author`"""
- author_email: _Validator[str] = _Validator()
+ author_email: _Validator[Optional[str]] = _Validator()
""":external:ref:`core-metadata-author-email`"""
- maintainer: _Validator[str] = _Validator(added="1.2")
+ maintainer: _Validator[Optional[str]] = _Validator(added="1.2")
""":external:ref:`core-metadata-maintainer`"""
- maintainer_email: _Validator[str] = _Validator(added="1.2")
+ maintainer_email: _Validator[Optional[str]] = _Validator(added="1.2")
""":external:ref:`core-metadata-maintainer-email`"""
- license: _Validator[str] = _Validator()
+ license: _Validator[Optional[str]] = _Validator()
""":external:ref:`core-metadata-license`"""
- classifiers: _Validator[List[str]] = _Validator(added="1.1")
+ classifiers: _Validator[Optional[List[str]]] = _Validator(added="1.1")
""":external:ref:`core-metadata-classifier`"""
- requires_dist: _Validator[List[requirements.Requirement]] =
_Validator(added="1.2")
+ requires_dist: _Validator[Optional[List[requirements.Requirement]]] =
_Validator(
+ added="1.2"
+ )
""":external:ref:`core-metadata-requires-dist`"""
- requires_python: _Validator[specifiers.SpecifierSet] =
_Validator(added="1.2")
+ requires_python: _Validator[Optional[specifiers.SpecifierSet]] =
_Validator(
+ added="1.2"
+ )
""":external:ref:`core-metadata-requires-python`"""
# Because `Requires-External` allows for non-PEP 440 version specifiers, we
# don't do any processing on the values.
- requires_external: _Validator[List[str]] = _Validator(added="1.2")
+ requires_external: _Validator[Optional[List[str]]] =
_Validator(added="1.2")
""":external:ref:`core-metadata-requires-external`"""
- project_urls: _Validator[Dict[str, str]] = _Validator(added="1.2")
+ project_urls: _Validator[Optional[Dict[str, str]]] =
_Validator(added="1.2")
""":external:ref:`core-metadata-project-url`"""
# PEP 685 lets us raise an error if an extra doesn't pass `Name` validation
# regardless of metadata version.
- provides_extra: _Validator[List[utils.NormalizedName]] = _Validator(
+ provides_extra: _Validator[Optional[List[utils.NormalizedName]]] =
_Validator(
added="2.1",
)
""":external:ref:`core-metadata-provides-extra`"""
- provides_dist: _Validator[List[str]] = _Validator(added="1.2")
+ provides_dist: _Validator[Optional[List[str]]] = _Validator(added="1.2")
""":external:ref:`core-metadata-provides-dist`"""
- obsoletes_dist: _Validator[List[str]] = _Validator(added="1.2")
+ obsoletes_dist: _Validator[Optional[List[str]]] = _Validator(added="1.2")
""":external:ref:`core-metadata-obsoletes-dist`"""
- requires: _Validator[List[str]] = _Validator(added="1.1")
+ requires: _Validator[Optional[List[str]]] = _Validator(added="1.1")
"""``Requires`` (deprecated)"""
- provides: _Validator[List[str]] = _Validator(added="1.1")
+ provides: _Validator[Optional[List[str]]] = _Validator(added="1.1")
"""``Provides`` (deprecated)"""
- obsoletes: _Validator[List[str]] = _Validator(added="1.1")
+ obsoletes: _Validator[Optional[List[str]]] = _Validator(added="1.1")
"""``Obsoletes`` (deprecated)"""
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/packaging-23.2/src/packaging/requirements.py
new/packaging-24.0/src/packaging/requirements.py
--- old/packaging-23.2/src/packaging/requirements.py 2023-10-01
14:58:59.371256600 +0200
+++ new/packaging-24.0/src/packaging/requirements.py 2024-03-10
10:34:41.956819000 +0100
@@ -38,7 +38,7 @@
self.name: str = parsed.name
self.url: Optional[str] = parsed.url or None
- self.extras: Set[str] = set(parsed.extras if parsed.extras else [])
+ self.extras: Set[str] = set(parsed.extras or [])
self.specifier: SpecifierSet = SpecifierSet(parsed.specifier)
self.marker: Optional[Marker] = None
if parsed.marker is not None:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/packaging-23.2/src/packaging/specifiers.py
new/packaging-24.0/src/packaging/specifiers.py
--- old/packaging-23.2/src/packaging/specifiers.py 2023-04-12
18:05:06.674899300 +0200
+++ new/packaging-24.0/src/packaging/specifiers.py 2024-03-10
10:34:41.957051500 +0100
@@ -11,17 +11,7 @@
import abc
import itertools
import re
-from typing import (
- Callable,
- Iterable,
- Iterator,
- List,
- Optional,
- Set,
- Tuple,
- TypeVar,
- Union,
-)
+from typing import Callable, Iterable, Iterator, List, Optional, Tuple,
TypeVar, Union
from .utils import canonicalize_version
from .version import Version
@@ -383,7 +373,7 @@
# We want everything but the last item in the version, but we want to
# ignore suffix segments.
- prefix = ".".join(
+ prefix = _version_join(
list(itertools.takewhile(_is_not_suffix,
_version_split(spec)))[:-1]
)
@@ -404,13 +394,13 @@
)
# Get the normalized version string ignoring the trailing .*
normalized_spec = canonicalize_version(spec[:-2],
strip_trailing_zero=False)
- # Split the spec out by dots, and pretend that there is an implicit
- # dot in between a release segment and a pre-release segment.
+ # Split the spec out by bangs and dots, and pretend that there is
+ # an implicit dot in between a release segment and a pre-release
segment.
split_spec = _version_split(normalized_spec)
- # Split the prospective version out by dots, and pretend that there
- # is an implicit dot in between a release segment and a pre-release
- # segment.
+ # Split the prospective version out by bangs and dots, and pretend
+ # that there is an implicit dot in between a release segment and
+ # a pre-release segment.
split_prospective = _version_split(normalized_prospective)
# 0-pad the prospective version before shortening it to get the
correct
@@ -644,8 +634,19 @@
def _version_split(version: str) -> List[str]:
+ """Split version into components.
+
+ The split components are intended for version comparison. The logic does
+ not attempt to retain the original version string, so joining the
+ components back with :func:`_version_join` may not produce the original
+ version string.
+ """
result: List[str] = []
- for item in version.split("."):
+
+ epoch, _, rest = version.rpartition("!")
+ result.append(epoch or "0")
+
+ for item in rest.split("."):
match = _prefix_regex.search(item)
if match:
result.extend(match.groups())
@@ -654,6 +655,17 @@
return result
+def _version_join(components: List[str]) -> str:
+ """Join split version components into a version string.
+
+ This function assumes the input came from :func:`_version_split`, where the
+ first component must be the epoch (either empty or numeric), and all other
+ components numeric.
+ """
+ epoch, *rest = components
+ return f"{epoch}!{'.'.join(rest)}"
+
+
def _is_not_suffix(segment: str) -> bool:
return not any(
segment.startswith(prefix) for prefix in ("dev", "a", "b", "rc",
"post")
@@ -675,7 +687,10 @@
left_split.insert(1, ["0"] * max(0, len(right_split[0]) -
len(left_split[0])))
right_split.insert(1, ["0"] * max(0, len(left_split[0]) -
len(right_split[0])))
- return (list(itertools.chain(*left_split)),
list(itertools.chain(*right_split)))
+ return (
+ list(itertools.chain.from_iterable(left_split)),
+ list(itertools.chain.from_iterable(right_split)),
+ )
class SpecifierSet(BaseSpecifier):
@@ -707,14 +722,8 @@
# strip each item to remove leading/trailing whitespace.
split_specifiers = [s.strip() for s in specifiers.split(",") if
s.strip()]
- # Parsed each individual specifier, attempting first to make it a
- # Specifier.
- parsed: Set[Specifier] = set()
- for specifier in split_specifiers:
- parsed.add(Specifier(specifier))
-
- # Turn our parsed specifiers into a frozen set and save them for later.
- self._specs = frozenset(parsed)
+ # Make each individual specifier a Specifier and save in a frozen set
for later.
+ self._specs = frozenset(map(Specifier, split_specifiers))
# Store our prereleases value so we can use it later to determine if
# we accept prereleases or not.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/packaging-23.2/src/packaging/tags.py
new/packaging-24.0/src/packaging/tags.py
--- old/packaging-23.2/src/packaging/tags.py 2023-10-01 14:58:59.371487600
+0200
+++ new/packaging-24.0/src/packaging/tags.py 2024-01-06 21:39:23.975305000
+0100
@@ -4,6 +4,7 @@
import logging
import platform
+import re
import struct
import subprocess
import sys
@@ -124,20 +125,37 @@
return string.replace(".", "_").replace("-", "_").replace(" ", "_")
-def _abi3_applies(python_version: PythonVersion) -> bool:
+def _is_threaded_cpython(abis: List[str]) -> bool:
+ """
+ Determine if the ABI corresponds to a threaded (`--disable-gil`) build.
+
+ The threaded builds are indicated by a "t" in the abiflags.
+ """
+ if len(abis) == 0:
+ return False
+ # expect e.g., cp313
+ m = re.match(r"cp\d+(.*)", abis[0])
+ if not m:
+ return False
+ abiflags = m.group(1)
+ return "t" in abiflags
+
+
+def _abi3_applies(python_version: PythonVersion, threading: bool) -> bool:
"""
Determine if the Python version supports abi3.
- PEP 384 was first implemented in Python 3.2.
+ PEP 384 was first implemented in Python 3.2. The threaded (`--disable-gil`)
+ builds do not support abi3.
"""
- return len(python_version) > 1 and tuple(python_version) >= (3, 2)
+ return len(python_version) > 1 and tuple(python_version) >= (3, 2) and not
threading
def _cpython_abis(py_version: PythonVersion, warn: bool = False) -> List[str]:
py_version = tuple(py_version) # To allow for version comparison.
abis = []
version = _version_nodot(py_version[:2])
- debug = pymalloc = ucs4 = ""
+ threading = debug = pymalloc = ucs4 = ""
with_debug = _get_config_var("Py_DEBUG", warn)
has_refcount = hasattr(sys, "gettotalrefcount")
# Windows doesn't set Py_DEBUG, so checking for support of debug-compiled
@@ -146,6 +164,8 @@
has_ext = "_d.pyd" in EXTENSION_SUFFIXES
if with_debug or (with_debug is None and (has_refcount or has_ext)):
debug = "d"
+ if py_version >= (3, 13) and _get_config_var("Py_GIL_DISABLED", warn):
+ threading = "t"
if py_version < (3, 8):
with_pymalloc = _get_config_var("WITH_PYMALLOC", warn)
if with_pymalloc or with_pymalloc is None:
@@ -159,13 +179,8 @@
elif debug:
# Debug builds can also load "normal" extension modules.
# We can also assume no UCS-4 or pymalloc requirement.
- abis.append(f"cp{version}")
- abis.insert(
- 0,
- "cp{version}{debug}{pymalloc}{ucs4}".format(
- version=version, debug=debug, pymalloc=pymalloc, ucs4=ucs4
- ),
- )
+ abis.append(f"cp{version}{threading}")
+ abis.insert(0, f"cp{version}{threading}{debug}{pymalloc}{ucs4}")
return abis
@@ -213,11 +228,14 @@
for abi in abis:
for platform_ in platforms:
yield Tag(interpreter, abi, platform_)
- if _abi3_applies(python_version):
+
+ threading = _is_threaded_cpython(abis)
+ use_abi3 = _abi3_applies(python_version, threading)
+ if use_abi3:
yield from (Tag(interpreter, "abi3", platform_) for platform_ in
platforms)
yield from (Tag(interpreter, "none", platform_) for platform_ in platforms)
- if _abi3_applies(python_version):
+ if use_abi3:
for minor_version in range(python_version[1] - 1, 1, -1):
for platform_ in platforms:
interpreter = "cp{version}".format(
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/packaging-23.2/tests/test_manylinux.py
new/packaging-24.0/tests/test_manylinux.py
--- old/packaging-23.2/tests/test_manylinux.py 2023-10-01 14:58:59.374029000
+0200
+++ new/packaging-24.0/tests/test_manylinux.py 2024-01-06 21:39:23.975467200
+0100
@@ -140,6 +140,7 @@
assert _glibc_version_string_ctypes() is None
[email protected](ctypes is None, reason="ctypes not available")
def test_glibc_version_string_ctypes_raise_oserror(monkeypatch):
def patched_cdll(name):
raise OSError("Dynamic loading not supported")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/packaging-23.2/tests/test_metadata.py
new/packaging-24.0/tests/test_metadata.py
--- old/packaging-23.2/tests/test_metadata.py 2023-10-01 14:58:59.374242300
+0200
+++ new/packaging-24.0/tests/test_metadata.py 2024-01-06 21:39:23.975622200
+0100
@@ -251,7 +251,7 @@
individual_exception = Exception("not important")
exc = metadata.ExceptionGroup("message", [individual_exception])
assert exc.message == "message"
- assert exc.exceptions == [individual_exception]
+ assert list(exc.exceptions) == [individual_exception]
def test_repr(self):
individual_exception = RuntimeError("not important")
@@ -378,12 +378,6 @@
with pytest.raises(ExceptionGroup):
metadata.Metadata.from_raw(raw, validate=True)
- @pytest.mark.parametrize("field", metadata._DICT_FIELDS)
- def test_dict_default(self, field):
- empty_meta = metadata.Metadata.from_raw({}, validate=False)
-
- assert getattr(empty_meta, field) == {}
-
@pytest.mark.parametrize(
"attribute",
[
@@ -403,10 +397,6 @@
assert getattr(meta, attribute) == value
- empty_meta = metadata.Metadata.from_raw({}, validate=False)
-
- assert getattr(empty_meta, attribute) == ""
-
@pytest.mark.parametrize(
"attribute",
[
@@ -426,14 +416,6 @@
assert getattr(meta, attribute) == values
- empty_meta = metadata.Metadata.from_raw({}, validate=False)
- assert getattr(empty_meta, attribute) == []
-
- def test_mapping_default_attribute(self):
- empty_meta = metadata.Metadata.from_raw({}, validate=False)
-
- assert empty_meta.project_urls == {}
-
@pytest.mark.parametrize("version", ["1.0", "1.1", "1.2", "2.1", "2.2",
"2.3"])
def test_valid_metadata_version(self, version):
meta = metadata.Metadata.from_raw({"metadata_version": version},
validate=False)
@@ -628,3 +610,11 @@
with pytest.raises(metadata.InvalidMetadata):
meta.dynamic
+
+ @pytest.mark.parametrize(
+ "field_name",
+ sorted(metadata._RAW_TO_EMAIL_MAPPING.keys() -
metadata._REQUIRED_ATTRS),
+ )
+ def test_optional_defaults_to_none(self, field_name):
+ meta = metadata.Metadata.from_raw({}, validate=False)
+ assert getattr(meta, field_name) is None
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/packaging-23.2/tests/test_specifiers.py
new/packaging-24.0/tests/test_specifiers.py
--- old/packaging-23.2/tests/test_specifiers.py 2023-04-12 18:05:06.676737300
+0200
+++ new/packaging-24.0/tests/test_specifiers.py 2024-03-10 10:34:41.957288300
+0100
@@ -235,8 +235,7 @@
@pytest.mark.parametrize(
("left", "right", "op"),
- itertools.chain(
- *
+ itertools.chain.from_iterable(
# Verify that the equal (==) operator works correctly
[[(x, x, operator.eq) for x in SPECIFIERS]]
+
@@ -260,8 +259,7 @@
@pytest.mark.parametrize(
("left", "right", "op"),
- itertools.chain(
- *
+ itertools.chain.from_iterable(
# Verify that the equal (==) operator works correctly
[[(x, x, operator.ne) for x in SPECIFIERS]]
+
@@ -369,6 +367,7 @@
("2!1.0", "==2!1.*"),
("2!1.0", "==2!1.0"),
("2!1.0", "!=1.0"),
+ ("2!1.0.0", "==2!1.0.0.0.*"),
("2!1.0.0", "==2!1.0.*"),
("2!1.0.0", "==2!1.*"),
("1.0", "!=2!1.0"),
@@ -467,6 +466,8 @@
("2!1.0", "~=1.0"),
("2!1.0", "==1.0"),
("1.0", "==2!1.0"),
+ ("2!1.0", "==1.0.0.*"),
+ ("1.0", "==2!1.0.0.*"),
("2!1.0", "==1.*"),
("1.0", "==2!1.*"),
("2!1.0", "!=2!1.0"),
@@ -812,8 +813,7 @@
@pytest.mark.parametrize(
("left", "right", "op"),
- itertools.chain(
- *
+ itertools.chain.from_iterable(
# Verify that the equal (==) operator works correctly
[[(x, x, operator.eq) for x in SPECIFIERS]]
+
@@ -833,8 +833,7 @@
@pytest.mark.parametrize(
("left", "right", "op"),
- itertools.chain(
- *
+ itertools.chain.from_iterable(
# Verify that the equal (==) operator works correctly
[[(x, x, operator.ne) for x in SPECIFIERS]]
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/packaging-23.2/tests/test_structures.py
new/packaging-24.0/tests/test_structures.py
--- old/packaging-23.2/tests/test_structures.py 2022-04-02 15:23:31.364833000
+0200
+++ new/packaging-24.0/tests/test_structures.py 2024-03-10 10:34:41.957458300
+0100
@@ -8,11 +8,11 @@
def test_infinity_repr():
- repr(Infinity) == "Infinity"
+ assert repr(Infinity) == "Infinity"
def test_negative_infinity_repr():
- repr(NegativeInfinity) == "-Infinity"
+ assert repr(NegativeInfinity) == "-Infinity"
def test_infinity_hash():
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/packaging-23.2/tests/test_tags.py
new/packaging-24.0/tests/test_tags.py
--- old/packaging-23.2/tests/test_tags.py 2023-10-01 14:58:59.375138500
+0200
+++ new/packaging-24.0/tests/test_tags.py 2024-01-06 21:39:23.976038500
+0100
@@ -781,6 +781,14 @@
tags.Tag("cp32", "abi3", "plat2"),
]
+ result = list(tags.cpython_tags((3, 13), ["cp313t"], ["plat1",
"plat2"]))
+ assert result == [
+ tags.Tag("cp313", "cp313t", "plat1"),
+ tags.Tag("cp313", "cp313t", "plat2"),
+ tags.Tag("cp313", "none", "plat1"),
+ tags.Tag("cp313", "none", "plat2"),
+ ]
+
def test_python_version_defaults(self):
tag = next(tags.cpython_tags(abis=["abi3"], platforms=["any"]))
interpreter = "cp" + tags._version_nodot(sys.version_info[:2])
@@ -894,6 +902,17 @@
monkeypatch.setattr(sysconfig, "get_config_var", config.__getitem__)
assert tags._generic_abi() == ["graalpy_38_native"]
+ def test__generic_abi_disable_gil(self, monkeypatch):
+ config = {
+ "Py_DEBUG": False,
+ "EXT_SUFFIX": ".cpython-313t-x86_64-linux-gnu.so",
+ "WITH_PYMALLOC": 0,
+ "Py_GIL_DISABLED": 1,
+ }
+ monkeypatch.setattr(sysconfig, "get_config_var", config.__getitem__)
+ assert tags._generic_abi() == ["cp313t"]
+ assert tags._generic_abi() == tags._cpython_abis((3, 13))
+
def test__generic_abi_none(self, monkeypatch):
config = {"EXT_SUFFIX": "..so"}
monkeypatch.setattr(sysconfig, "get_config_var", config.__getitem__)
@@ -922,6 +941,7 @@
"EXT_SUFFIX": ".pyd",
"Py_DEBUG": 0,
"WITH_PYMALLOC": 0,
+ "Py_GIL_DISABLED": 0,
}
monkeypatch.setattr(sysconfig, "get_config_var", config.__getitem__)
assert tags._generic_abi() == tags._cpython_abis(sys.version_info[:2])
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/packaging-23.2/tests/test_version.py
new/packaging-24.0/tests/test_version.py
--- old/packaging-23.2/tests/test_version.py 2023-01-30 16:24:13.040571200
+0100
+++ new/packaging-24.0/tests/test_version.py 2024-03-10 10:34:41.957671900
+0100
@@ -667,8 +667,7 @@
("left", "right", "op"),
# Below we'll generate every possible combination of VERSIONS that
# should be True for the given operator
- itertools.chain(
- *
+ itertools.chain.from_iterable(
# Verify that the less than (<) operator works correctly
[
[(x, y, operator.lt) for y in VERSIONS[i + 1 :]]
@@ -710,8 +709,7 @@
("left", "right", "op"),
# Below we'll generate every possible combination of VERSIONS that
# should be False for the given operator
- itertools.chain(
- *
+ itertools.chain.from_iterable(
# Verify that the less than (<) operator works correctly
[
[(x, y, operator.lt) for y in VERSIONS[: i + 1]]