27
27
from importlib import import_module
28
28
from importlib .abc import MetaPathFinder
29
29
from itertools import starmap
30
- from typing import Any , cast
30
+ from typing import Any
31
31
32
32
from . import _meta
33
33
from ._collections import FreezableDefaultDict , Pair
38
38
from ._functools import method_cache , pass_none
39
39
from ._itertools import always_iterable , bucket , unique_everseen
40
40
from ._meta import PackageMetadata , SimplePath
41
+ from ._typing import md_none
41
42
from .compat import py39 , py311
42
43
43
44
__all__ = [
@@ -511,7 +512,7 @@ def _discover_resolvers():
511
512
return filter (None , declared )
512
513
513
514
@property
514
- def metadata (self ) -> _meta .PackageMetadata :
515
+ def metadata (self ) -> _meta .PackageMetadata | None :
515
516
"""Return the parsed metadata for this Distribution.
516
517
517
518
The returned object will have keys that name the various bits of
@@ -521,24 +522,29 @@ def metadata(self) -> _meta.PackageMetadata:
521
522
Custom providers may provide the METADATA file or override this
522
523
property.
523
524
"""
524
- # deferred for performance (python/cpython#109829)
525
- from . import _adapters
526
525
527
- opt_text = (
526
+ text = (
528
527
self .read_text ('METADATA' )
529
528
or self .read_text ('PKG-INFO' )
530
529
# This last clause is here to support old egg-info files. Its
531
530
# effect is to just end up using the PathDistribution's self._path
532
531
# (which points to the egg-info file) attribute unchanged.
533
532
or self .read_text ('' )
534
533
)
535
- text = cast (str , opt_text )
534
+ return self ._assemble_message (text )
535
+
536
+ @staticmethod
537
+ @pass_none
538
+ def _assemble_message (text : str ) -> _meta .PackageMetadata :
539
+ # deferred for performance (python/cpython#109829)
540
+ from . import _adapters
541
+
536
542
return _adapters .Message (email .message_from_string (text ))
537
543
538
544
@property
539
545
def name (self ) -> str :
540
546
"""Return the 'Name' metadata for the distribution package."""
541
- return self .metadata ['Name' ]
547
+ return md_none ( self .metadata ) ['Name' ]
542
548
543
549
@property
544
550
def _normalized_name (self ):
@@ -548,7 +554,7 @@ def _normalized_name(self):
548
554
@property
549
555
def version (self ) -> str :
550
556
"""Return the 'Version' metadata for the distribution package."""
551
- return self .metadata ['Version' ]
557
+ return md_none ( self .metadata ) ['Version' ]
552
558
553
559
@property
554
560
def entry_points (self ) -> EntryPoints :
@@ -1045,7 +1051,7 @@ def distributions(**kwargs) -> Iterable[Distribution]:
1045
1051
return Distribution .discover (** kwargs )
1046
1052
1047
1053
1048
- def metadata (distribution_name : str ) -> _meta .PackageMetadata :
1054
+ def metadata (distribution_name : str ) -> _meta .PackageMetadata | None :
1049
1055
"""Get the metadata for the named package.
1050
1056
1051
1057
:param distribution_name: The name of the distribution package to query.
@@ -1120,7 +1126,7 @@ def packages_distributions() -> Mapping[str, list[str]]:
1120
1126
pkg_to_dist = collections .defaultdict (list )
1121
1127
for dist in distributions ():
1122
1128
for pkg in _top_level_declared (dist ) or _top_level_inferred (dist ):
1123
- pkg_to_dist [pkg ].append (dist .metadata ['Name' ])
1129
+ pkg_to_dist [pkg ].append (md_none ( dist .metadata ) ['Name' ])
1124
1130
return dict (pkg_to_dist )
1125
1131
1126
1132
0 commit comments