@@ -31,6 +31,7 @@
31313232from . import_meta
3333from ._collectionsimportFreezableDefaultDict, Pair
34+from ._contextimportExceptionTrap
3435from ._functoolsimportmethod_cache, noop, pass_none, passthrough
3536from ._itertoolsimportalways_iterable, bucket, unique_everseen
3637from ._metaimportPackageMetadata, SimplePath
@@ -42,6 +43,7 @@
4243'PackageMetadata',
4344'PackageNotFoundError',
4445'PackagePath',
46+'MetadataNotFound',
4547'SimplePath',
4648'distribution',
4749'distributions',
@@ -66,6 +68,10 @@ def name(self) -> str: # type: ignore[override] # make readonly
6668returnname
6769687071+classMetadataNotFound(FileNotFoundError):
72+"""No metadata file is present in the distribution."""
73+74+6975classSectioned:
7076"""
7177 A simple entry point config parser for performance
@@ -487,7 +493,12 @@ def _prefer_valid(dists: Iterable[Distribution]) -> Iterable[Distribution]:
487493488494 Ref python/importlib_resources#489.
489495 """
490-buckets=bucket(dists, lambdadist: bool(dist.metadata))
496+497+has_metadata=ExceptionTrap(MetadataNotFound).passes(
498+operator.attrgetter('metadata')
499+ )
500+501+buckets=bucket(dists, has_metadata)
491502returnitertools.chain(buckets[True], buckets[False])
492503493504@staticmethod
@@ -508,7 +519,7 @@ def _discover_resolvers():
508519returnfilter(None, declared)
509520510521@property
511-defmetadata(self) ->_meta.PackageMetadata|None:
522+defmetadata(self) ->_meta.PackageMetadata:
512523"""Return the parsed metadata for this Distribution.
513524514525 The returned object will have keys that name the various bits of
@@ -517,6 +528,8 @@ def metadata(self) -> _meta.PackageMetadata | None:
517528518529 Custom providers may provide the METADATA file or override this
519530 property.
531+532+ :raises MetadataNotFound: If no metadata file is present.
520533 """
521534522535text= (
@@ -527,20 +540,25 @@ def metadata(self) -> _meta.PackageMetadata | None:
527540# (which points to the egg-info file) attribute unchanged.
528541orself.read_text('')
529542 )
530-returnself._assemble_message(text)
543+returnself._assemble_message(self._ensure_metadata_present(text))
531544532545@staticmethod
533-@pass_none
534546def_assemble_message(text: str) ->_meta.PackageMetadata:
535547# deferred for performance (python/cpython#109829)
536548from . import_adapters
537549538550return_adapters.Message(email.message_from_string(text))
539551552+def_ensure_metadata_present(self, text: str|None) ->str:
553+iftextisnotNone:
554+returntext
555+556+raiseMetadataNotFound('No package metadata was found.')
557+540558@property
541559defname(self) ->str:
542560"""Return the 'Name' metadata for the distribution package."""
543-returnmd_none(self.metadata)['Name']
561+returnself.metadata['Name']
544562545563@property
546564def_normalized_name(self):
@@ -550,7 +568,7 @@ def _normalized_name(self):
550568@property
551569defversion(self) ->str:
552570"""Return the 'Version' metadata for the distribution package."""
553-returnmd_none(self.metadata)['Version']
571+returnself.metadata['Version']
554572555573@property
556574defentry_points(self) ->EntryPoints:
@@ -1063,11 +1081,12 @@ def distributions(**kwargs) -> Iterable[Distribution]:
10631081returnDistribution.discover(**kwargs)
10641082106510831066-defmetadata(distribution_name: str) ->_meta.PackageMetadata|None:
1084+defmetadata(distribution_name: str) ->_meta.PackageMetadata:
10671085"""Get the metadata for the named package.
1068108610691087 :param distribution_name: The name of the distribution package to query.
10701088 :return: A PackageMetadata containing the parsed metadata.
1089+ :raises MetadataNotFound: If no metadata file is present in the distribution.
10711090 """
10721091returnDistribution.from_name(distribution_name).metadata
10731092@@ -1138,7 +1157,7 @@ def packages_distributions() -> Mapping[str, list[str]]:
11381157pkg_to_dist=collections.defaultdict(list)
11391158fordistindistributions():
11401159forpkgin_top_level_declared(dist) or_top_level_inferred(dist):
1141-pkg_to_dist[pkg].append(md_none(dist.metadata)['Name'])
1160+pkg_to_dist[pkg].append(dist.metadata['Name'])
11421161returndict(pkg_to_dist)
1143116211441163