pyTooling.ControlFlow

A data structure to describe the control flow graph of a function: its basic blocks and the edges between them.

A ControlFlowGraph describes one function, e.g. a C or C++ function or a Python code object. A BasicBlock is a sequence of code, which control enters at its top and leaves at its bottom. An Edge leads from a block to a block control continues with, so a block with several outbound edges branches - a switch has an edge per target. An EdgeKind says why control continues there.

Every graph has an entry block and an exit block. An exception is an EdgeKind.Exception edge: to the block of the handler catching it - a C++ catch or a Python except clause - or, if none does, to the graph’s unwind block, through which it leaves the function.

Blocks and edges carry an optional execution count, e.g. from a code coverage report, and an optional value of any type, e.g. the source lines of a block. Graphs, blocks and edges carry key-value-pairs, e.g. the results of an analysis. ControlFlowGraph.ToGraph() converts a control flow graph into a Graph.

Hint

See high-level help for explanations and usage examples.

See also

pyTooling.CallGraph

→ The call graph of a program, whose calls are made from the blocks of control flow graphs.

pyTooling.Graph

→ The graph data structure a control flow graph is converted into.

pyTooling.Graph.GraphML

→ Writing a graph as a GraphML document.

Exceptions

Classes

  • BlockKind: Kind of a basic block.

  • EdgeKind: Kind of an edge: why control continues with the edge’s destination.

  • Base: Base-class of all control flow graph elements, adding a dictionary of arbitrary key-value-pairs to them.

  • BaseWithCountAndValue: Base-class of elements carrying an execution count and a value.

  • BasicBlock: A basic block of a control flow graph: a sequence of code, which control enters at its top and leaves at its bottom.

  • Edge: An edge of a control flow graph, leading from a block to a block control continues with.

  • ControlFlowGraph: The control flow graph of a function: its basic blocks, the edges between them, and its entry and exit block.


Exceptions

exception pyTooling.ControlFlow.ControlFlowError[source]

Base-exception of all exceptions raised by pyTooling.ControlFlow.

Inheritance

Inheritance diagram of ControlFlowError

__init__(*args, **kwargs)
classmethod __new__(*args, **kwargs)
exception pyTooling.ControlFlow.DuplicateBlockError[source]

The exception raised for a block a graph has already: one with the same ID, or a second entry, exit or unwind.

Inheritance

Inheritance diagram of DuplicateBlockError

__init__(*args, **kwargs)
classmethod __new__(*args, **kwargs)
exception pyTooling.ControlFlow.DuplicateEdgeError[source]

The exception raised for an edge, which connects the same two blocks as an edge of the same kind.

Inheritance

Inheritance diagram of DuplicateEdgeError

__init__(*args, **kwargs)
classmethod __new__(*args, **kwargs)

Classes

class pyTooling.ControlFlow.BlockKind[source]

Kind of a basic block.

A ControlFlowGraph has exactly one entry block and one exit block, and at most one unwind block. Every other block holds code.

Inheritance

Inheritance diagram of BlockKind

Code = 0

A block of code, which control enters at its top and leaves at its bottom.

Entry = 1

The block control enters the function through.

Exit = 2

The block control leaves the function through, when the function returns.

Unwind = 3

The block an exception leaves the function through, when no handler in the function catches it.

__str__()[source]

Return the member’s name.

Return type:

str

Returns:

Name of the member, e.g. Entry.

classmethod __contains__(value)

Return True if value is in cls.

value is in cls if: 1) value is a member of cls, or 2) value is the value of one of the cls’s members. 3) value is a pseudo-member (flags)

classmethod __getitem__(name)

Return the member matching name.

classmethod __iter__()

Return members in definition order.

classmethod __len__()

Return the number of members (no aliases)

class pyTooling.ControlFlow.EdgeKind[source]

Kind of an edge: why control continues with the edge’s destination.

Inheritance

Inheritance diagram of EdgeKind

Default = 0

The edge wasn’t classified, e.g. an arc between two lines a code coverage tool reports.

FallThrough = 1

Control continues with the next block in code order, e.g. the side of a condition not jumping.

Jump = 2

Control jumps to the destination, e.g. a taken branch, a goto, or a switch case.

Exception = 3

An exception leaves the block, e.g. by a C++ throw, a Python raise, or from a call.

Abnormal = 4

Control leaves the block without a jump or an exception, e.g. by calling exit().

__str__()[source]

Return the member’s name.

Return type:

str

Returns:

Name of the member, e.g. FallThrough.

classmethod __contains__(value)

Return True if value is in cls.

value is in cls if: 1) value is a member of cls, or 2) value is the value of one of the cls’s members. 3) value is a pseudo-member (flags)

classmethod __getitem__(name)

Return the member matching name.

classmethod __iter__()

Return members in definition order.

classmethod __len__()

Return the number of members (no aliases)

class pyTooling.ControlFlow.Base[source]

Base-class of all control flow graph elements, adding a dictionary of arbitrary key-value-pairs to them.

Every graph, block and edge can carry data attached by its user, e.g. the results of an analysis under a key of the analysis’ choice: block["dominator"] = entry. The element’s dunder methods serve this dictionary.

Inheritance

Inheritance diagram of Base

__init__(keyValuePairs=None)[source]

Initializes the key-value-pairs of an element.

Parameters:

keyValuePairs (Mapping[Hashable, Any] | None) – Optional, mapping (dictionary) of key-value-pairs. Default: None.

Return type:

None

_dict: dict[Hashable, Any]

A dictionary to store arbitrary key-value-pairs.

__getitem__(key)[source]

Read an attached attribute (key-value-pair) by key.

Parameters:

key (Hashable) – The key to look for.

Return type:

Any

Returns:

The value associated to the given key.

Raises:

KeyError – If the key doesn’t exist in the element’s attributes.

__setitem__(key, value)[source]

Create or update an attached attribute (key-value-pair) by key.

If a key doesn’t exist yet, a new key-value-pair is created.

Parameters:
  • key (Hashable) – The key to create or update.

  • value (Any) – The value to associate to the given key.

Return type:

None

__delitem__(key)[source]

Remove an attached attribute (key-value-pair) by key.

Parameters:

key (Hashable) – The key to remove.

Raises:

KeyError – If the key doesn’t exist in the element’s attributes.

Return type:

None

__contains__(key)[source]

Check if the key is an attached attribute (key-value-pair) of this element.

Parameters:

key (Hashable) – The key to check.

Return type:

bool

Returns:

True, if the key is an attached attribute.

__len__()[source]

Return the number of attached attributes (key-value-pairs) of this element.

Return type:

int

Returns:

Number of attached attributes.

__iter__()[source]

Iterate the keys of the attached attributes (key-value-pairs) of this element.

Return type:

Iterator[Hashable]

Returns:

An iterator over the keys, in the order they were created.

classmethod GetMethodsWithAttributes(predicate: type[TAttr] | Iterable[type[TAttr]] | None = None) → dict[Callable[[...], Any], tuple[Attribute, ...]]

Return the class’ methods that carry at least one matching attribute.

Parameters:

predicate (type[TypeVar(TAttr, bound= Attribute)] | Iterable[type[TypeVar(TAttr, bound= Attribute)]] | None) – Optional, an attribute class, an iterable of attribute classes, or None to accept every attribute.

Return type:

dict[Callable[..., Any], tuple[Attribute, ...]]

Returns:

Dictionary of methods and the matching attributes attached to them.

Raises:
  • ValueError – If an element of parameter ‘predicate’ is not a sub-class of Attribute.

  • ValueError – If parameter ‘predicate’ is neither an attribute class nor an iterable of those.

__getstate__() → dict[str, Any]

Return the object’s state for pickling, collecting every slot of the class hierarchy.

Return type:

dict[str, Any]

Returns:

Dictionary of slot names and their values.

Raises:

ExtendedTypeError – If a slot was never assigned, so it has no value to serialize.

__setstate__(state: dict[str, Any]) → None

Restore the object’s state from unpickling, requiring exactly the slots of the class hierarchy.

Parameters:

state (dict[str, Any]) – Dictionary of slot names and their values.

Raises:

ExtendedTypeError – If the given state misses a slot or carries an unexpected one.

Return type:

None

class pyTooling.ControlFlow.BaseWithCountAndValue[source]

Base-class of elements carrying an execution count and a value.

Basic blocks and edges are such elements.

Inheritance

Inheritance diagram of BaseWithCountAndValue

_count: int | None

How often the element was executed, or None if that’s unknown.

__init__(count=None, value=None, keyValuePairs=None)[source]

Initializes the execution count, the value and the key-value-pairs of an element.

Parameters:
  • count (int | None) – Optional, how often the element was executed. Default: None.

  • value (Any | None) – Optional, any value attached to the element. Default: None.

  • keyValuePairs (Mapping[Hashable, Any] | None) – Optional, mapping (dictionary) of key-value-pairs. Default: None.

Raises:
  • TypeError – If parameter ‘count’ is not of type int.

  • ValueError – If parameter ‘count’ is negative.

Return type:

None

_value: Any | None

Any value attached to the element, or None.

property Count: int | None

Property to access how often the element was executed (_count).

Returns:

The execution count, or None if it’s unknown.

Raises:
property Value: Any | None

Property to access the value attached to the element (_value).

Returns:

The value, or None if none is attached.

classmethod GetMethodsWithAttributes(predicate: type[TAttr] | Iterable[type[TAttr]] | None = None) → dict[Callable[[...], Any], tuple[Attribute, ...]]

Return the class’ methods that carry at least one matching attribute.

Parameters:

predicate (type[TypeVar(TAttr, bound= Attribute)] | Iterable[type[TypeVar(TAttr, bound= Attribute)]] | None) – Optional, an attribute class, an iterable of attribute classes, or None to accept every attribute.

Return type:

dict[Callable[..., Any], tuple[Attribute, ...]]

Returns:

Dictionary of methods and the matching attributes attached to them.

Raises:
  • ValueError – If an element of parameter ‘predicate’ is not a sub-class of Attribute.

  • ValueError – If parameter ‘predicate’ is neither an attribute class nor an iterable of those.

__contains__(key)

Check if the key is an attached attribute (key-value-pair) of this element.

Parameters:

key (Hashable) – The key to check.

Return type:

bool

Returns:

True, if the key is an attached attribute.

__delitem__(key)

Remove an attached attribute (key-value-pair) by key.

Parameters:

key (Hashable) – The key to remove.

Raises:

KeyError – If the key doesn’t exist in the element’s attributes.

Return type:

None

__getitem__(key)

Read an attached attribute (key-value-pair) by key.

Parameters:

key (Hashable) – The key to look for.

Return type:

Any

Returns:

The value associated to the given key.

Raises:

KeyError – If the key doesn’t exist in the element’s attributes.

__getstate__() → dict[str, Any]

Return the object’s state for pickling, collecting every slot of the class hierarchy.

Return type:

dict[str, Any]

Returns:

Dictionary of slot names and their values.

Raises:

ExtendedTypeError – If a slot was never assigned, so it has no value to serialize.

__iter__()

Iterate the keys of the attached attributes (key-value-pairs) of this element.

Return type:

Iterator[Hashable]

Returns:

An iterator over the keys, in the order they were created.

__len__()

Return the number of attached attributes (key-value-pairs) of this element.

Return type:

int

Returns:

Number of attached attributes.

__setitem__(key, value)

Create or update an attached attribute (key-value-pair) by key.

If a key doesn’t exist yet, a new key-value-pair is created.

Parameters:
  • key (Hashable) – The key to create or update.

  • value (Any) – The value to associate to the given key.

Return type:

None

__setstate__(state: dict[str, Any]) → None

Restore the object’s state from unpickling, requiring exactly the slots of the class hierarchy.

Parameters:

state (dict[str, Any]) – Dictionary of slot names and their values.

Raises:

ExtendedTypeError – If the given state misses a slot or carries an unexpected one.

Return type:

None

_dict: dict[Hashable, Any]

A dictionary to store arbitrary key-value-pairs.

class pyTooling.ControlFlow.BasicBlock[source]

A basic block of a control flow graph: a sequence of code, which control enters at its top and leaves at its bottom.

A block is identified by an ID unique within its graph, e.g. a compiler’s block number or a line number. Its outbound edges lead to the blocks control continues with.

Inheritance

Inheritance diagram of BasicBlock

__init__(controlFlowGraph, blockID, *, kind=BlockKind.Code, count=None, value=None, keyValuePairs=None)[source]

Initializes a basic block and adds it to its graph.

A graph creates its entry and exit block itself. A block of BlockKind.Unwind becomes the graph’s unwind block.

Parameters:
  • controlFlowGraph (ControlFlowGraph) – The control flow graph the block belongs to.

  • blockID (Hashable) – ID of the block, unique within its graph.

  • kind (BlockKind) – Optional, kind of the block. Default: BlockKind.Code.

  • count (int | None) – Optional, how often the block was executed. Default: None.

  • value (Any | None) – Optional, any value attached to the block, e.g. its source lines. Default: None.

  • keyValuePairs (Mapping[Hashable, Any] | None) – Optional, mapping (dictionary) of key-value-pairs. Default: None.

Raises:
Return type:

None

_controlFlowGraph: ControlFlowGraph

The control flow graph this block belongs to.

_id: Hashable

ID of the block, unique within its graph.

_kind: BlockKind

Kind of the block.

_inboundEdges: list[Edge]

Edges leading to this block.

_outboundEdges: list[Edge]

Edges leading from this block to the blocks control continues with.

property ControlFlowGraph: ControlFlowGraph

Read-only property to access the control flow graph this block belongs to (_controlFlowGraph).

Returns:

The control flow graph.

property ID: Hashable

Read-only property to access the block’s ID (_id).

Returns:

ID of the block, unique within its graph.

property Kind: BlockKind

Read-only property to access the block’s kind (_kind).

Returns:

Kind of the block.

property InboundEdges: tuple[Edge, ...]

Read-only property to return the edges leading to this block.

Returns:

The inbound edges, in the order they were created.

property OutboundEdges: tuple[Edge, ...]

Read-only property to return the edges leading from this block to the blocks control continues with.

Returns:

The outbound edges, in the order they were created.

EdgeTo(destination, edgeCount=None, edgeValue=None, edgeKind=EdgeKind.Default, keyValuePairs=None)[source]

Create an outbound edge from this block to the block control continues with.

Parameters:
  • destination (BasicBlock) – The block control continues with.

  • edgeCount (int | None) – Optional, how often control took the edge. Default: None.

  • edgeValue (Any | None) – Optional, any value attached to the edge, e.g. a case label. Default: None.

  • edgeKind (EdgeKind) – Optional, kind of the edge. Default: EdgeKind.Default.

  • keyValuePairs (Mapping[Hashable, Any] | None) – Optional, mapping (dictionary) of key-value-pairs for the edge. Default: None.

Return type:

Edge

Returns:

The edge leading from this block to the destination.

Raises:
  • ValueError – If this block is an exit or unwind block.

  • ValueError – If parameter ‘destination’ is None.

  • TypeError – If parameter ‘destination’ is not of type BasicBlock.

  • ValueError – If parameter ‘destination’ is an entry block.

  • ValueError – If parameter ‘destination’ belongs to another graph than this block.

  • TypeError – If parameter ‘edgeCount’ is not of type int.

  • ValueError – If parameter ‘edgeCount’ is negative.

  • ValueError – If parameter ‘edgeKind’ is None.

  • TypeError – If parameter ‘edgeKind’ is not of type EdgeKind.

  • DuplicateEdgeError – If an edge of the same kind connects the two blocks already.

See also

EdgeFrom()

→ Create an inbound edge from a block to this block.

EdgeFrom(source, edgeCount=None, edgeValue=None, edgeKind=EdgeKind.Default, keyValuePairs=None)[source]

Create an inbound edge from the block control leaves to this block.

Parameters:
  • source (BasicBlock) – The block control leaves.

  • edgeCount (int | None) – Optional, how often control took the edge. Default: None.

  • edgeValue (Any | None) – Optional, any value attached to the edge, e.g. a case label. Default: None.

  • edgeKind (EdgeKind) – Optional, kind of the edge. Default: EdgeKind.Default.

  • keyValuePairs (Mapping[Hashable, Any] | None) – Optional, mapping (dictionary) of key-value-pairs for the edge. Default: None.

Return type:

Edge

Returns:

The edge leading from the source to this block.

Raises:
  • ValueError – If parameter ‘source’ is None.

  • TypeError – If parameter ‘source’ is not of type BasicBlock.

  • ValueError – If parameter ‘source’ is an exit or unwind block.

  • ValueError – If this block is an entry block.

  • ValueError – If this block belongs to another graph than parameter ‘source’.

  • TypeError – If parameter ‘edgeCount’ is not of type int.

  • ValueError – If parameter ‘edgeCount’ is negative.

  • ValueError – If parameter ‘edgeKind’ is None.

  • TypeError – If parameter ‘edgeKind’ is not of type EdgeKind.

  • DuplicateEdgeError – If an edge of the same kind connects the two blocks already.

See also

EdgeTo()

→ Create an outbound edge from this block to a block control continues with.

property Count: int | None

Property to access how often the element was executed (_count).

Returns:

The execution count, or None if it’s unknown.

Raises:
classmethod GetMethodsWithAttributes(predicate: type[TAttr] | Iterable[type[TAttr]] | None = None) → dict[Callable[[...], Any], tuple[Attribute, ...]]

Return the class’ methods that carry at least one matching attribute.

Parameters:

predicate (type[TypeVar(TAttr, bound= Attribute)] | Iterable[type[TypeVar(TAttr, bound= Attribute)]] | None) – Optional, an attribute class, an iterable of attribute classes, or None to accept every attribute.

Return type:

dict[Callable[..., Any], tuple[Attribute, ...]]

Returns:

Dictionary of methods and the matching attributes attached to them.

Raises:
  • ValueError – If an element of parameter ‘predicate’ is not a sub-class of Attribute.

  • ValueError – If parameter ‘predicate’ is neither an attribute class nor an iterable of those.

property Value: Any | None

Property to access the value attached to the element (_value).

Returns:

The value, or None if none is attached.

__contains__(key)

Check if the key is an attached attribute (key-value-pair) of this element.

Parameters:

key (Hashable) – The key to check.

Return type:

bool

Returns:

True, if the key is an attached attribute.

__delitem__(key)

Remove an attached attribute (key-value-pair) by key.

Parameters:

key (Hashable) – The key to remove.

Raises:

KeyError – If the key doesn’t exist in the element’s attributes.

Return type:

None

__getitem__(key)

Read an attached attribute (key-value-pair) by key.

Parameters:

key (Hashable) – The key to look for.

Return type:

Any

Returns:

The value associated to the given key.

Raises:

KeyError – If the key doesn’t exist in the element’s attributes.

__getstate__() → dict[str, Any]

Return the object’s state for pickling, collecting every slot of the class hierarchy.

Return type:

dict[str, Any]

Returns:

Dictionary of slot names and their values.

Raises:

ExtendedTypeError – If a slot was never assigned, so it has no value to serialize.

__iter__()

Iterate the keys of the attached attributes (key-value-pairs) of this element.

Return type:

Iterator[Hashable]

Returns:

An iterator over the keys, in the order they were created.

__len__()

Return the number of attached attributes (key-value-pairs) of this element.

Return type:

int

Returns:

Number of attached attributes.

__setitem__(key, value)

Create or update an attached attribute (key-value-pair) by key.

If a key doesn’t exist yet, a new key-value-pair is created.

Parameters:
  • key (Hashable) – The key to create or update.

  • value (Any) – The value to associate to the given key.

Return type:

None

__setstate__(state: dict[str, Any]) → None

Restore the object’s state from unpickling, requiring exactly the slots of the class hierarchy.

Parameters:

state (dict[str, Any]) – Dictionary of slot names and their values.

Raises:

ExtendedTypeError – If the given state misses a slot or carries an unexpected one.

Return type:

None

_count: int | None

How often the element was executed, or None if that’s unknown.

_dict: dict[Hashable, Any]

A dictionary to store arbitrary key-value-pairs.

_value: Any | None

Any value attached to the element, or None.

class pyTooling.ControlFlow.Edge[source]

An edge of a control flow graph, leading from a block to a block control continues with.

The edge’s EdgeKind says why control continues there. Two blocks can be connected by edges of different kinds, but only by one edge of each kind.

Inheritance

Inheritance diagram of Edge

__init__(source, destination, kind=EdgeKind.Default, *, count=None, value=None, keyValuePairs=None)[source]

Initializes an edge between two blocks of a graph and adds it to the graph.

Parameters:
  • source (BasicBlock) – The block control leaves.

  • destination (BasicBlock) – The block control continues with.

  • kind (EdgeKind) – Optional, kind of the edge. Default: EdgeKind.Default.

  • count (int | None) – Optional, how often control took the edge. Default: None.

  • value (Any | None) – Optional, any value attached to the edge, e.g. a case label. Default: None.

  • keyValuePairs (Mapping[Hashable, Any] | None) – Optional, mapping (dictionary) of key-value-pairs. Default: None.

Raises:
  • TypeError – If parameter ‘count’ is not of type int.

  • ValueError – If parameter ‘count’ is negative.

  • ValueError – If parameter ‘source’ is None.

  • TypeError – If parameter ‘source’ is not of type BasicBlock.

  • ValueError – If parameter ‘source’ is an exit or unwind block.

  • ValueError – If parameter ‘destination’ is None.

  • TypeError – If parameter ‘destination’ is not of type BasicBlock.

  • ValueError – If parameter ‘destination’ is an entry block.

  • ValueError – If parameter ‘destination’ belongs to another graph than parameter ‘source’.

  • ValueError – If parameter ‘kind’ is None.

  • TypeError – If parameter ‘kind’ is not of type EdgeKind.

  • DuplicateEdgeError – If an edge of the same kind connects the two blocks already.

Return type:

None

_source: BasicBlock

The block control leaves.

_destination: BasicBlock

The block control continues with.

_kind: EdgeKind

Kind of the edge.

property Source: BasicBlock

Read-only property to access the block control leaves (_source).

Returns:

The source block.

property Destination: BasicBlock

Read-only property to access the block control continues with (_destination).

Returns:

The destination block.

property Kind: EdgeKind

Read-only property to access the edge’s kind (_kind).

Returns:

Kind of the edge.

property Count: int | None

Property to access how often the element was executed (_count).

Returns:

The execution count, or None if it’s unknown.

Raises:
classmethod GetMethodsWithAttributes(predicate: type[TAttr] | Iterable[type[TAttr]] | None = None) → dict[Callable[[...], Any], tuple[Attribute, ...]]

Return the class’ methods that carry at least one matching attribute.

Parameters:

predicate (type[TypeVar(TAttr, bound= Attribute)] | Iterable[type[TypeVar(TAttr, bound= Attribute)]] | None) – Optional, an attribute class, an iterable of attribute classes, or None to accept every attribute.

Return type:

dict[Callable[..., Any], tuple[Attribute, ...]]

Returns:

Dictionary of methods and the matching attributes attached to them.

Raises:
  • ValueError – If an element of parameter ‘predicate’ is not a sub-class of Attribute.

  • ValueError – If parameter ‘predicate’ is neither an attribute class nor an iterable of those.

property Value: Any | None

Property to access the value attached to the element (_value).

Returns:

The value, or None if none is attached.

__contains__(key)

Check if the key is an attached attribute (key-value-pair) of this element.

Parameters:

key (Hashable) – The key to check.

Return type:

bool

Returns:

True, if the key is an attached attribute.

__delitem__(key)

Remove an attached attribute (key-value-pair) by key.

Parameters:

key (Hashable) – The key to remove.

Raises:

KeyError – If the key doesn’t exist in the element’s attributes.

Return type:

None

__getitem__(key)

Read an attached attribute (key-value-pair) by key.

Parameters:

key (Hashable) – The key to look for.

Return type:

Any

Returns:

The value associated to the given key.

Raises:

KeyError – If the key doesn’t exist in the element’s attributes.

__getstate__() → dict[str, Any]

Return the object’s state for pickling, collecting every slot of the class hierarchy.

Return type:

dict[str, Any]

Returns:

Dictionary of slot names and their values.

Raises:

ExtendedTypeError – If a slot was never assigned, so it has no value to serialize.

__iter__()

Iterate the keys of the attached attributes (key-value-pairs) of this element.

Return type:

Iterator[Hashable]

Returns:

An iterator over the keys, in the order they were created.

__len__()

Return the number of attached attributes (key-value-pairs) of this element.

Return type:

int

Returns:

Number of attached attributes.

__setitem__(key, value)

Create or update an attached attribute (key-value-pair) by key.

If a key doesn’t exist yet, a new key-value-pair is created.

Parameters:
  • key (Hashable) – The key to create or update.

  • value (Any) – The value to associate to the given key.

Return type:

None

__setstate__(state: dict[str, Any]) → None

Restore the object’s state from unpickling, requiring exactly the slots of the class hierarchy.

Parameters:

state (dict[str, Any]) – Dictionary of slot names and their values.

Raises:

ExtendedTypeError – If the given state misses a slot or carries an unexpected one.

Return type:

None

_count: int | None

How often the element was executed, or None if that’s unknown.

_dict: dict[Hashable, Any]

A dictionary to store arbitrary key-value-pairs.

_value: Any | None

Any value attached to the element, or None.

class pyTooling.ControlFlow.ControlFlowGraph[source]

The control flow graph of a function: its basic blocks, the edges between them, and its entry and exit block.

A block is looked up by its ID: graph.GetBlock(3) returns the block with ID 3, and graph.ContainsBlock(3) checks if the graph has one. IterateBlocks() yields the blocks in the order they were created. The graph’s dunder methods serve its key-value-pairs, like a block’s or an edge’s.

Inheritance

Inheritance diagram of ControlFlowGraph

classmethod GetMethodsWithAttributes(predicate: type[TAttr] | Iterable[type[TAttr]] | None = None) → dict[Callable[[...], Any], tuple[Attribute, ...]]

Return the class’ methods that carry at least one matching attribute.

Parameters:

predicate (type[TypeVar(TAttr, bound= Attribute)] | Iterable[type[TypeVar(TAttr, bound= Attribute)]] | None) – Optional, an attribute class, an iterable of attribute classes, or None to accept every attribute.

Return type:

dict[Callable[..., Any], tuple[Attribute, ...]]

Returns:

Dictionary of methods and the matching attributes attached to them.

Raises:
  • ValueError – If an element of parameter ‘predicate’ is not a sub-class of Attribute.

  • ValueError – If parameter ‘predicate’ is neither an attribute class nor an iterable of those.

__contains__(key)

Check if the key is an attached attribute (key-value-pair) of this element.

Parameters:

key (Hashable) – The key to check.

Return type:

bool

Returns:

True, if the key is an attached attribute.

__delitem__(key)

Remove an attached attribute (key-value-pair) by key.

Parameters:

key (Hashable) – The key to remove.

Raises:

KeyError – If the key doesn’t exist in the element’s attributes.

Return type:

None

__getitem__(key)

Read an attached attribute (key-value-pair) by key.

Parameters:

key (Hashable) – The key to look for.

Return type:

Any

Returns:

The value associated to the given key.

Raises:

KeyError – If the key doesn’t exist in the element’s attributes.

__getstate__() → dict[str, Any]

Return the object’s state for pickling, collecting every slot of the class hierarchy.

Return type:

dict[str, Any]

Returns:

Dictionary of slot names and their values.

Raises:

ExtendedTypeError – If a slot was never assigned, so it has no value to serialize.

__init__(name, *, entryID='entry', exitID='exit', keyValuePairs=None)[source]

Initializes a control flow graph of a function, with an entry and an exit block.

The entry and the exit are the graph’s first two blocks. An unwind block is created like any other block, as a block of BlockKind.Unwind.

Parameters:
  • name (str) – Name of the function.

  • entryID (Hashable) – Optional, ID of the entry block. Default: "entry".

  • exitID (Hashable) – Optional, ID of the exit block. Default: "exit".

  • keyValuePairs (Mapping[Hashable, Any] | None) – Optional, mapping (dictionary) of key-value-pairs. Default: None.

Raises:
  • ValueError – If parameter ‘name’ is None.

  • TypeError – If parameter ‘name’ is not of type str.

  • ValueError – If parameter ‘name’ is empty.

  • ValueError – If parameter ‘entryID’ is None.

  • TypeError – If parameter ‘entryID’ is not hashable.

  • ValueError – If parameter ‘exitID’ is None.

  • TypeError – If parameter ‘exitID’ is not hashable.

  • ValueError – If parameter ‘exitID’ equals parameter ‘entryID’.

Return type:

None

__iter__()

Iterate the keys of the attached attributes (key-value-pairs) of this element.

Return type:

Iterator[Hashable]

Returns:

An iterator over the keys, in the order they were created.

__len__()

Return the number of attached attributes (key-value-pairs) of this element.

Return type:

int

Returns:

Number of attached attributes.

__setitem__(key, value)

Create or update an attached attribute (key-value-pair) by key.

If a key doesn’t exist yet, a new key-value-pair is created.

Parameters:
  • key (Hashable) – The key to create or update.

  • value (Any) – The value to associate to the given key.

Return type:

None

__setstate__(state: dict[str, Any]) → None

Restore the object’s state from unpickling, requiring exactly the slots of the class hierarchy.

Parameters:

state (dict[str, Any]) – Dictionary of slot names and their values.

Raises:

ExtendedTypeError – If the given state misses a slot or carries an unexpected one.

Return type:

None

_dict: dict[Hashable, Any]

A dictionary to store arbitrary key-value-pairs.

_name: str

Name of the function.

_blocks: dict[Hashable, BasicBlock]

Blocks of the graph by ID, in the order they were created.

_edges: list[Edge]

Edges of the graph, in the order they were created.

_unwind: BasicBlock | None

The block an exception leaves the function through, if the graph has one.

_entry: BasicBlock

The block control enters the function through.

_exit: BasicBlock

The block control leaves the function through, when the function returns.

property Name: str

Read-only property to access the name of the function (_name).

Returns:

Name of the function.

property Entry: BasicBlock

Read-only property to access the block control enters the function through (_entry).

Returns:

The entry block.

property Exit: BasicBlock

Read-only property to access the block control leaves the function through, when it returns (_exit).

Returns:

The exit block.

property Unwind: BasicBlock | None

Read-only property to access the block an exception leaves the function through (_unwind).

Returns:

The unwind block, or None if the graph has none.

property Blocks: dict[Hashable, BasicBlock]

Read-only property to access the blocks of the graph by ID (_blocks).

Returns:

The blocks, in the order they were created.

property Edges: list[Edge]

Read-only property to access the edges of the graph (_edges).

Returns:

The edges, in the order they were created.

property BlockCount: int

Read-only property to return the number of blocks in the graph, including its entry, exit and unwind block.

Returns:

Number of blocks.

ContainsBlock(blockID)[source]

Check if the graph has a block with the given ID.

Parameters:

blockID (Hashable) – ID of the block.

Return type:

bool

Returns:

True, if the graph has a block with that ID.

GetBlock(blockID)[source]

Return the block with the given ID.

Parameters:

blockID (Hashable) – ID of the block.

Return type:

BasicBlock

Returns:

The block with that ID.

Raises:

KeyError – If the graph has no block with that ID.

IterateBlocks(predicate=None)[source]

Iterate all or selected blocks of the graph.

If parameter predicate is not None, the given filter function is used to skip blocks in the generator.

Parameters:

predicate (Callable[[BasicBlock], bool] | None) – Optional, filter function accepting any block and returning a boolean.

Return type:

Generator[BasicBlock, None, None]

Returns:

A generator to iterate the blocks, in the order they were created.

ToGraph()[source]

Convert the control flow graph into a Graph.

Every block becomes a Vertex with the block’s ID as ID and the block’s value as Value, so Graph.GetVertexByID finds a block’s vertex. Every edge becomes an Edge in the direction control flows, with the edge’s kind as Kind and the edge’s value as value.

The graph, its vertices and its edges carry a copy of the key-value-pairs of the control flow graph, its blocks and its edges. Vertices and edges carry two key-value-pairs more, which a writer like pyTooling.Graph.GraphML writes out:

  • kind: the block’s BlockKind or the edge’s EdgeKind member, whose str() is its name.

  • count: the execution count; only if it’s known.

Return type:

Graph

Returns:

The graph, named like the control flow graph.