Skip to content

Commit ed637dd

Browse files
authored
Fix pyright errors when checking lib/ (#15681)
1 parent d28db09 commit ed637dd

3 files changed

Lines changed: 34 additions & 24 deletions

File tree

lib/ts_utils/metadata.py

Lines changed: 31 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
from collections.abc import Mapping
1414
from dataclasses import dataclass
1515
from pathlib import Path
16-
from typing import Annotated, Any, Final, NamedTuple, final
16+
from typing import Annotated, Any, Final, NamedTuple, cast, final
1717
from typing_extensions import TypeGuard
1818

1919
if sys.version_info >= (3, 11):
@@ -239,27 +239,32 @@ def read_metadata(distribution: str) -> StubMetadata:
239239
"""
240240
try:
241241
with metadata_path(distribution).open("rb") as f:
242-
data = tomlkit.load(f)
242+
# This cast is necessary for pyright to understand that the
243+
# variable is a dict with object values. Just using
244+
# `data: dict[str, object] = tomlkit.load(f)` doesn't work because
245+
# pyright still infers TOMLDocument which derives from
246+
# dict[Unknown, Unknown].
247+
data = cast(dict[str, object], tomlkit.load(f))
243248
except FileNotFoundError:
244249
raise NoSuchStubError(f"Typeshed has no stubs for {distribution!r}!") from None
245250

246251
unknown_metadata_fields = data.keys() - _KNOWN_METADATA_FIELDS
247252
assert not unknown_metadata_fields, f"Unexpected keys in METADATA.toml for {distribution!r}: {unknown_metadata_fields}"
248253

249254
assert "version" in data, f"Missing 'version' field in METADATA.toml for {distribution!r}"
250-
version: object = data.get("version") # pyright: ignore[reportUnknownMemberType]
255+
version = data.get("version")
251256
assert isinstance(version, str) and len(version) > 0, f"Invalid 'version' field in METADATA.toml for {distribution!r}"
252257
# Check that the version spec parses
253258
if version[0].isdigit():
254259
version = f"=={version}"
255260
version_spec = Specifier(version)
256261
assert version_spec.operator in {"==", "~="}, f"Invalid 'version' field in METADATA.toml for {distribution!r}"
257262

258-
dependencies_s: object = data.get("dependencies", []) # pyright: ignore[reportUnknownMemberType]
263+
dependencies_s = data.get("dependencies", [])
259264
assert isinstance(dependencies_s, list)
260265
dependencies = [parse_dependencies(distribution, dep) for dep in dependencies_s]
261266

262-
extra_description: object = data.get("extra-description") # pyright: ignore[reportUnknownMemberType]
267+
extra_description = data.get("extra-description")
263268
assert isinstance(extra_description, (str, type(None)))
264269

265270
if "stub-distribution" in data:
@@ -269,7 +274,7 @@ def read_metadata(distribution: str) -> StubMetadata:
269274
else:
270275
stub_distribution = f"types-{distribution}"
271276

272-
upstream_repository: object = data.get("upstream-repository") # pyright: ignore[reportUnknownMemberType]
277+
upstream_repository = data.get("upstream-repository")
273278
assert isinstance(upstream_repository, (str, type(None)))
274279
if isinstance(upstream_repository, str):
275280
parsed_url = urllib.parse.urlsplit(upstream_repository)
@@ -293,7 +298,7 @@ def read_metadata(distribution: str) -> StubMetadata:
293298
)
294299
assert num_url_path_parts == 2, bad_github_url_msg
295300

296-
obsolete_since: object = data.get("obsolete-since") # pyright: ignore[reportUnknownMemberType]
301+
obsolete_since = data.get("obsolete-since")
297302
assert isinstance(obsolete_since, (String, type(None)))
298303
if obsolete_since:
299304
comment = obsolete_since.trivia.comment
@@ -302,13 +307,13 @@ def read_metadata(distribution: str) -> StubMetadata:
302307
obsolete = ObsoleteMetadata(since_version=obsolete_since, since_date=since_date)
303308
else:
304309
obsolete = None
305-
no_longer_updated: object = data.get("no-longer-updated", False) # pyright: ignore[reportUnknownMemberType]
310+
no_longer_updated = data.get("no-longer-updated", False)
306311
assert type(no_longer_updated) is bool
307-
uploaded_to_pypi: object = data.get("upload", True) # pyright: ignore[reportUnknownMemberType]
312+
uploaded_to_pypi = data.get("upload", True)
308313
assert type(uploaded_to_pypi) is bool
309-
partial_stub: object = data.get("partial-stub", True) # pyright: ignore[reportUnknownMemberType]
314+
partial_stub = data.get("partial-stub", True)
310315
assert type(partial_stub) is bool
311-
requires_python_str: object = data.get("requires-python") # pyright: ignore[reportUnknownMemberType]
316+
requires_python_str = data.get("requires-python")
312317
oldest_supported_python = get_oldest_supported_python()
313318
oldest_supported_python_specifier = Specifier(f">={oldest_supported_python}")
314319
if requires_python_str is None:
@@ -324,11 +329,11 @@ def read_metadata(distribution: str) -> StubMetadata:
324329
assert requires_python.operator == ">=", "'requires-python' should be a minimum version specifier, use '>=3.x'"
325330

326331
empty_tools: dict[object, object] = {}
327-
tools_settings: object = data.get("tool", empty_tools) # pyright: ignore[reportUnknownMemberType]
332+
tools_settings = data.get("tool", empty_tools)
328333
assert isinstance(tools_settings, dict)
329334
assert tools_settings.keys() <= _KNOWN_METADATA_TOOL_FIELDS.keys(), f"Unrecognised tool for {distribution!r}"
330335
for tool, tk in _KNOWN_METADATA_TOOL_FIELDS.items():
331-
settings_for_tool: object = tools_settings.get(tool, {}) # pyright: ignore[reportUnknownMemberType]
336+
settings_for_tool = cast(dict[str, object], tools_settings).get(tool, {})
332337
assert isinstance(settings_for_tool, dict)
333338
for key in settings_for_tool:
334339
assert key in tk, f"Unrecognised {tool} key {key!r} for {distribution!r}"
@@ -349,23 +354,28 @@ def read_metadata(distribution: str) -> StubMetadata:
349354
)
350355

351356

352-
def update_metadata(distribution: str, **new_values: object) -> tomlkit.TOMLDocument:
357+
def update_metadata(distribution: str, **new_values: object) -> dict[str, object]:
353358
"""Update a distribution's METADATA.toml.
354359
355360
Return the updated TOML dictionary for use without having to open the file separately.
356361
"""
357362
path = metadata_path(distribution)
358363
try:
359-
with path.open("rb") as file:
360-
data = tomlkit.load(file)
364+
with path.open("rb") as f:
365+
# This cast is necessary for pyright to understand that the
366+
# variable is a dict with object values. Just using
367+
# `data: dict[str, object] = tomlkit.load(f)` doesn't work because
368+
# pyright still infers TOMLDocument which derives from
369+
# dict[Unknown, Unknown].
370+
data = cast(dict[str, object], tomlkit.load(f))
361371
except FileNotFoundError:
362372
raise NoSuchStubError(f"Typeshed has no stubs for {distribution!r}!") from None
363-
data.update(new_values) # pyright: ignore[reportUnknownMemberType] # tomlkit.TOMLDocument.update is partially typed
373+
data.update(new_values)
364374
for key in list(data.keys()):
365-
new_key = key.replace("_", "-") # pyright: ignore[reportUnknownMemberType] # tomlkit.TOMLDocument.keys is partially typed
366-
data[new_key] = data.pop(key) # pyright: ignore[reportUnknownMemberType] # tomlkit.TOMLDocument.pop is partially typed
367-
with path.open("w", encoding="UTF-8") as file:
368-
tomlkit.dump(data, file) # pyright: ignore[reportUnknownMemberType] # tomlkit.dump has partially unknown Mapping type
375+
new_key = key.replace("_", "-")
376+
data[new_key] = data.pop(key)
377+
with path.open("w", encoding="UTF-8") as f:
378+
tomlkit.dump(data, f) # pyright: ignore[reportUnknownMemberType] # tomlkit.dump has partially unknown Mapping type
369379
return data
370380

371381

lib/ts_utils/utils.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -261,12 +261,12 @@ def close(self: TemporaryFileWrapper[str]) -> None:
261261

262262

263263
@functools.cache
264-
def get_gitignore_spec() -> pathspec.PathSpec:
264+
def get_gitignore_spec() -> pathspec.GitIgnoreSpec:
265265
with GITIGNORE_PATH.open(encoding="UTF-8") as f:
266266
return pathspec.GitIgnoreSpec.from_lines(f)
267267

268268

269-
def spec_matches_path(spec: pathspec.PathSpec, path: Path) -> bool:
269+
def spec_matches_path(spec: pathspec.PathSpec[Any], path: Path) -> bool:
270270
normalized_path = path.as_posix()
271271
if path.is_dir():
272272
normalized_path += "/"

requirements-tests.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ aiohttp==3.13.5
88
grpcio-tools>=1.76.0 # For grpc_tools.protoc
99
mypy-protobuf==5.0.0
1010
packaging==26.0
11-
pathspec>=1.0.3
11+
pathspec>=1.1.1
1212
pre-commit
1313
# Required by create_baseline_stubs.py. Must match .pre-commit-config.yaml.
1414
ruff==0.15.8

0 commit comments

Comments
 (0)