From ea37877558cff33a718bd1cd71a8162fb5687b9b Mon Sep 17 00:00:00 2001 From: Jakub Stasiak Date: Thu, 10 Mar 2016 00:31:17 +0100 Subject: [PATCH] Improve Python 3 inspect stub This is follow-up to a similar commit improving Python 2.7 inspect stub[1]. Similarly, this commit consists of: * Splitting and reordering the content into sections corresponding to the module's documentation sections * Implementing missing functions, classes etc. * Adding TODOs for things that are either difficult to get or I can't figure them out right now * Making the existing code consistent with the newly added things As suggested in pull request #108 I'm modifying the generic Python 3 stub even though some things changed and were added in various Python 3.x releases - the changes seem to be backwards compatible and the additions, well, they should not break much except for some false positives on older Python 3 versions. Some of the types in this stub were not obvious so I either read the source code or used my judgment. [1] 630f7183762c96833a306629289c7e9e67cdce27 --- stdlib/3/inspect.pyi | 273 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 259 insertions(+), 14 deletions(-) diff --git a/stdlib/3/inspect.pyi b/stdlib/3/inspect.pyi index abbc7f6d3..fa751759a 100644 --- a/stdlib/3/inspect.pyi +++ b/stdlib/3/inspect.pyi @@ -1,26 +1,146 @@ # Stubs for inspect -from typing import Any, Tuple, List, Dict, Callable, NamedTuple -from types import FrameType +from typing import (AbstractSet, Any, Tuple, List, Dict, Callable, Generator, + Mapping, MutableMapping, NamedTuple, Optional, Sequence, Union, + ) +from types import FrameType, ModuleType, TracebackType -_object = object +# +# Types and members +# +ModuleInfo = NamedTuple('ModuleInfo', [('name', str), + ('suffix', str), + ('mode', str), + ('module_type', int), + ]) +def getmembers(object: object, + predicate: Callable[[Any], bool] = ..., + ) -> List[Tuple[str, object]]: ... +def getmoduleinfo(path: str) -> Optional[ModuleInfo]: ... +def getmodulename(path: str) -> Optional[str]: ... -def getmembers(obj: object, predicate: Callable[[Any], bool]) -> List[Tuple[str, object]]: ... +def ismodule(object: object) -> bool: ... +def isclass(object: object) -> bool: ... +def ismethod(object: object) -> bool: ... +def isfunction(object: object) -> bool: ... +def isisgeneratorfunction(object: object) -> bool: ... +def isgenerator(object: object) -> bool: ... -def isclass(obj: object) -> bool: ... +# Python 3.5+ +def iscoroutinefunction(object: object) -> bool: ... +def iscoroutine(object: object) -> bool: ... +def isawaitable(object: object) -> bool: ... -# namedtuple('Attribute', 'name kind defining_class object') -class Attribute(tuple): - name = ... # type: str - kind = ... # type: str - defining_class = ... # type: type - object = ... # type: _object +def istraceback(object: object) -> bool: ... +def isframe(object: object) -> bool: ... +def iscode(object: object) -> bool: ... +def isbuiltin(object: object) -> bool: ... +def isroutine(object: object) -> bool: ... +def isabstract(object: object) -> bool: ... +def ismethoddescriptor(object: object) -> bool: ... +def isdatadescriptor(object: object) -> bool: ... +def isgetsetdescriptor(object: object) -> bool: ... +def ismemberdescriptor(object: object) -> bool: ... -def classify_class_attrs(cls: type) -> List[Attribute]: ... +# +# Retrieving source code +# +def getdoc(object: object) -> str: ... +def getcomments(object: object) -> str: ... +def getfile(object: object) -> str: ... +def getmodule(object: object) -> ModuleType: ... +def getsourcefile(object: object) -> str: ... +# TODO restrict to "module, class, method, function, traceback, frame, +# or code object" +def getsourcelines(object: object) -> Tuple[List[str], int]: ... +# TODO restrict to "a module, class, method, function, traceback, frame, +# or code object" +def getsource(object: object) -> str: ... def cleandoc(doc: str) -> str: ... -def getsourcelines(obj: object) -> Tuple[List[str], int]: ... + +# +# Introspecting callables with the Signature object (Python 3.3+) +# +def signature(callable: Callable[..., Any], + *, + follow_wrapped: bool = True) -> 'Signature': ... + +class Signature: + def __init__(self, + parameters: Optional[Sequence['Parameter']] = ..., + *, + return_annotation: Any = ...) -> None: ... + # TODO: can we be more specific here? + empty = ... # type: object + + parameters = ... # type: Mapping[str, 'Parameter'] + + # TODO: can we be more specific here? + return_annotation = ... # type: Any + + def bind(self, *args: Any, **kwargs: Any) -> 'BoundArguments': ... + def bind_partial(self, *args: Any, **kwargs: Any) -> 'BoundArguments': ... + def replace(self, + *, + parameters: Optional[Sequence['Parameter']] = ..., + return_annotation: Any = ...) -> 'Signature': ... + + # Python 3.5+ + @classmethod + def from_callable(cls, + obj: Callable[..., Any], + *, + follow_wrapped: bool = True) -> 'Signature': ... + +# The name is the same as the enum's name in CPython +class _ParameterKind: pass + +class Parameter: + def __init__(self, + name: str, + kind: _ParameterKind, + *, + default: Any = ..., + annotation: Any = ...) -> None: ... + empty = ... # type: Any + name = ... # type: str + default = ... # type: Any + annotation = ... # type: Any + + kind = ... # type: _ParameterKind + POSITIONAL_ONLY = ... # type: _ParameterKind + POSITIONAL_OR_KEYWORD = ... # type: _ParameterKind + VAR_POSITIONAL = ... # type: _ParameterKind + KEYWORD_ONLY = ... # type: _ParameterKind + VAR_KEYWORD = ... # type: _ParameterKind + + def replace(self, + *, + name: Optional[str] = ..., + kind: Optional[_ParameterKind] = ..., + default: Any = ..., + annotation: Any = ...) -> 'Parameter': ... + +class BoundArguments: + arguments = ... # type: MutableMapping[str, Any] + args = ... # Tuple[Any, ...] + kwargs = ... # Dict[str, Any] + signature = ... # type: Signature + + # Python 3.5+ + def apply_defaults(self) -> None: ... + + +# +# Classes and functions +# + +# TODO: The actual return type should be List[_ClassTreeItem] but mypy doesn't +# seem to be supporting this at the moment: +# _ClassTreeItem = Union[List['_ClassTreeItem'], Tuple[type, Tuple[type, ...]]] +def getclasstree(classes: List[type], unique: bool = ...) -> Any: ... ArgSpec = NamedTuple('ArgSpec', [('args', List[str]), ('varargs', str), @@ -41,4 +161,129 @@ FullArgSpec = NamedTuple('FullArgSpec', [('args', List[str]), def getfullargspec(func: object) -> FullArgSpec: ... -def stack() -> List[Tuple[FrameType, str, int, str, List[str], int]]: ... +# TODO make the field types more specific here +ArgInfo = NamedTuple('ArgInfo', [('args', List[str]), + ('varargs', Optional[str]), + ('keywords', Optional[str]), + ('locals', Dict[str, Any]), + ]) + +def getargvalues(frame: FrameType) -> ArgInfo: ... +def formatargspec(args: List[str], + varargs: Optional[str] = ..., + varkw: Optional[str] = ..., + defaults: Optional[Tuple[Any]] = ..., + kwonlyargs: Optional[List[str]] = ..., + kwonlydefaults: Optional[Dict[str, Any]] = ..., + annotations: Optional[Dict[str, Any]] = ..., + formatarg: Optional[Callable[[str], str]] = ..., + formatvarargs: Optional[Callable[[str], str]] = ..., + formatvarkw: Optional[Callable[[str], str]] = ..., + formatvalue: Optional[Callable[[Any], str]] = ..., + formatreturns: Optional[Callable[[Any], str]] = ..., + formatannotations: Optional[Callable[[Any], str]] = ..., + ) -> str: ... +def formatargvalues(args: List[str], + varargs: Optional[str] = ..., + varkw: Optional[str] = ..., + locals: Optional[Dict[str, Any]] = ..., + formatarg: Optional[Callable[[str], str]] = ..., + formatvarargs: Optional[Callable[[str], str]] = ..., + formatvarkw: Optional[Callable[[str], str]] = ..., + formatvalue: Optional[Callable[[Any], str]] = ..., + ) -> str: ... +def getmro(cls: type) -> Tuple[type, ...]: ... + +# Python 3.2+ +def getcallargs(func: Callable[..., Any], + *args: Any, + **kwds: Any) -> Dict[str, Any]: ... + + +# Python 3.3+ +ClosureVars = NamedTuple('ClosureVars', [('nonlocals', Mapping[str, Any]), + ('globals', Mapping[str, Any]), + ('builtins', Mapping[str, Any]), + ('unbound', AbstractSet[str]), + ]) +def getclosurevars(func: Callable[..., Any]) -> ClosureVars: ... + +# Python 3.4+ +def unwrap(func: Callable[..., Any], + *, + stop: Callable[[Any], Any]) -> Any: ... + + +# +# The interpreter stack +# + +# Python 3.5+ (functions returning it used to return regular tuples) +FrameInfo = NamedTuple('FrameInfo', [('frame', FrameType), + ('filename', str), + ('lineno', int), + ('function', str), + ('code_context', List[str]), + ('index', int), + ]) + +# TODO make the frame type more specific +def getframeinfo(frame: Any, context: int = 1) -> FrameInfo: ... +def getouterframes(frame: Any, context: int = 1) -> List[FrameInfo]: ... +def getinnerframes(traceback: TracebackType, context: int = 1) -> List[FrameInfo]: + ... +def currentframe() -> Optional[FrameType]: ... +def stack(context: int = 1) -> List[FrameInfo]: ... +def trace(context: int = 1) -> List[FrameInfo]: ... + +# +# Fetching attributes statically +# + +# Python 3.2+ +def getattr_static(obj: object, attr: str, default: Optional[Any] = ...) -> Any: ... + + +# +# Current State of Generators and Coroutines +# + +# TODO In the next two blocks of code, can we be more specific regarding the +# type of the "enums"? + +# Python 3.2+ +GEN_CREATED = ... # type: str +GEN_RUNNING = ... # type: str +GEN_SUSPENDED = ... # type: str +GEN_CLOSED = ... # type: str +def getgeneratorstate(generator: Generator[Any, Any, Any]) -> str: ... + +# Python 3.5+ +CORO_CREATED = ... # type: str +CORO_RUNNING = ... # type: str +CORO_SUSPENDED = ... # type: str +CORO_CLOSED = ... # type: str +# TODO can we be more specific than "object"? +def getcoroutinestate(coroutine: object) -> str: ... + +# Python 3.3+ +def getgeneratorlocals(generator: Generator[Any, Any, Any]) -> Dict[str, Any]: ... + +# Python 3.5+ +# TODO can we be more specific than "object"? +def getcoroutinelocals(coroutine: object) -> Dict[str, Any]: ... + + +# +# The following seems undocumented but it was already present in this file +# +_object = object + +# namedtuple('Attribute', 'name kind defining_class object') +class Attribute(tuple): + name = ... # type: str + kind = ... # type: str + defining_class = ... # type: type + object = ... # type: _object + +def classify_class_attrs(cls: type) -> List[Attribute]: ...