pf.tracer

class procfunc.tracer.TraceLevel[source]

Bases: IntEnum

Higher = coarser. Lower = finer.

The resulting graph will contain nodes which are this level

GRAMMAR = 100
RANDOM_CONTROL = 60
RANDOM_PARAMS = 50
GENERATORS = 40
NODEGROUPS = 30
PRIMITIVES = 20

Supported special methods: __abs__, __add__, __and__, __bool__, __ceil__, __contains__, __divmod__, __float__, __floor__, __floordiv__, __getitem__, __getnewargs__, __index__, __int__, __invert__, __iter__, __len__, __lshift__, __mod__, __mul__, __neg__, __or__, __pos__, __pow__, __radd__, __rand__, __rdivmod__, __rfloordiv__, __rlshift__, __rmod__, __rmul__, __ror__, __round__, __rpow__, __rrshift__, __rshift__, __rsub__, __rtruediv__, __rxor__, __sub__, __truediv__, __trunc__, __xor__

procfunc.tracer.grammar(func=None, *, allow_exec=False, custom_trace_wrapper_create=None, mutates=None, normalize=True)
Parameters:
Return type:

Callable

procfunc.tracer.random_control(func=None, *, allow_exec=False, custom_trace_wrapper_create=None, mutates=None, normalize=True)
Parameters:
Return type:

Callable

procfunc.tracer.random_param(func=None, *, allow_exec=False, custom_trace_wrapper_create=None, mutates=None, normalize=True)
Parameters:
Return type:

Callable

procfunc.tracer.generator(func=None, *, allow_exec=False, custom_trace_wrapper_create=None, mutates=None, normalize=True)
Parameters:
Return type:

Callable

procfunc.tracer.primitive(func=None, *, allow_exec=False, custom_trace_wrapper_create=None, mutates=None, normalize=True)
Parameters:
Return type:

Callable

procfunc.tracer.register_trace_target(func, trace_level, allow_exec, custom_trace_wrapper_create, mutates=None, normalize=True)[source]

Helper function to register a function for tracing with consistent frame inspection

Parameters:
class procfunc.tracer.RngProxy[source]

Bases: Proxy

We will do specialcase handling to trace rng nodes through the graph

This allows us to know what the results of choice() and other random control flow will be, BUT only if the user has kept the rng non-dirty, i.e. the rng used for choice descends from the root via only spawn() calls

This is essential so that the result of choice() during tracing is the same as the result of choice() during generation

__init__(node, rng, dirty=False)[source]
Parameters:
rng: Generator
dirty: bool = False
spawn(n_children)[source]

Returns a mock node which can only be unpacked into its constitutent mock rngs

Parameters:

n_children (int)

Return type:

RngSpawnResultProxy

Supported special methods: __abs__, __add__, __and__, __bool__, __call__, __floordiv__, __getattr__, __getitem__, __invert__, __iter__, __len__, __lshift__, __mod__, __mul__, __neg__, __or__, __pos__, __pow__, __radd__, __rand___, __rfloordiv__, __rlshift__, __rmod__, __rmul__, __ror___, __rpow__, __rrshift__, __rshift__, __rsub__, __rtruediv__, __rxor__, __sub__, __truediv__, __xor__

class procfunc.tracer.PatchFunctionTarget[source]

Bases: object

PatchFunctionTarget(frame: dict, name: str, trace_level: procfunc.tracer.patch.TraceLevel, normalize: bool = True, allow_exec: bool = False, custom_trace_wrapper_create: Optional[Callable[[ForwardRef(‘PatchFunctionTarget’), ForwardRef(‘Patcher’)], Callable]] = None, source_name: str | None = None, mutates: list[str] | None = None)

frame: dict
name: str
trace_level: TraceLevel
normalize: bool = True
allow_exec: bool = False
custom_trace_wrapper_create: Callable[[PatchFunctionTarget, Patcher], Callable] | None = None
source_name: str | None = None
mutates: list[str] | None = None
__init__(frame, name, trace_level, normalize=True, allow_exec=False, custom_trace_wrapper_create=None, source_name=None, mutates=None)
Parameters:
Return type:

None

procfunc.tracer.trace(func, trace_level=TraceLevel.GENERATORS, name=None, **inputs)[source]

Turn a python function into a graph datastructure.

Using this datastructure is (usually) equivelent to executing the function.

Parameters:
  • func (Callable) – The function to trace

  • trace_level (TraceLevel) – Granularity of the graph. Functions at this level become leaves; finer functions are traced through. choice() peeks through all options when trace_level >= RANDOM_CONTROL, or resolves to the chosen branch when finer.

  • name (str | None)

  • inputs (Any)

procfunc.tracer.add_search_scope(module)[source]

Causes an intermediate module to be searched to discover any existing targets that need to be patched

e.g. for procfunc.nodes.to_mesh_object, the original to_mesh_object is already a target, but we need to add_search_scope on the nodes module so that that module’s references to to_mesh_object get wrapped.

Parameters:

module (ModuleType)

procfunc.tracer.autowrap_module(module, allow_exec=False, trace_level=TraceLevel.PRIMITIVES)[source]
Parameters: