Source code for pythonwrench.inspect

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import inspect
from types import CodeType
from typing import Any, Callable, List, Tuple, TypeVar, Union, get_args

T = TypeVar("T")


[docs] def get_argnames(fn: Callable) -> List[str]: """Get arguments names of a method, function or callable object. This function does not return the 'self' argument for methods.""" spec = inspect.getfullargspec(fn) all_args = spec.args + spec.kwonlyargs if inspect.ismethod(fn) or inspect.isclass(fn): return all_args[1:] else: return all_args
[docs] def get_current_fn_name(*, default: T = "") -> Union[str, T]: """Get caller function name.""" try: return inspect.currentframe().f_back.f_code.co_name # type: ignore except AttributeError: return default
[docs] def get_fullname(x: Any, *, inst_suffix: str = "(...)") -> str: """Returns the classname of an object with parent modules. Args: obj: Object to scan. inst_suffix: Suffix appended to the classname in case the object is an instance of a class. Examples -------- >>> get_fullname([0, 1, 2]) ... 'builtins.list(...)' >>> get_fullname(1.0) ... 'builtins.float(...)' >>> class A: def f(self): return 0 >>> a = A() >>> get_fullname(a) ... '__main__.A(...)' >>> get_fullname(A) ... '__main__.A' >>> get_fullname(a.f) ... '__main__.A.f' >>> get_fullname(A.f) ... '__main__.A.f' """ if hasattr(x, "__module__") and hasattr(x, "__qualname__"): if x.__module__ is None: name = f"{x.__qualname__}" else: name = f"{x.__module__}.{x.__qualname__}" elif inspect.ismodule(x): name = x.__name__ else: cls = x.__class__ name = f"{cls.__module__}.{cls.__qualname__}{inst_suffix}" cls_args = get_args(x) if len(cls_args) != 0: argsnames = [get_fullname(arg, inst_suffix=inst_suffix) for arg in cls_args] argsnames_str = ", ".join(argsnames) name = f"{name}[{argsnames_str}]" return name
def _get_code_and_start(fn: Callable) -> Tuple[CodeType, int]: if inspect.isfunction(fn): code = fn.__code__ start = 0 elif inspect.ismethod(fn): code = fn.__code__ start = 1 # If method, remove 'self' arg elif inspect.isclass(fn): # If init, remove 'self' arg code = fn.__init__.__code__ start = 1 # If init, remove 'self' arg else: code = fn.__call__.__code__ start = 0 return code, start