|
16 | 16 | from distutils.debug import DEBUG
|
17 | 17 | from distutils.fancy_getopt import translate_longopt
|
18 | 18 | import itertools
|
| 19 | +import textwrap |
| 20 | +from typing import List, Optional, TYPE_CHECKING |
19 | 21 |
|
20 | 22 | from collections import defaultdict
|
21 | 23 | from email import message_from_file
|
|
36 | 38 | from setuptools.config import parse_configuration
|
37 | 39 | import pkg_resources
|
38 | 40 |
|
| 41 | +if TYPE_CHECKING: |
| 42 | + from email.message import Message |
| 43 | + |
39 | 44 | __import__('setuptools.extern.packaging.specifiers')
|
40 | 45 | __import__('setuptools.extern.packaging.version')
|
41 | 46 |
|
@@ -67,53 +72,75 @@ def get_metadata_version(self):
|
67 | 72 | return mv
|
68 | 73 |
|
69 | 74 |
|
70 |
| -def read_pkg_file(self, file): |
71 |
| - """Reads the metadata values from a file object.""" |
72 |
| - msg = message_from_file(file) |
| 75 | +def rfc822_unescape(content: str) -> str: |
| 76 | + """Reverse RFC-822 escaping by removing leading whitespaces from content.""" |
| 77 | + lines = content.splitlines() |
| 78 | + if len(lines) == 1: |
| 79 | + return lines[0].lstrip() |
| 80 | + return '\n'.join( |
| 81 | + (lines[0].lstrip(), |
| 82 | + textwrap.dedent('\n'.join(lines[1:])))) |
| 83 | + |
| 84 | + |
| 85 | +def _read_field_from_msg(msg: "Message", field: str) -> Optional[str]: |
| 86 | + """Read Message header field.""" |
| 87 | + value = msg[field] |
| 88 | + if value == 'UNKNOWN': |
| 89 | + return None |
| 90 | + return value |
| 91 | + |
73 | 92 |
|
74 |
| - def _read_field(name): |
75 |
| - value = msg[name] |
76 |
| - if value == 'UNKNOWN': |
77 |
| - return None |
| 93 | +def _read_field_unescaped_from_msg(msg: "Message", field: str) -> Optional[str]: |
| 94 | + """Read Message header field and apply rfc822_unescape.""" |
| 95 | + value = _read_field_from_msg(msg, field) |
| 96 | + if value is None: |
78 | 97 | return value
|
| 98 | + return rfc822_unescape(value) |
79 | 99 |
|
80 |
| - def _read_list(name): |
81 |
| - values = msg.get_all(name, None) |
82 |
| - if values == []: |
83 |
| - return None |
84 |
| - return values |
| 100 | + |
| 101 | +def _read_list_from_msg(msg: "Message", field: str) -> Optional[List[str]]: |
| 102 | + """Read Message header field and return all results as list.""" |
| 103 | + values = msg.get_all(field, None) |
| 104 | + if values == []: |
| 105 | + return None |
| 106 | + return values |
| 107 | + |
| 108 | + |
| 109 | +def read_pkg_file(self, file): |
| 110 | + """Reads the metadata values from a file object.""" |
| 111 | + msg = message_from_file(file) |
85 | 112 |
|
86 | 113 | self.metadata_version = StrictVersion(msg['metadata-version'])
|
87 |
| - self.name = _read_field('name') |
88 |
| - self.version = _read_field('version') |
89 |
| - self.description = _read_field('summary') |
| 114 | + self.name = _read_field_from_msg(msg, 'name') |
| 115 | + self.version = _read_field_from_msg(msg, 'version') |
| 116 | + self.description = _read_field_from_msg(msg, 'summary') |
90 | 117 | # we are filling author only.
|
91 |
| - self.author = _read_field('author') |
| 118 | + self.author = _read_field_from_msg(msg, 'author') |
92 | 119 | self.maintainer = None
|
93 |
| - self.author_email = _read_field('author-email') |
| 120 | + self.author_email = _read_field_from_msg(msg, 'author-email') |
94 | 121 | self.maintainer_email = None
|
95 |
| - self.url = _read_field('home-page') |
96 |
| - self.license = _read_field('license') |
| 122 | + self.url = _read_field_from_msg(msg, 'home-page') |
| 123 | + self.license = _read_field_from_msg(msg, 'license') |
97 | 124 |
|
98 | 125 | if 'download-url' in msg:
|
99 |
| - self.download_url = _read_field('download-url') |
| 126 | + self.download_url = _read_field_from_msg(msg, 'download-url') |
100 | 127 | else:
|
101 | 128 | self.download_url = None
|
102 | 129 |
|
103 |
| - self.long_description = _read_field('description') |
104 |
| - self.description = _read_field('summary') |
| 130 | + self.long_description = _read_field_unescaped_from_msg(msg, 'description') |
| 131 | + self.description = _read_field_from_msg(msg, 'summary') |
105 | 132 |
|
106 | 133 | if 'keywords' in msg:
|
107 |
| - self.keywords = _read_field('keywords').split(',') |
| 134 | + self.keywords = _read_field_from_msg(msg, 'keywords').split(',') |
108 | 135 |
|
109 |
| - self.platforms = _read_list('platform') |
110 |
| - self.classifiers = _read_list('classifier') |
| 136 | + self.platforms = _read_list_from_msg(msg, 'platform') |
| 137 | + self.classifiers = _read_list_from_msg(msg, 'classifier') |
111 | 138 |
|
112 | 139 | # PEP 314 - these fields only exist in 1.1
|
113 | 140 | if self.metadata_version == StrictVersion('1.1'):
|
114 |
| - self.requires = _read_list('requires') |
115 |
| - self.provides = _read_list('provides') |
116 |
| - self.obsoletes = _read_list('obsoletes') |
| 141 | + self.requires = _read_list_from_msg(msg, 'requires') |
| 142 | + self.provides = _read_list_from_msg(msg, 'provides') |
| 143 | + self.obsoletes = _read_list_from_msg(msg, 'obsoletes') |
117 | 144 | else:
|
118 | 145 | self.requires = None
|
119 | 146 | self.provides = None
|
|
0 commit comments