Control Flow Graphs

This page describes an additional PythonTA feature: visualizing the control flow of a program. This feature makes it easier to visualize how the computer executes your program by producing a scalable control flow graph using Graphviz.

Code Example

x = 0
if x > 0:
    x = 4
else:
    x = -1

The corresponding control flow graph for the code example above is included below:

if_else.svg

Additional installation required!

To use PythonTA’s control flow graph visualizer, you’ll need to install some additional software:

  1. Install Graphviz. (This isn’t Python software.)

  2. Install some additional Python libraries. Run the following command in the terminal:

    $ python3 -m pip install python-ta[cfg]
    

Python API Usage

This feature uses python_ta.cfg.generate_cfg to produce these control flow graphs.

The first argument specifies which Python file to create a control flow graph for. By default, it generates a control flow graph of the current file in which it is called from.

# my_file.py

... # code here

if __name__ == "__main__":
    import python_ta.cfg as cfg

    cfg.generate_cfg()

After running this file, a new svg file is created called my_file.svg.

This feature is not limited to just the Python file from which the function is called. It can also be used to generate a control flow graph of a different Python file. The set-up is the exact same as before, except we can pass an argument to the function call which is the path to the target Python file.

import python_ta.cfg as cfg

cfg.generate_cfg("my_file.py")

There is also an additional optional argument that allows you to configure how the control flow graphs are generated. For example, you can separate the if condition from the preceding statements, or you can specify function and method names to restrict the creation of control flow graphs to just those functions.

# Assume my_file.py has a class `MyClass` with method `MyClass.foo` and a top-level method `foo`

import python_ta.cfg.cfg_generator as cfg_generator

options = {
        "separate-condition-blocks": True,
        "functions": ["MyClass.foo"]
    }

cfg_generator.generate_cfg(mod="my_file.py", visitor_options=options)

which produces the following control flow graph:

method_only.svg

Note: only one control flow graph can be generated per function call (i.e. you can’t pass in a list of files to generate control flow graphs for).

Command-Line Usage

PythonTA also provides a command-line interface for generating control flow graphs:

$ python -m python_ta.cfg my_file.py

This generates my_file.svg in the current directory containing the control flow graph for my_file.py.

Command-Line Options

The command-line interface accepts the following options:

  • --auto-open: Automatically open the generated graph in your default SVG viewer

  • --visitor-options: Comma-separated key=value pairs for configuration options. This accepts the same options as the visitor_options parameter in the programmatic API:

    • separate-condition-blocks: Separate if conditions into their own blocks (true/false)

    • functions: List of specific functions/methods to generate CFGs for

Examples

Generate a CFG and automatically open it:

$ python -m python_ta.cfg my_file.py --auto-open

Generate CFG only for specific functions:

$ python -m python_ta.cfg my_file.py --visitor-options "functions='MyClass.foo,main'"

Separate condition blocks in the graph:

$ python -m python_ta.cfg my_file.py --visitor-options "separate-condition-blocks=true"

Combine multiple options:

$ python -m python_ta.cfg my_file.py --auto-open --visitor-options "separate-condition-blocks=true,functions='analyze_data'"

For help and available options:

$ python -m python_ta.cfg --help

API

python_ta.cfg.generate_cfg(mod: str = '', auto_open: bool = False, visitor_options: dict[str, Any] | None = None, z3_enabled: bool = False) None

Generate a control flow graph for the given module.

Supported Options:
  • “separate-condition-blocks”: bool

    This option specifies whether the test condition of an if statement gets merged with any preceding statements or placed in a new block. By default, it will merge them.

  • “functions”: list[str]

    This option specifies whether to restrict the creation of cfgs to just top-level function definitions or methods provided in this list. By default, it will create the cfg for the entire file.

Parameters:
  • mod (str) – The path to the module. mod can either be the path of a file (must have .py extension) or have no argument (generates a CFG for the Python file from which this function is called).

  • auto_open (bool) – Automatically open the graph in your browser.

  • visitor_options (dict) – An options dict to configure how the cfgs are generated.

  • z3_enabled (bool) – An option that enables z3 when True (by default False).

Note: the specified functions must be top-level functions or methods. That is, function definitions that are nested inside other types of syntax aside from class definitions (e.g. if and for statements) will not be detected. For specifying methods, use their qualified names. For example, if you have a class named MyClass with the method foo, use MyClass.foo.