1313from collections .abc import Mapping
1414from dataclasses import dataclass
1515from pathlib import Path
16- from typing import Annotated , Any , Final , NamedTuple , final
17- from typing_extensions import TypeGuard
16+ from typing import Annotated , Any , Final , NamedTuple , TypeGuard , cast , final
1817
1918if sys .version_info >= (3 , 11 ):
2019 import tomllib
@@ -239,27 +238,32 @@ def read_metadata(distribution: str) -> StubMetadata:
239238 """
240239 try :
241240 with metadata_path (distribution ).open ("rb" ) as f :
242- data = tomlkit .load (f )
241+ # This cast is necessary for pyright to understand that the
242+ # variable is a dict with object values. Just using
243+ # `data: dict[str, object] = tomlkit.load(f)` doesn't work because
244+ # pyright still infers TOMLDocument which derives from
245+ # dict[Unknown, Unknown].
246+ data = cast (dict [str , object ], tomlkit .load (f ))
243247 except FileNotFoundError :
244248 raise NoSuchStubError (f"Typeshed has no stubs for { distribution !r} !" ) from None
245249
246250 unknown_metadata_fields = data .keys () - _KNOWN_METADATA_FIELDS
247251 assert not unknown_metadata_fields , f"Unexpected keys in METADATA.toml for { distribution !r} : { unknown_metadata_fields } "
248252
249253 assert "version" in data , f"Missing 'version' field in METADATA.toml for { distribution !r} "
250- version : object = data .get ("version" ) # pyright: ignore[reportUnknownMemberType]
254+ version = data .get ("version" )
251255 assert isinstance (version , str ) and len (version ) > 0 , f"Invalid 'version' field in METADATA.toml for { distribution !r} "
252256 # Check that the version spec parses
253257 if version [0 ].isdigit ():
254258 version = f"=={ version } "
255259 version_spec = Specifier (version )
256260 assert version_spec .operator in {"==" , "~=" }, f"Invalid 'version' field in METADATA.toml for { distribution !r} "
257261
258- dependencies_s : object = data .get ("dependencies" , []) # pyright: ignore[reportUnknownMemberType]
262+ dependencies_s = data .get ("dependencies" , [])
259263 assert isinstance (dependencies_s , list )
260264 dependencies = [parse_dependencies (distribution , dep ) for dep in dependencies_s ]
261265
262- extra_description : object = data .get ("extra-description" ) # pyright: ignore[reportUnknownMemberType]
266+ extra_description = data .get ("extra-description" )
263267 assert isinstance (extra_description , (str , type (None )))
264268
265269 if "stub-distribution" in data :
@@ -269,7 +273,7 @@ def read_metadata(distribution: str) -> StubMetadata:
269273 else :
270274 stub_distribution = f"types-{ distribution } "
271275
272- upstream_repository : object = data .get ("upstream-repository" ) # pyright: ignore[reportUnknownMemberType]
276+ upstream_repository = data .get ("upstream-repository" )
273277 assert isinstance (upstream_repository , (str , type (None )))
274278 if isinstance (upstream_repository , str ):
275279 parsed_url = urllib .parse .urlsplit (upstream_repository )
@@ -293,7 +297,7 @@ def read_metadata(distribution: str) -> StubMetadata:
293297 )
294298 assert num_url_path_parts == 2 , bad_github_url_msg
295299
296- obsolete_since : object = data .get ("obsolete-since" ) # pyright: ignore[reportUnknownMemberType]
300+ obsolete_since = data .get ("obsolete-since" )
297301 assert isinstance (obsolete_since , (String , type (None )))
298302 if obsolete_since :
299303 comment = obsolete_since .trivia .comment
@@ -302,13 +306,13 @@ def read_metadata(distribution: str) -> StubMetadata:
302306 obsolete = ObsoleteMetadata (since_version = obsolete_since , since_date = since_date )
303307 else :
304308 obsolete = None
305- no_longer_updated : object = data .get ("no-longer-updated" , False ) # pyright: ignore[reportUnknownMemberType]
309+ no_longer_updated = data .get ("no-longer-updated" , False )
306310 assert type (no_longer_updated ) is bool
307- uploaded_to_pypi : object = data .get ("upload" , True ) # pyright: ignore[reportUnknownMemberType]
311+ uploaded_to_pypi = data .get ("upload" , True )
308312 assert type (uploaded_to_pypi ) is bool
309- partial_stub : object = data .get ("partial-stub" , True ) # pyright: ignore[reportUnknownMemberType]
313+ partial_stub = data .get ("partial-stub" , True )
310314 assert type (partial_stub ) is bool
311- requires_python_str : object = data .get ("requires-python" ) # pyright: ignore[reportUnknownMemberType]
315+ requires_python_str = data .get ("requires-python" )
312316 oldest_supported_python = get_oldest_supported_python ()
313317 oldest_supported_python_specifier = Specifier (f">={ oldest_supported_python } " )
314318 if requires_python_str is None :
@@ -324,11 +328,11 @@ def read_metadata(distribution: str) -> StubMetadata:
324328 assert requires_python .operator == ">=" , "'requires-python' should be a minimum version specifier, use '>=3.x'"
325329
326330 empty_tools : dict [object , object ] = {}
327- tools_settings : object = data .get ("tool" , empty_tools ) # pyright: ignore[reportUnknownMemberType]
331+ tools_settings = data .get ("tool" , empty_tools )
328332 assert isinstance (tools_settings , dict )
329333 assert tools_settings .keys () <= _KNOWN_METADATA_TOOL_FIELDS .keys (), f"Unrecognised tool for { distribution !r} "
330334 for tool , tk in _KNOWN_METADATA_TOOL_FIELDS .items ():
331- settings_for_tool : object = tools_settings .get (tool , {}) # pyright: ignore[reportUnknownMemberType]
335+ settings_for_tool = cast ( dict [ str , object ], tools_settings ) .get (tool , {})
332336 assert isinstance (settings_for_tool , dict )
333337 for key in settings_for_tool :
334338 assert key in tk , f"Unrecognised { tool } key { key !r} for { distribution !r} "
@@ -349,23 +353,28 @@ def read_metadata(distribution: str) -> StubMetadata:
349353 )
350354
351355
352- def update_metadata (distribution : str , ** new_values : object ) -> tomlkit . TOMLDocument :
356+ def update_metadata (distribution : str , ** new_values : object ) -> dict [ str , object ] :
353357 """Update a distribution's METADATA.toml.
354358
355359 Return the updated TOML dictionary for use without having to open the file separately.
356360 """
357361 path = metadata_path (distribution )
358362 try :
359- with path .open ("rb" ) as file :
360- data = tomlkit .load (file )
363+ with path .open ("rb" ) as f :
364+ # This cast is necessary for pyright to understand that the
365+ # variable is a dict with object values. Just using
366+ # `data: dict[str, object] = tomlkit.load(f)` doesn't work because
367+ # pyright still infers TOMLDocument which derives from
368+ # dict[Unknown, Unknown].
369+ data = cast (dict [str , object ], tomlkit .load (f ))
361370 except FileNotFoundError :
362371 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
372+ data .update (new_values )
364373 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
374+ new_key = key .replace ("_" , "-" )
375+ data [new_key ] = data .pop (key )
376+ with path .open ("w" , encoding = "UTF-8" ) as f :
377+ tomlkit .dump (data , f ) # pyright: ignore[reportUnknownMemberType] # tomlkit.dump has partially unknown Mapping type
369378 return data
370379
371380
0 commit comments