Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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
Expand Down
17 changes: 16 additions & 1 deletion lib/ts_utils/metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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",
Expand Down Expand Up @@ -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)))

Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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]
Expand Down