complexipy 3.0.0__tar.gz → 3.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {complexipy-3.0.0 → complexipy-3.2.0}/Cargo.lock +1 -1
- {complexipy-3.0.0 → complexipy-3.2.0}/Cargo.toml +1 -1
- complexipy-3.2.0/PKG-INFO +454 -0
- complexipy-3.2.0/README.md +423 -0
- {complexipy-3.0.0 → complexipy-3.2.0}/complexipy/main.py +25 -19
- {complexipy-3.0.0 → complexipy-3.2.0}/complexipy/utils.py +14 -4
- complexipy-3.2.0/docs/index.md +394 -0
- {complexipy-3.0.0 → complexipy-3.2.0}/src/cognitive_complexity/mod.rs +50 -30
- {complexipy-3.0.0 → complexipy-3.2.0}/src/cognitive_complexity/utils.rs +2 -2
- {complexipy-3.0.0 → complexipy-3.2.0}/uv.lock +81 -60
- {complexipy-3.0.0 → complexipy-3.2.0}/vscode/complexipy/CHANGELOG.md +5 -5
- {complexipy-3.0.0 → complexipy-3.2.0}/vscode/complexipy/README.md +4 -4
- {complexipy-3.0.0 → complexipy-3.2.0}/vscode/complexipy/extension.js +1 -1
- {complexipy-3.0.0 → complexipy-3.2.0}/vscode/complexipy/package.json +1 -1
- complexipy-3.0.0/PKG-INFO +0 -465
- complexipy-3.0.0/README.md +0 -434
- complexipy-3.0.0/docs/index.md +0 -410
- {complexipy-3.0.0 → complexipy-3.2.0}/.pre-commit-config.yaml +0 -0
- {complexipy-3.0.0 → complexipy-3.2.0}/LICENSE +0 -0
- {complexipy-3.0.0 → complexipy-3.2.0}/build-wasm.sh +0 -0
- {complexipy-3.0.0 → complexipy-3.2.0}/complexipy/__init__.py +0 -0
- {complexipy-3.0.0 → complexipy-3.2.0}/complexipy/types.py +0 -0
- {complexipy-3.0.0 → complexipy-3.2.0}/docs/img/complexipy_icon.svg +0 -0
- {complexipy-3.0.0 → complexipy-3.2.0}/mkdocs.yml +0 -0
- {complexipy-3.0.0 → complexipy-3.2.0}/pyproject.toml +0 -0
- {complexipy-3.0.0 → complexipy-3.2.0}/serve-web-version.sh +0 -0
- {complexipy-3.0.0 → complexipy-3.2.0}/src/classes/mod.rs +0 -0
- {complexipy-3.0.0 → complexipy-3.2.0}/src/lib.rs +0 -0
- {complexipy-3.0.0 → complexipy-3.2.0}/src/wasm.rs +0 -0
- {complexipy-3.0.0 → complexipy-3.2.0}/vscode/complexipy/.vscode-test.mjs +0 -0
- {complexipy-3.0.0 → complexipy-3.2.0}/vscode/complexipy/.vscodeignore +0 -0
- {complexipy-3.0.0 → complexipy-3.2.0}/vscode/complexipy/LICENSE +0 -0
- {complexipy-3.0.0 → complexipy-3.2.0}/vscode/complexipy/eslint.config.mjs +0 -0
- {complexipy-3.0.0 → complexipy-3.2.0}/vscode/complexipy/img/complexipy.png +0 -0
- {complexipy-3.0.0 → complexipy-3.2.0}/vscode/complexipy/img/complexipy_icon.png +0 -0
- {complexipy-3.0.0 → complexipy-3.2.0}/vscode/complexipy/img/complexipy_icon.svg +0 -0
- {complexipy-3.0.0 → complexipy-3.2.0}/vscode/complexipy/jsconfig.json +0 -0
- {complexipy-3.0.0 → complexipy-3.2.0}/vscode/complexipy/package-lock.json +0 -0
- {complexipy-3.0.0 → complexipy-3.2.0}/vscode/complexipy/test/extension.test.js +0 -0
- {complexipy-3.0.0 → complexipy-3.2.0}/vscode/complexipy/vsc-extension-quickstart.md +0 -0
|
@@ -0,0 +1,454 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: complexipy
|
|
3
|
+
Version: 3.2.0
|
|
4
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
5
|
+
Classifier: Environment :: Console
|
|
6
|
+
Classifier: Intended Audience :: Developers
|
|
7
|
+
Classifier: Operating System :: OS Independent
|
|
8
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
9
|
+
Classifier: Programming Language :: Python
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
15
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
16
|
+
Classifier: Topic :: Software Development :: Quality Assurance
|
|
17
|
+
Classifier: Topic :: Software Development :: Testing
|
|
18
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
19
|
+
Requires-Dist: typer>=0.12.5
|
|
20
|
+
License-File: LICENSE
|
|
21
|
+
Summary: An extremely fast Python library to calculate the cognitive complexity of Python files, written in Rust.
|
|
22
|
+
Keywords: cognitive,complexity,cognitive complexity,quality,quality assurance,testing,libraries,performance,sonar
|
|
23
|
+
Home-Page: https://github.com/rohaquinlop/complexipy
|
|
24
|
+
Author: Robin Quintero <rohaquinlop301@gmail.com>
|
|
25
|
+
Author-email: Robin Quintero <rohaquinlop301@gmail.com>
|
|
26
|
+
License: MIT
|
|
27
|
+
Requires-Python: >=3.8
|
|
28
|
+
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
|
|
29
|
+
Project-URL: Source Code, https://github.com/rohaquinlop/complexipy
|
|
30
|
+
|
|
31
|
+
# complexipy
|
|
32
|
+
|
|
33
|
+
<div align="center">
|
|
34
|
+
<a href="https://sonarcloud.io/summary/new_code?id=rohaquinlop_complexipy" target="_blank">
|
|
35
|
+
<img src="https://sonarcloud.io/api/project_badges/measure?project=rohaquinlop_complexipy&metric=alert_status" alt="Quality Gate">
|
|
36
|
+
</a>
|
|
37
|
+
<a href="https://pypi.org/project/complexipy" target="_blank">
|
|
38
|
+
<img src="https://img.shields.io/pypi/v/complexipy?color=%2334D058&label=pypi%20package" alt="Package version">
|
|
39
|
+
</a>
|
|
40
|
+
<a href="https://pepy.tech/project/complexipy" target="_blank">
|
|
41
|
+
<img src="https://static.pepy.tech/badge/complexipy" alt="Downloads">
|
|
42
|
+
</a>
|
|
43
|
+
<a href="https://github.com/rohaquinlop/complexipy/blob/main/LICENSE" target="_blank">
|
|
44
|
+
<img src="https://img.shields.io/github/license/rohaquinlop/complexipy" alt="License">
|
|
45
|
+
</a>
|
|
46
|
+
<a href="https://github.com/marketplace/actions/complexipy" target="_blank">
|
|
47
|
+
<img src="https://img.shields.io/badge/GitHub%20Actions-complexipy-2088FF?logo=github-actions&logoColor=white" alt="GitHub Actions">
|
|
48
|
+
</a>
|
|
49
|
+
<a href="https://marketplace.visualstudio.com/items?itemName=rohaquinlop.complexipy" target="_blank">
|
|
50
|
+
<img src="https://img.shields.io/visual-studio-marketplace/v/rohaquinlop.complexipy?color=%2334D058&label=vscode%20extension" alt="VSCode Extension">
|
|
51
|
+
</a>
|
|
52
|
+
<a href="https://github.com/rohaquinlop/complexipy-pre-commit" target="_blank">
|
|
53
|
+
<img src="https://img.shields.io/badge/pre--commit-complexipy-2088FF?logo=pre-commit&logoColor=white" alt="Pre-commit">
|
|
54
|
+
</a>
|
|
55
|
+
</div>
|
|
56
|
+
|
|
57
|
+
An extremely fast Python library to calculate the cognitive complexity of Python files, written in Rust.
|
|
58
|
+
|
|
59
|
+
## Table of Contents
|
|
60
|
+
- [complexipy](#complexipy)
|
|
61
|
+
- [Table of Contents](#table-of-contents)
|
|
62
|
+
- [What is Cognitive Complexity?](#what-is-cognitive-complexity)
|
|
63
|
+
- [Documentation](#documentation)
|
|
64
|
+
- [Requirements](#requirements)
|
|
65
|
+
- [Installation](#installation)
|
|
66
|
+
- [Usage](#usage)
|
|
67
|
+
- [Command Line Interface](#command-line-interface)
|
|
68
|
+
- [Command-line options](#command-line-options)
|
|
69
|
+
- [GitHub Action](#github-action)
|
|
70
|
+
- [Action Inputs](#action-inputs)
|
|
71
|
+
- [Examples](#examples)
|
|
72
|
+
- [Pre-commit Hook](#pre-commit-hook)
|
|
73
|
+
- [VSCode Extension](#vscode-extension)
|
|
74
|
+
- [Python API](#python-api)
|
|
75
|
+
- [Quick-start](#quick-start)
|
|
76
|
+
- [End-to-End Example](#end-to-end-example)
|
|
77
|
+
- [1. Prepare a sample file](#1--prepare-a-sample-file)
|
|
78
|
+
- [2. Run the CLI](#2--run-the-cli)
|
|
79
|
+
- [3. Use the Python API](#3--use-the-python-api)
|
|
80
|
+
- [4. Why is the score 1?](#4--why-is-the-score-1)
|
|
81
|
+
- [5. Persisting the results](#5--persisting-the-results)
|
|
82
|
+
- [6. Scaling up your analysis](#6--scaling-up-your-analysis)
|
|
83
|
+
- [Contributors](#contributors)
|
|
84
|
+
- [License](#license)
|
|
85
|
+
- [Acknowledgments](#acknowledgments)
|
|
86
|
+
- [References](#references)
|
|
87
|
+
|
|
88
|
+
## What is Cognitive Complexity?
|
|
89
|
+
|
|
90
|
+
Cognitive Complexity breaks from using mathematical models to assess software
|
|
91
|
+
maintainability by combining Cyclomatic Complexity precedents with human
|
|
92
|
+
assessment. It yields method complexity scores that align well with how
|
|
93
|
+
developers perceive maintainability.
|
|
94
|
+
|
|
95
|
+
Unlike traditional complexity metrics, cognitive complexity focuses on how difficult code is to *understand* by humans, making it more relevant for maintaining and reviewing code.
|
|
96
|
+
|
|
97
|
+
**Key benefits:**
|
|
98
|
+
- Identifies hard-to-understand code sections
|
|
99
|
+
- Helps improve code quality and maintainability
|
|
100
|
+
- Provides a more intuitive metric than traditional complexity measures
|
|
101
|
+
|
|
102
|
+
📄 Read the white paper: [Cognitive Complexity, a new way of measuring understandability](https://www.sonarsource.com/resources/cognitive-complexity/)
|
|
103
|
+
|
|
104
|
+
## Documentation
|
|
105
|
+
|
|
106
|
+
**Documentation**: <a href="https://rohaquinlop.github.io/complexipy/" target="_blank">https://rohaquinlop.github.io/complexipy/</a>
|
|
107
|
+
|
|
108
|
+
**Source Code**: <a href="https://github.com/rohaquinlop/complexipy" target="_blank">https://github.com/rohaquinlop/complexipy</a>
|
|
109
|
+
|
|
110
|
+
**PyPI**: <a href="https://pypi.org/project/complexipy/" target="_blank">https://pypi.org/project/complexipy/</a>
|
|
111
|
+
|
|
112
|
+
## Requirements
|
|
113
|
+
|
|
114
|
+
- Python >= 3.8
|
|
115
|
+
- Git (optional) - required only if you want to analyze a git repository
|
|
116
|
+
|
|
117
|
+
## Installation
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
pip install complexipy
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## Usage
|
|
124
|
+
|
|
125
|
+
### Command Line Interface
|
|
126
|
+
|
|
127
|
+
```shell
|
|
128
|
+
# Analyze the current directory (recursively)
|
|
129
|
+
complexipy .
|
|
130
|
+
|
|
131
|
+
# Analyze a specific directory (recursively)
|
|
132
|
+
complexipy path/to/directory
|
|
133
|
+
|
|
134
|
+
# Analyze a remote Git repository
|
|
135
|
+
complexipy https://github.com/user/repo.git
|
|
136
|
+
|
|
137
|
+
# Analyze a single file
|
|
138
|
+
complexipy path/to/file.py
|
|
139
|
+
|
|
140
|
+
# Suppress console output
|
|
141
|
+
complexipy path/to/directory --quiet # or -q
|
|
142
|
+
|
|
143
|
+
# List every function, ignoring the 15-point complexity threshold
|
|
144
|
+
complexipy path/to/file.py --ignore-complexity # or -i
|
|
145
|
+
|
|
146
|
+
# Show only files / functions whose complexity exceeds the threshold
|
|
147
|
+
complexipy path/to/directory --details low # or -d low
|
|
148
|
+
|
|
149
|
+
# Sort results (asc: ascending complexity, desc: descending complexity, name: A→Z)
|
|
150
|
+
complexipy path/to/directory --sort desc # or -s desc
|
|
151
|
+
|
|
152
|
+
# Save results
|
|
153
|
+
complexipy path/to/directory --output-csv # -c, writes complexipy.csv
|
|
154
|
+
complexipy path/to/directory --output-json # -j, writes complexipy.json
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
#### Command-line options
|
|
158
|
+
|
|
159
|
+
| Short | Long | Parameters | Description | Default |
|
|
160
|
+
| ----- | ------------------------ | ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- |
|
|
161
|
+
| `-c` | `--output-csv` | – | Write the report to `complexipy.csv` in the current working directory. | false |
|
|
162
|
+
| `-j` | `--output-json` | – | Write the report to `complexipy.json` in the current working directory. | false |
|
|
163
|
+
| `-i` | `--ignore-complexity` | – | Do not stop with an error when a function's cognitive complexity is > 15. All functions are still listed in the output. | off |
|
|
164
|
+
| `-d` | `--details <normal∣low>` | required | Control the verbosity of the output.<br>• `normal` – show every file and function (default)<br>• `low` – show only entries that exceed the complexity threshold | `normal` |
|
|
165
|
+
| `-q` | `--quiet` | – | Suppress console output. Exit codes are still returned. | false |
|
|
166
|
+
| `-s` | `--sort <asc∣desc∣name>` | required | Order the results.<br>• `asc` – complexity ascending (default)<br>• `desc` – complexity descending<br>• `name` – alphabetical A→Z | `asc` |
|
|
167
|
+
|
|
168
|
+
> **Note** The CLI exits with code **1** when at least one function exceeds the threshold of **15** points. Pass `--ignore-complexity` (`-i`) to disable this behaviour.
|
|
169
|
+
|
|
170
|
+
### GitHub Action
|
|
171
|
+
|
|
172
|
+
You can use complexipy as a GitHub Action to automatically check code complexity in your CI/CD pipeline:
|
|
173
|
+
|
|
174
|
+
```yaml
|
|
175
|
+
name: Check Code Complexity
|
|
176
|
+
on: [push, pull_request]
|
|
177
|
+
|
|
178
|
+
jobs:
|
|
179
|
+
complexity:
|
|
180
|
+
runs-on: ubuntu-latest
|
|
181
|
+
steps:
|
|
182
|
+
- uses: actions/checkout@v4
|
|
183
|
+
- name: Check Python Code Complexity
|
|
184
|
+
uses: rohaquinlop/complexipy-action@v2
|
|
185
|
+
with:
|
|
186
|
+
paths: . # Analyze the entire repository
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
#### Action Inputs
|
|
190
|
+
|
|
191
|
+
| Input | Type / Allowed Values | Required |
|
|
192
|
+
| ----------------- | ------------------------------------- | -------- |
|
|
193
|
+
| paths | string (single path or list of paths) | Yes |
|
|
194
|
+
| quiet | boolean | No |
|
|
195
|
+
| ignore_complexity | boolean | No |
|
|
196
|
+
| details | normal, low | No |
|
|
197
|
+
| sort | asc, desc, name | No |
|
|
198
|
+
| output_csv | boolean | No |
|
|
199
|
+
| output_json | boolean | No |
|
|
200
|
+
|
|
201
|
+
#### Examples
|
|
202
|
+
|
|
203
|
+
Basic Usage:
|
|
204
|
+
```yaml
|
|
205
|
+
- uses: rohaquinlop/complexipy-action@v1
|
|
206
|
+
with:
|
|
207
|
+
paths: |
|
|
208
|
+
.
|
|
209
|
+
project_path
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
Generate CSV Report:
|
|
213
|
+
```yaml
|
|
214
|
+
- uses: rohaquinlop/complexipy-action@v1
|
|
215
|
+
with:
|
|
216
|
+
paths: .
|
|
217
|
+
output_csv: true
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
Generate JSON Report:
|
|
221
|
+
```yaml
|
|
222
|
+
- uses: rohaquinlop/complexipy-action@v1
|
|
223
|
+
with:
|
|
224
|
+
paths: .
|
|
225
|
+
output_json: true
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
Analyze Specific Directory with Low Detail Output:
|
|
229
|
+
```yaml
|
|
230
|
+
- uses: rohaquinlop/complexipy-action@v1
|
|
231
|
+
with:
|
|
232
|
+
paths: ./src/python
|
|
233
|
+
details: low
|
|
234
|
+
sort: desc
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
### Pre-commit Hook
|
|
238
|
+
|
|
239
|
+
You can use complexipy as a pre-commit hook to automatically check code complexity before each commit. This helps maintain code quality by preventing complex code from being committed.
|
|
240
|
+
|
|
241
|
+
To use complexipy with pre-commit, add the following to your `.pre-commit-config.yaml`:
|
|
242
|
+
|
|
243
|
+
```yaml
|
|
244
|
+
repos:
|
|
245
|
+
- repo: https://github.com/rohaquinlop/complexipy-pre-commit
|
|
246
|
+
rev: v3.0.0 # Use the latest version
|
|
247
|
+
hooks:
|
|
248
|
+
- id: complexipy
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
The pre-commit hook will:
|
|
252
|
+
- Run automatically before each commit
|
|
253
|
+
- Check the cognitive complexity of your Python files
|
|
254
|
+
- Prevent commits if any function exceeds the complexity threshold
|
|
255
|
+
- Help maintain code quality standards in your repository
|
|
256
|
+
|
|
257
|
+
### VSCode Extension
|
|
258
|
+
|
|
259
|
+
You can also use complexipy directly in Visual Studio Code through our official [extension](https://marketplace.visualstudio.com/items?itemName=rohaquinlop.complexipy):
|
|
260
|
+
|
|
261
|
+
1. Open VS Code
|
|
262
|
+
2. Go to the Extensions view (Ctrl+Shift+X / Cmd+Shift+X)
|
|
263
|
+
3. Search for "complexipy"
|
|
264
|
+
4. Click Install
|
|
265
|
+
|
|
266
|
+
The extension provides:
|
|
267
|
+
- Real-time complexity analysis as you type
|
|
268
|
+
- Visual complexity indicators:
|
|
269
|
+
- Function complexity shown with ƒ symbol
|
|
270
|
+
- Line-level complexity shown with + symbol
|
|
271
|
+
- Color-coded indicators:
|
|
272
|
+
- Green: Low complexity (functions ≤ 15, lines ≤ 5)
|
|
273
|
+
- Red: High complexity (functions > 15, lines > 5)
|
|
274
|
+
- Automatic updates on:
|
|
275
|
+
- File save
|
|
276
|
+
- Active editor change
|
|
277
|
+
- Text changes
|
|
278
|
+
|
|
279
|
+
You can also trigger a manual analysis by:
|
|
280
|
+
1. Opening the Command Palette (Ctrl+Shift+P / Cmd+Shift+P)
|
|
281
|
+
2. Typing "complexipy"
|
|
282
|
+
3. Selecting the "complexipy" command
|
|
283
|
+
|
|
284
|
+
## Python API
|
|
285
|
+
|
|
286
|
+
Complexipy can also be used directly from your Python code. The high-level helper functions below wrap the Rust core and return lightweight Python classes that behave like regular dataclasses.
|
|
287
|
+
|
|
288
|
+
- `complexipy.file_complexity(path: str) -> FileComplexity` – analyse a Python file on disk.
|
|
289
|
+
- `complexipy.code_complexity(src: str) -> CodeComplexity` – analyse a string that contains Python source.
|
|
290
|
+
|
|
291
|
+
Both helpers return objects whose public attributes you can freely access:
|
|
292
|
+
|
|
293
|
+
```text
|
|
294
|
+
FileComplexity
|
|
295
|
+
├─ path: str # Relative path of the analysed file
|
|
296
|
+
├─ file_name: str # Filename without the directory part
|
|
297
|
+
├─ complexity: int # Cognitive complexity of the whole file
|
|
298
|
+
└─ functions: List[FunctionComplexity]
|
|
299
|
+
|
|
300
|
+
FunctionComplexity
|
|
301
|
+
├─ name: str
|
|
302
|
+
├─ complexity: int
|
|
303
|
+
├─ line_start: int
|
|
304
|
+
├─ line_end: int
|
|
305
|
+
└─ line_complexities: List[LineComplexity]
|
|
306
|
+
|
|
307
|
+
LineComplexity
|
|
308
|
+
├─ line: int
|
|
309
|
+
└─ complexity: int
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
### Quick-start
|
|
313
|
+
|
|
314
|
+
```python
|
|
315
|
+
from complexipy import file_complexity, code_complexity
|
|
316
|
+
|
|
317
|
+
# Analyse a file
|
|
318
|
+
fc = file_complexity("path/to/your/file.py")
|
|
319
|
+
print(f"Total file complexity: {fc.complexity}")
|
|
320
|
+
|
|
321
|
+
for fn in fc.functions:
|
|
322
|
+
print(f"{fn.name}:{fn.line_start}-{fn.line_end} → {fn.complexity}")
|
|
323
|
+
|
|
324
|
+
# Analyse an in-memory snippet
|
|
325
|
+
snippet = """
|
|
326
|
+
def example_function(x):
|
|
327
|
+
if x > 0:
|
|
328
|
+
for i in range(x):
|
|
329
|
+
print(i)
|
|
330
|
+
"""
|
|
331
|
+
cc = code_complexity(snippet)
|
|
332
|
+
print(f"Snippet complexity: {cc.complexity}")
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
## End-to-End Example
|
|
336
|
+
|
|
337
|
+
The following walk-through shows how to use **Complexipy** from both the **command line** *and* the **Python API**, how to interpret the scores it returns, and how to save them for later use.
|
|
338
|
+
|
|
339
|
+
### 1. Prepare a sample file
|
|
340
|
+
|
|
341
|
+
Create `example.py` with two simple functions:
|
|
342
|
+
|
|
343
|
+
```python
|
|
344
|
+
def a_decorator(a, b):
|
|
345
|
+
def inner(func):
|
|
346
|
+
return func
|
|
347
|
+
return inner
|
|
348
|
+
|
|
349
|
+
|
|
350
|
+
def b_decorator(a, b):
|
|
351
|
+
def inner(func):
|
|
352
|
+
if func:
|
|
353
|
+
return None
|
|
354
|
+
return func
|
|
355
|
+
return inner
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
### 2. Run the CLI
|
|
359
|
+
|
|
360
|
+
Analyse the file from your terminal:
|
|
361
|
+
|
|
362
|
+
```bash
|
|
363
|
+
complexipy example.py
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
Typical output (shortened):
|
|
367
|
+
|
|
368
|
+
```text
|
|
369
|
+
───────────────────────────── 🐙 complexipy 3.2.0 ──────────────────────────────
|
|
370
|
+
Summary
|
|
371
|
+
┏━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━━━━━┓
|
|
372
|
+
┃ Path ┃ File ┃ Function ┃ Complexity ┃
|
|
373
|
+
┡━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━━━━━┩
|
|
374
|
+
│ test_decorator.py │ test_decorator.py │ a_decorator │ 0 │
|
|
375
|
+
├───────────────────┼───────────────────┼─────────────┼────────────┤
|
|
376
|
+
│ test_decorator.py │ test_decorator.py │ b_decorator │ 1 │
|
|
377
|
+
└───────────────────┴───────────────────┴─────────────┴────────────┘
|
|
378
|
+
🧠 Total Cognitive Complexity: 1
|
|
379
|
+
1 file analyzed in 0.0092 seconds
|
|
380
|
+
────────────────────────── 🎉 Analysis completed! 🎉 ───────────────────────────
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
**What do those columns mean?**
|
|
384
|
+
|
|
385
|
+
* **Path / File** – location of the analysed source file
|
|
386
|
+
* **Function** – function or method name that was measured
|
|
387
|
+
* **Complexity** – the cognitive complexity score of that function *(lower is better)*
|
|
388
|
+
|
|
389
|
+
### 3. Use the Python API
|
|
390
|
+
|
|
391
|
+
```python
|
|
392
|
+
from complexipy import file_complexity, code_complexity
|
|
393
|
+
|
|
394
|
+
# Analyse the file on disk
|
|
395
|
+
fc = file_complexity("example.py")
|
|
396
|
+
print(fc.complexity) # → 1
|
|
397
|
+
|
|
398
|
+
# Analyse an in-memory snippet
|
|
399
|
+
snippet = "for x in range(10):\n print(x)"
|
|
400
|
+
cc = code_complexity(snippet)
|
|
401
|
+
print(cc.complexity) # → 1
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
### 4. Why is the score 1?
|
|
405
|
+
|
|
406
|
+
```python
|
|
407
|
+
def b_decorator(a, b): # 0
|
|
408
|
+
def inner(func): # 0
|
|
409
|
+
if func: # +1 – decision point
|
|
410
|
+
return None # 0
|
|
411
|
+
return func # 0
|
|
412
|
+
return inner # 0
|
|
413
|
+
```
|
|
414
|
+
|
|
415
|
+
Only a single `if` branch is encountered, therefore the file's total complexity is **1**.
|
|
416
|
+
|
|
417
|
+
### 5. Persisting the results
|
|
418
|
+
|
|
419
|
+
* **CSV** – `complexipy example.py -c` → creates `complexipy.csv`
|
|
420
|
+
* **JSON** – `complexipy example.py -j` → creates `complexipy.json`
|
|
421
|
+
|
|
422
|
+
### 6. Scaling up your analysis
|
|
423
|
+
|
|
424
|
+
* **Entire folder (recursively):** `complexipy .`
|
|
425
|
+
* **Specific directory:** `complexipy ~/projects/my_app`
|
|
426
|
+
* **Remote Git repository:**
|
|
427
|
+
```bash
|
|
428
|
+
complexipy https://github.com/rohaquinlop/complexipy # print to screen
|
|
429
|
+
complexipy https://github.com/rohaquinlop/complexipy -c # save as CSV
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
## Contributors
|
|
433
|
+
|
|
434
|
+
<p align="center">
|
|
435
|
+
<a href = "https://github.com/rohaquinlop/complexipy/graphs/contributors">
|
|
436
|
+
<img src = "https://contrib.rocks/image?repo=rohaquinlop/complexipy"/>
|
|
437
|
+
</a>
|
|
438
|
+
</p>
|
|
439
|
+
|
|
440
|
+
Made with [contributors-img](https://contrib.rocks)
|
|
441
|
+
|
|
442
|
+
## License
|
|
443
|
+
|
|
444
|
+
This project is licensed under the MIT License - see the [LICENSE](https://github.com/rohaquinlop/complexipy/blob/main/LICENSE) file for details.
|
|
445
|
+
|
|
446
|
+
## Acknowledgments
|
|
447
|
+
|
|
448
|
+
- Thanks to G. Ann Campbell for publishing the paper "Cognitive Complexity a new way to measure understandability".
|
|
449
|
+
- This project is inspired by the Sonar way to calculate cognitive complexity.
|
|
450
|
+
|
|
451
|
+
## References
|
|
452
|
+
|
|
453
|
+
- [Cognitive Complexity](https://www.sonarsource.com/resources/cognitive-complexity/)
|
|
454
|
+
|