Skip to main content

Lib/inspect.py (part 2)

Source:

cpython 3.14 @ ab2d84fe1023/Lib/inspect.py

This annotation covers member introspection and source retrieval. See lib_inspect_detail for isfunction, isclass, ismodule, frame and stack helpers.

Map

LinesSymbolRole
1-80getmembersReturn (name, value) pairs for all attributes of an object
81-200getmoduleDeduce the module an object was defined in
201-350getsourcefile / getfileReturn the .py or .pyc source path
351-550getsourcelines / getsourceRead and return source lines plus starting line number
551-800signature / SignatureBuild a Signature object from a callable
801-1100ParameterRepresent one parameter (name, kind, default, annotation)
1101-1400BoundArgumentsResult of Signature.bind() — maps args to parameters

Reading

getmembers

# CPython: Lib/inspect.py:480 getmembers
def getmembers(object, predicate=None):
"""Return all members of an object as (name, value) pairs sorted by name.
Optionally, only return members for which predicate(value) is true."""
mro = ()
names = dir(object)
# :dd any DynamicClassAttribute from the class MRO
for base in getattr(type(object), '__mro__', ()):
for k, v in base.__dict__.items():
if isinstance(v, types.DynamicClassAttribute):
names.append(k)
results = []
processed = set()
for key in names:
try:
value = getattr(object, key)
except AttributeError:
for base in mro:
if key in base.__dict__:
value = base.__dict__[key]
break
else:
continue
if not predicate or predicate(value):
results.append((key, value))
processed.add(key)
results.sort(key=lambda pair: pair[0])
return results

getmembers is used by help() and IDEs to enumerate callable attributes. It tolerates descriptors that raise AttributeError on access.

getsource

# CPython: Lib/inspect.py:1080 getsource
def getsource(object):
"""Return the source code for an object as a string."""
lines, lnum = getsourcelines(object)
return ''.join(lines)

def getsourcelines(object):
object = unwrap(object)
lines, lnum = findsource(object)
return getblock(lines[lnum:]), lnum + 1

getsource opens the .py file via getsourcefile, reads all lines, finds the definition using findsource, then extracts the indented block.

signature

# CPython: Lib/inspect.py:1580 signature
def signature(obj, *, follow_wrapped=True, globals=None, locals=None,
eval_str=False):
"""Get a `Signature` object for the given callable."""
return Signature.from_callable(obj, follow_wrapped=follow_wrapped,
globals=globals, locals=locals,
eval_str=eval_str)

Signature.from_callable dispatches on the type: built-in functions use __text_signature__, Python functions use co_varnames/co_flags from the code object, functools.partial unwraps the partial, and __wrapped__ is followed when follow_wrapped=True.

Parameter

# CPython: Lib/inspect.py:2180 Parameter
class Parameter:
POSITIONAL_ONLY = _ParameterKind.POSITIONAL_ONLY
POSITIONAL_OR_KEYWORD = _ParameterKind.POSITIONAL_OR_KEYWORD
VAR_POSITIONAL = _ParameterKind.VAR_POSITIONAL
KEYWORD_ONLY = _ParameterKind.KEYWORD_ONLY
VAR_KEYWORD = _ParameterKind.VAR_KEYWORD
empty = _empty

def __init__(self, name, kind, *, default=_empty, annotation=_empty):
...

kind determines how the parameter can be passed. POSITIONAL_ONLY (before / in the signature), POSITIONAL_OR_KEYWORD (normal), VAR_POSITIONAL (*args), KEYWORD_ONLY (after *), VAR_KEYWORD (**kwargs).

BoundArguments

# CPython: Lib/inspect.py:2580 BoundArguments
class BoundArguments:
"""Result of Signature.bind() or Signature.bind_partial()."""
__slots__ = ('arguments', '_signature')

@property
def args(self):
"""Tuple of positional arguments values."""
...

@property
def kwargs(self):
"""Dict of keyword arguments values."""
...

def apply_defaults(self):
"""Set default values for missing arguments."""
...

apply_defaults fills in Parameter.default for any parameter not supplied by the caller. Useful before calling the function with func(*ba.args, **ba.kwargs).

gopy notes

getmembers uses objects.Dir then objects.GetAttr in a loop. getsource opens the file with os.Open and reads lines. signature dispatches through objects.GetAttr(obj, "__text_signature__") for builtins and code object inspection via compile.Code for Python functions. BoundArguments is a plain Go struct mirroring the CPython class.