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 libaries. Run the following command in the terminal:

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

Sample Usage

This feature uses python_ta.cfg.cfg_generator.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.cfg_generator as cfg_generator

    cfg_generator.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.cfg_generator as cfg_generator

cfg_generator.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).

API

python_ta.cfg.cfg_generator.generate_cfg(mod: str = '', auto_open: bool = False, visitor_options: Dict[str, Any] | None = None) 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.

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.