complexipy 5.3.0__tar.gz → 5.4.1__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 (62) hide show
  1. {complexipy-5.3.0 → complexipy-5.4.1}/Cargo.lock +1 -1
  2. {complexipy-5.3.0 → complexipy-5.4.1}/Cargo.toml +1 -1
  3. {complexipy-5.3.0 → complexipy-5.4.1}/PKG-INFO +15 -7
  4. {complexipy-5.3.0 → complexipy-5.4.1}/README.md +13 -2
  5. {complexipy-5.3.0 → complexipy-5.4.1}/complexipy/_complexipy.pyi +7 -2
  6. {complexipy-5.3.0 → complexipy-5.4.1}/complexipy/main.py +25 -38
  7. complexipy-5.4.1/complexipy/utils/constants.py +20 -0
  8. {complexipy-5.3.0 → complexipy-5.4.1}/docs/es/index.md +13 -2
  9. {complexipy-5.3.0 → complexipy-5.4.1}/docs/es/usage-guide.md +26 -30
  10. {complexipy-5.3.0 → complexipy-5.4.1}/docs/index.md +13 -2
  11. {complexipy-5.3.0 → complexipy-5.4.1}/docs/usage-guide.md +25 -29
  12. {complexipy-5.3.0 → complexipy-5.4.1}/pyproject.toml +15 -7
  13. {complexipy-5.3.0 → complexipy-5.4.1}/src/classes.rs +9 -4
  14. {complexipy-5.3.0 → complexipy-5.4.1}/src/cognitive_complexity.rs +26 -9
  15. {complexipy-5.3.0 → complexipy-5.4.1}/src/lib.rs +4 -3
  16. {complexipy-5.3.0 → complexipy-5.4.1}/src/utils.rs +0 -49
  17. {complexipy-5.3.0 → complexipy-5.4.1}/src/wasm.rs +3 -1
  18. {complexipy-5.3.0 → complexipy-5.4.1}/uv.lock +64 -91
  19. {complexipy-5.3.0 → complexipy-5.4.1}/.pre-commit-config.yaml +0 -0
  20. {complexipy-5.3.0 → complexipy-5.4.1}/LICENSE +0 -0
  21. {complexipy-5.3.0 → complexipy-5.4.1}/build-wasm.sh +0 -0
  22. {complexipy-5.3.0 → complexipy-5.4.1}/complexipy/__init__.py +0 -0
  23. {complexipy-5.3.0 → complexipy-5.4.1}/complexipy/api.py +0 -0
  24. {complexipy-5.3.0 → complexipy-5.4.1}/complexipy/py.typed +0 -0
  25. {complexipy-5.3.0 → complexipy-5.4.1}/complexipy/types.py +0 -0
  26. {complexipy-5.3.0 → complexipy-5.4.1}/complexipy/utils/__init__.py +0 -0
  27. {complexipy-5.3.0 → complexipy-5.4.1}/complexipy/utils/cache.py +0 -0
  28. {complexipy-5.3.0 → complexipy-5.4.1}/complexipy/utils/csv.py +0 -0
  29. {complexipy-5.3.0 → complexipy-5.4.1}/complexipy/utils/diff.py +0 -0
  30. {complexipy-5.3.0 → complexipy-5.4.1}/complexipy/utils/gitlab.py +0 -0
  31. {complexipy-5.3.0 → complexipy-5.4.1}/complexipy/utils/json.py +0 -0
  32. {complexipy-5.3.0 → complexipy-5.4.1}/complexipy/utils/output.py +0 -0
  33. {complexipy-5.3.0 → complexipy-5.4.1}/complexipy/utils/sarif.py +0 -0
  34. {complexipy-5.3.0 → complexipy-5.4.1}/complexipy/utils/snapshot.py +0 -0
  35. {complexipy-5.3.0 → complexipy-5.4.1}/complexipy/utils/toml.py +0 -0
  36. {complexipy-5.3.0 → complexipy-5.4.1}/complexipy.toml +0 -0
  37. {complexipy-5.3.0 → complexipy-5.4.1}/docs/about.md +0 -0
  38. {complexipy-5.3.0 → complexipy-5.4.1}/docs/comparison-with-ruff.md +0 -0
  39. {complexipy-5.3.0 → complexipy-5.4.1}/docs/es/about.md +0 -0
  40. {complexipy-5.3.0 → complexipy-5.4.1}/docs/es/comparison-with-ruff.md +0 -0
  41. {complexipy-5.3.0 → complexipy-5.4.1}/docs/es/img/complexipy_icon.svg +0 -0
  42. {complexipy-5.3.0 → complexipy-5.4.1}/docs/es/understanding-scores.md +0 -0
  43. {complexipy-5.3.0 → complexipy-5.4.1}/docs/img/complexipy_icon.svg +0 -0
  44. {complexipy-5.3.0 → complexipy-5.4.1}/docs/understanding-scores.md +0 -0
  45. {complexipy-5.3.0 → complexipy-5.4.1}/mkdocs.es.yml +0 -0
  46. {complexipy-5.3.0 → complexipy-5.4.1}/mkdocs.yml +0 -0
  47. {complexipy-5.3.0 → complexipy-5.4.1}/serve-web-version.sh +0 -0
  48. {complexipy-5.3.0 → complexipy-5.4.1}/vscode/complexipy/.vscode-test.mjs +0 -0
  49. {complexipy-5.3.0 → complexipy-5.4.1}/vscode/complexipy/.vscodeignore +0 -0
  50. {complexipy-5.3.0 → complexipy-5.4.1}/vscode/complexipy/CHANGELOG.md +0 -0
  51. {complexipy-5.3.0 → complexipy-5.4.1}/vscode/complexipy/LICENSE +0 -0
  52. {complexipy-5.3.0 → complexipy-5.4.1}/vscode/complexipy/README.md +0 -0
  53. {complexipy-5.3.0 → complexipy-5.4.1}/vscode/complexipy/eslint.config.mjs +0 -0
  54. {complexipy-5.3.0 → complexipy-5.4.1}/vscode/complexipy/extension.js +0 -0
  55. {complexipy-5.3.0 → complexipy-5.4.1}/vscode/complexipy/img/complexipy.png +0 -0
  56. {complexipy-5.3.0 → complexipy-5.4.1}/vscode/complexipy/img/complexipy_icon.png +0 -0
  57. {complexipy-5.3.0 → complexipy-5.4.1}/vscode/complexipy/img/complexipy_icon.svg +0 -0
  58. {complexipy-5.3.0 → complexipy-5.4.1}/vscode/complexipy/jsconfig.json +0 -0
  59. {complexipy-5.3.0 → complexipy-5.4.1}/vscode/complexipy/package-lock.json +0 -0
  60. {complexipy-5.3.0 → complexipy-5.4.1}/vscode/complexipy/package.json +0 -0
  61. {complexipy-5.3.0 → complexipy-5.4.1}/vscode/complexipy/test/extension.test.js +0 -0
  62. {complexipy-5.3.0 → complexipy-5.4.1}/vscode/complexipy/test/statusbar.test.js +0 -0
@@ -113,7 +113,7 @@ dependencies = [
113
113
 
114
114
  [[package]]
115
115
  name = "complexipy"
116
- version = "5.3.0"
116
+ version = "5.4.1"
117
117
  dependencies = [
118
118
  "console_error_panic_hook",
119
119
  "csv",
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "complexipy"
3
- version = "5.3.0"
3
+ version = "5.4.1"
4
4
  edition = "2024"
5
5
  authors = ["Robin Quintero <rohaquinlop301@gmail.com>"]
6
6
  license = "MIT"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: complexipy
3
- Version: 5.3.0
3
+ Version: 5.4.1
4
4
  Classifier: Development Status :: 5 - Production/Stable
5
5
  Classifier: Environment :: Console
6
6
  Classifier: Intended Audience :: Developers
@@ -18,12 +18,9 @@ Classifier: Topic :: Software Development :: Testing
18
18
  Classifier: Topic :: Software Development :: Libraries
19
19
  Requires-Dist: tomli>=2.2.1
20
20
  Requires-Dist: typer>=0.12.5
21
- Requires-Dist: ruff>=0.9.0 ; extra == 'dev'
22
- Requires-Dist: ty>=0.0.1a1 ; extra == 'dev'
23
- Provides-Extra: dev
24
21
  License-File: LICENSE
25
22
  Summary: An extremely fast Python library to calculate the cognitive complexity of Python files, written in Rust.
26
- Keywords: cognitive,complexity,cognitive complexity,quality,quality assurance,testing,libraries,performance
23
+ Keywords: maintainability,usability,DevEx tools,cognitive,complexity,cognitive complexity,quality,quality assurance,libraries,performance,static analysis,code quality,technical debt,refactoring,CI/CD,fast
27
24
  Home-Page: https://github.com/rohaquinlop/complexipy
28
25
  Author-email: Robin Quintero <rohaquinlop301@gmail.com>
29
26
  License: MIT
@@ -50,7 +47,8 @@ Project-URL: Repository, https://github.com/rohaquinlop/complexipy
50
47
  <a href="#installation">Installation</a> •
51
48
  <a href="#quick-start">Quick Start</a> •
52
49
  <a href="#integrations">Integrations</a> •
53
- <a href="https://rohaquinlop.github.io/complexipy/">Documentation</a>
50
+ <a href="https://rohaquinlop.github.io/complexipy/">Documentation</a>
51
+ <a href="https://www.complexipy-teams.com/">Complexipy Teams</a>
54
52
  </p>
55
53
  </div>
56
54
 
@@ -398,6 +396,7 @@ code_complexity(source: str, check_script: bool = False) -> CodeComplexity
398
396
  # Return types
399
397
  FileComplexity:
400
398
  ├─ path: str
399
+ ├─ file_name: str
401
400
  ├─ complexity: int
402
401
  └─ functions: List[FunctionComplexity]
403
402
 
@@ -405,7 +404,16 @@ FunctionComplexity:
405
404
  ├─ name: str
406
405
  ├─ complexity: int
407
406
  ├─ line_start: int
408
- └─ line_end: int
407
+ ├─ line_end: int
408
+ └─ line_complexities: List[LineComplexity]
409
+
410
+ LineComplexity:
411
+ ├─ line: int
412
+ └─ complexity: int
413
+
414
+ CodeComplexity:
415
+ ├─ complexity: int
416
+ └─ functions: List[FunctionComplexity]
409
417
  ```
410
418
 
411
419
  ---
@@ -15,7 +15,8 @@
15
15
  <a href="#installation">Installation</a> •
16
16
  <a href="#quick-start">Quick Start</a> •
17
17
  <a href="#integrations">Integrations</a> •
18
- <a href="https://rohaquinlop.github.io/complexipy/">Documentation</a>
18
+ <a href="https://rohaquinlop.github.io/complexipy/">Documentation</a>
19
+ <a href="https://www.complexipy-teams.com/">Complexipy Teams</a>
19
20
  </p>
20
21
  </div>
21
22
 
@@ -363,6 +364,7 @@ code_complexity(source: str, check_script: bool = False) -> CodeComplexity
363
364
  # Return types
364
365
  FileComplexity:
365
366
  ├─ path: str
367
+ ├─ file_name: str
366
368
  ├─ complexity: int
367
369
  └─ functions: List[FunctionComplexity]
368
370
 
@@ -370,7 +372,16 @@ FunctionComplexity:
370
372
  ├─ name: str
371
373
  ├─ complexity: int
372
374
  ├─ line_start: int
373
- └─ line_end: int
375
+ ├─ line_end: int
376
+ └─ line_complexities: List[LineComplexity]
377
+
378
+ LineComplexity:
379
+ ├─ line: int
380
+ └─ complexity: int
381
+
382
+ CodeComplexity:
383
+ ├─ complexity: int
384
+ └─ functions: List[FunctionComplexity]
374
385
  ```
375
386
 
376
387
  ---
@@ -262,7 +262,10 @@ class CodeComplexity:
262
262
  ) -> None: ...
263
263
 
264
264
  def main(
265
- paths: List[str], quiet: bool, exclude: List[str], check_script: bool = False
265
+ paths: List[str],
266
+ quiet: bool,
267
+ exclude: List[str],
268
+ check_script: bool = False,
266
269
  ) -> Tuple[List[FileComplexity], List[str]]:
267
270
  """
268
271
  Analyze cognitive complexity of Python files and directories.
@@ -355,7 +358,9 @@ def code_complexity(code: str, check_script: bool = False) -> CodeComplexity:
355
358
  """
356
359
  ...
357
360
 
358
- def file_complexity(file_path: str, base_path: str, check_script: bool = False) -> FileComplexity:
361
+ def file_complexity(
362
+ file_path: str, base_path: str, check_script: bool = False
363
+ ) -> FileComplexity:
359
364
  """
360
365
  Analyze cognitive complexity of a single Python source file.
361
366
 
@@ -23,56 +23,48 @@ from complexipy import (
23
23
  )
24
24
  from complexipy._complexipy import FileComplexity
25
25
 
26
- from .types import (
26
+ from complexipy.types import (
27
27
  ColorTypes,
28
28
  OutputFormat,
29
29
  Sort,
30
30
  )
31
- from .utils.cache import remember_previous_functions
32
- from .utils.csv import store_csv
33
- from .utils.diff import DiffEntry, compute_diff, format_diff, has_regressions
34
- from .utils.gitlab import store_gitlab
35
- from .utils.json import store_json
36
- from .utils.output import (
31
+ from complexipy.utils.cache import remember_previous_functions
32
+ from complexipy.utils.csv import store_csv
33
+ from complexipy.utils.diff import (
34
+ DiffEntry,
35
+ compute_diff,
36
+ format_diff,
37
+ has_regressions,
38
+ )
39
+ from complexipy.utils.gitlab import store_gitlab
40
+ from complexipy.utils.json import store_json
41
+ from complexipy.utils.output import (
37
42
  has_success_functions,
38
43
  output_summary,
39
44
  print_invalid_paths,
40
45
  )
41
- from .utils.sarif import store_sarif
42
- from .utils.snapshot import (
46
+ from complexipy.utils.sarif import store_sarif
47
+ from complexipy.utils.snapshot import (
43
48
  build_snapshot_map,
44
49
  handle_snapshot_file_creation,
45
50
  handle_snapshot_functions_load,
46
51
  handle_snapshot_watermark,
47
52
  )
48
- from .utils.toml import (
53
+ from complexipy.utils.toml import (
49
54
  get_argument_value,
50
55
  get_arguments_value,
51
56
  get_complexipy_toml_config,
52
57
  )
58
+ from complexipy.utils.constants import (
59
+ DEFAULT_OUTPUT_FILENAMES,
60
+ LEGACY_OUTPUT_CONFIG_KEYS,
61
+ LEGACY_OUTPUT_FLAGS,
62
+ )
53
63
 
54
64
  app = typer.Typer(name="complexipy")
55
65
  console = Console(color_system="auto")
56
66
  INVOCATION_PATH = os.getcwd()
57
67
  TOML_CONFIG = get_complexipy_toml_config(INVOCATION_PATH)
58
- DEFAULT_OUTPUT_FILENAMES = {
59
- OutputFormat.csv: "complexipy-results.csv",
60
- OutputFormat.json: "complexipy-results.json",
61
- OutputFormat.gitlab: "complexipy-results.gitlab.json",
62
- OutputFormat.sarif: "complexipy-results.sarif",
63
- }
64
- LEGACY_OUTPUT_FLAGS = {
65
- OutputFormat.csv: "--output-csv",
66
- OutputFormat.json: "--output-json",
67
- OutputFormat.gitlab: "--output-gitlab",
68
- OutputFormat.sarif: "--output-sarif",
69
- }
70
- LEGACY_OUTPUT_CONFIG_KEYS = {
71
- OutputFormat.csv: "output-csv",
72
- OutputFormat.json: "output-json",
73
- OutputFormat.gitlab: "output-gitlab",
74
- OutputFormat.sarif: "output-sarif",
75
- }
76
68
 
77
69
 
78
70
  def _version_callback(value: bool):
@@ -164,18 +156,18 @@ def main(
164
156
  None,
165
157
  "--output-csv",
166
158
  "-c",
167
- help="Output the results to a CSV file.",
159
+ help="Deprecated. Use `--output-format csv` instead. Output the results to a CSV file.",
168
160
  ),
169
161
  output_json: Optional[bool] = typer.Option(
170
162
  None,
171
163
  "--output-json",
172
164
  "-j",
173
- help="Output the results to a JSON file.",
165
+ help="Deprecated. Use `--output-format json` instead. Output the results to a JSON file.",
174
166
  ),
175
167
  output_gitlab: Optional[bool] = typer.Option(
176
168
  None,
177
169
  "--output-gitlab",
178
- help="Output the results as a GitLab Code Quality JSON report.",
170
+ help="Deprecated. Use `--output-format gitlab` instead. Output the results as a GitLab Code Quality JSON report.",
179
171
  ),
180
172
  diff: Optional[str] = typer.Option(
181
173
  None,
@@ -281,8 +273,6 @@ def main(
281
273
  ratchet = bool(get_argument_value(TOML_CONFIG, "ratchet", ratchet, False))
282
274
  validate_ratchet(ratchet, diff)
283
275
 
284
- # --plain is intentionally CLI-only (not resolved via TOML) because it is
285
- # a session-level display preference, not a project-wide default.
286
276
  if plain is None:
287
277
  plain = False
288
278
 
@@ -364,9 +354,6 @@ def main(
364
354
  watermark_success,
365
355
  )
366
356
  if should_run_snapshot_watermark:
367
- # When the snapshot watermark is active, it is the authoritative
368
- # success check. Functions exceeding the threshold that are already
369
- # in the snapshot (and haven't regressed) should not cause a failure.
370
357
  has_success = snapshot_result
371
358
  else:
372
359
  has_success = has_success and snapshot_result
@@ -505,8 +492,8 @@ def emit_deprecated_output_warnings(
505
492
  if legacy_cli_output_flags[output_format]:
506
493
  console.print(
507
494
  f"[yellow]Deprecated:[/yellow] {flag_name} will be removed "
508
- f"in a future release. Use --output-format "
509
- f"{output_format.value} instead."
495
+ f"in a future release. Use `--output-format "
496
+ f"{output_format.value}` instead."
510
497
  )
511
498
 
512
499
  if toml_config is None:
@@ -0,0 +1,20 @@
1
+ from complexipy.types import OutputFormat
2
+
3
+ DEFAULT_OUTPUT_FILENAMES = {
4
+ OutputFormat.csv: "complexipy-results.csv",
5
+ OutputFormat.json: "complexipy-results.json",
6
+ OutputFormat.gitlab: "complexipy-results.gitlab.json",
7
+ OutputFormat.sarif: "complexipy-results.sarif",
8
+ }
9
+ LEGACY_OUTPUT_FLAGS = {
10
+ OutputFormat.csv: "--output-csv",
11
+ OutputFormat.json: "--output-json",
12
+ OutputFormat.gitlab: "--output-gitlab",
13
+ OutputFormat.sarif: "--output-sarif",
14
+ }
15
+ LEGACY_OUTPUT_CONFIG_KEYS = {
16
+ OutputFormat.csv: "output-csv",
17
+ OutputFormat.json: "output-json",
18
+ OutputFormat.gitlab: "output-gitlab",
19
+ OutputFormat.sarif: "output-sarif",
20
+ }
@@ -15,7 +15,8 @@
15
15
  <a href="#instalación">Instalación</a> •
16
16
  <a href="#inicio-rápido">Inicio Rápido</a> •
17
17
  <a href="#integraciones">Integraciones</a> •
18
- <a href="https://rohaquinlop.github.io/complexipy/">Documentación</a>
18
+ <a href="https://rohaquinlop.github.io/complexipy/">Documentación</a>
19
+ <a href="https://www.complexipy-teams.com/">Complexipy Teams</a>
19
20
  </p>
20
21
  </div>
21
22
 
@@ -321,6 +322,7 @@ code_complexity(source: str, check_script: bool = False) -> CodeComplexity
321
322
  # Tipos de retorno
322
323
  FileComplexity:
323
324
  ├─ path: str
325
+ ├─ file_name: str
324
326
  ├─ complexity: int
325
327
  └─ functions: List[FunctionComplexity]
326
328
 
@@ -328,7 +330,16 @@ FunctionComplexity:
328
330
  ├─ name: str
329
331
  ├─ complexity: int
330
332
  ├─ line_start: int
331
- └─ line_end: int
333
+ ├─ line_end: int
334
+ └─ line_complexities: List[LineComplexity]
335
+
336
+ LineComplexity:
337
+ ├─ line: int
338
+ └─ complexity: int
339
+
340
+ CodeComplexity:
341
+ ├─ complexity: int
342
+ └─ functions: List[FunctionComplexity]
332
343
  ```
333
344
 
334
345
  ---
@@ -65,7 +65,7 @@ complexipy . --top 10
65
65
  Cuando se usa `--top`, los resultados se reordenan globalmente por complejidad
66
66
  descendente antes de truncarse.
67
67
 
68
- Suprimir toda la salida (útil para pipelines de CI):
68
+ Suprimir la salida del análisis (útil para pipelines de CI):
69
69
 
70
70
  ```bash
71
71
  complexipy . --quiet
@@ -104,7 +104,7 @@ complexipy . --exclude src/legacy/old_code.py
104
104
 
105
105
  ### Formatos de Salida
106
106
 
107
- Guarda los resultados en JSON o CSV:
107
+ Guarda los resultados en JSON, CSV, GitLab Code Quality o SARIF:
108
108
 
109
109
  ```bash
110
110
  # Salida JSON (guardada en complexipy-results.json)
@@ -198,25 +198,18 @@ fuera de las funciones.
198
198
  **Estructura de Salida JSON:**
199
199
 
200
200
  ```json
201
- {
202
- "files": [
203
- {
204
- "path": "src/main.py",
205
- "complexity": 42,
206
- "functions": [
207
- {
208
- "name": "process_data",
209
- "complexity": 18,
210
- "line_start": 10,
211
- "line_end": 45
212
- }
213
- ]
214
- }
215
- ],
216
- "total_complexity": 42
217
- }
201
+ [
202
+ {
203
+ "path": "src",
204
+ "file_name": "main.py",
205
+ "function_name": "process_data",
206
+ "complexity": 18
207
+ }
208
+ ]
218
209
  ```
219
210
 
211
+ Las salidas JSON y CSV contienen una entrada por cada función emitida. Los rangos de líneas están disponibles mediante la API de Python (`line_start`, `line_end`), pero no se incluyen en las salidas JSON/CSV legibles por máquina de la CLI.
212
+
220
213
  ### Salida en Color
221
214
 
222
215
  Controla la salida en color:
@@ -487,19 +480,22 @@ complexipy . --snapshot-ignore
487
480
  ### Formato del Archivo de snapshot
488
481
 
489
482
  ```json
490
- {
491
- "version": "1.0",
492
- "threshold": 15,
493
- "functions": {
494
- "src/legacy.py::old_function": {
495
- "complexity": 23,
496
- "line_start": 10,
497
- "line_end": 50
498
- }
483
+ [
484
+ {
485
+ "path": "src",
486
+ "file_name": "legacy.py",
487
+ "functions": [
488
+ {
489
+ "name": "old_function",
490
+ "complexity": 23
491
+ }
492
+ ]
499
493
  }
500
- }
494
+ ]
501
495
  ```
502
496
 
497
+ Los snapshots se guardan como un arreglo JSON de archivos analizados. Cada entrada contiene solo las funciones por encima del umbral cuando se escribió el snapshot. El archivo se reescribe después de verificaciones de snapshot exitosas, así que las funciones que mejoran se eliminan automáticamente. Es posible que los snapshots creados por versiones anteriores de complexipy deban regenerarse con `--snapshot-create`.
498
+
503
499
  ## Ignorar en Línea
504
500
 
505
501
  Suprime las advertencias de complejidad para funciones específicas usando el comentario `# complexipy: ignore`:
@@ -546,7 +542,7 @@ Usa la acción oficial:
546
542
  with:
547
543
  paths: src tests
548
544
  max_complexity_allowed: 15
549
- output_json: true
545
+ output_format: json
550
546
  ```
551
547
 
552
548
  O ejecuta directamente:
@@ -15,7 +15,8 @@
15
15
  <a href="#installation">Installation</a> •
16
16
  <a href="#quick-start">Quick Start</a> •
17
17
  <a href="#integrations">Integrations</a> •
18
- <a href="https://rohaquinlop.github.io/complexipy/">Documentation</a>
18
+ <a href="https://rohaquinlop.github.io/complexipy/">Documentation</a>
19
+ <a href="https://www.complexipy-teams.com/">Complexipy Teams</a>
19
20
  </p>
20
21
  </div>
21
22
 
@@ -321,6 +322,7 @@ code_complexity(source: str, check_script: bool = False) -> CodeComplexity
321
322
  # Return types
322
323
  FileComplexity:
323
324
  ├─ path: str
325
+ ├─ file_name: str
324
326
  ├─ complexity: int
325
327
  └─ functions: List[FunctionComplexity]
326
328
 
@@ -328,7 +330,16 @@ FunctionComplexity:
328
330
  ├─ name: str
329
331
  ├─ complexity: int
330
332
  ├─ line_start: int
331
- └─ line_end: int
333
+ ├─ line_end: int
334
+ └─ line_complexities: List[LineComplexity]
335
+
336
+ LineComplexity:
337
+ ├─ line: int
338
+ └─ complexity: int
339
+
340
+ CodeComplexity:
341
+ ├─ complexity: int
342
+ └─ functions: List[FunctionComplexity]
332
343
  ```
333
344
 
334
345
  ---
@@ -65,7 +65,7 @@ complexipy . --top 10
65
65
  When `--top` is set, results are globally re-sorted by complexity descending
66
66
  before truncation.
67
67
 
68
- Suppress all output (useful for CI pipelines):
68
+ Suppress analysis output (useful for CI pipelines):
69
69
 
70
70
  ```bash
71
71
  complexipy . --quiet
@@ -201,25 +201,18 @@ functions.
201
201
  **JSON Output Structure:**
202
202
 
203
203
  ```json
204
- {
205
- "files": [
206
- {
207
- "path": "src/main.py",
208
- "complexity": 42,
209
- "functions": [
210
- {
211
- "name": "process_data",
212
- "complexity": 18,
213
- "line_start": 10,
214
- "line_end": 45
215
- }
216
- ]
217
- }
218
- ],
219
- "total_complexity": 42
220
- }
204
+ [
205
+ {
206
+ "path": "src",
207
+ "file_name": "main.py",
208
+ "function_name": "process_data",
209
+ "complexity": 18
210
+ }
211
+ ]
221
212
  ```
222
213
 
214
+ The JSON and CSV outputs contain one entry per emitted function. Line ranges are available through the Python API (`line_start`, `line_end`), but are not included in the machine-readable CLI JSON/CSV outputs.
215
+
223
216
  ### Color Output
224
217
 
225
218
  Control color output:
@@ -490,19 +483,22 @@ Use this when:
490
483
  ### Snapshot File Format
491
484
 
492
485
  ```json
493
- {
494
- "version": "1.0",
495
- "threshold": 15,
496
- "functions": {
497
- "src/legacy.py::old_function": {
498
- "complexity": 23,
499
- "line_start": 10,
500
- "line_end": 50
501
- }
486
+ [
487
+ {
488
+ "path": "src",
489
+ "file_name": "legacy.py",
490
+ "functions": [
491
+ {
492
+ "name": "old_function",
493
+ "complexity": 23
494
+ }
495
+ ]
502
496
  }
503
- }
497
+ ]
504
498
  ```
505
499
 
500
+ Snapshots are stored as a JSON array of analyzed files. Each entry contains only functions above the threshold at the time the snapshot was written. The file is rewritten after successful snapshot checks, so improved functions are removed automatically. Snapshots created by older complexipy versions may need to be regenerated with `--snapshot-create`.
501
+
506
502
  ## Inline Ignores
507
503
 
508
504
  Suppress complexity warnings for specific functions using the `# complexipy: ignore` comment:
@@ -549,7 +545,7 @@ Use the official action:
549
545
  with:
550
546
  paths: src tests
551
547
  max_complexity_allowed: 15
552
- output_json: true
548
+ output_format: json
553
549
  ```
554
550
 
555
551
  Or run directly:
@@ -9,14 +9,22 @@ readme = "README.md"
9
9
  license = { text = "MIT" }
10
10
  authors = [{name = "Robin Quintero", email = "rohaquinlop301@gmail.com"}]
11
11
  keywords = [
12
+ "maintainability",
13
+ "usability",
14
+ "DevEx tools",
12
15
  "cognitive",
13
16
  "complexity",
14
17
  "cognitive complexity",
15
18
  "quality",
16
19
  "quality assurance",
17
- "testing",
18
20
  "libraries",
19
21
  "performance",
22
+ "static analysis",
23
+ "code quality",
24
+ "technical debt",
25
+ "refactoring",
26
+ "CI/CD",
27
+ "fast",
20
28
  ]
21
29
  requires-python = ">=3.8"
22
30
  classifiers = [
@@ -74,12 +82,6 @@ indent-width = 4
74
82
  [tool.ty.src]
75
83
  exclude = ["tests"]
76
84
 
77
- [project.optional-dependencies]
78
- dev = [
79
- "ruff>=0.9.0",
80
- "ty>=0.0.1a1",
81
- ]
82
-
83
85
  [dependency-groups]
84
86
  dev = [
85
87
  "maturin>=1.8.3",
@@ -89,3 +91,9 @@ dev = [
89
91
  "ruff>=0.9.0",
90
92
  "ty>=0.0.1a1",
91
93
  ]
94
+
95
+ [tool.pytest.ini_options]
96
+ testpaths = ["tests"]
97
+ python_files = ["test_*.py", "main.py"]
98
+ python_functions = ["test_*"]
99
+ norecursedirs = ["tests/src"]
@@ -24,21 +24,24 @@ pub struct LineComplexity {
24
24
  pub struct FunctionComplexity {
25
25
  pub name: String,
26
26
  pub complexity: u64,
27
+ #[cfg_attr(feature = "python", serde(skip))]
27
28
  pub line_start: u64,
29
+ #[cfg_attr(feature = "python", serde(skip))]
28
30
  pub line_end: u64,
31
+ #[cfg_attr(feature = "python", serde(skip))]
29
32
  pub line_complexities: Vec<LineComplexity>,
30
33
  }
31
34
 
32
- #[cfg_attr(feature = "python", pyclass(module = "complexipy", get_all))]
33
35
  #[cfg_attr(
34
- any(feature = "python", feature = "wasm"),
35
- derive(Serialize, Deserialize)
36
+ feature = "python",
37
+ pyclass(module = "complexipy", get_all),
38
+ derive(Serialize, Deserialize, Clone)
36
39
  )]
37
- #[derive(Clone)]
38
40
  pub struct FileComplexity {
39
41
  pub path: String,
40
42
  pub file_name: String,
41
43
  pub functions: Vec<FunctionComplexity>,
44
+ #[cfg_attr(feature = "python", serde(skip))]
42
45
  pub complexity: u64,
43
46
  }
44
47
 
@@ -51,4 +54,6 @@ pub struct FileComplexity {
51
54
  pub struct CodeComplexity {
52
55
  pub functions: Vec<FunctionComplexity>,
53
56
  pub complexity: u64,
57
+ #[cfg(feature = "wasm")]
58
+ pub version: String,
54
59
  }