thailint 0.2.1__py3-none-any.whl → 0.3.1__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: thailint
3
- Version: 0.2.1
3
+ Version: 0.3.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
@@ -48,6 +48,11 @@ thailint is a modern, enterprise-ready multi-language linter designed specifical
48
48
 
49
49
  ### Core Capabilities
50
50
  - **File Placement Linting** - Enforce project structure and organization
51
+ - **Magic Numbers Linting** - Detect unnamed numeric literals that should be constants
52
+ - Python and TypeScript support with AST analysis
53
+ - Context-aware detection (ignores constants, test files, range() usage)
54
+ - Configurable allowed numbers and thresholds
55
+ - Helpful suggestions for extracting to named constants
51
56
  - **Nesting Depth Linting** - Detect excessive code nesting with AST analysis
52
57
  - Python and TypeScript support with tree-sitter
53
58
  - Configurable max depth (default: 4, recommended: 3)
@@ -57,8 +62,8 @@ thailint is a modern, enterprise-ready multi-language linter designed specifical
57
62
  - Language-specific thresholds (Python, TypeScript, JavaScript)
58
63
  - Refactoring patterns from real-world examples
59
64
  - **DRY Linting** - Detect duplicate code across projects
60
- - Token-based hash detection with SQLite caching
61
- - Fast incremental scans (10-50x speedup with cache)
65
+ - Token-based hash detection with SQLite storage
66
+ - Fast duplicate detection (in-memory or disk-backed)
62
67
  - Configurable thresholds (lines, tokens, occurrences)
63
68
  - Language-specific detection (Python, TypeScript, JavaScript)
64
69
  - False positive filtering (keyword args, imports)
@@ -125,6 +130,9 @@ thailint nesting src/
125
130
  # Check for duplicate code
126
131
  thailint dry .
127
132
 
133
+ # Check for magic numbers
134
+ thailint magic-numbers src/
135
+
128
136
  # With config file
129
137
  thailint dry --config .thailint.yaml src/
130
138
 
@@ -228,14 +236,19 @@ dry:
228
236
  python:
229
237
  min_occurrences: 3 # Python: require 3+ occurrences
230
238
 
231
- # Cache settings (SQLite)
232
- cache_enabled: true
233
- cache_path: ".thailint-cache/dry.db"
239
+ # Storage settings (SQLite)
240
+ storage_mode: "memory" # Options: "memory" (default) or "tempfile"
234
241
 
235
242
  # Ignore patterns
236
243
  ignore:
237
244
  - "tests/"
238
245
  - "__init__.py"
246
+
247
+ # Magic numbers linter configuration
248
+ magic-numbers:
249
+ enabled: true
250
+ allowed_numbers: [-1, 0, 1, 2, 10, 100, 1000] # Numbers allowed without constants
251
+ max_small_integer: 10 # Max value allowed in range() or enumerate()
239
252
  ```
240
253
 
241
254
  **JSON format also supported** (`.thailint.json`):
@@ -268,15 +281,21 @@ dry:
268
281
  "python": {
269
282
  "min_occurrences": 3
270
283
  },
271
- "cache_enabled": true,
272
- "cache_path": ".thailint-cache/dry.db",
284
+ "storage_mode": "memory",
273
285
  "ignore": ["tests/", "__init__.py"]
286
+ },
287
+ "magic-numbers": {
288
+ "enabled": true,
289
+ "allowed_numbers": [-1, 0, 1, 2, 10, 100, 1000],
290
+ "max_small_integer": 10
274
291
  }
275
292
  }
276
293
  ```
277
294
 
278
295
  See [Configuration Guide](docs/configuration.md) for complete reference.
279
296
 
297
+ **Need help with ignores?** See **[How to Ignore Violations](docs/how-to-ignore-violations.md)** for complete guide to all ignore levels (line, method, class, file, repository).
298
+
280
299
  ## Nesting Depth Linter
281
300
 
282
301
  ### Overview
@@ -484,7 +503,7 @@ See [SRP Linter Guide](docs/srp-linter.md) for comprehensive documentation and r
484
503
 
485
504
  ### Overview
486
505
 
487
- The DRY linter detects duplicate code blocks across your entire project using token-based hashing with SQLite caching. It identifies identical or near-identical code that violates the Don't Repeat Yourself (DRY) principle, helping maintain code quality at scale.
506
+ The DRY linter detects duplicate code blocks across your entire project using token-based hashing with SQLite storage. It identifies identical or near-identical code that violates the Don't Repeat Yourself (DRY) principle, helping maintain code quality at scale.
488
507
 
489
508
  ### Quick Start
490
509
 
@@ -495,8 +514,8 @@ thailint dry .
495
514
  # Use custom thresholds
496
515
  thailint dry --min-lines 5 src/
497
516
 
498
- # Clear cache and re-scan
499
- thailint dry --clear-cache src/
517
+ # Use tempfile storage for large projects
518
+ thailint dry --storage-mode tempfile src/
500
519
 
501
520
  # Get JSON output
502
521
  thailint dry --format json src/
@@ -519,10 +538,8 @@ dry:
519
538
  typescript:
520
539
  min_occurrences: 3 # TypeScript: require 3+ occurrences
521
540
 
522
- # Cache settings (SQLite for fast incremental scans)
523
- cache_enabled: true
524
- cache_path: ".thailint-cache/dry.db"
525
- cache_max_age_days: 30
541
+ # Storage settings
542
+ storage_mode: "memory" # Options: "memory" (default) or "tempfile"
526
543
 
527
544
  # Ignore patterns
528
545
  ignore:
@@ -543,11 +560,11 @@ dry:
543
560
  3. Store hashes in SQLite database with file locations
544
561
  4. Query for hashes appearing 2+ times across project
545
562
 
546
- **SQLite Caching:**
547
- - First scan: Hash all files (~1-3s for 1000 files)
548
- - Subsequent scans: Load cached hashes for unchanged files (~0.1-0.5s)
549
- - 10-50x speedup for incremental scans
550
- - Mtime-based cache invalidation (automatic and safe)
563
+ **SQLite Storage:**
564
+ - In-memory mode (default): Stores in RAM for best performance
565
+ - Tempfile mode: Stores in temporary disk file for large projects
566
+ - Fresh analysis on every run (no persistence between runs)
567
+ - Fast duplicate detection using B-tree indexes
551
568
 
552
569
  ### Example Violation
553
570
 
@@ -605,31 +622,14 @@ def validate_admin(admin_data):
605
622
  return validate_credentials(admin_data)
606
623
  ```
607
624
 
608
- ### Cache Management
609
-
610
- ```bash
611
- # Normal cached run (default)
612
- thailint dry src/
613
-
614
- # Force re-analysis (ignore cache)
615
- thailint dry --no-cache src/
616
-
617
- # Clear cache before running
618
- thailint dry --clear-cache src/
619
-
620
- # Manual cache cleanup
621
- rm -rf .thailint-cache/dry.db
622
- ```
623
-
624
625
  ### Performance
625
626
 
626
- | Operation | Performance | Cache Status |
627
+ | Operation | Performance | Storage Mode |
627
628
  |-----------|-------------|--------------|
628
- | First scan (1000 files) | 1-3s | Cache write |
629
- | Unchanged files | 0.1-0.5s | Cache hit |
630
- | 50 changed files | 0.5-1s | Partial cache |
629
+ | Scan (1000 files) | 1-3s | Memory (default) |
630
+ | Large project (5000+ files) | Use tempfile mode | Tempfile |
631
631
 
632
- **Speedup**: 3-10x for incremental scans with cache
632
+ **Note**: Every run analyzes files fresh - no persistence between runs ensures accurate results
633
633
 
634
634
  ### Language Support
635
635
 
@@ -650,7 +650,159 @@ Built-in filters automatically exclude common non-duplication patterns:
650
650
  3. **Extract Utility Module**: Move helper functions to shared utilities
651
651
  4. **Template Method**: Use function parameters for variations
652
652
 
653
- See [DRY Linter Guide](docs/dry-linter.md) for comprehensive documentation, cache management, and refactoring patterns.
653
+ See [DRY Linter Guide](docs/dry-linter.md) for comprehensive documentation, storage modes, and refactoring patterns.
654
+
655
+ ## Magic Numbers Linter
656
+
657
+ ### Overview
658
+
659
+ The magic numbers linter detects unnamed numeric literals (magic numbers) that should be extracted to named constants. It uses AST analysis to identify numeric literals that lack meaningful context.
660
+
661
+ ### What are Magic Numbers?
662
+
663
+ **Magic numbers** are unnamed numeric literals in code without explanation:
664
+
665
+ ```python
666
+ # Bad - Magic numbers
667
+ timeout = 3600 # What is 3600?
668
+ max_retries = 5 # Why 5?
669
+
670
+ # Good - Named constants
671
+ TIMEOUT_SECONDS = 3600
672
+ MAX_RETRY_ATTEMPTS = 5
673
+ ```
674
+
675
+ ### Quick Start
676
+
677
+ ```bash
678
+ # Check for magic numbers in current directory
679
+ thailint magic-numbers .
680
+
681
+ # Check specific directory
682
+ thailint magic-numbers src/
683
+
684
+ # Get JSON output
685
+ thailint magic-numbers --format json src/
686
+ ```
687
+
688
+ ### Configuration
689
+
690
+ Add to `.thailint.yaml`:
691
+
692
+ ```yaml
693
+ magic-numbers:
694
+ enabled: true
695
+ allowed_numbers: [-1, 0, 1, 2, 10, 100, 1000]
696
+ max_small_integer: 10 # Max for range() to be acceptable
697
+ ```
698
+
699
+ ### Example Violation
700
+
701
+ **Code with magic numbers:**
702
+ ```python
703
+ def calculate_timeout():
704
+ return 3600 # Magic number - what is 3600?
705
+
706
+ def process_items(items):
707
+ for i in range(100): # Magic number - why 100?
708
+ items[i] *= 1.5 # Magic number - what is 1.5?
709
+ ```
710
+
711
+ **Violation messages:**
712
+ ```
713
+ src/example.py:2 - Magic number 3600 should be a named constant
714
+ src/example.py:5 - Magic number 100 should be a named constant
715
+ src/example.py:6 - Magic number 1.5 should be a named constant
716
+ ```
717
+
718
+ **Refactored code:**
719
+ ```python
720
+ TIMEOUT_SECONDS = 3600
721
+ MAX_ITEMS = 100
722
+ PRICE_MULTIPLIER = 1.5
723
+
724
+ def calculate_timeout():
725
+ return TIMEOUT_SECONDS
726
+
727
+ def process_items(items):
728
+ for i in range(MAX_ITEMS):
729
+ items[i] *= PRICE_MULTIPLIER
730
+ ```
731
+
732
+ ### Acceptable Contexts
733
+
734
+ The linter **does not** flag numbers in these contexts:
735
+
736
+ | Context | Example | Why Acceptable |
737
+ |---------|---------|----------------|
738
+ | Constants | `MAX_SIZE = 100` | UPPERCASE name provides context |
739
+ | Small `range()` | `range(5)` | Small loop bounds are clear |
740
+ | Test files | `test_*.py` | Test data can be literal |
741
+ | Allowed numbers | `-1, 0, 1, 2, 10` | Common values are self-explanatory |
742
+
743
+ ### Refactoring Patterns
744
+
745
+ **Pattern 1: Extract to Module Constants**
746
+ ```python
747
+ # Before
748
+ def connect():
749
+ timeout = 30
750
+ retries = 3
751
+
752
+ # After
753
+ DEFAULT_TIMEOUT_SECONDS = 30
754
+ DEFAULT_MAX_RETRIES = 3
755
+
756
+ def connect():
757
+ timeout = DEFAULT_TIMEOUT_SECONDS
758
+ retries = DEFAULT_MAX_RETRIES
759
+ ```
760
+
761
+ **Pattern 2: Extract with Units in Name**
762
+ ```python
763
+ # Before
764
+ delay = 3600 # Is this seconds? Minutes?
765
+
766
+ # After
767
+ TASK_DELAY_SECONDS = 3600 # Clear unit
768
+
769
+ delay = TASK_DELAY_SECONDS
770
+ ```
771
+
772
+ **Pattern 3: Use Standard Library**
773
+ ```python
774
+ # Before
775
+ if status == 200:
776
+ return "success"
777
+
778
+ # After
779
+ from http import HTTPStatus
780
+
781
+ if status == HTTPStatus.OK:
782
+ return "success"
783
+ ```
784
+
785
+ ### Language Support
786
+
787
+ - **Python**: Full support (int, float, scientific notation)
788
+ - **TypeScript**: Full support (int, float, scientific notation)
789
+ - **JavaScript**: Supported via TypeScript parser
790
+
791
+ ### Ignoring Violations
792
+
793
+ ```python
794
+ # Line-level ignore
795
+ timeout = 3600 # thailint: ignore[magic-numbers] - Industry standard
796
+
797
+ # Method-level ignore
798
+ def get_ports(): # thailint: ignore[magic-numbers] - Standard ports
799
+ return {80: "HTTP", 443: "HTTPS"}
800
+
801
+ # File-level ignore
802
+ # thailint: ignore-file[magic-numbers]
803
+ ```
804
+
805
+ See **[How to Ignore Violations](docs/how-to-ignore-violations.md)** and **[Magic Numbers Linter Guide](docs/magic-numbers-linter.md)** for complete documentation.
654
806
 
655
807
  ## Pre-commit Hooks
656
808
 
@@ -844,10 +996,12 @@ docker run --rm -v $(pwd):/data \
844
996
 
845
997
  - **[Getting Started](docs/getting-started.md)** - Installation, first lint, basic config
846
998
  - **[Configuration Reference](docs/configuration.md)** - Complete config options (YAML/JSON)
999
+ - **[How to Ignore Violations](docs/how-to-ignore-violations.md)** - Complete guide to all ignore levels
847
1000
  - **[API Reference](docs/api-reference.md)** - Library API documentation
848
1001
  - **[CLI Reference](docs/cli-reference.md)** - All CLI commands and options
849
1002
  - **[Deployment Modes](docs/deployment-modes.md)** - CLI, Library, and Docker usage
850
1003
  - **[File Placement Linter](docs/file-placement-linter.md)** - Detailed linter guide
1004
+ - **[Magic Numbers Linter](docs/magic-numbers-linter.md)** - Magic numbers detection guide
851
1005
  - **[Nesting Depth Linter](docs/nesting-linter.md)** - Nesting depth analysis guide
852
1006
  - **[SRP Linter](docs/srp-linter.md)** - Single Responsibility Principle guide
853
1007
  - **[DRY Linter](docs/dry-linter.md)** - Duplicate code detection guide
@@ -2,10 +2,10 @@ 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=TTg7nrMF3tEfcj_rbotfvosTjuIWaQqpBjxxj9Tlipw,32421
6
- src/config.py,sha256=VCnsguO4BRTYlzmaD6lYJwgJNPcsquDg7P2Tn6Xa5nk,12333
5
+ src/cli.py,sha256=1qhjXAy7JDdav90xQ5pOeH1_f1A9qYJLIwxTQzq3oiU,35657
6
+ src/config.py,sha256=2ebAjIpAhw4bHbOxViEA5nCjfBlDEIrMR59DBrzcYzM,12460
7
7
  src/core/__init__.py,sha256=5FtsDvhMt4SNRx3pbcGURrxn135XRbeRrjSUxiXwkNc,381
8
- src/core/base.py,sha256=cFnFSK0K7JqYiXA31lr0JAKRoxvytdqzmlFpCz1tUJI,4787
8
+ src/core/base.py,sha256=Eklcagi2ktfY4Kytl_ObXov2U49N9OGDpw4cu4PUzGY,7824
9
9
  src/core/cli_utils.py,sha256=rYOJz4mnr8RLP-nJdHOy-GJyxGNqkWtK3_rvKriHXj4,6083
10
10
  src/core/config_parser.py,sha256=0PfLNSC0awV21SrpqdcJ2L8Cn2-B2YcwbA8znaC5YnE,3195
11
11
  src/core/linter_utils.py,sha256=4jmC2YfpPvGhS_XHlHXa5SBIJh9CQlNj5zuW_GpdPKc,5273
@@ -19,23 +19,23 @@ src/linter_config/loader.py,sha256=HB09W-uVsEcgCbvUwUHS5Jm2n0bqBXA3744vMc4GAqk,2
19
19
  src/linters/__init__.py,sha256=-nnNsL8E5-2p9qlLKp_TaShHAjPH-NacOEU1sXmAR9k,77
20
20
  src/linters/dry/__init__.py,sha256=p58tN3z_VbulfTkRm1kLZJ43Bemt66T2sro1teirUY8,826
21
21
  src/linters/dry/base_token_analyzer.py,sha256=SgnsX4a4kUzOsA9hTkLkg4yB8I77ewAyiUp6cAybUrg,2684
22
- src/linters/dry/block_filter.py,sha256=_ooo5g3PJMUUua_0-eu5NE9dFpEK42ZiundkzYQNyyY,8116
22
+ src/linters/dry/block_filter.py,sha256=FN1QDXQu6HYhdHo6fkzUDUrMX4TqaLV_myBOQRsmPfk,8242
23
23
  src/linters/dry/block_grouper.py,sha256=gBvSPgy8jumChZ53px3P7hDCJfi5PDrKhwxLTgNy7ig,1810
24
- src/linters/dry/cache.py,sha256=QTQY5TSFU2OFFqua-uxazFzzylgkVawHTOyS3S5qdO8,6957
24
+ src/linters/dry/cache.py,sha256=QbFajUNb3v2LVuYbTJXY9ExXjjIsd73DQ5Y1hB-SH1s,5879
25
25
  src/linters/dry/cache_query.py,sha256=NTBh4ISy76LJb9tJ6G94fE0R2OiE0eQ-zVvB08WG2bA,1802
26
- src/linters/dry/config.py,sha256=CEcYK3SXZJP0kekiuX5us15xwCXDuU0k289A8vDV5Qs,5244
26
+ src/linters/dry/config.py,sha256=XaHX5SnbH8cEBHiNKMSuYQJwCbKL-Q9XgZVRcc9UBgQ,5439
27
27
  src/linters/dry/config_loader.py,sha256=wikqnigOp6p1h9jaAATV_3bDXSiaIUFaf9xg1jQMDpo,1313
28
28
  src/linters/dry/deduplicator.py,sha256=a1TRvldxCszf5QByo1ihXF3W98dpGuyaRT74jPfQftM,3988
29
- src/linters/dry/duplicate_storage.py,sha256=K-FDuFrRvSocSbFp-OuiTjOE36IKsy_8St0n30bHeuk,4376
30
- src/linters/dry/file_analyzer.py,sha256=7bmXPMERsiI9uMVzuDYRzGVxdCeBxNM8txPLcveMLAY,4070
29
+ src/linters/dry/duplicate_storage.py,sha256=3OxE2mtoWGAsNNrB8J2c-4JirLUoqZ9ptydO5beM-mg,1971
30
+ src/linters/dry/file_analyzer.py,sha256=ufSQ85ddsGTqGnBHZNTdV_5DGfTpUmJOB58sIdJNV0I,2928
31
31
  src/linters/dry/inline_ignore.py,sha256=ASfA-fp_1aPpkakN2e0T6qdTh8S7Jqj89ovxXJLmFlc,4439
32
- src/linters/dry/linter.py,sha256=EmwDvjkapeoxazlkzC_FGcloftTUJYn5SuAO-tb_c1E,6127
33
- src/linters/dry/python_analyzer.py,sha256=OdSemHuWiXofHUhZzFDRNJmO-BoOTbgsAG1gP80jcZQ,20937
34
- src/linters/dry/storage_initializer.py,sha256=8FQPhnTOkU52QUrJVSH4qIo2v2uxwlp0X-KPmwqKnIU,1727
32
+ src/linters/dry/linter.py,sha256=XMLwCgGrFX0l0dVUJs1jpsXOfgxeKKDbxOtN5h5Emhk,5835
33
+ src/linters/dry/python_analyzer.py,sha256=Qj9dElypv8K3Qno20F5JfuOm7IKGvDyuGSvb4032n7Q,21140
34
+ src/linters/dry/storage_initializer.py,sha256=ykMALFs4uMUrN0_skEwySDl_t5Dm_LGHllF0OxDhiUI,1366
35
35
  src/linters/dry/token_hasher.py,sha256=mCFuP0FQFALyKghBgZHcspsoOxgT7C7ZkfspnhFA5U4,3609
36
36
  src/linters/dry/typescript_analyzer.py,sha256=n1rsQYp7nuPhgErbG8hWawkywRz-iFGhrGlQXDrIa14,21494
37
37
  src/linters/dry/violation_builder.py,sha256=EUiEQIOZjzAoHEqZiIR8WZP8m4dgqJjcveR5mdMyClI,2803
38
- src/linters/dry/violation_filter.py,sha256=lco3Gyt6qhxKMKQvNxdtoWsO03J9HicjCWg_gicEOAc,3013
38
+ src/linters/dry/violation_filter.py,sha256=aTOMz8kXG2sZlSVcf3cAxgxHs7f2kBXInfr1V_04fUQ,3125
39
39
  src/linters/dry/violation_generator.py,sha256=cc6aKvTxtHSZm0F7Y-gL1bmD3JUphRmAvcbqk9aUzGg,6128
40
40
  src/linters/file_placement/__init__.py,sha256=vJ43GZujcbAk-K3DwfsQZ0J3yP_5G35CKssatLyntXk,862
41
41
  src/linters/file_placement/config_loader.py,sha256=Of5sTG2S-04efn3KOlXrSxpMcC1ipBpSvCjtJOMmWno,2640
@@ -46,18 +46,25 @@ src/linters/file_placement/pattern_matcher.py,sha256=3HZWYgQKXz_y13z3lO1YHn51khC
46
46
  src/linters/file_placement/pattern_validator.py,sha256=eMt5GB5lgJMhhQACOlfDXQFfSfNrOY-wJN1JanGka6Q,3717
47
47
  src/linters/file_placement/rule_checker.py,sha256=JONXcaYxZ8CM_7Zg6Th01p5cve1rJ8YkReAUJ44nfUg,7795
48
48
  src/linters/file_placement/violation_factory.py,sha256=NkQmBcgpa3g3W2ZdFZNQ5djLVP4x9OKs65d7F1rCKvM,6040
49
- src/linters/nesting/__init__.py,sha256=zBxZJPhxTO91ezWwXJ72wyxUS7i8t6lehjlJFJKRYvA,3134
50
- src/linters/nesting/config.py,sha256=qU66jynd_GDVwFRFpk2S2--MhmLPoPdw1hj7oKpgoB0,2265
51
- src/linters/nesting/linter.py,sha256=Mtbdbp-0rrfg4FMCt8Q8V78J-fEpgqUzE4qjIxJPiIE,6623
49
+ src/linters/magic_numbers/__init__.py,sha256=17dkCUf0uiYLvpOZF01VDojj92NzxXZMtRhrSBUzsdc,1689
50
+ src/linters/magic_numbers/config.py,sha256=xtT1kFD68VScUf5BRL1mpzWUiQLIWoI6iqniwBu0GgY,2946
51
+ src/linters/magic_numbers/context_analyzer.py,sha256=cGXozlKll10Zao56c2E8ThIyH2mSQaPaUau_g7ngRLw,8446
52
+ src/linters/magic_numbers/linter.py,sha256=f240nyxsSN9-ttF6c7gA0LNwo6mBd85bWVO2I45G3DI,16354
53
+ src/linters/magic_numbers/python_analyzer.py,sha256=0u1cFaaFCqOW5yeW-YbmPoZuVIeN_KtmkFyyxup6aR0,2803
54
+ src/linters/magic_numbers/typescript_analyzer.py,sha256=DCYRdxjgMd6PkhJWKnc1W-S1T0sa-F9AHCLV2JwcR8g,7468
55
+ src/linters/magic_numbers/violation_builder.py,sha256=SqIQv3N9lpP2GRC1TC5InrvaEdrAq24V7Ec2Xj5olb0,3308
56
+ src/linters/nesting/__init__.py,sha256=tszmyCEQMpEwB5H84WcAUfRYDQl7jpsn04es5DtAHsM,3200
57
+ src/linters/nesting/config.py,sha256=PfPA2wJn3i6HHXeM0qu6Qx-v1KJdRwlRkFOdpf7NhS8,2405
58
+ src/linters/nesting/linter.py,sha256=-klbXIbg145beICop81CNQ5J1OInQaeycDT8u3Ff2Ww,6236
52
59
  src/linters/nesting/python_analyzer.py,sha256=DF2lVnxYstakOpP_Zizox583Ypkb4eUpgQYEpu6x8gk,3078
53
60
  src/linters/nesting/typescript_analyzer.py,sha256=up1Cf6W-NYCMZSX9YOvS2Uxm7-XrLtAi94lvL9UDemo,3774
54
61
  src/linters/nesting/typescript_function_extractor.py,sha256=dDB1otJnFMCo-Pj4mTr4gekKe7V4ArOAtX6gV0dBDc4,4494
55
62
  src/linters/nesting/violation_builder.py,sha256=sMHS45F2lrA1WYrG3Uug8HfeRPljnXcyJPHSe2F76Bs,4828
56
- src/linters/srp/__init__.py,sha256=P3yHH57xUMVYncZ8kEkERbRn01AxDE9dColmYQqmbNU,3259
63
+ src/linters/srp/__init__.py,sha256=GbhaSB2_AYY-mWgG_ThbyAcDXoVZuB5eLzguoShf38w,3367
57
64
  src/linters/srp/class_analyzer.py,sha256=wuwviwhN1F_VVPaQ3pZvffmY3e9ToxPNJhv6BjhsgZc,3761
58
- src/linters/srp/config.py,sha256=idaPWd8QBFutzFgOYEg358s5inxqDlVmNqclm3Qvku4,3116
65
+ src/linters/srp/config.py,sha256=hTxrM21HIOmg0sM6eJ_h3hRnuxqRZEgs13Ie97-PDr4,3397
59
66
  src/linters/srp/heuristics.py,sha256=Fwrro3I0qOV4o0epM0ZkqgQUU9bK1b2igxoxWjReljU,3185
60
- src/linters/srp/linter.py,sha256=E23NPYpjHtu6JhyuJmE0ECy8mPWXJb-6uw2RVZoczqI,7404
67
+ src/linters/srp/linter.py,sha256=aXeMKmMf5PC5P2E-mstys2xndkrvpZF6tAq9xRdzOYo,7624
61
68
  src/linters/srp/metrics_evaluator.py,sha256=Prk_dPacas_dX7spAzV0g734srmzT5u0t5d4mTG9g2o,1606
62
69
  src/linters/srp/python_analyzer.py,sha256=hA1gtiLJISier6B3rHJX5EkimQc8FJapy-XNtR7xaBQ,2621
63
70
  src/linters/srp/typescript_analyzer.py,sha256=Wi0P_G1v5AnZYtMN3sNm1iHva84-8Kep2LZ5RmAS4c4,2885
@@ -68,8 +75,8 @@ src/orchestrator/core.py,sha256=zb4H4HtDNLmnsRCUXI3oNtfM3T-nTPW9Q2pAbI61VEs,8374
68
75
  src/orchestrator/language_detector.py,sha256=rHyVMApit80NTTNyDH1ObD1usKD8LjGmH3DwqNAWYGc,2736
69
76
  src/utils/__init__.py,sha256=NiBtKeQ09Y3kuUzeN4O1JNfUIYPQDS2AP1l5ODq-Dec,125
70
77
  src/utils/project_root.py,sha256=ldv2-XeMT0IElpSgrHdTaP2CUfwmdZix8vQ2qXO1O5s,2735
71
- thailint-0.2.1.dist-info/LICENSE,sha256=kxh1J0Sb62XvhNJ6MZsVNe8PqNVJ7LHRn_EWa-T3djw,1070
72
- thailint-0.2.1.dist-info/METADATA,sha256=QlQOYyn3OostFqz8NmMf9OCx_TeaE0VEhJQGo2bvTVo,27109
73
- thailint-0.2.1.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
74
- thailint-0.2.1.dist-info/entry_points.txt,sha256=l7DQJgU18sVLDpSaXOXY3lLhnQHQIRrSJZTQjG1cEAk,62
75
- thailint-0.2.1.dist-info/RECORD,,
78
+ thailint-0.3.1.dist-info/LICENSE,sha256=kxh1J0Sb62XvhNJ6MZsVNe8PqNVJ7LHRn_EWa-T3djw,1070
79
+ thailint-0.3.1.dist-info/METADATA,sha256=iBzUfrCD01KiYQ5_s4y49pS9gxhJfeesm6uYXLlKBAs,31385
80
+ thailint-0.3.1.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
81
+ thailint-0.3.1.dist-info/entry_points.txt,sha256=l7DQJgU18sVLDpSaXOXY3lLhnQHQIRrSJZTQjG1cEAk,62
82
+ thailint-0.3.1.dist-info/RECORD,,