From 86b982faf09bac7ec072d94352fc781269baa9ff Mon Sep 17 00:00:00 2001 From: Sebastian Rittau Date: Thu, 7 May 2026 15:31:03 +0200 Subject: [PATCH 1/2] Support optional-dependencies for third party packages Part of #15549 --- CONTRIBUTING.md | 7 ++++++- lib/ts_utils/metadata.py | 17 ++++++++++++++++- stubs/Authlib/@tests/stubtest_allowlist.txt | 1 - stubs/Authlib/METADATA.toml | 1 + 4 files changed, 23 insertions(+), 3 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f8263498c4da..f8f4809825b3 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -169,6 +169,10 @@ supported: be listed here, for security reasons. See [this issue](https://github.com/typeshed-internal/stub_uploader/issues/90) for more information about what external dependencies are allowed. +* `optional-dependencies` (optional): A list of other stub packages or packages + with type information that are imported by some stubs in this package. This + is often used for packages that provide optional features that require extra + dependencies. The same limitations apply to this field as to `dependencies`. * `extra-description` (optional): Can be used to add a custom description to the package's long description. It should be a multi-line string in Markdown format. @@ -204,7 +208,8 @@ This has the following keys: this field should be identical to `partial-stub`. * `stubtest-dependencies` (default: `[]`): A list of Python packages that need to be installed for stubtest to run successfully. These packages are installed - in addition to the dependencies in the `dependencies` field. + in addition to the dependencies in the `dependencies` and + `optional-dependencies` fields. * `apt-dependencies` (default: `[]`): A list of Ubuntu APT packages that need to be installed for stubtest to run successfully. * `brew-dependencies` (default: `[]`): A list of MacOS Homebrew packages diff --git a/lib/ts_utils/metadata.py b/lib/ts_utils/metadata.py index 4243129b64a7..0135077164ce 100644 --- a/lib/ts_utils/metadata.py +++ b/lib/ts_utils/metadata.py @@ -175,6 +175,7 @@ class StubMetadata: distribution: Annotated[str, "The name of the distribution on PyPI"] version_spec: Annotated[Specifier, "Upstream versions that the stubs are compatible with"] dependencies: Annotated[list[Requirement], "The parsed dependencies as listed in METADATA.toml"] + optional_dependencies: Annotated[list[Requirement], "The parsed optional dependencies 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 @@ -189,11 +190,20 @@ class StubMetadata: def is_obsolete(self) -> bool: return self.obsolete is not None + @property + def all_dependencies(self) -> list[Requirement]: + """The dependencies and optional dependencies of this stubs package. + + Does not include the stubtest dependencies. + """ + return self.dependencies + self.optional_dependencies + _KNOWN_METADATA_FIELDS: Final = frozenset( { "version", "dependencies", + "optional-dependencies", "extra-description", "stub-distribution", "upstream-repository", @@ -264,6 +274,10 @@ def read_metadata(distribution: str) -> StubMetadata: assert isinstance(dependencies_s, list) dependencies = [parse_dependencies(distribution, dep) for dep in dependencies_s] + optional_dependencies_s = data.get("optional-dependencies", []) + assert isinstance(optional_dependencies_s, list) + optional_dependencies = [parse_dependencies(distribution, dep) for dep in optional_dependencies_s] + extra_description = data.get("extra-description") assert isinstance(extra_description, (str, type(None))) @@ -342,6 +356,7 @@ def read_metadata(distribution: str) -> StubMetadata: distribution=distribution, version_spec=version_spec, dependencies=dependencies, + optional_dependencies=optional_dependencies, extra_description=extra_description, stub_distribution=stub_distribution, upstream_repository=upstream_repository, @@ -411,7 +426,7 @@ def read_dependencies(distribution: str) -> PackageDependencies: pypi_name_to_typeshed_name_mapping = get_pypi_name_to_typeshed_name_mapping() typeshed: list[Requirement] = [] external: list[Requirement] = [] - for dependency in read_metadata(distribution).dependencies: + for dependency in read_metadata(distribution).all_dependencies: 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] diff --git a/stubs/Authlib/@tests/stubtest_allowlist.txt b/stubs/Authlib/@tests/stubtest_allowlist.txt index 42440a12d667..0bffd44ab229 100644 --- a/stubs/Authlib/@tests/stubtest_allowlist.txt +++ b/stubs/Authlib/@tests/stubtest_allowlist.txt @@ -49,6 +49,5 @@ authlib.integrations.flask_client.* authlib.integrations.flask_oauth1.* authlib.integrations.flask_oauth2.* authlib.integrations.httpx_client.* -authlib.integrations.requests_client.* authlib.integrations.sqla_oauth2.* authlib.integrations.starlette_client.* diff --git a/stubs/Authlib/METADATA.toml b/stubs/Authlib/METADATA.toml index 5c2a9e76e1ed..5c334ea03dc7 100644 --- a/stubs/Authlib/METADATA.toml +++ b/stubs/Authlib/METADATA.toml @@ -1,3 +1,4 @@ version = "1.6.11" upstream-repository = "https://github.com/authlib/authlib" dependencies = ["cryptography"] +optional-dependencies = ["requests"] From 1e39c251694fe575216a5571b8661362cba6ba27 Mon Sep 17 00:00:00 2001 From: Sebastian Rittau Date: Thu, 7 May 2026 16:18:00 +0200 Subject: [PATCH 2/2] Revert Authlib changes --- stubs/Authlib/@tests/stubtest_allowlist.txt | 1 + stubs/Authlib/METADATA.toml | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/stubs/Authlib/@tests/stubtest_allowlist.txt b/stubs/Authlib/@tests/stubtest_allowlist.txt index 0bffd44ab229..42440a12d667 100644 --- a/stubs/Authlib/@tests/stubtest_allowlist.txt +++ b/stubs/Authlib/@tests/stubtest_allowlist.txt @@ -49,5 +49,6 @@ authlib.integrations.flask_client.* authlib.integrations.flask_oauth1.* authlib.integrations.flask_oauth2.* authlib.integrations.httpx_client.* +authlib.integrations.requests_client.* authlib.integrations.sqla_oauth2.* authlib.integrations.starlette_client.* diff --git a/stubs/Authlib/METADATA.toml b/stubs/Authlib/METADATA.toml index 5c334ea03dc7..5c2a9e76e1ed 100644 --- a/stubs/Authlib/METADATA.toml +++ b/stubs/Authlib/METADATA.toml @@ -1,4 +1,3 @@ version = "1.6.11" upstream-repository = "https://github.com/authlib/authlib" dependencies = ["cryptography"] -optional-dependencies = ["requests"]