aa460d3eda50fbb174623a1b5bbca54645fd588a
[SubU] /
1 import re
2 import textwrap
3 import email.message
4
5 from ._text import FoldedCase
6
7
8 class Message(email.message.Message):
9     multiple_use_keys = set(
10         map(
11             FoldedCase,
12             [
13                 'Classifier',
14                 'Obsoletes-Dist',
15                 'Platform',
16                 'Project-URL',
17                 'Provides-Dist',
18                 'Provides-Extra',
19                 'Requires-Dist',
20                 'Requires-External',
21                 'Supported-Platform',
22                 'Dynamic',
23             ],
24         )
25     )
26     """
27     Keys that may be indicated multiple times per PEP 566.
28     """
29
30     def __new__(cls, orig: email.message.Message):
31         res = super().__new__(cls)
32         vars(res).update(vars(orig))
33         return res
34
35     def __init__(self, *args, **kwargs):
36         self._headers = self._repair_headers()
37
38     # suppress spurious error from mypy
39     def __iter__(self):
40         return super().__iter__()
41
42     def _repair_headers(self):
43         def redent(value):
44             "Correct for RFC822 indentation"
45             if not value or '\n' not in value:
46                 return value
47             return textwrap.dedent(' ' * 8 + value)
48
49         headers = [(key, redent(value)) for key, value in vars(self)['_headers']]
50         if self._payload:
51             headers.append(('Description', self.get_payload()))
52         return headers
53
54     @property
55     def json(self):
56         """
57         Convert PackageMetadata to a JSON-compatible format
58         per PEP 0566.
59         """
60
61         def transform(key):
62             value = self.get_all(key) if key in self.multiple_use_keys else self[key]
63             if key == 'Keywords':
64                 value = re.split(r'\s+', value)
65             tk = key.lower().replace('-', '_')
66             return tk, value
67
68         return dict(map(transform, map(FoldedCase, self)))