|
2 | 2 | import textwrap
|
3 | 3 | import email.message
|
4 | 4 |
|
5 |
| -from ._functools import method_cache |
| 5 | +from ._text import FoldedCase |
6 | 6 |
|
7 | 7 |
|
8 | 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 | + ], |
| 23 | + ) |
| 24 | + ) |
| 25 | + """ |
| 26 | + Keys that may be indicated multiple times per PEP 566. |
| 27 | + """ |
| 28 | + |
9 | 29 | def __new__(cls, orig: email.message.Message):
|
10 | 30 | res = super().__new__(cls)
|
11 | 31 | vars(res).update(vars(orig))
|
@@ -36,124 +56,12 @@ def json(self):
|
36 | 56 | Convert PackageMetadata to a JSON-compatible format
|
37 | 57 | per PEP 0566.
|
38 | 58 | """
|
39 |
| - multiple_use = set( |
40 |
| - map( |
41 |
| - FoldedCase, |
42 |
| - [ |
43 |
| - 'Classifier', |
44 |
| - 'Obsoletes-Dist', |
45 |
| - 'Platform', |
46 |
| - 'Project-URL', |
47 |
| - 'Provides-Dist', |
48 |
| - 'Provides-Extra', |
49 |
| - 'Requires-Dist', |
50 |
| - 'Requires-External', |
51 |
| - 'Supported-Platform', |
52 |
| - ], |
53 |
| - ) |
54 |
| - ) |
55 | 59 |
|
56 | 60 | def transform(key):
|
57 |
| - value = self.get_all(key) if key in multiple_use else self[key] |
| 61 | + value = self.get_all(key) if key in self.multiple_use_keys else self[key] |
58 | 62 | if key == 'Keywords':
|
59 | 63 | value = re.split(r'\s+', value)
|
60 | 64 | tk = key.lower().replace('-', '_')
|
61 | 65 | return tk, value
|
62 | 66 |
|
63 | 67 | return dict(map(transform, map(FoldedCase, self)))
|
64 |
| - |
65 |
| - |
66 |
| -# from jaraco.text 3.5 |
67 |
| -class FoldedCase(str): |
68 |
| - """ |
69 |
| - A case insensitive string class; behaves just like str |
70 |
| - except compares equal when the only variation is case. |
71 |
| -
|
72 |
| - >>> s = FoldedCase('hello world') |
73 |
| -
|
74 |
| - >>> s == 'Hello World' |
75 |
| - True |
76 |
| -
|
77 |
| - >>> 'Hello World' == s |
78 |
| - True |
79 |
| -
|
80 |
| - >>> s != 'Hello World' |
81 |
| - False |
82 |
| -
|
83 |
| - >>> s.index('O') |
84 |
| - 4 |
85 |
| -
|
86 |
| - >>> s.split('O') |
87 |
| - ['hell', ' w', 'rld'] |
88 |
| -
|
89 |
| - >>> sorted(map(FoldedCase, ['GAMMA', 'alpha', 'Beta'])) |
90 |
| - ['alpha', 'Beta', 'GAMMA'] |
91 |
| -
|
92 |
| - Sequence membership is straightforward. |
93 |
| -
|
94 |
| - >>> "Hello World" in [s] |
95 |
| - True |
96 |
| - >>> s in ["Hello World"] |
97 |
| - True |
98 |
| -
|
99 |
| - You may test for set inclusion, but candidate and elements |
100 |
| - must both be folded. |
101 |
| -
|
102 |
| - >>> FoldedCase("Hello World") in {s} |
103 |
| - True |
104 |
| - >>> s in {FoldedCase("Hello World")} |
105 |
| - True |
106 |
| -
|
107 |
| - String inclusion works as long as the FoldedCase object |
108 |
| - is on the right. |
109 |
| -
|
110 |
| - >>> "hello" in FoldedCase("Hello World") |
111 |
| - True |
112 |
| -
|
113 |
| - But not if the FoldedCase object is on the left: |
114 |
| -
|
115 |
| - >>> FoldedCase('hello') in 'Hello World' |
116 |
| - False |
117 |
| -
|
118 |
| - In that case, use in_: |
119 |
| -
|
120 |
| - >>> FoldedCase('hello').in_('Hello World') |
121 |
| - True |
122 |
| -
|
123 |
| - >>> FoldedCase('hello') > FoldedCase('Hello') |
124 |
| - False |
125 |
| - """ |
126 |
| - |
127 |
| - def __lt__(self, other): |
128 |
| - return self.lower() < other.lower() |
129 |
| - |
130 |
| - def __gt__(self, other): |
131 |
| - return self.lower() > other.lower() |
132 |
| - |
133 |
| - def __eq__(self, other): |
134 |
| - return self.lower() == other.lower() |
135 |
| - |
136 |
| - def __ne__(self, other): |
137 |
| - return self.lower() != other.lower() |
138 |
| - |
139 |
| - def __hash__(self): |
140 |
| - return hash(self.lower()) |
141 |
| - |
142 |
| - def __contains__(self, other): |
143 |
| - return super(FoldedCase, self).lower().__contains__(other.lower()) |
144 |
| - |
145 |
| - def in_(self, other): |
146 |
| - "Does self appear in other?" |
147 |
| - return self in FoldedCase(other) |
148 |
| - |
149 |
| - # cache lower since it's likely to be called frequently. |
150 |
| - @method_cache |
151 |
| - def lower(self): |
152 |
| - return super(FoldedCase, self).lower() |
153 |
| - |
154 |
| - def index(self, sub): |
155 |
| - return self.lower().index(sub.lower()) |
156 |
| - |
157 |
| - def split(self, splitter=' ', maxsplit=0): |
158 |
| - pattern = re.compile(re.escape(splitter), re.I) |
159 |
| - return pattern.split(self, maxsplit) |
0 commit comments