pinspect module

This module supplements Python’s introspection capabilities. The class pexdoc.pinspect.Callables “traces” modules and produces a database of callables (functions, classes, methods and class properties) and their attributes (callable type, file name, starting line number). Enclosed functions and classes are supported. For example:

# pinspect_example_1.py
from __future__ import print_function
import math


def my_func(version):  # noqa: D202
    """Enclosing function."""

    class MyClass(object):
        """Enclosed class."""

        if version == 2:
            import docs.support.python2_module as pm
        else:
            import docs.support.python3_module as pm

        def __init__(self, value):
            self._value = value

        def _get_value(self):
            return self._value

        value = property(_get_value, pm._set_value, None, "Value property")


def print_name(name):
    print("My name is {0}, and sqrt(2) = {1}".format(name, math.sqrt(2)))

with

# python2_module.py

def _set_value(self, value):
    self._value = value + 2

and

# python3_module.py

def _set_value(self, value):
    self._value = value + 3

gives:

>>> from __future__ import print_function
>>> import docs.support.pinspect_example_1, pexdoc.pinspect, sys
>>> cobj = pexdoc.pinspect.Callables(
...     [sys.modules['docs.support.pinspect_example_1'].__file__]
... )
>>> print(cobj)
Modules:
   docs.support.pinspect_example_1
Classes:
   docs.support.pinspect_example_1.my_func.MyClass
docs.support.pinspect_example_1.my_func: func (10-29)
docs.support.pinspect_example_1.my_func.MyClass: class (13-29)
docs.support.pinspect_example_1.my_func.MyClass.__init__: meth (21-23)
docs.support.pinspect_example_1.my_func.MyClass._get_value: meth (24-26)
docs.support.pinspect_example_1.my_func.MyClass.value: prop (27-29)
docs.support.pinspect_example_1.print_name: func (30-31)

The numbers in parenthesis indicate the line number in which the callable starts and ends within the file it is defined in.

Functions

pexdoc.pinspect.get_function_args(func, no_self=False, no_varargs=False)

Return tuple of the function argument names in the order of the function signature.

Parameters:
  • func (function object) – Function
  • no_self (boolean) – Flag that indicates whether the function argument self, if present, is included in the output (False) or not (True)
  • no_varargs (boolean) – Flag that indicates whether keyword arguments are included in the output (True) or not (False)
Return type:

tuple

For example:

>>> import pexdoc.pinspect
>>> class MyClass(object):
...     def __init__(self, value, **kwargs):
...         pass
...
>>> pexdoc.pinspect.get_function_args(MyClass.__init__)
('self', 'value', '**kwargs')
>>> pexdoc.pinspect.get_function_args(
...     MyClass.__init__, no_self=True
... )
('value', '**kwargs')
>>> pexdoc.pinspect.get_function_args(
...     MyClass.__init__, no_self=True, no_varargs=True
... )
('value',)
>>> pexdoc.pinspect.get_function_args(
...     MyClass.__init__, no_varargs=True
... )
('self', 'value')
pexdoc.pinspect.get_module_name(module_obj)

Retrieve the module name from a module object.

Parameters:

module_obj (object) – Module object

Return type:

string

Raises:
  • RuntimeError (Argument `module_obj` is not valid)
  • RuntimeError (Module object `*[module_name]*` could not be found in loaded modules)

For example:

>>> import pexdoc.pinspect
>>> pexdoc.pinspect.get_module_name(sys.modules['pexdoc.pinspect'])
'pexdoc.pinspect'
pexdoc.pinspect.is_object_module(obj)

Test if the argument is a module object.

Parameters:obj (any) – Object
Return type:boolean
pexdoc.pinspect.is_special_method(name)

Test if callable name is a special Python method.

Parameters:name (string) – Callable name
Return type:boolean
pexdoc.pinspect.private_props(obj)

Yield private properties of an object.

A private property is defined as one that has a single underscore (_) before its name

Parameters:obj (object) – Object
Returns:iterator

Classes

class pexdoc.pinspect.Callables(fnames=None)

Bases: object

Generate a list of module callables and get their attributes.

Callables are functions, classes, methods and class properties; attributes are callable type, file name, and lines span.

Information from multiple modules can be stored in the callables database of the object by repeatedly calling pexdoc.pinspect.Callables.trace() with different module file names. A pexdoc.pinspect.Callables object retains knowledge of which modules have been traced so repeated calls to pexdoc.pinspect.Callables.trace() with the same module object will not result in module re-traces (and the consequent performance hit)

Parameters:

fnames (list of strings or None) – File names of the modules to trace. If None no immediate tracing is done

Raises:
  • OSError (File [fname] could not be found)
  • RuntimeError (Argument `fnames` is not valid)
__add__(other)

Merge two objects.

Raises:RuntimeError (Conflicting information between objects)

For example:

>>> import pexdoc.pcontracts, pexdoc.exh, pexdoc.pinspect, sys
>>> obj1 = pexdoc.pinspect.Callables(
...     [sys.modules['pexdoc.exh'].__file__]
... )
>>> obj2 = pexdoc.pinspect.Callables(
...     [sys.modules['pexdoc.pcontracts'].__file__]
... )
>>> obj3 = pexdoc.pinspect.Callables([
... sys.modules['pexdoc.exh'].__file__,
... sys.modules['pexdoc.pcontracts'].__file__,
... ])
>>> obj1 == obj3
False
>>> obj1 == obj2
False
>>> obj1+obj2 == obj3
True
__copy__()

Copy object.

For example:

>>> import copy, pexdoc.exh, pexdoc.pinspect, sys
>>> obj1 = pexdoc.pinspect.Callables(
...     [sys.modules['pexdoc.exh'].__file__]
... )
>>> obj2 = copy.copy(obj1)
>>> obj1 == obj2
True
__eq__(other)

Test object equality.

For example:

>>> import pexdoc.pcontracts, pexdoc.exh, pexdoc.pinspect, sys
>>> obj1 = pexdoc.pinspect.Callables(
...     [sys.modules['pexdoc.exh'].__file__]
... )
>>> obj2 = pexdoc.pinspect.Callables(
...     [sys.modules['pexdoc.exh'].__file__]
... )
>>> obj3 = pexdoc.pinspect.Callables(
...     [sys.modules['pexdoc.pcontracts'].__file__]
... )
>>> obj1 == obj2
True
>>> obj1 == obj3
False
>>> 5 == obj3
False
__iadd__(other)

Merge an object into an existing object.

Raises:RuntimeError (Conflicting information between objects)

For example:

>>> import pexdoc.pcontracts, pexdoc.exh, pexdoc.pinspect, sys
>>> obj1 = pexdoc.pinspect.Callables(
...     [sys.modules['pexdoc.exh'].__file__]
... )
>>> obj2 = pexdoc.pinspect.Callables(
...     [sys.modules['pexdoc.pcontracts'].__file__]
... )
>>> obj3 = pexdoc.pinspect.Callables([
...     sys.modules['pexdoc.exh'].__file__,
...     sys.modules['pexdoc.pcontracts'].__file__,
... ])
>>> obj1 == obj3
False
>>> obj1 == obj2
False
>>> obj1 += obj2
>>> obj1 == obj3
True
__nonzero__()

Return False if no modules have been traced, True otherwise.

For example:

>>> from __future__ import print_function
>>> import pexdoc.pcontracts, pexdoc.pinspect, sys
>>> obj = pexdoc.pinspect.Callables()
>>> if obj:
...     print('Boolean test returned: True')
... else:
...     print('Boolean test returned: False')
Boolean test returned: False
>>> obj.trace([sys.modules['pexdoc.pcontracts'].__file__])
>>> if obj:
...     print('Boolean test returned: True')
... else:
...     print('Boolean test returned: False')
Boolean test returned: True
__repr__()

Return a string with the expression needed to re-create the object.

For example:

>>> import pexdoc.exh, pexdoc.pinspect, sys
>>> obj1 = pexdoc.pinspect.Callables(
...     [sys.modules['pexdoc.exh'].__file__]
... )
>>> repr(obj1)  #doctest: +ELLIPSIS
"pexdoc.pinspect.Callables(['...exh.py'])"
>>> exec("obj2="+repr(obj1))
>>> obj1 == obj2
True
__str__()

Return a string with a detailed description of the object’s contents.

For example:

>>> from __future__ import print_function
>>> import pexdoc.pinspect, os, sys
>>> import docs.support.pinspect_example_1
>>> cobj = pexdoc.pinspect.Callables([
...     sys.modules['docs.support.pinspect_example_1'].__file__
... ])
>>> print(cobj) #doctest: +ELLIPSIS
Modules:
   ...pinspect_example_1
Classes:
   ...pinspect_example_1.my_func.MyClass
...pinspect_example_1.my_func: func (10-29)
...pinspect_example_1.my_func.MyClass: class (13-29)
...pinspect_example_1.my_func.MyClass.__init__: meth (21-23)
...pinspect_example_1.my_func.MyClass._get_value: meth (24-26)
...pinspect_example_1.my_func.MyClass.value: prop (27-29)
...pinspect_example_1.print_name: func (30-31)

The numbers in parenthesis indicate the line number in which the callable starts and ends within the file it is defined in

load(callables_fname)

Load traced modules information from a JSON file.

The loaded module information is merged with any existing module information

Parameters:

callables_fname (FileNameExists) – File name

Raises:
  • OSError (File [fname] could not be found)
  • RuntimeError (Argument `callables_fname` is not valid)
refresh()

Re-traces modules modified since the time they were traced.

save(callables_fname)

Save traced modules information to a JSON file.

If the file exists it is overwritten

Parameters:callables_fname (FileName) – File name
Raises:RuntimeError (Argument `fname` is not valid)
trace(fnames)

Generate a list of module callables and gets their attributes.

Callables are functions, classes, methods and class properties; their attributes are callable type, file name, and lines span

Parameters:

fnames (list) – File names of the modules to trace

Raises:
  • OSError (File [fname] could not be found)
  • RuntimeError (Argument `fnames` is not valid)
callables_db

Return the callables database.

Return type:dictionary

The callable database is a dictionary that has the following structure:

  • full callable name (string) – Dictionary key. Elements in the callable path are separated by periods ('.'). For example, method my_method() from class MyClass from module my_module appears as 'my_module.MyClass.my_method'
  • callable properties (dictionary) – Dictionary value. The elements of this dictionary are:
  • type (string)'class' for classes, 'meth' for methods, 'func' for functions or 'prop' for properties or class attributes
  • code_id (tuple or None) – A tuple with the following items:
    • file name (string) – the first item contains the file name where the callable can be found
    • line number (integer) – the second item contains the line number in which the callable code starts (including decorators)
  • last_lineno (integer) – line number in which the callable code ends (including blank lines and comments regardless of their indentation level)
reverse_callables_db

Returns the reverse callables database

Return type:dictionary

The reverse callable database is a dictionary that has the following structure:

  • callable id (tuple) – Dictionary key. Two-element tuple in which the first tuple item is the file name where the callable is defined and the second tuple item is the line number where the callable definition starts
  • full callable name (string) – Dictionary value. Elements in the callable path are separated by periods ('.'). For example, method my_method() from class MyClass from module my_module appears as 'my_module.MyClass.my_method'