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.
Files changed (40) hide show
  1. {complexipy-3.0.0 → complexipy-3.2.0}/Cargo.lock +1 -1
  2. {complexipy-3.0.0 → complexipy-3.2.0}/Cargo.toml +1 -1
  3. complexipy-3.2.0/PKG-INFO +454 -0
  4. complexipy-3.2.0/README.md +423 -0
  5. {complexipy-3.0.0 → complexipy-3.2.0}/complexipy/main.py +25 -19
  6. {complexipy-3.0.0 → complexipy-3.2.0}/complexipy/utils.py +14 -4
  7. complexipy-3.2.0/docs/index.md +394 -0
  8. {complexipy-3.0.0 → complexipy-3.2.0}/src/cognitive_complexity/mod.rs +50 -30
  9. {complexipy-3.0.0 → complexipy-3.2.0}/src/cognitive_complexity/utils.rs +2 -2
  10. {complexipy-3.0.0 → complexipy-3.2.0}/uv.lock +81 -60
  11. {complexipy-3.0.0 → complexipy-3.2.0}/vscode/complexipy/CHANGELOG.md +5 -5
  12. {complexipy-3.0.0 → complexipy-3.2.0}/vscode/complexipy/README.md +4 -4
  13. {complexipy-3.0.0 → complexipy-3.2.0}/vscode/complexipy/extension.js +1 -1
  14. {complexipy-3.0.0 → complexipy-3.2.0}/vscode/complexipy/package.json +1 -1
  15. complexipy-3.0.0/PKG-INFO +0 -465
  16. complexipy-3.0.0/README.md +0 -434
  17. complexipy-3.0.0/docs/index.md +0 -410
  18. {complexipy-3.0.0 → complexipy-3.2.0}/.pre-commit-config.yaml +0 -0
  19. {complexipy-3.0.0 → complexipy-3.2.0}/LICENSE +0 -0
  20. {complexipy-3.0.0 → complexipy-3.2.0}/build-wasm.sh +0 -0
  21. {complexipy-3.0.0 → complexipy-3.2.0}/complexipy/__init__.py +0 -0
  22. {complexipy-3.0.0 → complexipy-3.2.0}/complexipy/types.py +0 -0
  23. {complexipy-3.0.0 → complexipy-3.2.0}/docs/img/complexipy_icon.svg +0 -0
  24. {complexipy-3.0.0 → complexipy-3.2.0}/mkdocs.yml +0 -0
  25. {complexipy-3.0.0 → complexipy-3.2.0}/pyproject.toml +0 -0
  26. {complexipy-3.0.0 → complexipy-3.2.0}/serve-web-version.sh +0 -0
  27. {complexipy-3.0.0 → complexipy-3.2.0}/src/classes/mod.rs +0 -0
  28. {complexipy-3.0.0 → complexipy-3.2.0}/src/lib.rs +0 -0
  29. {complexipy-3.0.0 → complexipy-3.2.0}/src/wasm.rs +0 -0
  30. {complexipy-3.0.0 → complexipy-3.2.0}/vscode/complexipy/.vscode-test.mjs +0 -0
  31. {complexipy-3.0.0 → complexipy-3.2.0}/vscode/complexipy/.vscodeignore +0 -0
  32. {complexipy-3.0.0 → complexipy-3.2.0}/vscode/complexipy/LICENSE +0 -0
  33. {complexipy-3.0.0 → complexipy-3.2.0}/vscode/complexipy/eslint.config.mjs +0 -0
  34. {complexipy-3.0.0 → complexipy-3.2.0}/vscode/complexipy/img/complexipy.png +0 -0
  35. {complexipy-3.0.0 → complexipy-3.2.0}/vscode/complexipy/img/complexipy_icon.png +0 -0
  36. {complexipy-3.0.0 → complexipy-3.2.0}/vscode/complexipy/img/complexipy_icon.svg +0 -0
  37. {complexipy-3.0.0 → complexipy-3.2.0}/vscode/complexipy/jsconfig.json +0 -0
  38. {complexipy-3.0.0 → complexipy-3.2.0}/vscode/complexipy/package-lock.json +0 -0
  39. {complexipy-3.0.0 → complexipy-3.2.0}/vscode/complexipy/test/extension.test.js +0 -0
  40. {complexipy-3.0.0 → complexipy-3.2.0}/vscode/complexipy/vsc-extension-quickstart.md +0 -0
@@ -71,7 +71,7 @@ dependencies = [
71
71
 
72
72
  [[package]]
73
73
  name = "complexipy"
74
- version = "3.0.0"
74
+ version = "3.2.0"
75
75
  dependencies = [
76
76
  "console_error_panic_hook",
77
77
  "csv",
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "complexipy"
3
- version = "3.0.0"
3
+ version = "3.2.0"
4
4
  edition = "2024"
5
5
  authors = ["Robin Quintero <rohaquinlop301@gmail.com>"]
6
6
  license = "MIT"
@@ -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
+