thailint 0.5.0__py3-none-any.whl → 0.8.0__py3-none-any.whl

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 (37) hide show
  1. src/cli.py +236 -2
  2. src/core/cli_utils.py +16 -1
  3. src/core/registry.py +1 -1
  4. src/formatters/__init__.py +22 -0
  5. src/formatters/sarif.py +202 -0
  6. src/linter_config/loader.py +5 -4
  7. src/linters/dry/block_filter.py +11 -8
  8. src/linters/dry/cache.py +3 -2
  9. src/linters/dry/duplicate_storage.py +5 -4
  10. src/linters/dry/violation_generator.py +1 -1
  11. src/linters/file_header/atemporal_detector.py +11 -11
  12. src/linters/file_header/base_parser.py +89 -0
  13. src/linters/file_header/bash_parser.py +58 -0
  14. src/linters/file_header/config.py +76 -16
  15. src/linters/file_header/css_parser.py +70 -0
  16. src/linters/file_header/field_validator.py +35 -29
  17. src/linters/file_header/linter.py +113 -121
  18. src/linters/file_header/markdown_parser.py +124 -0
  19. src/linters/file_header/python_parser.py +14 -58
  20. src/linters/file_header/typescript_parser.py +73 -0
  21. src/linters/file_header/violation_builder.py +13 -12
  22. src/linters/file_placement/linter.py +9 -11
  23. src/linters/method_property/__init__.py +49 -0
  24. src/linters/method_property/config.py +135 -0
  25. src/linters/method_property/linter.py +419 -0
  26. src/linters/method_property/python_analyzer.py +472 -0
  27. src/linters/method_property/violation_builder.py +116 -0
  28. src/linters/print_statements/config.py +7 -12
  29. src/linters/print_statements/linter.py +13 -15
  30. src/linters/print_statements/python_analyzer.py +8 -14
  31. src/linters/print_statements/typescript_analyzer.py +9 -14
  32. src/linters/print_statements/violation_builder.py +12 -14
  33. {thailint-0.5.0.dist-info → thailint-0.8.0.dist-info}/METADATA +155 -3
  34. {thailint-0.5.0.dist-info → thailint-0.8.0.dist-info}/RECORD +37 -25
  35. {thailint-0.5.0.dist-info → thailint-0.8.0.dist-info}/WHEEL +0 -0
  36. {thailint-0.5.0.dist-info → thailint-0.8.0.dist-info}/entry_points.txt +0 -0
  37. {thailint-0.5.0.dist-info → thailint-0.8.0.dist-info}/licenses/LICENSE +0 -0
@@ -1,28 +1,22 @@
1
1
  """
2
- File: src/linters/print_statements/python_analyzer.py
3
-
4
2
  Purpose: Python AST analysis for finding print() call nodes
5
3
 
6
- Exports: PythonPrintStatementAnalyzer class
7
-
8
- Depends: ast module for AST parsing and node types
9
-
10
- Implements: PythonPrintStatementAnalyzer.find_print_calls(tree) -> list[tuple],
11
- PythonPrintStatementAnalyzer.is_in_main_block(node) -> bool
12
-
13
- Related: src/linters/magic_numbers/python_analyzer.py
4
+ Scope: Python print() statement detection and __main__ block context analysis
14
5
 
15
6
  Overview: Provides PythonPrintStatementAnalyzer class that traverses Python AST to find all
16
7
  print() function calls. Uses ast.walk() to traverse the syntax tree and collect
17
8
  Call nodes where the function is 'print'. Tracks parent nodes to detect if print calls
18
9
  are within __main__ blocks (if __name__ == "__main__":) for allow_in_scripts filtering.
19
10
  Returns structured data about each print call including the AST node, parent context,
20
- and line number for violation reporting.
11
+ and line number for violation reporting. Handles both simple print() and builtins.print() calls.
12
+
13
+ Dependencies: ast module for AST parsing and node types
14
+
15
+ Exports: PythonPrintStatementAnalyzer class
21
16
 
22
- Usage: analyzer = PythonPrintStatementAnalyzer()
23
- print_calls = analyzer.find_print_calls(ast.parse(code))
17
+ Interfaces: find_print_calls(tree) -> list[tuple[Call, AST | None, int]], is_in_main_block(node) -> bool
24
18
 
25
- Notes: AST walk pattern with parent tracking for context detection
19
+ Implementation: AST walk pattern with parent map for context detection and __main__ block identification
26
20
  """
27
21
 
28
22
  import ast
@@ -1,28 +1,23 @@
1
1
  """
2
- File: src/linters/print_statements/typescript_analyzer.py
3
-
4
2
  Purpose: TypeScript/JavaScript console.* call detection using Tree-sitter AST analysis
5
3
 
6
- Exports: TypeScriptPrintStatementAnalyzer class
7
-
8
- Depends: TypeScriptBaseAnalyzer for tree-sitter parsing, tree-sitter Node type
9
-
10
- Implements: find_console_calls(root_node, methods) -> list[tuple]
11
-
12
- Related: src/linters/magic_numbers/typescript_analyzer.py, src/analyzers/typescript_base.py
4
+ Scope: TypeScript and JavaScript console statement detection
13
5
 
14
6
  Overview: Analyzes TypeScript and JavaScript code to detect console.* method calls that should
15
7
  be replaced with proper logging. Uses Tree-sitter parser to traverse TypeScript/JavaScript
16
8
  AST and identify call expressions where the callee is console.log, console.warn, console.error,
17
9
  console.debug, or console.info (configurable). Returns structured data with the node, method
18
10
  name, and line number for each detected console call. Supports both TypeScript and JavaScript
19
- files with shared detection logic.
11
+ files with shared detection logic. Handles member expression pattern matching to identify
12
+ console object method calls.
13
+
14
+ Dependencies: TypeScriptBaseAnalyzer for tree-sitter parsing infrastructure, tree-sitter Node type, logging module
15
+
16
+ Exports: TypeScriptPrintStatementAnalyzer class
20
17
 
21
- Usage: analyzer = TypeScriptPrintStatementAnalyzer()
22
- root = analyzer.parse_typescript(code)
23
- calls = analyzer.find_console_calls(root, {"log", "warn", "error"})
18
+ Interfaces: find_console_calls(root_node, methods) -> list[tuple[Node, str, int]]
24
19
 
25
- Notes: Tree-sitter node traversal with call_expression and member_expression pattern matching
20
+ Implementation: Tree-sitter node traversal with call_expression and member_expression pattern matching
26
21
  """
27
22
 
28
23
  import logging
@@ -1,27 +1,25 @@
1
1
  """
2
- File: src/linters/print_statements/violation_builder.py
3
-
4
2
  Purpose: Builds Violation objects for print statement detection
5
3
 
6
- Exports: ViolationBuilder class
7
-
8
- Depends: ast, pathlib.Path, src.core.types.Violation
9
-
10
- Implements: ViolationBuilder.create_python_violation(node, line, file_path) -> Violation,
11
- ViolationBuilder.create_typescript_violation(method, line, file_path) -> Violation
12
-
13
- Related: src/linters/magic_numbers/violation_builder.py, src/core/types.py
4
+ Scope: Violation creation for print and console statement detections
14
5
 
15
6
  Overview: Provides ViolationBuilder class that creates Violation objects for print statement
16
7
  detections. Generates descriptive messages suggesting the use of proper logging instead of
17
8
  print/console statements. Constructs complete Violation instances with rule_id, file_path,
18
9
  line number, column, message, and suggestions. Provides separate methods for Python print()
19
- violations and TypeScript/JavaScript console.* violations with language-appropriate messages.
10
+ violations and TypeScript/JavaScript console.* violations with language-appropriate messages
11
+ and helpful remediation guidance.
12
+
13
+ Dependencies: ast module for Python AST nodes, pathlib.Path for file paths,
14
+ src.core.types.Violation for violation structure
15
+
16
+ Exports: ViolationBuilder class
20
17
 
21
- Usage: builder = ViolationBuilder("print-statements.detected")
22
- violation = builder.create_python_violation(node, line, file_path)
18
+ Interfaces: create_python_violation(node, line, file_path) -> Violation,
19
+ create_typescript_violation(method, line, file_path) -> Violation
23
20
 
24
- Notes: Message templates suggest logging as alternative, consistent with other linter patterns
21
+ Implementation: Builder pattern with message templates suggesting logging as alternative
22
+ to print/console statements
25
23
  """
26
24
 
27
25
  import ast
@@ -1,13 +1,13 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: thailint
3
- Version: 0.5.0
3
+ Version: 0.8.0
4
4
  Summary: The AI Linter - Enterprise-grade linting and governance for AI-generated code across multiple languages
5
5
  License: MIT
6
6
  License-File: LICENSE
7
7
  Keywords: linter,ai,code-quality,static-analysis,file-placement,governance,multi-language,cli,docker,python
8
8
  Author: Steve Jackson
9
9
  Requires-Python: >=3.11,<4.0
10
- Classifier: Development Status :: 3 - Alpha
10
+ Classifier: Development Status :: 4 - Beta
11
11
  Classifier: Environment :: Console
12
12
  Classifier: Intended Audience :: Developers
13
13
  Classifier: License :: OSI Approved :: MIT License
@@ -37,9 +37,10 @@ Description-Content-Type: text/markdown
37
37
 
38
38
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
39
39
  [![Python 3.11+](https://img.shields.io/badge/python-3.11+-blue.svg)](https://www.python.org/downloads/)
40
- [![Tests](https://img.shields.io/badge/tests-393%2F393%20passing-brightgreen.svg)](tests/)
40
+ [![Tests](https://img.shields.io/badge/tests-682%2F682%20passing-brightgreen.svg)](tests/)
41
41
  [![Coverage](https://img.shields.io/badge/coverage-87%25-brightgreen.svg)](htmlcov/)
42
42
  [![Documentation Status](https://readthedocs.org/projects/thai-lint/badge/?version=latest)](https://thai-lint.readthedocs.io/en/latest/?badge=latest)
43
+ [![SARIF 2.1.0](https://img.shields.io/badge/SARIF-2.1.0-orange.svg)](docs/sarif-output.md)
43
44
 
44
45
  The AI Linter - Enterprise-ready linting and governance for AI-generated code across multiple languages.
45
46
 
@@ -73,6 +74,11 @@ thailint complements your existing linting stack by catching the patterns AI too
73
74
 
74
75
  ### Core Capabilities
75
76
  - **File Placement Linting** - Enforce project structure and organization
77
+ - **File Header Linting** - Validate documentation headers in source files
78
+ - Python, TypeScript, JavaScript, Bash, Markdown, CSS support
79
+ - Mandatory field validation (Purpose, Scope, Overview)
80
+ - Atemporal language detection (no dates, "currently", "now")
81
+ - Language-specific header format parsing
76
82
  - **Magic Numbers Linting** - Detect unnamed numeric literals that should be constants
77
83
  - Python and TypeScript support with AST analysis
78
84
  - Context-aware detection (ignores constants, test files, range() usage)
@@ -92,6 +98,12 @@ thailint complements your existing linting stack by catching the patterns AI too
92
98
  - Configurable thresholds (lines, tokens, occurrences)
93
99
  - Language-specific detection (Python, TypeScript, JavaScript)
94
100
  - False positive filtering (keyword args, imports)
101
+ - **Method Property Linting** - Detect methods that should be @property decorators
102
+ - Python AST-based detection
103
+ - get_* prefix detection (Java-style getters)
104
+ - Simple computed value detection
105
+ - Action verb exclusion (to_*, finalize, serialize)
106
+ - Test file detection
95
107
  - **Pluggable Architecture** - Easy to extend with custom linters
96
108
  - **Multi-Language Support** - Python, TypeScript, JavaScript, and more
97
109
  - **Flexible Configuration** - YAML/JSON configs with pattern matching
@@ -158,11 +170,17 @@ thailint dry .
158
170
  # Check for magic numbers
159
171
  thailint magic-numbers src/
160
172
 
173
+ # Check file headers
174
+ thailint file-header src/
175
+
161
176
  # With config file
162
177
  thailint dry --config .thailint.yaml src/
163
178
 
164
179
  # JSON output for CI/CD
165
180
  thailint dry --format json src/
181
+
182
+ # SARIF output for GitHub Code Scanning
183
+ thailint nesting --format sarif src/ > results.sarif
166
184
  ```
167
185
 
168
186
  **New to thailint?** See the **[Quick Start Guide](https://thai-lint.readthedocs.io/en/latest/quick-start/)** for a complete walkthrough including config generation, understanding output, and next steps.
@@ -869,6 +887,136 @@ def get_ports(): # thailint: ignore[magic-numbers] - Standard ports
869
887
 
870
888
  See **[How to Ignore Violations](https://thai-lint.readthedocs.io/en/latest/how-to-ignore-violations/)** and **[Magic Numbers Linter Guide](https://thai-lint.readthedocs.io/en/latest/magic-numbers-linter/)** for complete documentation.
871
889
 
890
+ ## File Header Linter
891
+
892
+ ### Overview
893
+
894
+ The file header linter validates that source files have proper documentation headers containing required fields (Purpose, Scope, Overview) and don't use temporal language (dates, "currently", "now"). It enforces consistent documentation patterns across entire codebases.
895
+
896
+ ### Why File Headers?
897
+
898
+ File headers serve as **self-documentation** that helps developers (and AI assistants) quickly understand:
899
+
900
+ - **Purpose**: What does this file do?
901
+ - **Scope**: What area of the system does it cover?
902
+ - **Dependencies**: What does it rely on?
903
+ - **Exports**: What does it provide to other modules?
904
+
905
+ ### Quick Start
906
+
907
+ ```bash
908
+ # Check file headers in current directory
909
+ thailint file-header .
910
+
911
+ # Check specific directory
912
+ thailint file-header src/
913
+
914
+ # Get JSON output
915
+ thailint file-header --format json src/
916
+
917
+ # Get SARIF output for CI/CD
918
+ thailint file-header --format sarif src/ > results.sarif
919
+ ```
920
+
921
+ ### Configuration
922
+
923
+ Add to `.thailint.yaml`:
924
+
925
+ ```yaml
926
+ file-header:
927
+ enabled: true
928
+ mandatory_fields:
929
+ - Purpose
930
+ - Scope
931
+ - Overview
932
+ ignore:
933
+ - "**/__init__.py"
934
+ - "**/migrations/**"
935
+ ```
936
+
937
+ ### Example Violation
938
+
939
+ **Code without proper header:**
940
+ ```python
941
+ import os
942
+
943
+ def process_data():
944
+ pass
945
+ ```
946
+
947
+ **Violation messages:**
948
+ ```
949
+ src/utils.py:1 - Missing mandatory field: Purpose
950
+ src/utils.py:1 - Missing mandatory field: Scope
951
+ src/utils.py:1 - Missing mandatory field: Overview
952
+ ```
953
+
954
+ **Refactored with header:**
955
+ ```python
956
+ """
957
+ Purpose: Data processing utilities for ETL pipeline
958
+
959
+ Scope: Data transformation layer, used by batch processing jobs
960
+
961
+ Overview: Provides data transformation functions for the ETL pipeline.
962
+ Handles parsing, validation, and normalization of incoming data.
963
+
964
+ Dependencies: os, json
965
+
966
+ Exports: process_data(), validate_input(), transform_record()
967
+ """
968
+ import os
969
+
970
+ def process_data():
971
+ pass
972
+ ```
973
+
974
+ ### Atemporal Language Detection
975
+
976
+ The linter detects temporal language that becomes stale:
977
+
978
+ **Temporal (flagged):**
979
+ ```python
980
+ """
981
+ Purpose: Authentication module
982
+
983
+ Overview: Currently handles OAuth. This was recently updated.
984
+ Created: 2024-01-15. Will be extended in the future.
985
+ """
986
+ ```
987
+
988
+ **Atemporal (correct):**
989
+ ```python
990
+ """
991
+ Purpose: Authentication module
992
+
993
+ Overview: Handles OAuth authentication with Google and GitHub.
994
+ Implements authorization code flow with PKCE for security.
995
+ """
996
+ ```
997
+
998
+ ### Language Support
999
+
1000
+ - **Python**: Module docstrings (`"""..."""`)
1001
+ - **TypeScript/JavaScript**: JSDoc comments (`/** ... */`)
1002
+ - **Bash**: Hash comments after shebang (`# ...`)
1003
+ - **Markdown**: YAML frontmatter (`---...---`)
1004
+ - **CSS/SCSS**: Block comments (`/* ... */`)
1005
+
1006
+ ### Ignoring Violations
1007
+
1008
+ ```python
1009
+ # File-level ignore
1010
+ # thailint: ignore-file[file-header]
1011
+
1012
+ # Line-level ignore for atemporal violation
1013
+ """
1014
+ Overview: Created 2024-01-15. # thailint: ignore[file-header]
1015
+ """
1016
+ ```
1017
+
1018
+ See **[How to Ignore Violations](https://thai-lint.readthedocs.io/en/latest/how-to-ignore-violations/)** and **[File Header Linter Guide](https://thai-lint.readthedocs.io/en/latest/file-header-linter/)** for complete documentation.
1019
+
872
1020
  ## Pre-commit Hooks
873
1021
 
874
1022
  Automate code quality checks before every commit and push with pre-commit hooks.
@@ -1153,11 +1301,13 @@ docker run --rm -v /path/to/workspace:/workspace \
1153
1301
  - **[CLI Reference](https://thai-lint.readthedocs.io/en/latest/cli-reference/)** - All CLI commands and options
1154
1302
  - **[Deployment Modes](https://thai-lint.readthedocs.io/en/latest/deployment-modes/)** - CLI, Library, and Docker usage
1155
1303
  - **[File Placement Linter](https://thai-lint.readthedocs.io/en/latest/file-placement-linter/)** - Detailed linter guide
1304
+ - **[File Header Linter](https://thai-lint.readthedocs.io/en/latest/file-header-linter/)** - File header validation guide
1156
1305
  - **[Magic Numbers Linter](https://thai-lint.readthedocs.io/en/latest/magic-numbers-linter/)** - Magic numbers detection guide
1157
1306
  - **[Nesting Depth Linter](https://thai-lint.readthedocs.io/en/latest/nesting-linter/)** - Nesting depth analysis guide
1158
1307
  - **[SRP Linter](https://thai-lint.readthedocs.io/en/latest/srp-linter/)** - Single Responsibility Principle guide
1159
1308
  - **[DRY Linter](https://thai-lint.readthedocs.io/en/latest/dry-linter/)** - Duplicate code detection guide
1160
1309
  - **[Pre-commit Hooks](https://thai-lint.readthedocs.io/en/latest/pre-commit-hooks/)** - Automated quality checks
1310
+ - **[SARIF Output Guide](docs/sarif-output.md)** - SARIF format for GitHub Code Scanning and CI/CD
1161
1311
  - **[Publishing Guide](https://thai-lint.readthedocs.io/en/latest/releasing/)** - Release and publishing workflow
1162
1312
  - **[Publishing Checklist](https://thai-lint.readthedocs.io/en/latest/publishing-checklist/)** - Post-publication validation
1163
1313
 
@@ -1168,6 +1318,8 @@ See [`examples/`](examples/) directory for working code:
1168
1318
  - **[basic_usage.py](examples/basic_usage.py)** - Simple library API usage
1169
1319
  - **[advanced_usage.py](examples/advanced_usage.py)** - Advanced patterns and workflows
1170
1320
  - **[ci_integration.py](examples/ci_integration.py)** - CI/CD integration example
1321
+ - **[sarif_usage.py](examples/sarif_usage.py)** - SARIF output format examples
1322
+ - **[file_header_usage.py](examples/file_header_usage.py)** - File header validation examples
1171
1323
 
1172
1324
  ## Project Structure
1173
1325
 
@@ -2,31 +2,33 @@ src/__init__.py,sha256=f601zncODr2twrUHqTLS5wyOdZqZi9tMjAe2INhRKqU,2175
2
2
  src/analyzers/__init__.py,sha256=fFloZtjkBGwYbAhKTxS3Qy3yDr2_3i3WSfKTw1mAioo,972
3
3
  src/analyzers/typescript_base.py,sha256=4I7fAcMOAY9vY1AXh52QpohgFmguBECwOkvBRP4zCS4,5054
4
4
  src/api.py,sha256=pJ5l3qxccKBEY-BkANwzTgLAl1ZFq7OP6hx6LSxbhDw,4664
5
- src/cli.py,sha256=t72ZeeBpXJTIR1Gx_nIak-ZlUJhfXhEORXNNcjdp2-I,51820
5
+ src/cli.py,sha256=E0PEazl-fuuNu8psnUBAQ53PihtLwgKyAOL3v193Z-o,59424
6
6
  src/config.py,sha256=2ebAjIpAhw4bHbOxViEA5nCjfBlDEIrMR59DBrzcYzM,12460
7
7
  src/core/__init__.py,sha256=5FtsDvhMt4SNRx3pbcGURrxn135XRbeRrjSUxiXwkNc,381
8
8
  src/core/base.py,sha256=Eklcagi2ktfY4Kytl_ObXov2U49N9OGDpw4cu4PUzGY,7824
9
- src/core/cli_utils.py,sha256=rYOJz4mnr8RLP-nJdHOy-GJyxGNqkWtK3_rvKriHXj4,6083
9
+ src/core/cli_utils.py,sha256=vKw0jF1rZv_N7gbzvV5TeO9rV5VPfd89fneKrglQ2Hs,6502
10
10
  src/core/config_parser.py,sha256=zAY4bDptNlVID0a4JDXN0YlUKXLM92cFqTAwhp_8uGc,4183
11
11
  src/core/linter_utils.py,sha256=4jmC2YfpPvGhS_XHlHXa5SBIJh9CQlNj5zuW_GpdPKc,5273
12
- src/core/registry.py,sha256=IMkic1ukmo8HCX1TY5YoKjwKT_IT-ZmVx6sdntC5X2M,3289
12
+ src/core/registry.py,sha256=yRA8mQLiZwjmgxl1wSTgdj1cuo_QXuRdrXt3NpCBUgE,3285
13
13
  src/core/rule_discovery.py,sha256=smxJ9PEyMqEAIicsWaHOaSHD1PHUAOeFZT_a3DNRwgE,4163
14
14
  src/core/types.py,sha256=dIYLaCDNtCAzVaplx5S5yxywkLIuX0BN9No_l2zCfV0,2887
15
15
  src/core/violation_builder.py,sha256=7AQODqxwc3qp_4m1MPzknkeNGlht1LsDjPsTPpWAGJY,4678
16
+ src/formatters/__init__.py,sha256=yE1yIL8lplTMEjsmQm7F-kOMaYq7OjmbFuiwwK0D-gM,815
17
+ src/formatters/sarif.py,sha256=gGOwb_v7j4mx4bpvV1NNDd-JyHH8i8XX89iQ6uRSvG4,7050
16
18
  src/linter_config/__init__.py,sha256=_I2VVlZlfKyT-tKukuUA5-aVcHLOe3m6C2cev43AiEc,298
17
19
  src/linter_config/ignore.py,sha256=S2Ub0CCOOC-wpU5Y_EodMprciw18fgWcnp4z_h1MYNk,19638
18
- src/linter_config/loader.py,sha256=HB09W-uVsEcgCbvUwUHS5Jm2n0bqBXA3744vMc4GAqk,2542
20
+ src/linter_config/loader.py,sha256=BM4GJZqkEJSKxR3jIMgz0WqB_uWxXNiHsKWtwUA43AE,2545
19
21
  src/linters/__init__.py,sha256=-nnNsL8E5-2p9qlLKp_TaShHAjPH-NacOEU1sXmAR9k,77
20
22
  src/linters/dry/__init__.py,sha256=p58tN3z_VbulfTkRm1kLZJ43Bemt66T2sro1teirUY8,826
21
23
  src/linters/dry/base_token_analyzer.py,sha256=SgnsX4a4kUzOsA9hTkLkg4yB8I77ewAyiUp6cAybUrg,2684
22
- src/linters/dry/block_filter.py,sha256=FN1QDXQu6HYhdHo6fkzUDUrMX4TqaLV_myBOQRsmPfk,8242
24
+ src/linters/dry/block_filter.py,sha256=8Sc4tZqHj5GpVxJTQRMCtbMLt6zscuylF2fccEwPo2w,8248
23
25
  src/linters/dry/block_grouper.py,sha256=gBvSPgy8jumChZ53px3P7hDCJfi5PDrKhwxLTgNy7ig,1810
24
- src/linters/dry/cache.py,sha256=QbFajUNb3v2LVuYbTJXY9ExXjjIsd73DQ5Y1hB-SH1s,5879
26
+ src/linters/dry/cache.py,sha256=dedkGU5SolTjmTTsmj-dwPEnxyhWZ2aBiHGkQy1JwXo,5881
25
27
  src/linters/dry/cache_query.py,sha256=NTBh4ISy76LJb9tJ6G94fE0R2OiE0eQ-zVvB08WG2bA,1802
26
28
  src/linters/dry/config.py,sha256=XaHX5SnbH8cEBHiNKMSuYQJwCbKL-Q9XgZVRcc9UBgQ,5439
27
29
  src/linters/dry/config_loader.py,sha256=wikqnigOp6p1h9jaAATV_3bDXSiaIUFaf9xg1jQMDpo,1313
28
30
  src/linters/dry/deduplicator.py,sha256=a1TRvldxCszf5QByo1ihXF3W98dpGuyaRT74jPfQftM,3988
29
- src/linters/dry/duplicate_storage.py,sha256=3OxE2mtoWGAsNNrB8J2c-4JirLUoqZ9ptydO5beM-mg,1971
31
+ src/linters/dry/duplicate_storage.py,sha256=9pIALnwAuz5BJUYNXrPbObbP932CE9x0vgUkICryT_s,1970
30
32
  src/linters/dry/file_analyzer.py,sha256=ufSQ85ddsGTqGnBHZNTdV_5DGfTpUmJOB58sIdJNV0I,2928
31
33
  src/linters/dry/inline_ignore.py,sha256=ASfA-fp_1aPpkakN2e0T6qdTh8S7Jqj89ovxXJLmFlc,4439
32
34
  src/linters/dry/linter.py,sha256=XMLwCgGrFX0l0dVUJs1jpsXOfgxeKKDbxOtN5h5Emhk,5835
@@ -36,18 +38,23 @@ src/linters/dry/token_hasher.py,sha256=71njBzUsWvQjIWo38AKeRHQsG8K4jrjLTKuih-i6G
36
38
  src/linters/dry/typescript_analyzer.py,sha256=ShNoB2KfPe010wKEZoFxn-ZKh0MnRUwgADDQKQtfedI,21627
37
39
  src/linters/dry/violation_builder.py,sha256=EUiEQIOZjzAoHEqZiIR8WZP8m4dgqJjcveR5mdMyClI,2803
38
40
  src/linters/dry/violation_filter.py,sha256=aTOMz8kXG2sZlSVcf3cAxgxHs7f2kBXInfr1V_04fUQ,3125
39
- src/linters/dry/violation_generator.py,sha256=cc6aKvTxtHSZm0F7Y-gL1bmD3JUphRmAvcbqk9aUzGg,6128
41
+ src/linters/dry/violation_generator.py,sha256=hbMs8Fo2hS8JCXicZcZni6NEkv4fJRsyrsjzrqN6qVw,6122
40
42
  src/linters/file_header/__init__.py,sha256=S3a2xrOlxnNWD02To5K2ZwILsNEvSj1IvUAH8RjgOV4,791
41
- src/linters/file_header/atemporal_detector.py,sha256=Rbjs2GHsgO-1r2kUHUuDRsX3XAX0INFZWVrKoUh5v-8,3104
42
- src/linters/file_header/config.py,sha256=1pjfa0hIUEiE0riMLTH9FQiETXfEkhAFuv1HBx0SGgI,2073
43
- src/linters/file_header/field_validator.py,sha256=bR0xZ5DhPHBE8lopbcaNwJr0auZlNDkCwml3Q8_7XOY,2380
44
- src/linters/file_header/linter.py,sha256=ISNnt-YMgkKQl4psVLefp5P7qTQ6wIGidq4dTkTNbaI,11228
45
- src/linters/file_header/python_parser.py,sha256=TcnA8OCbHK3YtixmFwSP7OCvxjjGLZBioez9wVukz28,2951
46
- src/linters/file_header/violation_builder.py,sha256=yDNqsZ-hDnURpph9oZNj2lCkJgd_7hprjk3Fr0iPphs,2653
43
+ src/linters/file_header/atemporal_detector.py,sha256=bgQJPDuJj1J5gHKIIOz1TYbBwu8GHrcMafWFVqZ_zZE,3192
44
+ src/linters/file_header/base_parser.py,sha256=HbuJpXQ4V3zTDTP_D0iFqoT7kab6gk8A1lZdlqCb6tc,3202
45
+ src/linters/file_header/bash_parser.py,sha256=ZnPleRD4c16ibYMBc682N9W-Qgtz9lKtLSqSmbo7oqg,2147
46
+ src/linters/file_header/config.py,sha256=Ewrln4W4QDnInTgWr8WgSlQEjAuDyMbUuh9GHAa9a4c,4030
47
+ src/linters/file_header/css_parser.py,sha256=ijpGMixg2ZqNWWdiZjSNtMXCOhm6XDfSY7OU68B9fS8,2332
48
+ src/linters/file_header/field_validator.py,sha256=uASqHj7ID4JJZzgc6X3SmRRLWV35NnX2iZElCt3HW1o,2830
49
+ src/linters/file_header/linter.py,sha256=rbfpHBCCn0cRKUyadc2luZSQay_gJfVC79JcqkwUMb4,12192
50
+ src/linters/file_header/markdown_parser.py,sha256=dmrB8JCxKTHyw-qMU6S-UjKaFbqJ6ZQY1f23tND5_Jo,4964
51
+ src/linters/file_header/python_parser.py,sha256=RTOeEt1b3tCvFWbZIt89awQA37CUOSBIGagEYnayn-M,1432
52
+ src/linters/file_header/typescript_parser.py,sha256=R11Vkr6dUVaU8t90m8rrkMzODtBYk7u-TYFsMDRwzX8,2532
53
+ src/linters/file_header/violation_builder.py,sha256=HPYTmrcCmcO6Dx5dhmj85zZgEBM5EZqTgql-0CA0A0k,2745
47
54
  src/linters/file_placement/__init__.py,sha256=vJ43GZujcbAk-K3DwfsQZ0J3yP_5G35CKssatLyntXk,862
48
55
  src/linters/file_placement/config_loader.py,sha256=Of5sTG2S-04efn3KOlXrSxpMcC1ipBpSvCjtJOMmWno,2640
49
56
  src/linters/file_placement/directory_matcher.py,sha256=YaBeLGiT4bgqN_v4FmEmSASOBxkMC1lyEYpL17wLIDY,2607
50
- src/linters/file_placement/linter.py,sha256=HtQf08UmKCe5YAHoPvVgWmxdUFu6ZeP2qicg-q7BgzM,14438
57
+ src/linters/file_placement/linter.py,sha256=A4mndpyIyxEzq64rLw2ILNA7APx_QmwzUfnhB0PyuCs,14190
51
58
  src/linters/file_placement/path_resolver.py,sha256=S6g7xOYsoSc0O_RDJh8j4Z2klcwzp16rSUfEAErGOTI,1972
52
59
  src/linters/file_placement/pattern_matcher.py,sha256=3HZWYgQKXz_y13z3lO1YHn51khCaiGOrneGxKXGWGw0,1898
53
60
  src/linters/file_placement/pattern_validator.py,sha256=eMt5GB5lgJMhhQACOlfDXQFfSfNrOY-wJN1JanGka6Q,3717
@@ -60,6 +67,11 @@ src/linters/magic_numbers/linter.py,sha256=maj4NgrDapv0RurKvaVgOI1BUujixZv4E7UeY
60
67
  src/linters/magic_numbers/python_analyzer.py,sha256=0u1cFaaFCqOW5yeW-YbmPoZuVIeN_KtmkFyyxup6aR0,2803
61
68
  src/linters/magic_numbers/typescript_analyzer.py,sha256=NTU1XY-Hudse5oxOtEiG6nA0Rs5Icn9HXELnyPj8OZU,7554
62
69
  src/linters/magic_numbers/violation_builder.py,sha256=SqIQv3N9lpP2GRC1TC5InrvaEdrAq24V7Ec2Xj5olb0,3308
70
+ src/linters/method_property/__init__.py,sha256=t0C6zD5WLm-McgmvVajQJg4HQfOi7_4YzNLhKNA484w,1415
71
+ src/linters/method_property/config.py,sha256=lcKfeCIeWBcD91j0AchccWhGvc68epiQeKbgL6DCEA8,5359
72
+ src/linters/method_property/linter.py,sha256=zdXUqx76A8J7Ryvg333jrAUDFWx4I4n3dzayAcN2k8w,12721
73
+ src/linters/method_property/python_analyzer.py,sha256=QQTpKrdCJzFqu7gdQfAqno9_wbzHlOQYQdCzMPriRM0,15244
74
+ src/linters/method_property/violation_builder.py,sha256=GKZC8TS9vZq_lKK5ffOVUHUlMpZN3_-Mv3inRE-v2pE,4141
63
75
  src/linters/nesting/__init__.py,sha256=tszmyCEQMpEwB5H84WcAUfRYDQl7jpsn04es5DtAHsM,3200
64
76
  src/linters/nesting/config.py,sha256=PfPA2wJn3i6HHXeM0qu6Qx-v1KJdRwlRkFOdpf7NhS8,2405
65
77
  src/linters/nesting/linter.py,sha256=-klbXIbg145beICop81CNQ5J1OInQaeycDT8u3Ff2Ww,6236
@@ -68,11 +80,11 @@ src/linters/nesting/typescript_analyzer.py,sha256=wO6p6QNnyW1uaieTCZjaqR56C68Aji
68
80
  src/linters/nesting/typescript_function_extractor.py,sha256=dDB1otJnFMCo-Pj4mTr4gekKe7V4ArOAtX6gV0dBDc4,4494
69
81
  src/linters/nesting/violation_builder.py,sha256=sMHS45F2lrA1WYrG3Uug8HfeRPljnXcyJPHSe2F76Bs,4828
70
82
  src/linters/print_statements/__init__.py,sha256=yhvdTFSqBB4UDreeadTHKFzhayxeT6JkF3yxUHMgn1g,1893
71
- src/linters/print_statements/config.py,sha256=GTYIAVovc6e7i4eTrSl2D0Nmf55U5bpEd7FI6Knx_CE,3133
72
- src/linters/print_statements/linter.py,sha256=MieQfEdmVJoiRR7Aa2-OW2RnOC4Cheu0jgDezc-ndH8,14572
73
- src/linters/print_statements/python_analyzer.py,sha256=5bzYWLKqQOW0xnsZYZgUJh6sl3SYDKdQe_BAw93HTug,5543
74
- src/linters/print_statements/typescript_analyzer.py,sha256=aKTA2E96qxA1PzsRVL5DLYE-abCFM67OGhqU-9iFgzA,5265
75
- src/linters/print_statements/violation_builder.py,sha256=z01K-2kpR9VnGo_S9hcU0Y6_QMol0XxxnJxj36GdL7E,3426
83
+ src/linters/print_statements/config.py,sha256=rth3XmzqZGzXkRXDIVZswdtNOXIe1vIRaF46tVLKnyQ,3041
84
+ src/linters/print_statements/linter.py,sha256=J23gtU6FQ2uH2Sj38PPRiV4k2HU0uto2Bqf2D28pKrI,14630
85
+ src/linters/print_statements/python_analyzer.py,sha256=SyCkh8HkYAfcSM7LCwDE1ahhxwPgrlnSVLs1iRemyaw,5461
86
+ src/linters/print_statements/typescript_analyzer.py,sha256=v2R6ZG80eTQq92oE3Y3E4ZwUfBmXwB9G5QKftqbRbD8,5155
87
+ src/linters/print_statements/violation_builder.py,sha256=Vs5m3AnWjrQqQHf6JJDaPP5B1V3YNl5pepG_oiTJnx4,3333
76
88
  src/linters/srp/__init__.py,sha256=GbhaSB2_AYY-mWgG_ThbyAcDXoVZuB5eLzguoShf38w,3367
77
89
  src/linters/srp/class_analyzer.py,sha256=wuwviwhN1F_VVPaQ3pZvffmY3e9ToxPNJhv6BjhsgZc,3761
78
90
  src/linters/srp/config.py,sha256=hTxrM21HIOmg0sM6eJ_h3hRnuxqRZEgs13Ie97-PDr4,3397
@@ -89,8 +101,8 @@ src/orchestrator/language_detector.py,sha256=rHyVMApit80NTTNyDH1ObD1usKD8LjGmH3D
89
101
  src/templates/thailint_config_template.yaml,sha256=vxyhRRi25_xOnHDRx0jzz69dgPqKU2IU5-YFGUoX5lM,4953
90
102
  src/utils/__init__.py,sha256=NiBtKeQ09Y3kuUzeN4O1JNfUIYPQDS2AP1l5ODq-Dec,125
91
103
  src/utils/project_root.py,sha256=b3YTEGTa9RPcOeHn1IByMMWyRiUabfVlpnlektL0A0o,6156
92
- thailint-0.5.0.dist-info/METADATA,sha256=anESyXpJOqYeRjeHVOOL38dY56zD0XLPkCMmUNBKfx8,37838
93
- thailint-0.5.0.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
94
- thailint-0.5.0.dist-info/entry_points.txt,sha256=l7DQJgU18sVLDpSaXOXY3lLhnQHQIRrSJZTQjG1cEAk,62
95
- thailint-0.5.0.dist-info/licenses/LICENSE,sha256=kxh1J0Sb62XvhNJ6MZsVNe8PqNVJ7LHRn_EWa-T3djw,1070
96
- thailint-0.5.0.dist-info/RECORD,,
104
+ thailint-0.8.0.dist-info/METADATA,sha256=JLoEBO87HaZBzNk9wlkn1MeCO_S2wG5dKnL6itrbDe0,42115
105
+ thailint-0.8.0.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
106
+ thailint-0.8.0.dist-info/entry_points.txt,sha256=l7DQJgU18sVLDpSaXOXY3lLhnQHQIRrSJZTQjG1cEAk,62
107
+ thailint-0.8.0.dist-info/licenses/LICENSE,sha256=kxh1J0Sb62XvhNJ6MZsVNe8PqNVJ7LHRn_EWa-T3djw,1070
108
+ thailint-0.8.0.dist-info/RECORD,,