Mercurial > repos > guerler > hhblits
comparison lib/python3.8/site-packages/wheel/metadata.py @ 0:9e54283cc701 draft
"planemo upload commit d12c32a45bcd441307e632fca6d9af7d60289d44"
| author | guerler |
|---|---|
| date | Mon, 27 Jul 2020 03:47:31 -0400 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| -1:000000000000 | 0:9e54283cc701 |
|---|---|
| 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 |
