thailint 0.4.0__tar.gz → 0.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 (83) hide show
  1. {thailint-0.4.0 → thailint-0.4.1}/PKG-INFO +15 -2
  2. {thailint-0.4.0 → thailint-0.4.1}/README.md +14 -1
  3. {thailint-0.4.0 → thailint-0.4.1}/pyproject.toml +1 -1
  4. {thailint-0.4.0 → thailint-0.4.1}/src/linters/magic_numbers/config.py +6 -0
  5. {thailint-0.4.0 → thailint-0.4.1}/src/linters/magic_numbers/linter.py +49 -0
  6. {thailint-0.4.0 → thailint-0.4.1}/CHANGELOG.md +0 -0
  7. {thailint-0.4.0 → thailint-0.4.1}/LICENSE +0 -0
  8. {thailint-0.4.0 → thailint-0.4.1}/src/__init__.py +0 -0
  9. {thailint-0.4.0 → thailint-0.4.1}/src/analyzers/__init__.py +0 -0
  10. {thailint-0.4.0 → thailint-0.4.1}/src/analyzers/typescript_base.py +0 -0
  11. {thailint-0.4.0 → thailint-0.4.1}/src/api.py +0 -0
  12. {thailint-0.4.0 → thailint-0.4.1}/src/cli.py +0 -0
  13. {thailint-0.4.0 → thailint-0.4.1}/src/config.py +0 -0
  14. {thailint-0.4.0 → thailint-0.4.1}/src/core/__init__.py +0 -0
  15. {thailint-0.4.0 → thailint-0.4.1}/src/core/base.py +0 -0
  16. {thailint-0.4.0 → thailint-0.4.1}/src/core/cli_utils.py +0 -0
  17. {thailint-0.4.0 → thailint-0.4.1}/src/core/config_parser.py +0 -0
  18. {thailint-0.4.0 → thailint-0.4.1}/src/core/linter_utils.py +0 -0
  19. {thailint-0.4.0 → thailint-0.4.1}/src/core/registry.py +0 -0
  20. {thailint-0.4.0 → thailint-0.4.1}/src/core/rule_discovery.py +0 -0
  21. {thailint-0.4.0 → thailint-0.4.1}/src/core/types.py +0 -0
  22. {thailint-0.4.0 → thailint-0.4.1}/src/core/violation_builder.py +0 -0
  23. {thailint-0.4.0 → thailint-0.4.1}/src/linter_config/__init__.py +0 -0
  24. {thailint-0.4.0 → thailint-0.4.1}/src/linter_config/ignore.py +0 -0
  25. {thailint-0.4.0 → thailint-0.4.1}/src/linter_config/loader.py +0 -0
  26. {thailint-0.4.0 → thailint-0.4.1}/src/linters/__init__.py +0 -0
  27. {thailint-0.4.0 → thailint-0.4.1}/src/linters/dry/__init__.py +0 -0
  28. {thailint-0.4.0 → thailint-0.4.1}/src/linters/dry/base_token_analyzer.py +0 -0
  29. {thailint-0.4.0 → thailint-0.4.1}/src/linters/dry/block_filter.py +0 -0
  30. {thailint-0.4.0 → thailint-0.4.1}/src/linters/dry/block_grouper.py +0 -0
  31. {thailint-0.4.0 → thailint-0.4.1}/src/linters/dry/cache.py +0 -0
  32. {thailint-0.4.0 → thailint-0.4.1}/src/linters/dry/cache_query.py +0 -0
  33. {thailint-0.4.0 → thailint-0.4.1}/src/linters/dry/config.py +0 -0
  34. {thailint-0.4.0 → thailint-0.4.1}/src/linters/dry/config_loader.py +0 -0
  35. {thailint-0.4.0 → thailint-0.4.1}/src/linters/dry/deduplicator.py +0 -0
  36. {thailint-0.4.0 → thailint-0.4.1}/src/linters/dry/duplicate_storage.py +0 -0
  37. {thailint-0.4.0 → thailint-0.4.1}/src/linters/dry/file_analyzer.py +0 -0
  38. {thailint-0.4.0 → thailint-0.4.1}/src/linters/dry/inline_ignore.py +0 -0
  39. {thailint-0.4.0 → thailint-0.4.1}/src/linters/dry/linter.py +0 -0
  40. {thailint-0.4.0 → thailint-0.4.1}/src/linters/dry/python_analyzer.py +0 -0
  41. {thailint-0.4.0 → thailint-0.4.1}/src/linters/dry/storage_initializer.py +0 -0
  42. {thailint-0.4.0 → thailint-0.4.1}/src/linters/dry/token_hasher.py +0 -0
  43. {thailint-0.4.0 → thailint-0.4.1}/src/linters/dry/typescript_analyzer.py +0 -0
  44. {thailint-0.4.0 → thailint-0.4.1}/src/linters/dry/violation_builder.py +0 -0
  45. {thailint-0.4.0 → thailint-0.4.1}/src/linters/dry/violation_filter.py +0 -0
  46. {thailint-0.4.0 → thailint-0.4.1}/src/linters/dry/violation_generator.py +0 -0
  47. {thailint-0.4.0 → thailint-0.4.1}/src/linters/file_placement/__init__.py +0 -0
  48. {thailint-0.4.0 → thailint-0.4.1}/src/linters/file_placement/config_loader.py +0 -0
  49. {thailint-0.4.0 → thailint-0.4.1}/src/linters/file_placement/directory_matcher.py +0 -0
  50. {thailint-0.4.0 → thailint-0.4.1}/src/linters/file_placement/linter.py +0 -0
  51. {thailint-0.4.0 → thailint-0.4.1}/src/linters/file_placement/path_resolver.py +0 -0
  52. {thailint-0.4.0 → thailint-0.4.1}/src/linters/file_placement/pattern_matcher.py +0 -0
  53. {thailint-0.4.0 → thailint-0.4.1}/src/linters/file_placement/pattern_validator.py +0 -0
  54. {thailint-0.4.0 → thailint-0.4.1}/src/linters/file_placement/rule_checker.py +0 -0
  55. {thailint-0.4.0 → thailint-0.4.1}/src/linters/file_placement/violation_factory.py +0 -0
  56. {thailint-0.4.0 → thailint-0.4.1}/src/linters/magic_numbers/__init__.py +0 -0
  57. {thailint-0.4.0 → thailint-0.4.1}/src/linters/magic_numbers/context_analyzer.py +0 -0
  58. {thailint-0.4.0 → thailint-0.4.1}/src/linters/magic_numbers/python_analyzer.py +0 -0
  59. {thailint-0.4.0 → thailint-0.4.1}/src/linters/magic_numbers/typescript_analyzer.py +0 -0
  60. {thailint-0.4.0 → thailint-0.4.1}/src/linters/magic_numbers/violation_builder.py +0 -0
  61. {thailint-0.4.0 → thailint-0.4.1}/src/linters/nesting/__init__.py +0 -0
  62. {thailint-0.4.0 → thailint-0.4.1}/src/linters/nesting/config.py +0 -0
  63. {thailint-0.4.0 → thailint-0.4.1}/src/linters/nesting/linter.py +0 -0
  64. {thailint-0.4.0 → thailint-0.4.1}/src/linters/nesting/python_analyzer.py +0 -0
  65. {thailint-0.4.0 → thailint-0.4.1}/src/linters/nesting/typescript_analyzer.py +0 -0
  66. {thailint-0.4.0 → thailint-0.4.1}/src/linters/nesting/typescript_function_extractor.py +0 -0
  67. {thailint-0.4.0 → thailint-0.4.1}/src/linters/nesting/violation_builder.py +0 -0
  68. {thailint-0.4.0 → thailint-0.4.1}/src/linters/srp/__init__.py +0 -0
  69. {thailint-0.4.0 → thailint-0.4.1}/src/linters/srp/class_analyzer.py +0 -0
  70. {thailint-0.4.0 → thailint-0.4.1}/src/linters/srp/config.py +0 -0
  71. {thailint-0.4.0 → thailint-0.4.1}/src/linters/srp/heuristics.py +0 -0
  72. {thailint-0.4.0 → thailint-0.4.1}/src/linters/srp/linter.py +0 -0
  73. {thailint-0.4.0 → thailint-0.4.1}/src/linters/srp/metrics_evaluator.py +0 -0
  74. {thailint-0.4.0 → thailint-0.4.1}/src/linters/srp/python_analyzer.py +0 -0
  75. {thailint-0.4.0 → thailint-0.4.1}/src/linters/srp/typescript_analyzer.py +0 -0
  76. {thailint-0.4.0 → thailint-0.4.1}/src/linters/srp/typescript_metrics_calculator.py +0 -0
  77. {thailint-0.4.0 → thailint-0.4.1}/src/linters/srp/violation_builder.py +0 -0
  78. {thailint-0.4.0 → thailint-0.4.1}/src/orchestrator/__init__.py +0 -0
  79. {thailint-0.4.0 → thailint-0.4.1}/src/orchestrator/core.py +0 -0
  80. {thailint-0.4.0 → thailint-0.4.1}/src/orchestrator/language_detector.py +0 -0
  81. {thailint-0.4.0 → thailint-0.4.1}/src/templates/thailint_config_template.yaml +0 -0
  82. {thailint-0.4.0 → thailint-0.4.1}/src/utils/__init__.py +0 -0
  83. {thailint-0.4.0 → thailint-0.4.1}/src/utils/project_root.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: thailint
3
- Version: 0.4.0
3
+ Version: 0.4.1
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,11 +35,20 @@ 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-253%2F253%20passing-brightgreen.svg)](tests/)
38
+ [![Tests](https://img.shields.io/badge/tests-263%2F263%20passing-brightgreen.svg)](tests/)
39
39
  [![Coverage](https://img.shields.io/badge/coverage-87%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
+ ## Documentation
44
+
45
+ **New to thailint?** Start here:
46
+ - **[Quick Start Guide](docs/quick-start.md)** - Get running in 5 minutes
47
+ - **[Configuration Reference](docs/configuration.md)** - Complete config options for all linters
48
+ - **[Troubleshooting Guide](docs/troubleshooting.md)** - Common issues and solutions
49
+
50
+ **Full Documentation:** Browse the **[docs/](docs/)** folder for comprehensive guides covering installation, all linters, configuration patterns, and integration examples.
51
+
43
52
  ## Overview
44
53
 
45
54
  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.
@@ -55,6 +64,8 @@ We're not trying to replace the wonderful existing linters like Pylint, ESLint,
55
64
 
56
65
  thailint complements your existing linting stack by catching the patterns AI tools repeatedly miss.
57
66
 
67
+ **Complete documentation available in the [docs/](docs/) folder** covering installation, configuration, all linters, and troubleshooting.
68
+
58
69
  ## Features
59
70
 
60
71
  ### Core Capabilities
@@ -151,6 +162,8 @@ thailint dry --config .thailint.yaml src/
151
162
  thailint dry --format json src/
152
163
  ```
153
164
 
165
+ **New to thailint?** See the **[Quick Start Guide](docs/quick-start.md)** for a complete walkthrough including config generation, understanding output, and next steps.
166
+
154
167
  ### Library Mode
155
168
 
156
169
  ```python
@@ -2,11 +2,20 @@
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-253%2F253%20passing-brightgreen.svg)](tests/)
5
+ [![Tests](https://img.shields.io/badge/tests-263%2F263%20passing-brightgreen.svg)](tests/)
6
6
  [![Coverage](https://img.shields.io/badge/coverage-87%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
+ ## Documentation
11
+
12
+ **New to thailint?** Start here:
13
+ - **[Quick Start Guide](docs/quick-start.md)** - Get running in 5 minutes
14
+ - **[Configuration Reference](docs/configuration.md)** - Complete config options for all linters
15
+ - **[Troubleshooting Guide](docs/troubleshooting.md)** - Common issues and solutions
16
+
17
+ **Full Documentation:** Browse the **[docs/](docs/)** folder for comprehensive guides covering installation, all linters, configuration patterns, and integration examples.
18
+
10
19
  ## Overview
11
20
 
12
21
  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.
@@ -22,6 +31,8 @@ We're not trying to replace the wonderful existing linters like Pylint, ESLint,
22
31
 
23
32
  thailint complements your existing linting stack by catching the patterns AI tools repeatedly miss.
24
33
 
34
+ **Complete documentation available in the [docs/](docs/) folder** covering installation, configuration, all linters, and troubleshooting.
35
+
25
36
  ## Features
26
37
 
27
38
  ### Core Capabilities
@@ -118,6 +129,8 @@ thailint dry --config .thailint.yaml src/
118
129
  thailint dry --format json src/
119
130
  ```
120
131
 
132
+ **New to thailint?** See the **[Quick Start Guide](docs/quick-start.md)** for a complete walkthrough including config generation, understanding output, and next steps.
133
+
121
134
  ### Library Mode
122
135
 
123
136
  ```python
@@ -17,7 +17,7 @@ build-backend = "poetry.core.masonry.api"
17
17
 
18
18
  [tool.poetry]
19
19
  name = "thailint"
20
- version = "0.4.0"
20
+ version = "0.4.1"
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"
@@ -33,6 +33,7 @@ class MagicNumberConfig:
33
33
  default_factory=lambda: {-1, 0, 1, 2, 3, 4, 5, 10, 100, 1000}
34
34
  )
35
35
  max_small_integer: int = 10
36
+ ignore: list[str] = field(default_factory=list)
36
37
 
37
38
  def __post_init__(self) -> None:
38
39
  """Validate configuration values."""
@@ -69,8 +70,13 @@ class MagicNumberConfig:
69
70
  )
70
71
  max_small_integer = config.get("max_small_integer", 10)
71
72
 
73
+ ignore_patterns = config.get("ignore", [])
74
+ if not isinstance(ignore_patterns, list):
75
+ ignore_patterns = []
76
+
72
77
  return cls(
73
78
  enabled=config.get("enabled", True),
74
79
  allowed_numbers=allowed_numbers,
75
80
  max_small_integer=max_small_integer,
81
+ ignore=ignore_patterns,
76
82
  )
@@ -24,6 +24,7 @@ Implementation: Composition pattern with helper classes, AST-based analysis with
24
24
  """
25
25
 
26
26
  import ast
27
+ from pathlib import Path
27
28
 
28
29
  from src.core.base import BaseLintContext, MultiLanguageLintRule
29
30
  from src.core.linter_utils import load_linter_config
@@ -98,6 +99,48 @@ class MagicNumberRule(MultiLanguageLintRule): # thailint: ignore[srp]
98
99
  return None
99
100
  return load_linter_config(context, "magic_numbers", MagicNumberConfig)
100
101
 
102
+ def _is_file_ignored(self, context: BaseLintContext, config: MagicNumberConfig) -> bool:
103
+ """Check if file matches ignore patterns.
104
+
105
+ Args:
106
+ context: Lint context
107
+ config: Magic numbers configuration
108
+
109
+ Returns:
110
+ True if file should be ignored
111
+ """
112
+ if not config.ignore:
113
+ return False
114
+
115
+ if not context.file_path:
116
+ return False
117
+
118
+ file_path = Path(context.file_path)
119
+ for pattern in config.ignore:
120
+ if self._matches_pattern(file_path, pattern):
121
+ return True
122
+ return False
123
+
124
+ def _matches_pattern(self, file_path: Path, pattern: str) -> bool:
125
+ """Check if file path matches a glob pattern.
126
+
127
+ Args:
128
+ file_path: Path to check
129
+ pattern: Glob pattern (e.g., "test/**", "**/test_*.py", "specific/file.py")
130
+
131
+ Returns:
132
+ True if path matches pattern
133
+ """
134
+ # Try glob pattern matching first (handles **, *, etc.)
135
+ if file_path.match(pattern):
136
+ return True
137
+
138
+ # Also check if pattern is a substring (for partial path matching)
139
+ if pattern in str(file_path):
140
+ return True
141
+
142
+ return False
143
+
101
144
  def _check_python(self, context: BaseLintContext, config: MagicNumberConfig) -> list[Violation]:
102
145
  """Check Python code for magic number violations.
103
146
 
@@ -108,6 +151,9 @@ class MagicNumberRule(MultiLanguageLintRule): # thailint: ignore[srp]
108
151
  Returns:
109
152
  List of violations found in Python code
110
153
  """
154
+ if self._is_file_ignored(context, config):
155
+ return []
156
+
111
157
  tree = self._parse_python_code(context.file_content)
112
158
  if tree is None:
113
159
  return []
@@ -267,6 +313,9 @@ class MagicNumberRule(MultiLanguageLintRule): # thailint: ignore[srp]
267
313
  Returns:
268
314
  List of violations found in TypeScript/JavaScript code
269
315
  """
316
+ if self._is_file_ignored(context, config):
317
+ return []
318
+
270
319
  analyzer = TypeScriptMagicNumberAnalyzer()
271
320
  root_node = analyzer.parse_typescript(context.file_content or "")
272
321
  if root_node is None:
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
File without changes