injectify package

Submodules

injectify.api module

This module contains the apis that power Injectify.

injectify.api.inject(target, injector)

A decorator that injects code in the target object.

Parameters:
  • target – The object to inject code into.
  • injector – A BaseInjector to represent an injection point.

injectify.injectors module

This module contains the model objects that power Injectify.

class injectify.injectors.BaseInjector(save_state=True)

Bases: abc.ABC, ast.NodeTransformer

An abstract class that identifies an injection point.

Parameters:save_state – Whether or not the target object should allow multiple injections.
compile(tree)

Recompile the target object with the handler.

inject(node)

Abstract method that merges the handler into the target.

is_target_module()

Check whether the target object is a module.

prepare(target, handler)

Prepares the injector with the given parameters.

prepare_handler(handler)

Prepares the given handler function.

prepare_target(target)

Prepares the given target object.

visit_target()

Visit the AST node of the target object.

class injectify.injectors.FieldInjector(field, ordinal=None, insert=None, *args, **kwargs)

Bases: injectify.injectors.BaseInjector

An injector that injects code at a field’s assignment.

Parameters:
  • field – The field to inject at.
  • ordinal – Zero-based index to choose specific point of injection.
  • insert – Where to insert the handler’s code relative to the target. Options include ‘before’ and ‘after’.
Usage
from injectify import inject, FieldInjector

def get_rank(year):
    if year == 1:
        rank = 'Freshman'
    elif year == 2:
        rank = 'Sophomore'
    elif year == 3:
        rank = 'Junior'
    else:
        rank = 'Senor'
    return rank

@inject(target=target,
        injector=FieldInjector('rank', ordinal=3, insert='after'))
def handler():
    rank = 'Senior'

After the injection happens, the function stat has code that is equivalent to

inject(node)

Inject the handler at the assignment of the given field in the target object.

visit_Assign(node)

Visit an Assign node.

class injectify.injectors.HeadInjector(save_state=True)

Bases: injectify.injectors.BaseInjector

An injector that injects code at the top of the object.

Usage
After the injection happens, the function file_write has code that is equivalent to
inject(node)

Inject the handler at the top of the target object.

visit_AsyncFunctionDef(node)

Visit a FunctionDef node.

visit_ClassDef(node)

Visit a ClassDef node.

visit_FunctionDef(node)

Visit a FunctionDef node.

visit_Module(node)

Visit a Module node.

If the target object is a module then inject the handler in this node, else keep traversing. This is because the root of the AST will be this node for code parsed using the exec mode.

class injectify.injectors.NestedInjector(nested, injector, *args, **kwargs)

Bases: injectify.injectors.BaseInjector

An injector that injects code in a nested function.

Note: The NestedInjector can only be used when the target is a function or method.

Parameters:
  • nested – Name of the nested function.
  • injector – Injector to use in the nested function.
Usage
from time import time
from injectify import inject, FieldInjector

def timing(f):
    def wrapper(*args, **kwargs):
        ts = time()
        result = f(*args, **kwargs)
        te = time()
        return result

@inject(target=target,
        injector=NestedInjector('wrapper', ReturnInjector()))
def handler():
    print('func:{!r} args:[{!r}, {!r}] took: {:2.f} sec'.format(
            f.__name__, args, kwargs, te-ts))

After the injection happens, the function stat has code that is equivalent to

inject(node)

Inject the handler into the nested function with the given injector.

prepare(target, handler)

Prepares the injector and the nested injector with the given parameters.

visit_AsyncFunctionDef(node)

Visit a FunctionDef node.

visit_FunctionDef(node)

Visit a FunctionDef node.

class injectify.injectors.ReturnInjector(ordinal=None, *args, **kwargs)

Bases: injectify.injectors.BaseInjector

An injector that injects code before a return statement.

Note: The ReturnInjector can only be used when the target is a function or method.

Parameters:ordinal – Optional zero-based index to choose specific point of injection. Multiple indices can be given in the form of a list.
Usage
import statistics
from injectify import inject, ReturnInjector

def stat(operation, seq):
    if operation == 'mean':
        return statistics.mean(seq)
    elif operation == 'median':
        return statistics.median(seq)
    elif operation == 'mode':
        return staistics.mode(seq)

@inject(target=target, injector=ReturnInjector(ordinal=[1,2]))
def handler():
    seq = list(seq)
    seq.append(10)

After the injection happens, the function stat has code that is equivalent to

inject(node)

Inject the handler before each return statement in the target object.

visit_Return(node)
class injectify.injectors.TailInjector(save_state=True)

Bases: injectify.injectors.BaseInjector

An injector that injects code at the bottom of the object.

Usage
import os.path
from injectify import inject, TailInjector

def file_read(filename):
    if os.path.exists(filename):
        with open(filename_, 'r') as f:
            return f.read()

@inject(target=target, injector=TailInjector())
def handler():
    raise FileNotFoundError('File does not exist')

After the injection happens, the function file_open has code that is equivalent to

inject(node)

Inject the handler at the bottom of the target object.

visit_AsyncFunctionDef(node)

Visit a FunctionDef node.

visit_ClassDef(node)

Visit a ClassDef node.

visit_FunctionDef(node)

Visit a FunctionDef node.

visit_Module(node)

Visit a Module node.

If the target object is a module then inject the handler in this node, else keep traversing. This is because the root of the AST will be this node for code parsed using the exec mode.

injectify.structures module

This module contains the data structures that power Injectify.

class injectify.structures.listify(initlist)

Bases: collections.UserList

A list-like object that wraps an object into a list if it is not a sequence, or converts the object to a list if it is a sequence.

injectify.utils module

This module contains the utility functions that power Injectify.

injectify.utils.caninject(obj)

Check whether the given object can be injected with code.

injectify.utils.get_defining_class(obj)

Return the class that defines the given object or None if there is no class.

injectify.utils.parse_object(obj)

Parse the source into an AST node.

injectify.utils.tryattrs(obj, *attrs)

Return the first value of the named attributes found of the given object.

Module contents

Code Injection Library