mirror of
https://github.com/davidhalter/typeshed.git
synced 2025-12-22 03:41:28 +08:00
Pass Requirement objects around (#12709)
This allows us to keep metadata like python_version and platform_system and use it to conditionally install packages.
This commit is contained in:
@@ -131,7 +131,7 @@ class StubMetadata:
|
||||
"""
|
||||
|
||||
version: str
|
||||
requires: Annotated[list[str], "The raw requirements as listed in METADATA.toml"]
|
||||
requires: Annotated[list[Requirement], "The parsed requirements as listed in METADATA.toml"]
|
||||
extra_description: str | None
|
||||
stub_distribution: Annotated[str, "The name under which the distribution is uploaded to PyPI"]
|
||||
upstream_repository: Annotated[str, "The URL of the upstream repository"] | None
|
||||
@@ -201,14 +201,9 @@ def read_metadata(distribution: str) -> StubMetadata:
|
||||
# Check that the version parses
|
||||
Version(version[:-2] if version.endswith(".*") else version)
|
||||
|
||||
requires: object = data.get("requires", [])
|
||||
assert isinstance(requires, list)
|
||||
for req in requires:
|
||||
assert isinstance(req, str), f"Invalid requirement {req!r} for {distribution!r}"
|
||||
for space in " \t\n":
|
||||
assert space not in req, f"For consistency, requirement should not have whitespace: {req!r}"
|
||||
# Check that the requirement parses
|
||||
Requirement(req)
|
||||
requires_s: object = data.get("requires", [])
|
||||
assert isinstance(requires_s, list)
|
||||
requires = [parse_requires(distribution, req) for req in requires_s]
|
||||
|
||||
extra_description: object = data.get("extra_description")
|
||||
assert isinstance(extra_description, (str, type(None)))
|
||||
@@ -292,9 +287,16 @@ def read_metadata(distribution: str) -> StubMetadata:
|
||||
)
|
||||
|
||||
|
||||
def parse_requires(distribution: str, req: object) -> Requirement:
|
||||
assert isinstance(req, str), f"Invalid requirement {req!r} for {distribution!r}"
|
||||
for space in " \t\n":
|
||||
assert space not in req, f"For consistency, requirement should not have whitespace: {req!r}"
|
||||
return Requirement(req)
|
||||
|
||||
|
||||
class PackageDependencies(NamedTuple):
|
||||
typeshed_pkgs: tuple[str, ...]
|
||||
external_pkgs: tuple[str, ...]
|
||||
typeshed_pkgs: tuple[Requirement, ...]
|
||||
external_pkgs: tuple[Requirement, ...]
|
||||
|
||||
|
||||
@cache
|
||||
@@ -317,17 +319,15 @@ def read_dependencies(distribution: str) -> PackageDependencies:
|
||||
If a typeshed stub is removed, this function will consider it to be an external dependency.
|
||||
"""
|
||||
pypi_name_to_typeshed_name_mapping = get_pypi_name_to_typeshed_name_mapping()
|
||||
typeshed: list[str] = []
|
||||
external: list[str] = []
|
||||
typeshed: list[Requirement] = []
|
||||
external: list[Requirement] = []
|
||||
for dependency in read_metadata(distribution).requires:
|
||||
maybe_typeshed_dependency = Requirement(dependency).name
|
||||
if maybe_typeshed_dependency in pypi_name_to_typeshed_name_mapping:
|
||||
typeshed.append(pypi_name_to_typeshed_name_mapping[maybe_typeshed_dependency])
|
||||
if dependency.name in pypi_name_to_typeshed_name_mapping:
|
||||
req = Requirement(str(dependency)) # copy the requirement
|
||||
req.name = pypi_name_to_typeshed_name_mapping[dependency.name]
|
||||
typeshed.append(req)
|
||||
else:
|
||||
# convert to Requirement and then back to str
|
||||
# to make sure that the requirements all have a normalised string representation
|
||||
# (This will also catch any malformed requirements early)
|
||||
external.append(str(Requirement(dependency)))
|
||||
external.append(dependency)
|
||||
return PackageDependencies(tuple(typeshed), tuple(external))
|
||||
|
||||
|
||||
@@ -341,13 +341,13 @@ def get_recursive_requirements(package_name: str) -> PackageDependencies:
|
||||
`get_recursive_requirements("caldav")` will determine that the stubs for `caldav`
|
||||
have both `requests` and `urllib3` as typeshed-internal dependencies.
|
||||
"""
|
||||
typeshed: set[str] = set()
|
||||
external: set[str] = set()
|
||||
typeshed: set[Requirement] = set()
|
||||
external: set[Requirement] = set()
|
||||
non_recursive_requirements = read_dependencies(package_name)
|
||||
typeshed.update(non_recursive_requirements.typeshed_pkgs)
|
||||
external.update(non_recursive_requirements.external_pkgs)
|
||||
for pkg in non_recursive_requirements.typeshed_pkgs:
|
||||
reqs = get_recursive_requirements(pkg)
|
||||
reqs = get_recursive_requirements(pkg.name)
|
||||
typeshed.update(reqs.typeshed_pkgs)
|
||||
external.update(reqs.external_pkgs)
|
||||
return PackageDependencies(tuple(sorted(typeshed)), tuple(sorted(external)))
|
||||
return PackageDependencies(tuple(typeshed), tuple(external))
|
||||
|
||||
Reference in New Issue
Block a user