thailint 0.3.0__tar.gz → 0.3.2__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 (82) hide show
  1. {thailint-0.3.0 → thailint-0.3.2}/PKG-INFO +79 -21
  2. {thailint-0.3.0 → thailint-0.3.2}/README.md +78 -20
  3. {thailint-0.3.0 → thailint-0.3.2}/pyproject.toml +2 -1
  4. {thailint-0.3.0 → thailint-0.3.2}/src/cli.py +101 -0
  5. {thailint-0.3.0 → thailint-0.3.2}/CHANGELOG.md +0 -0
  6. {thailint-0.3.0 → thailint-0.3.2}/LICENSE +0 -0
  7. {thailint-0.3.0 → thailint-0.3.2}/src/__init__.py +0 -0
  8. {thailint-0.3.0 → thailint-0.3.2}/src/analyzers/__init__.py +0 -0
  9. {thailint-0.3.0 → thailint-0.3.2}/src/analyzers/typescript_base.py +0 -0
  10. {thailint-0.3.0 → thailint-0.3.2}/src/api.py +0 -0
  11. {thailint-0.3.0 → thailint-0.3.2}/src/config.py +0 -0
  12. {thailint-0.3.0 → thailint-0.3.2}/src/core/__init__.py +0 -0
  13. {thailint-0.3.0 → thailint-0.3.2}/src/core/base.py +0 -0
  14. {thailint-0.3.0 → thailint-0.3.2}/src/core/cli_utils.py +0 -0
  15. {thailint-0.3.0 → thailint-0.3.2}/src/core/config_parser.py +0 -0
  16. {thailint-0.3.0 → thailint-0.3.2}/src/core/linter_utils.py +0 -0
  17. {thailint-0.3.0 → thailint-0.3.2}/src/core/registry.py +0 -0
  18. {thailint-0.3.0 → thailint-0.3.2}/src/core/rule_discovery.py +0 -0
  19. {thailint-0.3.0 → thailint-0.3.2}/src/core/types.py +0 -0
  20. {thailint-0.3.0 → thailint-0.3.2}/src/core/violation_builder.py +0 -0
  21. {thailint-0.3.0 → thailint-0.3.2}/src/linter_config/__init__.py +0 -0
  22. {thailint-0.3.0 → thailint-0.3.2}/src/linter_config/ignore.py +0 -0
  23. {thailint-0.3.0 → thailint-0.3.2}/src/linter_config/loader.py +0 -0
  24. {thailint-0.3.0 → thailint-0.3.2}/src/linters/__init__.py +0 -0
  25. {thailint-0.3.0 → thailint-0.3.2}/src/linters/dry/__init__.py +0 -0
  26. {thailint-0.3.0 → thailint-0.3.2}/src/linters/dry/base_token_analyzer.py +0 -0
  27. {thailint-0.3.0 → thailint-0.3.2}/src/linters/dry/block_filter.py +0 -0
  28. {thailint-0.3.0 → thailint-0.3.2}/src/linters/dry/block_grouper.py +0 -0
  29. {thailint-0.3.0 → thailint-0.3.2}/src/linters/dry/cache.py +0 -0
  30. {thailint-0.3.0 → thailint-0.3.2}/src/linters/dry/cache_query.py +0 -0
  31. {thailint-0.3.0 → thailint-0.3.2}/src/linters/dry/config.py +0 -0
  32. {thailint-0.3.0 → thailint-0.3.2}/src/linters/dry/config_loader.py +0 -0
  33. {thailint-0.3.0 → thailint-0.3.2}/src/linters/dry/deduplicator.py +0 -0
  34. {thailint-0.3.0 → thailint-0.3.2}/src/linters/dry/duplicate_storage.py +0 -0
  35. {thailint-0.3.0 → thailint-0.3.2}/src/linters/dry/file_analyzer.py +0 -0
  36. {thailint-0.3.0 → thailint-0.3.2}/src/linters/dry/inline_ignore.py +0 -0
  37. {thailint-0.3.0 → thailint-0.3.2}/src/linters/dry/linter.py +0 -0
  38. {thailint-0.3.0 → thailint-0.3.2}/src/linters/dry/python_analyzer.py +0 -0
  39. {thailint-0.3.0 → thailint-0.3.2}/src/linters/dry/storage_initializer.py +0 -0
  40. {thailint-0.3.0 → thailint-0.3.2}/src/linters/dry/token_hasher.py +0 -0
  41. {thailint-0.3.0 → thailint-0.3.2}/src/linters/dry/typescript_analyzer.py +0 -0
  42. {thailint-0.3.0 → thailint-0.3.2}/src/linters/dry/violation_builder.py +0 -0
  43. {thailint-0.3.0 → thailint-0.3.2}/src/linters/dry/violation_filter.py +0 -0
  44. {thailint-0.3.0 → thailint-0.3.2}/src/linters/dry/violation_generator.py +0 -0
  45. {thailint-0.3.0 → thailint-0.3.2}/src/linters/file_placement/__init__.py +0 -0
  46. {thailint-0.3.0 → thailint-0.3.2}/src/linters/file_placement/config_loader.py +0 -0
  47. {thailint-0.3.0 → thailint-0.3.2}/src/linters/file_placement/directory_matcher.py +0 -0
  48. {thailint-0.3.0 → thailint-0.3.2}/src/linters/file_placement/linter.py +0 -0
  49. {thailint-0.3.0 → thailint-0.3.2}/src/linters/file_placement/path_resolver.py +0 -0
  50. {thailint-0.3.0 → thailint-0.3.2}/src/linters/file_placement/pattern_matcher.py +0 -0
  51. {thailint-0.3.0 → thailint-0.3.2}/src/linters/file_placement/pattern_validator.py +0 -0
  52. {thailint-0.3.0 → thailint-0.3.2}/src/linters/file_placement/rule_checker.py +0 -0
  53. {thailint-0.3.0 → thailint-0.3.2}/src/linters/file_placement/violation_factory.py +0 -0
  54. {thailint-0.3.0 → thailint-0.3.2}/src/linters/magic_numbers/__init__.py +0 -0
  55. {thailint-0.3.0 → thailint-0.3.2}/src/linters/magic_numbers/config.py +0 -0
  56. {thailint-0.3.0 → thailint-0.3.2}/src/linters/magic_numbers/context_analyzer.py +0 -0
  57. {thailint-0.3.0 → thailint-0.3.2}/src/linters/magic_numbers/linter.py +0 -0
  58. {thailint-0.3.0 → thailint-0.3.2}/src/linters/magic_numbers/python_analyzer.py +0 -0
  59. {thailint-0.3.0 → thailint-0.3.2}/src/linters/magic_numbers/typescript_analyzer.py +0 -0
  60. {thailint-0.3.0 → thailint-0.3.2}/src/linters/magic_numbers/violation_builder.py +0 -0
  61. {thailint-0.3.0 → thailint-0.3.2}/src/linters/nesting/__init__.py +0 -0
  62. {thailint-0.3.0 → thailint-0.3.2}/src/linters/nesting/config.py +0 -0
  63. {thailint-0.3.0 → thailint-0.3.2}/src/linters/nesting/linter.py +0 -0
  64. {thailint-0.3.0 → thailint-0.3.2}/src/linters/nesting/python_analyzer.py +0 -0
  65. {thailint-0.3.0 → thailint-0.3.2}/src/linters/nesting/typescript_analyzer.py +0 -0
  66. {thailint-0.3.0 → thailint-0.3.2}/src/linters/nesting/typescript_function_extractor.py +0 -0
  67. {thailint-0.3.0 → thailint-0.3.2}/src/linters/nesting/violation_builder.py +0 -0
  68. {thailint-0.3.0 → thailint-0.3.2}/src/linters/srp/__init__.py +0 -0
  69. {thailint-0.3.0 → thailint-0.3.2}/src/linters/srp/class_analyzer.py +0 -0
  70. {thailint-0.3.0 → thailint-0.3.2}/src/linters/srp/config.py +0 -0
  71. {thailint-0.3.0 → thailint-0.3.2}/src/linters/srp/heuristics.py +0 -0
  72. {thailint-0.3.0 → thailint-0.3.2}/src/linters/srp/linter.py +0 -0
  73. {thailint-0.3.0 → thailint-0.3.2}/src/linters/srp/metrics_evaluator.py +0 -0
  74. {thailint-0.3.0 → thailint-0.3.2}/src/linters/srp/python_analyzer.py +0 -0
  75. {thailint-0.3.0 → thailint-0.3.2}/src/linters/srp/typescript_analyzer.py +0 -0
  76. {thailint-0.3.0 → thailint-0.3.2}/src/linters/srp/typescript_metrics_calculator.py +0 -0
  77. {thailint-0.3.0 → thailint-0.3.2}/src/linters/srp/violation_builder.py +0 -0
  78. {thailint-0.3.0 → thailint-0.3.2}/src/orchestrator/__init__.py +0 -0
  79. {thailint-0.3.0 → thailint-0.3.2}/src/orchestrator/core.py +0 -0
  80. {thailint-0.3.0 → thailint-0.3.2}/src/orchestrator/language_detector.py +0 -0
  81. {thailint-0.3.0 → thailint-0.3.2}/src/utils/__init__.py +0 -0
  82. {thailint-0.3.0 → thailint-0.3.2}/src/utils/project_root.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: thailint
3
- Version: 0.3.0
3
+ Version: 0.3.2
4
4
  Summary: The AI Linter - Enterprise-grade linting and governance for AI-generated code across multiple languages
5
5
  License: MIT
6
6
  Keywords: linter,ai,code-quality,static-analysis,file-placement,governance,multi-language,cli,docker,python
@@ -35,14 +35,25 @@ Description-Content-Type: text/markdown
35
35
 
36
36
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
37
37
  [![Python 3.11+](https://img.shields.io/badge/python-3.11+-blue.svg)](https://www.python.org/downloads/)
38
- [![Tests](https://img.shields.io/badge/tests-317%2F317%20passing-brightgreen.svg)](tests/)
39
- [![Coverage](https://img.shields.io/badge/coverage-90%25-brightgreen.svg)](htmlcov/)
38
+ [![Tests](https://img.shields.io/badge/tests-253%2F253%20passing-brightgreen.svg)](tests/)
39
+ [![Coverage](https://img.shields.io/badge/coverage-88%25-brightgreen.svg)](htmlcov/)
40
40
 
41
41
  The AI Linter - Enterprise-ready linting and governance for AI-generated code across multiple languages.
42
42
 
43
43
  ## Overview
44
44
 
45
- thailint is a modern, enterprise-ready multi-language linter designed specifically for AI-generated code. It enforces project structure, file placement rules, and coding standards across Python, TypeScript, and other languages.
45
+ thailint is a modern, enterprise-ready multi-language linter designed specifically for AI-generated code. It focuses on common mistakes and anti-patterns that AI coding assistants frequently introduce—issues that existing linters don't catch or don't handle consistently across languages.
46
+
47
+ **Why thailint?**
48
+
49
+ We're not trying to replace the wonderful existing linters like Pylint, ESLint, or Ruff. Instead, thailint fills critical gaps:
50
+
51
+ - **AI-Specific Patterns**: AI assistants have predictable blind spots (excessive nesting, magic numbers, SRP violations) that traditional linters miss
52
+ - **Cross-Language Consistency**: Detects the same anti-patterns across Python, TypeScript, and JavaScript with unified rules
53
+ - **No Existing Solutions**: Issues like excessive nesting depth, file placement violations, and cross-project code duplication lack comprehensive multi-language detection
54
+ - **Governance Layer**: Enforces project-wide structure and organization patterns that AI can't infer from local context
55
+
56
+ thailint complements your existing linting stack by catching the patterns AI tools repeatedly miss.
46
57
 
47
58
  ## Features
48
59
 
@@ -917,49 +928,96 @@ def test_no_violations():
917
928
  ### Setup Development Environment
918
929
 
919
930
  ```bash
920
- # Install development dependencies
921
- pip install -e ".[dev]"
931
+ # Install dependencies and activate virtualenv
932
+ just init
922
933
 
923
- # Install pre-commit hooks (if using)
924
- pre-commit install
934
+ # Or manually:
935
+ poetry install
936
+ source $(poetry env info --path)/bin/activate
925
937
  ```
926
938
 
927
939
  ### Running Tests
928
940
 
929
941
  ```bash
930
- # Run all tests
931
- pytest
942
+ # Run all tests (parallel mode - fast)
943
+ just test
932
944
 
933
- # Run with coverage
934
- pytest --cov=src --cov-report=html
945
+ # Run with coverage (serial mode)
946
+ just test-coverage
935
947
 
936
948
  # Run specific test
937
- pytest tests/test_cli.py::test_hello_command
949
+ poetry run pytest tests/test_cli.py::test_hello_command -v
938
950
  ```
939
951
 
940
952
  ### Code Quality
941
953
 
942
954
  ```bash
943
- # Lint code
944
- ruff check src tests
955
+ # Fast linting (Ruff only - use during development)
956
+ just lint
957
+
958
+ # Comprehensive linting (Ruff + Pylint + Flake8 + MyPy)
959
+ just lint-all
960
+
961
+ # Security scanning
962
+ just lint-security
963
+
964
+ # Complexity analysis (Radon + Xenon + Nesting)
965
+ just lint-complexity
966
+
967
+ # SOLID principles (SRP)
968
+ just lint-solid
969
+
970
+ # DRY principles (duplicate code detection)
971
+ just lint-dry
972
+
973
+ # ALL quality checks (runs everything)
974
+ just lint-full
975
+
976
+ # Auto-fix formatting issues
977
+ just format
978
+ ```
979
+
980
+ ### Dogfooding (Lint Our Own Code)
981
+
982
+ ```bash
983
+ # Lint file placement
984
+ just lint-placement
945
985
 
946
- # Format code
947
- ruff format src tests
986
+ # Check nesting depth
987
+ just lint-nesting
948
988
 
949
- # Type checking
950
- mypy src/
989
+ # Check for magic numbers
990
+ poetry run thai-lint magic-numbers src/
951
991
  ```
952
992
 
953
- ### Building
993
+ ### Building and Publishing
954
994
 
955
995
  ```bash
956
996
  # Build Python package
957
997
  poetry build
958
998
 
959
- # Build Docker image locally (optional)
999
+ # Build Docker image locally
960
1000
  docker build -t washad/thailint:latest .
1001
+
1002
+ # Publish to PyPI and Docker Hub (runs tests + linting + version bump)
1003
+ just publish
961
1004
  ```
962
1005
 
1006
+ ### Quick Development Workflows
1007
+
1008
+ ```bash
1009
+ # Make changes, then run quality checks
1010
+ just lint-full
1011
+
1012
+ # Share changes for collaboration (skips hooks)
1013
+ just share "WIP: feature description"
1014
+
1015
+ # Clean up cache and artifacts
1016
+ just clean
1017
+ ```
1018
+
1019
+ See `just --list` or `just help` for all available commands.
1020
+
963
1021
  ## Docker Usage
964
1022
 
965
1023
  ```bash
@@ -2,14 +2,25 @@
2
2
 
3
3
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
4
4
  [![Python 3.11+](https://img.shields.io/badge/python-3.11+-blue.svg)](https://www.python.org/downloads/)
5
- [![Tests](https://img.shields.io/badge/tests-317%2F317%20passing-brightgreen.svg)](tests/)
6
- [![Coverage](https://img.shields.io/badge/coverage-90%25-brightgreen.svg)](htmlcov/)
5
+ [![Tests](https://img.shields.io/badge/tests-253%2F253%20passing-brightgreen.svg)](tests/)
6
+ [![Coverage](https://img.shields.io/badge/coverage-88%25-brightgreen.svg)](htmlcov/)
7
7
 
8
8
  The AI Linter - Enterprise-ready linting and governance for AI-generated code across multiple languages.
9
9
 
10
10
  ## Overview
11
11
 
12
- thailint is a modern, enterprise-ready multi-language linter designed specifically for AI-generated code. It enforces project structure, file placement rules, and coding standards across Python, TypeScript, and other languages.
12
+ thailint is a modern, enterprise-ready multi-language linter designed specifically for AI-generated code. It focuses on common mistakes and anti-patterns that AI coding assistants frequently introduce—issues that existing linters don't catch or don't handle consistently across languages.
13
+
14
+ **Why thailint?**
15
+
16
+ We're not trying to replace the wonderful existing linters like Pylint, ESLint, or Ruff. Instead, thailint fills critical gaps:
17
+
18
+ - **AI-Specific Patterns**: AI assistants have predictable blind spots (excessive nesting, magic numbers, SRP violations) that traditional linters miss
19
+ - **Cross-Language Consistency**: Detects the same anti-patterns across Python, TypeScript, and JavaScript with unified rules
20
+ - **No Existing Solutions**: Issues like excessive nesting depth, file placement violations, and cross-project code duplication lack comprehensive multi-language detection
21
+ - **Governance Layer**: Enforces project-wide structure and organization patterns that AI can't infer from local context
22
+
23
+ thailint complements your existing linting stack by catching the patterns AI tools repeatedly miss.
13
24
 
14
25
  ## Features
15
26
 
@@ -884,49 +895,96 @@ def test_no_violations():
884
895
  ### Setup Development Environment
885
896
 
886
897
  ```bash
887
- # Install development dependencies
888
- pip install -e ".[dev]"
898
+ # Install dependencies and activate virtualenv
899
+ just init
889
900
 
890
- # Install pre-commit hooks (if using)
891
- pre-commit install
901
+ # Or manually:
902
+ poetry install
903
+ source $(poetry env info --path)/bin/activate
892
904
  ```
893
905
 
894
906
  ### Running Tests
895
907
 
896
908
  ```bash
897
- # Run all tests
898
- pytest
909
+ # Run all tests (parallel mode - fast)
910
+ just test
899
911
 
900
- # Run with coverage
901
- pytest --cov=src --cov-report=html
912
+ # Run with coverage (serial mode)
913
+ just test-coverage
902
914
 
903
915
  # Run specific test
904
- pytest tests/test_cli.py::test_hello_command
916
+ poetry run pytest tests/test_cli.py::test_hello_command -v
905
917
  ```
906
918
 
907
919
  ### Code Quality
908
920
 
909
921
  ```bash
910
- # Lint code
911
- ruff check src tests
922
+ # Fast linting (Ruff only - use during development)
923
+ just lint
924
+
925
+ # Comprehensive linting (Ruff + Pylint + Flake8 + MyPy)
926
+ just lint-all
927
+
928
+ # Security scanning
929
+ just lint-security
930
+
931
+ # Complexity analysis (Radon + Xenon + Nesting)
932
+ just lint-complexity
933
+
934
+ # SOLID principles (SRP)
935
+ just lint-solid
936
+
937
+ # DRY principles (duplicate code detection)
938
+ just lint-dry
939
+
940
+ # ALL quality checks (runs everything)
941
+ just lint-full
942
+
943
+ # Auto-fix formatting issues
944
+ just format
945
+ ```
946
+
947
+ ### Dogfooding (Lint Our Own Code)
948
+
949
+ ```bash
950
+ # Lint file placement
951
+ just lint-placement
912
952
 
913
- # Format code
914
- ruff format src tests
953
+ # Check nesting depth
954
+ just lint-nesting
915
955
 
916
- # Type checking
917
- mypy src/
956
+ # Check for magic numbers
957
+ poetry run thai-lint magic-numbers src/
918
958
  ```
919
959
 
920
- ### Building
960
+ ### Building and Publishing
921
961
 
922
962
  ```bash
923
963
  # Build Python package
924
964
  poetry build
925
965
 
926
- # Build Docker image locally (optional)
966
+ # Build Docker image locally
927
967
  docker build -t washad/thailint:latest .
968
+
969
+ # Publish to PyPI and Docker Hub (runs tests + linting + version bump)
970
+ just publish
928
971
  ```
929
972
 
973
+ ### Quick Development Workflows
974
+
975
+ ```bash
976
+ # Make changes, then run quality checks
977
+ just lint-full
978
+
979
+ # Share changes for collaboration (skips hooks)
980
+ just share "WIP: feature description"
981
+
982
+ # Clean up cache and artifacts
983
+ just clean
984
+ ```
985
+
986
+ See `just --list` or `just help` for all available commands.
987
+
930
988
  ## Docker Usage
931
989
 
932
990
  ```bash
@@ -17,7 +17,7 @@ build-backend = "poetry.core.masonry.api"
17
17
 
18
18
  [tool.poetry]
19
19
  name = "thailint"
20
- version = "0.3.0"
20
+ version = "0.3.2"
21
21
  description = "The AI Linter - Enterprise-grade linting and governance for AI-generated code across multiple languages"
22
22
  authors = ["Steve Jackson"]
23
23
  license = "MIT"
@@ -101,6 +101,7 @@ xenon = "^0.9.3"
101
101
  safety = "^3.2.11"
102
102
  pip-audit = "^2.8.0"
103
103
  loguru = "^0.7.3"
104
+ pytest-xdist = "^3.8.0"
104
105
 
105
106
  [tool.poetry.scripts]
106
107
  thailint = "src.cli:cli"
@@ -1077,5 +1077,106 @@ def _run_dry_lint(orchestrator, path_objs, recursive):
1077
1077
  return dry_violations
1078
1078
 
1079
1079
 
1080
+ def _setup_magic_numbers_orchestrator(
1081
+ path_objs: list[Path], config_file: str | None, verbose: bool
1082
+ ):
1083
+ """Set up orchestrator for magic-numbers command."""
1084
+ first_path = path_objs[0] if path_objs else Path.cwd()
1085
+ project_root = first_path if first_path.is_dir() else first_path.parent
1086
+
1087
+ from src.orchestrator.core import Orchestrator
1088
+
1089
+ orchestrator = Orchestrator(project_root=project_root)
1090
+
1091
+ if config_file:
1092
+ _load_config_file(orchestrator, config_file, verbose)
1093
+
1094
+ return orchestrator
1095
+
1096
+
1097
+ def _run_magic_numbers_lint(orchestrator, path_objs: list[Path], recursive: bool):
1098
+ """Execute magic-numbers lint on files or directories."""
1099
+ all_violations = _execute_linting_on_paths(orchestrator, path_objs, recursive)
1100
+ return [v for v in all_violations if "magic-number" in v.rule_id]
1101
+
1102
+
1103
+ @cli.command("magic-numbers")
1104
+ @click.argument("paths", nargs=-1, type=click.Path())
1105
+ @click.option("--config", "-c", "config_file", type=click.Path(), help="Path to config file")
1106
+ @format_option
1107
+ @click.option("--recursive/--no-recursive", default=True, help="Scan directories recursively")
1108
+ @click.pass_context
1109
+ def magic_numbers( # pylint: disable=too-many-arguments,too-many-positional-arguments
1110
+ ctx,
1111
+ paths: tuple[str, ...],
1112
+ config_file: str | None,
1113
+ format: str,
1114
+ recursive: bool,
1115
+ ):
1116
+ """Check for magic numbers in code.
1117
+
1118
+ Detects unnamed numeric literals in Python and TypeScript/JavaScript code
1119
+ that should be extracted as named constants for better readability.
1120
+
1121
+ PATHS: Files or directories to lint (defaults to current directory if none provided)
1122
+
1123
+ Examples:
1124
+
1125
+ \b
1126
+ # Check current directory (all files recursively)
1127
+ thai-lint magic-numbers
1128
+
1129
+ \b
1130
+ # Check specific directory
1131
+ thai-lint magic-numbers src/
1132
+
1133
+ \b
1134
+ # Check single file
1135
+ thai-lint magic-numbers src/app.py
1136
+
1137
+ \b
1138
+ # Check multiple files
1139
+ thai-lint magic-numbers src/app.py src/utils.py tests/test_app.py
1140
+
1141
+ \b
1142
+ # Check mix of files and directories
1143
+ thai-lint magic-numbers src/app.py tests/
1144
+
1145
+ \b
1146
+ # Get JSON output
1147
+ thai-lint magic-numbers --format json .
1148
+
1149
+ \b
1150
+ # Use custom config file
1151
+ thai-lint magic-numbers --config .thailint.yaml src/
1152
+ """
1153
+ verbose = ctx.obj.get("verbose", False)
1154
+
1155
+ if not paths:
1156
+ paths = (".",)
1157
+
1158
+ path_objs = [Path(p) for p in paths]
1159
+
1160
+ try:
1161
+ _execute_magic_numbers_lint(path_objs, config_file, format, recursive, verbose)
1162
+ except Exception as e:
1163
+ _handle_linting_error(e, verbose)
1164
+
1165
+
1166
+ def _execute_magic_numbers_lint( # pylint: disable=too-many-arguments,too-many-positional-arguments
1167
+ path_objs, config_file, format, recursive, verbose
1168
+ ):
1169
+ """Execute magic-numbers lint."""
1170
+ _validate_paths_exist(path_objs)
1171
+ orchestrator = _setup_magic_numbers_orchestrator(path_objs, config_file, verbose)
1172
+ magic_numbers_violations = _run_magic_numbers_lint(orchestrator, path_objs, recursive)
1173
+
1174
+ if verbose:
1175
+ logger.info(f"Found {len(magic_numbers_violations)} magic number violation(s)")
1176
+
1177
+ format_violations(magic_numbers_violations, format)
1178
+ sys.exit(1 if magic_numbers_violations else 0)
1179
+
1180
+
1080
1181
  if __name__ == "__main__":
1081
1182
  cli()
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes