Decorators
Decorators for Autopilot classes
Add functionality to autopilot classes without entering into or depending on the inheritance hierarchy.
Classes:
Decorator to be used around methods (particularly __init__) to store arguments given on call. |
- class Introspect[source]
Bases:
object
Decorator to be used around methods (particularly __init__) to store arguments given on call.
Stores args and kwargs in
self._introspect[wrapped_function.__name__] = {'kwarg_1': val_1, 'kwarg_2': val_2}
Note that this will unpack positional arguments into keyword arguments. If the topmost class is given positional arguments, they will be stored in the special field
'args': [arg1,arg2,...]
Works by wrapping the method in such a way that
self
is preserved, and can patch into the existing MRO.Note
This class was intended for use on
__init__
methods and has not been tested on other methods. Though they should work in theory, there may be unexpected behavior in introspecting across multiple frames, as the check is for whether we are within the calling object’s calling hierarchy.For example, given a Superclass and a Subclass (and a mock Introspect object) like this:
class Introspect: def __call__(self, func) -> typing.Callable: @wraps(func) def wrapped_fn(wrapped_self, *args, **kwargs): print('2. start of introspection') ret = func(wrapped_self, *args, **kwargs) print('4. end of introspection') return ret return wrapped_fn class Superclass: @Introspect() def __init__(self, *args, **kwargs): self.args = args self.kwargs = kwargs print(f"3. superclass function call") class Subclass(Superclass): def __init__(self, *args, **kwargs): print('1. inheriting class, pre super call') super(Subclass, self).__init__(*args, **kwargs) print('5. inheriting class, post super call')
One would get the following output:
>>> instance = Subclass('a', 'b', 'c') 1. inheriting class, pre super call 2. start of introspection 3. superclass function call 4. end of introspection 5. inheriting class, post super call
To hoist the call back up into the (potentially multiple) subclass frames, we use
inspect
and iterate through frames, grabbing their arguments, until we reach a frame that is no longer in our calling hierarchy.