Mercurial > repos > guerler > hhblits
comparison lib/python3.8/site-packages/wheel/metadata.py @ 1:64071f2a4cf0 draft default tip
Deleted selected files
author | guerler |
---|---|
date | Mon, 27 Jul 2020 03:55:49 -0400 |
parents | 9e54283cc701 |
children |
comparison
equal
deleted
inserted
replaced
0:9e54283cc701 | 1:64071f2a4cf0 |
---|---|
1 """ | |
2 Tools for converting old- to new-style metadata. | |
3 """ | |
4 | |
5 import os.path | |
6 import re | |
7 import textwrap | |
8 | |
9 import pkg_resources | |
10 | |
11 from .pkginfo import read_pkg_info | |
12 | |
13 # Support markers syntax with the extra at the end only | |
14 EXTRA_RE = re.compile( | |
15 r"""^(?P<package>.*?)(;\s*(?P<condition>.*?)(extra == '(?P<extra>.*?)')?)$""") | |
16 | |
17 | |
18 def requires_to_requires_dist(requirement): | |
19 """Return the version specifier for a requirement in PEP 345/566 fashion.""" | |
20 if getattr(requirement, 'url', None): | |
21 return " @ " + requirement.url | |
22 | |
23 requires_dist = [] | |
24 for op, ver in requirement.specs: | |
25 requires_dist.append(op + ver) | |
26 if not requires_dist: | |
27 return '' | |
28 return " (%s)" % ','.join(sorted(requires_dist)) | |
29 | |
30 | |
31 def convert_requirements(requirements): | |
32 """Yield Requires-Dist: strings for parsed requirements strings.""" | |
33 for req in requirements: | |
34 parsed_requirement = pkg_resources.Requirement.parse(req) | |
35 spec = requires_to_requires_dist(parsed_requirement) | |
36 extras = ",".join(sorted(parsed_requirement.extras)) | |
37 if extras: | |
38 extras = "[%s]" % extras | |
39 yield (parsed_requirement.project_name + extras + spec) | |
40 | |
41 | |
42 def generate_requirements(extras_require): | |
43 """ | |
44 Convert requirements from a setup()-style dictionary to ('Requires-Dist', 'requirement') | |
45 and ('Provides-Extra', 'extra') tuples. | |
46 | |
47 extras_require is a dictionary of {extra: [requirements]} as passed to setup(), | |
48 using the empty extra {'': [requirements]} to hold install_requires. | |
49 """ | |
50 for extra, depends in extras_require.items(): | |
51 condition = '' | |
52 extra = extra or '' | |
53 if ':' in extra: # setuptools extra:condition syntax | |
54 extra, condition = extra.split(':', 1) | |
55 | |
56 extra = pkg_resources.safe_extra(extra) | |
57 if extra: | |
58 yield 'Provides-Extra', extra | |
59 if condition: | |
60 condition = "(" + condition + ") and " | |
61 condition += "extra == '%s'" % extra | |
62 | |
63 if condition: | |
64 condition = ' ; ' + condition | |
65 | |
66 for new_req in convert_requirements(depends): | |
67 yield 'Requires-Dist', new_req + condition | |
68 | |
69 | |
70 def pkginfo_to_metadata(egg_info_path, pkginfo_path): | |
71 """ | |
72 Convert .egg-info directory with PKG-INFO to the Metadata 2.1 format | |
73 """ | |
74 pkg_info = read_pkg_info(pkginfo_path) | |
75 pkg_info.replace_header('Metadata-Version', '2.1') | |
76 # Those will be regenerated from `requires.txt`. | |
77 del pkg_info['Provides-Extra'] | |
78 del pkg_info['Requires-Dist'] | |
79 requires_path = os.path.join(egg_info_path, 'requires.txt') | |
80 if os.path.exists(requires_path): | |
81 with open(requires_path) as requires_file: | |
82 requires = requires_file.read() | |
83 | |
84 parsed_requirements = sorted(pkg_resources.split_sections(requires), | |
85 key=lambda x: x[0] or '') | |
86 for extra, reqs in parsed_requirements: | |
87 for key, value in generate_requirements({extra: reqs}): | |
88 if (key, value) not in pkg_info.items(): | |
89 pkg_info[key] = value | |
90 | |
91 description = pkg_info['Description'] | |
92 if description: | |
93 pkg_info.set_payload(dedent_description(pkg_info)) | |
94 del pkg_info['Description'] | |
95 | |
96 return pkg_info | |
97 | |
98 | |
99 def pkginfo_unicode(pkg_info, field): | |
100 """Hack to coax Unicode out of an email Message() - Python 3.3+""" | |
101 text = pkg_info[field] | |
102 field = field.lower() | |
103 if not isinstance(text, str): | |
104 for item in pkg_info.raw_items(): | |
105 if item[0].lower() == field: | |
106 text = item[1].encode('ascii', 'surrogateescape') \ | |
107 .decode('utf-8') | |
108 break | |
109 | |
110 return text | |
111 | |
112 | |
113 def dedent_description(pkg_info): | |
114 """ | |
115 Dedent and convert pkg_info['Description'] to Unicode. | |
116 """ | |
117 description = pkg_info['Description'] | |
118 | |
119 # Python 3 Unicode handling, sorta. | |
120 surrogates = False | |
121 if not isinstance(description, str): | |
122 surrogates = True | |
123 description = pkginfo_unicode(pkg_info, 'Description') | |
124 | |
125 description_lines = description.splitlines() | |
126 description_dedent = '\n'.join( | |
127 # if the first line of long_description is blank, | |
128 # the first line here will be indented. | |
129 (description_lines[0].lstrip(), | |
130 textwrap.dedent('\n'.join(description_lines[1:])), | |
131 '\n')) | |
132 | |
133 if surrogates: | |
134 description_dedent = description_dedent \ | |
135 .encode("utf8") \ | |
136 .decode("ascii", "surrogateescape") | |
137 | |
138 return description_dedent |