codekingpro/portable-devtools
114k
1import functools2import warnings3import re4import textwrap5import email.message6 7from ._text import FoldedCase8from ._compat import pypy_partial9 10 11# Do not remove prior to 2024-01-01 or Python 3.1412_warn = functools.partial(13 warnings.warn,14 "Implicit None on return values is deprecated and will raise KeyErrors.",15 DeprecationWarning,16 stacklevel=pypy_partial(2),17)18 19 20class Message(email.message.Message):21 multiple_use_keys = set(22 map(23 FoldedCase,24 [25 'Classifier',26 'Obsoletes-Dist',27 'Platform',28 'Project-URL',29 'Provides-Dist',30 'Provides-Extra',31 'Requires-Dist',32 'Requires-External',33 'Supported-Platform',34 'Dynamic',35 ],36 )37 )38 """39 Keys that may be indicated multiple times per PEP 566.40 """41 42 def __new__(cls, orig: email.message.Message):43 res = super().__new__(cls)44 vars(res).update(vars(orig))45 return res46 47 def __init__(self, *args, **kwargs):48 self._headers = self._repair_headers()49 50 # suppress spurious error from mypy51 def __iter__(self):52 return super().__iter__()53 54 def __getitem__(self, item):55 """56 Warn users that a ``KeyError`` can be expected when a57 missing key is supplied. Ref python/importlib_metadata#371.58 """59 res = super().__getitem__(item)60 if res is None:61 _warn()62 return res63 64 def _repair_headers(self):65 def redent(value):66 "Correct for RFC822 indentation"67 if not value or '\n' not in value:68 return value69 return textwrap.dedent(' ' * 8 + value)70 71 headers = [(key, redent(value)) for key, value in vars(self)['_headers']]72 if self._payload:73 headers.append(('Description', self.get_payload()))74 return headers75 76 @property77 def json(self):78 """79 Convert PackageMetadata to a JSON-compatible format80 per PEP 0566.81 """82 83 def transform(key):84 value = self.get_all(key) if key in self.multiple_use_keys else self[key]85 if key == 'Keywords':86 value = re.split(r'\s+', value)87 tk = key.lower().replace('-', '_')88 return tk, value89 90 return dict(map(transform, map(FoldedCase, self)))91 