Spaces:
Paused
Paused
import re | |
import textwrap | |
import email.message | |
from ._text import FoldedCase | |
class Message(email.message.Message): | |
multiple_use_keys = set( | |
map( | |
FoldedCase, | |
[ | |
'Classifier', | |
'Obsoletes-Dist', | |
'Platform', | |
'Project-URL', | |
'Provides-Dist', | |
'Provides-Extra', | |
'Requires-Dist', | |
'Requires-External', | |
'Supported-Platform', | |
'Dynamic', | |
], | |
) | |
) | |
""" | |
Keys that may be indicated multiple times per PEP 566. | |
""" | |
def __new__(cls, orig: email.message.Message): | |
res = super().__new__(cls) | |
vars(res).update(vars(orig)) | |
return res | |
def __init__(self, *args, **kwargs): | |
self._headers = self._repair_headers() | |
# suppress spurious error from mypy | |
def __iter__(self): | |
return super().__iter__() | |
def __getitem__(self, item): | |
""" | |
Override parent behavior to typical dict behavior. | |
``email.message.Message`` will emit None values for missing | |
keys. Typical mappings, including this ``Message``, will raise | |
a key error for missing keys. | |
Ref python/importlib_metadata#371. | |
""" | |
res = super().__getitem__(item) | |
if res is None: | |
raise KeyError(item) | |
return res | |
def _repair_headers(self): | |
def redent(value): | |
"Correct for RFC822 indentation" | |
if not value or '\n' not in value: | |
return value | |
return textwrap.dedent(' ' * 8 + value) | |
headers = [(key, redent(value)) for key, value in vars(self)['_headers']] | |
if self._payload: | |
headers.append(('Description', self.get_payload())) | |
return headers | |
def json(self): | |
""" | |
Convert PackageMetadata to a JSON-compatible format | |
per PEP 0566. | |
""" | |
def transform(key): | |
value = self.get_all(key) if key in self.multiple_use_keys else self[key] | |
if key == 'Keywords': | |
value = re.split(r'\s+', value) | |
tk = key.lower().replace('-', '_') | |
return tk, value | |
return dict(map(transform, map(FoldedCase, self))) | |