diff --git a/CHANGELOG.rst b/CHANGELOG.rst index a218ff9a..3b5c8c9f 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -10,6 +10,8 @@ Changelog * 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 ~~~~~~~~~~~~~~~~~ diff --git a/src/packaging/metadata.py b/src/packaging/metadata.py index 6ebcc24e..fb274930 100644 --- a/src/packaging/metadata.py +++ b/src/packaging/metadata.py @@ -41,10 +41,10 @@ def __init_subclass__(*_args, **_kwargs): 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 __init__(self, message: str, exceptions: List[Exception]) -> None: 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.""" @@ -672,7 +675,7 @@ def from_raw(cls, data: RawMetadata, *, validate: bool = True) -> "Metadata": 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) @@ -727,10 +730,10 @@ def from_email( 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" @@ -744,8 +747,9 @@ def from_email( 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` diff --git a/tests/test_metadata.py b/tests/test_metadata.py index a10b0c60..7362d62f 100644 --- a/tests/test_metadata.py +++ b/tests/test_metadata.py @@ -251,7 +251,7 @@ def test_attributes(self): 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")