3838from ._functools import method_cache , noop , pass_none , passthrough
3939from ._itertools import always_iterable , bucket , unique_everseen
4040from ._meta import PackageMetadata , SimplePath
41- from ._typing import md_none
4241from .compat import py39 , py311
4342
4443__all__ = [
4544 'Distribution' ,
4645 'DistributionFinder' ,
4746 'PackageMetadata' ,
4847 'PackageNotFoundError' ,
48+ 'MetadataNotFound' ,
4949 'SimplePath' ,
5050 'distribution' ,
5151 'distributions' ,
@@ -70,6 +70,10 @@ def name(self) -> str: # type: ignore[override] # make readonly
7070 return name
7171
7272
73+ class MetadataNotFound (FileNotFoundError ):
74+ """No metadata file is present in the distribution."""
75+
76+
7377class Sectioned :
7478 """
7579 A simple entry point config parser for performance
@@ -491,7 +495,14 @@ def _prefer_valid(dists: Iterable[Distribution]) -> Iterable[Distribution]:
491495
492496 Ref python/importlib_resources#489.
493497 """
494- buckets = bucket (dists , lambda dist : bool (dist .metadata ))
498+
499+ def has_metadata (dist : Distribution ) -> bool :
500+ with suppress (MetadataNotFound ):
501+ dist .metadata
502+ return True
503+ return False
504+
505+ buckets = bucket (dists , has_metadata )
495506 return itertools .chain (buckets [True ], buckets [False ])
496507
497508 @staticmethod
@@ -512,7 +523,7 @@ def _discover_resolvers():
512523 return filter (None , declared )
513524
514525 @property
515- def metadata (self ) -> _meta .PackageMetadata | None :
526+ def metadata (self ) -> _meta .PackageMetadata :
516527 """Return the parsed metadata for this Distribution.
517528
518529 The returned object will have keys that name the various bits of
@@ -521,6 +532,8 @@ def metadata(self) -> _meta.PackageMetadata | None:
521532
522533 Custom providers may provide the METADATA file or override this
523534 property.
535+
536+ :raises MetadataNotFound: If no metadata file is present.
524537 """
525538
526539 text = (
@@ -531,20 +544,25 @@ def metadata(self) -> _meta.PackageMetadata | None:
531544 # (which points to the egg-info file) attribute unchanged.
532545 or self .read_text ('' )
533546 )
534- return self ._assemble_message (text )
547+ return self ._assemble_message (self . _ensure_metadata_present ( text ) )
535548
536549 @staticmethod
537- @pass_none
538550 def _assemble_message (text : str ) -> _meta .PackageMetadata :
539551 # deferred for performance (python/cpython#109829)
540552 from . import _adapters
541553
542554 return _adapters .Message (email .message_from_string (text ))
543555
556+ def _ensure_metadata_present (self , text : str | None ) -> str :
557+ if text is not None :
558+ return text
559+
560+ raise MetadataNotFound ('No package metadata was found.' )
561+
544562 @property
545563 def name (self ) -> str :
546564 """Return the 'Name' metadata for the distribution package."""
547- return md_none ( self .metadata ) ['Name' ]
565+ return self .metadata ['Name' ]
548566
549567 @property
550568 def _normalized_name (self ):
@@ -554,7 +572,7 @@ def _normalized_name(self):
554572 @property
555573 def version (self ) -> str :
556574 """Return the 'Version' metadata for the distribution package."""
557- return md_none ( self .metadata ) ['Version' ]
575+ return self .metadata ['Version' ]
558576
559577 @property
560578 def entry_points (self ) -> EntryPoints :
@@ -1067,11 +1085,12 @@ def distributions(**kwargs) -> Iterable[Distribution]:
10671085 return Distribution .discover (** kwargs )
10681086
10691087
1070- def metadata (distribution_name : str ) -> _meta .PackageMetadata | None :
1088+ def metadata (distribution_name : str ) -> _meta .PackageMetadata :
10711089 """Get the metadata for the named package.
10721090
10731091 :param distribution_name: The name of the distribution package to query.
10741092 :return: A PackageMetadata containing the parsed metadata.
1093+ :raises MetadataNotFound: If no metadata file is present in the distribution.
10751094 """
10761095 return Distribution .from_name (distribution_name ).metadata
10771096
@@ -1142,7 +1161,7 @@ def packages_distributions() -> Mapping[str, list[str]]:
11421161 pkg_to_dist = collections .defaultdict (list )
11431162 for dist in distributions ():
11441163 for pkg in _top_level_declared (dist ) or _top_level_inferred (dist ):
1145- pkg_to_dist [pkg ].append (md_none ( dist .metadata ) ['Name' ])
1164+ pkg_to_dist [pkg ].append (dist .metadata ['Name' ])
11461165 return dict (pkg_to_dist )
11471166
11481167
0 commit comments