An extremely fast Python library to calculate the cognitive complexity of Python files, written in Rust.
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/
Made with contributors-img
- Python >= 3.8
- You also need to install
git
in your computer if you want to analyze a git repository.
pip install complexipy
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.
-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 becomplexipy.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.
The available library commands are:
complexipy.file_complexity
: takes in a file-path and returns the complexity of the filecomplexipy.code_complexity
: takes in a string and (provided the string is a parsable snippet of python code) returns the complexity of the snippet.
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.
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! 🎉 ───────────────────────────
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
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.
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
You can also analyze a directory, for example:
$ complexipy .
And complexipy will analyze all the files in the current directory and any subdirectories.
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
This project is licensed under the MIT License - see the LICENSE file for details.
- 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.