@@ -55,7 +55,7 @@ class LinkHash:
55
55
name : str
56
56
value : str
57
57
58
- _hash_re = re .compile (
58
+ _hash_url_fragment_re = re .compile (
59
59
# NB: we do not validate that the second group (.*) is a valid hex
60
60
# digest. Instead, we simply keep that string in this class, and then check it
61
61
# against Hashes when hash-checking is needed. This is easier to debug than
@@ -67,13 +67,26 @@ class LinkHash:
67
67
)
68
68
69
69
def __post_init__ (self ) -> None :
70
- assert self ._hash_re .match (f"#{ self .name } ={ self .value } " )
70
+ assert self ._hash_url_fragment_re .match (f"#{ self .name } ={ self .value } " )
71
+
72
+ @classmethod
73
+ def parse_pep658_hash (cls , dist_info_metadata : str ) -> Optional ["LinkHash" ]:
74
+ """Parse a PEP 658 data-dist-info-metadata hash."""
75
+ if dist_info_metadata == "true" :
76
+ return None
77
+ try :
78
+ name , value = dist_info_metadata .split ("=" , 1 )
79
+ except ValueError :
80
+ return None
81
+ if name not in _SUPPORTED_HASHES :
82
+ return None
83
+ return cls (name = name , value = value )
71
84
72
85
@classmethod
73
86
@functools .lru_cache (maxsize = None )
74
- def split_hash_name_and_value (cls , url : str ) -> Optional ["LinkHash" ]:
87
+ def find_hash_url_fragment (cls , url : str ) -> Optional ["LinkHash" ]:
75
88
"""Search a string for a checksum algorithm name and encoded output value."""
76
- match = cls ._hash_re .search (url )
89
+ match = cls ._hash_url_fragment_re .search (url )
77
90
if match is None :
78
91
return None
79
92
name , value = match .groups ()
@@ -217,7 +230,7 @@ def __init__(
217
230
# trying to set a new value.
218
231
self ._url = url
219
232
220
- link_hash = LinkHash .split_hash_name_and_value (url )
233
+ link_hash = LinkHash .find_hash_url_fragment (url )
221
234
hashes_from_link = {} if link_hash is None else link_hash .as_dict ()
222
235
if hashes is None :
223
236
self ._hashes = hashes_from_link
@@ -402,15 +415,10 @@ def metadata_link(self) -> Optional["Link"]:
402
415
if self .dist_info_metadata is None :
403
416
return None
404
417
metadata_url = f"{ self .url_without_fragment } .metadata"
405
- # If data-dist-info-metadata="true" is set, then the metadata file exists,
406
- # but there is no information about its checksum or anything else.
407
- if self .dist_info_metadata != "true" :
408
- link_hash = LinkHash .split_hash_name_and_value (self .dist_info_metadata )
409
- else :
410
- link_hash = None
411
- if link_hash is None :
418
+ metadata_link_hash = LinkHash .parse_pep658_hash (self .dist_info_metadata )
419
+ if metadata_link_hash is None :
412
420
return Link (metadata_url )
413
- return Link (metadata_url , hashes = link_hash .as_dict ())
421
+ return Link (metadata_url , hashes = metadata_link_hash .as_dict ())
414
422
415
423
def as_hashes (self ) -> Hashes :
416
424
return Hashes ({k : [v ] for k , v in self ._hashes .items ()})
0 commit comments