tessl install tessl/pypi-typeshed-client@2.8.4A library for accessing stubs in typeshed.
A comprehensive Python library for retrieving and analyzing type stub information from typeshed (Python's repository of type stubs for the standard library and third-party packages) and PEP 561 stub packages. It enables developers to programmatically find stub file paths for specific modules, collect and parse names defined in stubs with their AST representations, and resolve fully qualified names to their definitions across multiple stub files.
pip install typeshed_clientimport typeshed_clientCommon imports for finding stubs:
from typeshed_client import (
get_stub_file,
get_stub_ast,
get_stub_names,
get_search_context,
SearchContext,
)For name resolution:
from typeshed_client import ResolverFor working with parsed names:
from typeshed_client import (
NameInfo,
NameDict,
ImportedName,
OverloadedName,
)Additional useful imports:
from typeshed_client import (
ModulePath,
PythonVersion,
ResolvedName,
ImportedInfo,
Module,
)For exception handling:
from typeshed_client.parser import InvalidStubFor advanced operations:
from typeshed_client.finder import (
find_typeshed,
parse_stub_file,
safe_exists,
safe_is_dir,
safe_is_file,
)from typeshed_client.parser import (
parse_ast,
get_import_star_names,
get_dunder_all_from_info,
)| Function | Purpose | Returns None? |
|---|---|---|
get_stub_file(module_name) | Find path to stub file | Yes, if not found |
get_stub_ast(module_name) | Get parsed AST of stub | Yes, if not found |
get_stub_names(module_name) | Get all names in stub | Yes, if not found |
get_search_context(...) | Create configuration | Never |
Resolver() | Create name resolver | Never |
| Type | Description |
|---|---|
SearchContext | Configuration for stub finding |
NameDict | dict[str, NameInfo] mapping names to info |
NameInfo | Information about a name (AST, export status) |
ImportedName | Represents imported name |
OverloadedName | Function with multiple overloads |
ResolvedName | Union[ModulePath, ImportedInfo, NameInfo, None] |
from typeshed_client import get_stub_file, get_stub_names, Resolver
# Find the path to a module's stub file
stub_path = get_stub_file('typing')
if stub_path:
print(f"Found: {stub_path}")
# Get all names defined in a module
names = get_stub_names('collections')
if names:
exported = [name for name, info in names.items() if info.is_exported]
print(f"Exported names: {exported[:5]}")
# Resolve a fully qualified name to its definition
resolver = Resolver()
result = resolver.get_fully_qualified_name('collections.OrderedDict')
if result:
print(f"Resolved: {type(result).__name__}")The library consists of three main components:
Finder Module: Locates stub files following PEP 561 resolution order
Parser Module: Parses stub ASTs into structured name dictionaries
Resolver Module: Resolves names across module boundaries
Locate stub files for Python modules with support for typeshed, PEP 561 stub packages, and inline stubs.
def get_stub_file(module_name: str, *, search_context: Optional[SearchContext] = None) -> Optional[Path]: ...def get_stub_ast(module_name: str, *, search_context: Optional[SearchContext] = None) -> Optional[ast.Module]: ...def get_all_stub_files(search_context: Optional[SearchContext] = None) -> Iterable[tuple[str, Path]]: ...Parse stub files into structured dictionaries mapping names to AST nodes with export information.
def get_stub_names(module_name: str, *, search_context: Optional[SearchContext] = None) -> Optional[NameDict]: ...def parse_ast(ast: ast.AST, search_context: SearchContext, module_name: ModulePath, *, is_init: bool = False) -> NameDict: ...Resolve fully qualified names across module boundaries, following imports to find original definitions.
class Resolver:
def __init__(self, search_context: Optional[SearchContext] = None) -> None: ...
def get_fully_qualified_name(self, name: str) -> ResolvedName: ...
def get_name(self, module_name: ModulePath, name: str) -> ResolvedName: ...
def get_module(self, module_name: ModulePath) -> Module: ...Configure stub finding behavior with custom typeshed paths, search paths, Python versions, and platform settings.
def get_search_context(
*,
typeshed: Optional[Path] = None,
search_path: Optional[Sequence[Path]] = None,
version: Optional[PythonVersion] = None,
platform: str = sys.platform,
raise_on_warnings: bool = False,
allow_py_files: bool = False
) -> SearchContext: ...Always check functions that return Optional types:
# CORRECT
stub_path = get_stub_file('module')
if stub_path is None:
print("Module not found")
else:
print(f"Found: {stub_path}")
# INCORRECT - may crash
stub_path = get_stub_file('module')
with open(stub_path) as f: # TypeError if None
content = f.read()Use isinstance() to determine resolved name type:
result = resolver.get_fully_qualified_name('collections.OrderedDict')
if result is None:
print("Not found")
elif isinstance(result, ModulePath):
print("It's a module")
elif isinstance(result, ImportedInfo):
print(f"Imported from {'.'.join(result.source_module)}")
elif isinstance(result, NameInfo):
print("Defined directly")Cache resolvers for performance:
# CORRECT - reuse resolver
resolver = Resolver()
for name in ['typing.List', 'typing.Dict', 'typing.Set']:
result = resolver.get_fully_qualified_name(name)
# INCORRECT - creates new resolver each time
for name in ['typing.List', 'typing.Dict', 'typing.Set']:
resolver = Resolver() # Wasteful
result = resolver.get_fully_qualified_name(name)Compare stubs across Python versions:
from typeshed_client import get_search_context, get_stub_names
versions = [(3, 9), (3, 10), (3, 11)]
for version in versions:
ctx = get_search_context(version=version)
names = get_stub_names('typing', search_context=ctx)
if names:
print(f"Python {version}: {len(names)} names")Information about a name defined in a stub:
class NameInfo(NamedTuple):
name: str
is_exported: bool
ast: Union[ast.AST, ImportedName, OverloadedName]
child_nodes: Optional[NameDict] = None_ or in __all__)Represents a name imported from another module:
class ImportedName(NamedTuple):
module_name: ModulePath
name: Optional[str] = NoneConfiguration for stub operations:
class SearchContext(NamedTuple):
typeshed: Path
search_path: Sequence[Path]
version: PythonVersion
platform: str
raise_on_warnings: bool = False
allow_py_files: bool = FalseRaised for parsing errors or warnings (when raise_on_warnings=True):
class InvalidStub(Exception):
def __init__(self, message: str, file_path: Optional[Path] = None) -> None: ...Usage:
from typeshed_client.parser import InvalidStub
ctx = get_search_context(raise_on_warnings=True)
try:
names = get_stub_names('module', search_context=ctx)
except InvalidStub as e:
print(f"Parsing error: {e}")get_stub_file() return None when module not foundisinstance() for union types like ResolvedNamesafe_exists(), safe_is_file() over direct path operationsraise_on_warnings=TrueStep-by-step instructions for common tasks:
Real-world scenarios and use cases:
Detailed specifications and comprehensive documentation:
__version__: str # Current version: "2.8.2"