Skip to content

An extremely fast Python library to calculate the cognitive complexity of Python files, written in Rust.

License

Notifications You must be signed in to change notification settings

rohaquinlop/complexipy

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

complexipy

complexipy

An extremely fast Python library to calculate the cognitive complexity of Python files, written in Rust.

Quality Gate Package version

Cognitive Complexity breaks from using mathematical models to assess software maintainability by combining Cyclomatic Complexity precedents with human assessment. It yields method complexity scores that align well with how developers perceive maintainability. Read the white paper here: Cognitive Complexity, a new way of measuring understandability


Documentation: https://rohaquinlop.github.io/complexipy/

Source Code: https://github.com/rohaquinlop/complexipy

PyPI: https://pypi.org/project/complexipy/


Contributors

Made with contributors-img

Requirements

  • Python >= 3.8
  • You also need to install git in your computer if you want to analyze a git repository.

Installation

pip install complexipy

Usage

To run complexipy from the command line, use the following commands:

complexipy .                            # Analyze the current directory and any subdirectories
complexipy path/to/directory            # Analyze a specific directory and any subdirectories
complexipy git_repository_url           # Analyze a git repository
complexipy path/to/file.py              # Analyze a specific file
complexipy path/to/file.py -c 20        # Use the -c option to set the maximum congnitive complexity, default is 15
complexipy path/to/directory -c 0       # Set the maximum cognitive complexity to 0 to disable the exit with error
complexipy path/to/directory -o         # Use the -o option to output the results to a CSV file, default is False
complexipy path/to/directory -d low     # Use the -d option to set detail level, default is "normal". If set to "low" will show only files with complexity greater than the maximum complexity
complexipy path/to/directory -l file    # Use the -l option to set the level of measurement, default is "function". If set to "file" will measure the complexity of the file and will validate the maximum complexity according to the file complexity.
complexipy path/to/directory -q         # Use the -q option to disable the output to the console, default is False.
complexipy path/to/directory -s desc    # Use the -s option to set the sort order, default is "asc". If set to "desc" will sort the results in descending order. If set to "asc" will sort the results in ascending order. If set to "name" will sort the results by name.

Options

  • -c or --max-complexity: Set the maximum cognitive complexity, default is 15. If the cognitive complexity of a file is greater than the maximum cognitive, then the return code will be 1 and exit with error, otherwise it will be 0. If set to 0, the exit with error will be disabled.
  • -o or --output: Output the results to a CSV file, default is False. The filename will be complexipy.csv and will be saved in the invocation directory.
  • -d or --details: Set the detail level, default is "normal". If set to "low" will show only files or functions with complexity greater than the maximum complexity.
  • -l or --level Set the level of measurement, default is "function". If set to "file" will measure the complexity of the file and will validate the maximum complexity according to the file complexity. If set to "function" will measure the complexity of the functions and will validate the maximum complexity according to the function complexity. This option is useful if you want to set a maximum complexity according for each file or for each function in the file (or files).
  • -q or --quiet: Disable the output to the console, default is False.
  • -s or --sort: Set the sort order, default is "asc". If set to "desc" will sort the results in descending order. If set to "asc" will sort the results in ascending order. If set to "name" will sort the results by name. This option will affect the output to the console and the output to the CSV file.

If the cognitive complexity of a file or a function is greater than the maximum cognitive cognitive complexity, then the return code will be 1 and exit with error, otherwise it will be 0.

Use the library from python code

The available library commands are:

  • complexipy.file_complexity: takes in a file-path and returns the complexity of the file
  • complexipy.code_complexity: takes in a string and (provided the string is a parsable snippet of python code) returns the complexity of the snippet.

Example

Analyzing a file

Given the following file:

def a_decorator(a, b):
    def inner(func):
        return func
    return inner

def b_decorator(a, b):
    def inner(func):
        if func:
            return None
        return func
    return inner

The cognitive complexity of the file is 1.

From the CLI

The output of the command complexipy path/to/file.py will be:

───────────────────────────── 🐙 complexipy 0.4.0 ──────────────────────────────
                                    Summary
      ┏━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━━━━━┓
      ┃ Path              ┃ File              ┃ Function    ┃ Complexity ┃
      ┡━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━━━━━┩
      │ test_decorator.py │ test_decorator.py │ a_decorator │ 0          │
      ├───────────────────┼───────────────────┼─────────────┼────────────┤
      │ test_decorator.py │ test_decorator.py │ b_decorator │ 1          │
      └───────────────────┴───────────────────┴─────────────┴────────────┘
🧠 Total Cognitive Complexity in ./tests/src/test_decorator.py: 1
1 file analyzed in 0.0032 seconds
────────────────────────── 🎉 Analysis completed! 🎉 ───────────────────────────

Using the library

Calling file_complexity on a file-path:

>>> from complexipy import file_complexity
>>> fc = file_complexity("path/to/file.py")
>>> fc.complexity
1

Calling code_complexity on a snippet of code:

>>> from complexipy import code_complexity
>>> snippet = """for x in range(0, 10):
    print(x)
"""
>>> cc = code_complexity(snippet)
cc.complexity
1

Explaining the results of the analysis

def a_decorator(a, b): # 0
    def inner(func): # 0
        return func # 0
    return inner # 0

def b_decorator(a, b): # 0
    def inner(func): # 0
        if func: # 1 (nested = 0), total 1
            return None # 0
        return func # 0
    return inner # 0

The cognitive complexity of the file is 1, and the cognitive complexity of the function b_decorator is 1. This example is simple, but it shows how complexipy calculates the cognitive complexity according to the specifications of the paper "Cognitive Complexity a new way to measure understandability", considering the decorators and the if statement.

Output to a CSV file

If you want to output the results to a CSV file, you can use the -o option, this is really useful if you want to integrate complexipy with other tools, for example, a CI/CD pipeline. You will get the output in the console and will create a CSV file with the results of the analysis.

The filename will be complexipy.csv and will be saved in the current directory.

$ complexipy path/to/file.py -o

The output will be:

Path,File Name,Function Name,Cognitive Complexity
test_decorator.py,test_decorator.py,a_decorator,0
test_decorator.py,test_decorator.py,b_decorator,1

Analyzing a directory

You can also analyze a directory, for example:

$ complexipy .

And complexipy will analyze all the files in the current directory and any subdirectories.

Analyzing a git repository

You can also analyze a git repository, for example:

$ complexipy https://github.com/rohaquinlop/complexipy

And to generate the output to a CSV file:

$ complexipy https://github.com/rohaquinlop/complexipy -o

License

This project is licensed under the MIT License - see the LICENSE file for details.

Acknowledgments

  • Thanks to G. Ann Campbell for publishing the paper "Cognitive Complexity a new way to measure understandability".
  • This project is inspired by the Sonar way to calculate the cognitive complexity.

References