def split_sections(s): """Split a string or iterable thereof into (section, content) pairs
Each ``section`` is a stripped version of the section header ("[section]") and each ``content`` is a list of stripped lines excluding blank lines and
comment-only lines. If there are any such lines before the first section
header, they're returned in a first ``section`` of ``None``. """
section = None
content = [] for line in yield_lines(s): if line.startswith("["): if line.endswith("]"): if section or content: yield section, content
section = line[1:-1].strip()
content = [] else: raise ValueError("Invalid section heading", line) else:
content.append(line)
# wrap up last segment yield section, content
def safe_extra(extra): """Convert an arbitrary string to a standard 'extra' name
Any runs of non-alphanumeric characters are replaced with a single '_', and the result is always lowercased. """ return re.sub("[^A-Za-z0-9.-]+", "_", extra).lower()
def safe_name(name): """Convert an arbitrary string to a standard distribution name
Any runs of non-alphanumeric/. characters are replaced with a single '-'. """ return re.sub("[^A-Za-z0-9.]+", "-", name)
def requires_to_requires_dist(requirement: Requirement) -> str: """Return the version specifier for a requirement in PEP 345/566 fashion.""" if getattr(requirement, "url", None): return" @ " + requirement.url
requires_dist = [] for spec in requirement.specifier:
requires_dist.append(spec.operator + spec.version)
if requires_dist: return" " + ",".join(sorted(requires_dist)) else: return""
def convert_requirements(requirements: list[str]) -> Iterator[str]: """Yield Requires-Dist: strings for parsed requirements strings.""" for req in requirements:
parsed_requirement = Requirement(req)
spec = requires_to_requires_dist(parsed_requirement)
extras = ",".join(sorted(safe_extra(e) for e in parsed_requirement.extras)) if extras:
extras = f"[{extras}]"
def generate_requirements(
extras_require: dict[str, list[str]],
) -> Iterator[tuple[str, str]]: """
Convert requirements from a setup()-style dictionary to
('Requires-Dist', 'requirement') and ('Provides-Extra', 'extra') tuples.
extras_require is a dictionary of {extra: [requirements]} as passed to setup(),
using the empty extra {'': [requirements]} to hold install_requires. """ for extra, depends in extras_require.items():
condition = ""
extra = extra or"" if":"in extra: # setuptools extra:condition syntax
extra, condition = extra.split(":", 1)
extra = safe_extra(extra) if extra: yield"Provides-Extra", extra if condition:
condition = "(" + condition + ") and "
condition += "extra == '%s'" % extra
if condition:
condition = " ; " + condition
for new_req in convert_requirements(depends): yield"Requires-Dist", new_req + condition
def pkginfo_to_metadata(egg_info_path: str, pkginfo_path: str) -> Message: """
Convert .egg-info directory with PKG-INFO to the Metadata 2.1 format """ with open(pkginfo_path, encoding="utf-8") as headers:
pkg_info = Parser().parse(headers)
pkg_info.replace_header("Metadata-Version", "2.1") # Those will be regenerated from `requires.txt`. del pkg_info["Provides-Extra"] del pkg_info["Requires-Dist"]
requires_path = os.path.join(egg_info_path, "requires.txt") if os.path.exists(requires_path): with open(requires_path, encoding="utf-8") as requires_file:
requires = requires_file.read()
parsed_requirements = sorted(split_sections(requires), key=lambda x: x[0] or"") for extra, reqs in parsed_requirements: for key, value in generate_requirements({extra: reqs}): if (key, value) notin pkg_info.items():
pkg_info[key] = value
description = pkg_info["Description"] if description:
description_lines = pkg_info["Description"].splitlines()
dedented_description = "\n".join( # if the first line of long_description is blank, # the first line here will be indented.
(
description_lines[0].lstrip(),
textwrap.dedent("\n".join(description_lines[1:])), "\n",
)
)
pkg_info.set_payload(dedented_description) del pkg_info["Description"]
return pkg_info
Messung V0.5
¤ Dauer der Verarbeitung: 0.12 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.