Some times you need to register a handle for your thread to monitor whether some values have been used or not. All interactions with this variable will infect your source, so you need a way to find them and elliminate them. Satella’s tainting is at your disposal.


Tainting won’t work correctly on earlier versions than Python 3.7 due to the fact that per-opcode tracing was added there.

class satella.debug.TaintingEnvironment

A round of tainting. Taints will be invalidated at the end. Basically any Python opcode that relates to tainting will be tainted itself.

As an added extra, function values will be tainted as well if at least one of the parameters has been tainted

Use like this:

>>> with TaintingEnvironment() as env:
>>>     a = taint(a)
>>>     b = a + 5
>>>     ...


Using environment tainting will slow down your Python scripts since they install a per opcode handler.


Using functions that take at least one tainted argument is supposed to return a tainted result, but I couldn’t get that shipped in time at this involved some serious tweaking with the Python bytecode.

static get_session_in_progress() TaintingEnvironment

Obtain current tainting session in progress


RuntimeError – no tainting session started yet

get_tainted_variables() Iterator[T]

Return all, of the tainted variables

satella.debug.taint(v: T) TaintedObject[T]

Taints the object if necessary. If already tainted will leave it as is


RuntimeError – no tainting session in progress

satella.debug.access_tainted(v: T | TaintedObject[T]) T

If v is tainted, this will extract it’s value.

If it is not, v will be returned

There is a class that is a thin proxy at the objects that you taint, namely:

class satella.debug.TaintedObject(v)

This works rather similar to satella.coding.structures.Proxy.