tree-sitter-analyzer 1.6.1.3__py3-none-any.whl → 1.6.1.4__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.

Potentially problematic release.


This version of tree-sitter-analyzer might be problematic. Click here for more details.

@@ -11,7 +11,7 @@ Architecture:
11
11
  - Data Models: Generic and language-specific code element representations
12
12
  """
13
13
 
14
- __version__ = "1.6.1.3"
14
+ __version__ = "1.6.1.4"
15
15
  __author__ = "aisheng.yu"
16
16
  __email__ = "aimasteracc@gmail.com"
17
17
 
@@ -456,6 +456,61 @@ def extract_text_slice(
456
456
  )
457
457
 
458
458
 
459
+ def read_file_safe_streaming(file_path: str | Path):
460
+ """
461
+ Context manager for streaming file reading with automatic encoding detection.
462
+
463
+ This function opens a file with the correct encoding detected from the file's
464
+ content and yields a file handle that can be used for line-by-line reading.
465
+ This is memory-efficient for large files as it doesn't load the entire content.
466
+
467
+ Args:
468
+ file_path: Path to the file to read
469
+
470
+ Yields:
471
+ File handle opened with the correct encoding
472
+
473
+ Example:
474
+ with read_file_safe_streaming("large_file.txt") as f:
475
+ for line_num, line in enumerate(f, 1):
476
+ if line_num >= start_line:
477
+ # Process line
478
+ pass
479
+ """
480
+ import contextlib
481
+
482
+ file_path = Path(file_path)
483
+
484
+ # First, detect encoding by reading a small sample
485
+ try:
486
+ with open(file_path, "rb") as f:
487
+ # Read first 8KB to detect encoding
488
+ sample_data = f.read(8192)
489
+
490
+ if not sample_data:
491
+ # Empty file, use default encoding
492
+ detected_encoding = EncodingManager.DEFAULT_ENCODING
493
+ else:
494
+ # Detect encoding from sample with file path for caching
495
+ detected_encoding = EncodingManager.detect_encoding(sample_data, str(file_path))
496
+
497
+ except OSError as e:
498
+ log_warning(f"Failed to read file for encoding detection {file_path}: {e}")
499
+ raise e
500
+
501
+ # Open file with detected encoding for streaming
502
+ @contextlib.contextmanager
503
+ def _file_context():
504
+ try:
505
+ with open(file_path, "r", encoding=detected_encoding, errors="replace") as f:
506
+ yield f
507
+ except OSError as e:
508
+ log_warning(f"Failed to open file for streaming {file_path}: {e}")
509
+ raise e
510
+
511
+ return _file_context()
512
+
513
+
459
514
  def clear_encoding_cache() -> None:
460
515
  """Clear the global encoding cache"""
461
516
  _encoding_cache.clear()
@@ -5,9 +5,10 @@ File Handler Module
5
5
  This module provides file reading functionality with encoding detection and fallback.
6
6
  """
7
7
 
8
+ import itertools
8
9
  from pathlib import Path
9
10
 
10
- from .encoding_utils import read_file_safe
11
+ from .encoding_utils import read_file_safe, read_file_safe_streaming
11
12
  from .utils import log_error, log_info, log_warning
12
13
 
13
14
 
@@ -81,7 +82,10 @@ def read_file_partial(
81
82
  end_column: int | None = None,
82
83
  ) -> str | None:
83
84
  """
84
- Read partial file content by line/column range
85
+ Read partial file content by line/column range using streaming approach.
86
+
87
+ This function uses a memory-efficient streaming approach that reads only
88
+ the required lines from the file, making it suitable for very large files.
85
89
 
86
90
  Args:
87
91
  file_path: Path to file
@@ -109,30 +113,39 @@ def read_file_partial(
109
113
  return None
110
114
 
111
115
  try:
112
- # Read whole file safely
113
- content, detected_encoding = read_file_safe(file_path)
114
-
115
- # Split to lines
116
- lines = content.splitlines(keepends=True)
117
- total_lines = len(lines)
118
-
119
- # Adjust line indexes
120
- start_idx = start_line - 1 # convert to 0-based
121
- end_idx = min(
122
- end_line - 1 if end_line is not None else total_lines - 1, total_lines - 1
123
- )
124
-
125
- # Range check
126
- if start_idx >= total_lines:
127
- log_warning(
128
- f"start_line ({start_line}) exceeds file length ({total_lines})"
129
- )
130
- return ""
131
-
132
- # Select lines
133
- selected_lines = lines[start_idx : end_idx + 1]
116
+ # Use streaming approach for memory efficiency
117
+ with read_file_safe_streaming(file_path) as f:
118
+ # Convert to 0-based indexing
119
+ start_idx = start_line - 1
120
+ end_idx = end_line - 1 if end_line is not None else None
121
+
122
+ # Use itertools.islice for efficient line selection
123
+ if end_idx is not None:
124
+ # Read specific range
125
+ selected_lines_iter = itertools.islice(f, start_idx, end_idx + 1)
126
+ else:
127
+ # Read from start_line to end of file
128
+ selected_lines_iter = itertools.islice(f, start_idx, None)
129
+
130
+ # Convert iterator to list for processing
131
+ selected_lines = list(selected_lines_iter)
132
+
133
+ # Check if we got any lines
134
+ if not selected_lines:
135
+ # Check if start_line is beyond file length by counting lines
136
+ with read_file_safe_streaming(file_path) as f_count:
137
+ total_lines = sum(1 for _ in f_count)
138
+
139
+ if start_idx >= total_lines:
140
+ log_warning(
141
+ f"start_line ({start_line}) exceeds file length ({total_lines})"
142
+ )
143
+ return ""
144
+ else:
145
+ # File might be empty or other issue
146
+ return ""
134
147
 
135
- # Handle column range
148
+ # Handle column range if specified
136
149
  if start_column is not None or end_column is not None:
137
150
  processed_lines = []
138
151
  for i, line in enumerate(selected_lines):
@@ -167,7 +180,7 @@ def read_file_partial(
167
180
  # Preserve original newline (except last line)
168
181
  if i < len(selected_lines) - 1:
169
182
  # Detect original newline char of the line
170
- original_line = lines[start_idx + i]
183
+ original_line = selected_lines[i]
171
184
  if original_line.endswith("\r\n"):
172
185
  line_content += "\r\n"
173
186
  elif original_line.endswith("\n"):
@@ -182,9 +195,12 @@ def read_file_partial(
182
195
  # No column range: join lines directly
183
196
  result = "".join(selected_lines)
184
197
 
198
+ # Calculate end line for logging
199
+ actual_end_line = end_line or (start_line + len(selected_lines) - 1)
200
+
185
201
  log_info(
186
202
  f"Successfully read partial file {file_path}: "
187
- f"lines {start_line}-{end_line or total_lines}"
203
+ f"lines {start_line}-{actual_end_line}"
188
204
  f"{f', columns {start_column}-{end_column}' if start_column is not None or end_column is not None else ''}"
189
205
  )
190
206
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tree-sitter-analyzer
3
- Version: 1.6.1.3
3
+ Version: 1.6.1.4
4
4
  Summary: Extensible multi-language code analyzer framework using Tree-sitter with dynamic plugin architecture
5
5
  Project-URL: Homepage, https://github.com/aimasteracc/tree-sitter-analyzer
6
6
  Project-URL: Documentation, https://github.com/aimasteracc/tree-sitter-analyzer#readme
@@ -165,11 +165,11 @@ Description-Content-Type: text/markdown
165
165
 
166
166
  [![Python Version](https://img.shields.io/badge/python-3.10%2B-blue.svg)](https://python.org)
167
167
  [![License](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)
168
- [![Tests](https://img.shields.io/badge/tests-1967%20tests-brightgreen.svg)](#quality-assurance)
168
+ [![Tests](https://img.shields.io/badge/tests-1980%20tests-brightgreen.svg)](#quality-assurance)
169
169
  [![Coverage](https://img.shields.io/badge/coverage-71.48%25-green.svg)](#quality-assurance)
170
170
  [![Quality](https://img.shields.io/badge/quality-enterprise%20grade-blue.svg)](#quality-assurance)
171
171
  [![PyPI](https://img.shields.io/pypi/v/tree-sitter-analyzer.svg)](https://pypi.org/project/tree-sitter-analyzer/)
172
- [![Version](https://img.shields.io/badge/version-1.6.1.3-blue.svg)](https://github.com/aimasteracc/tree-sitter-analyzer/releases)
172
+ [![Version](https://img.shields.io/badge/version-1.6.1.4-blue.svg)](https://github.com/aimasteracc/tree-sitter-analyzer/releases)
173
173
  [![GitHub Stars](https://img.shields.io/github/stars/aimasteracc/tree-sitter-analyzer.svg?style=social)](https://github.com/aimasteracc/tree-sitter-analyzer)
174
174
 
175
175
  ## 🚀 Enterprise-Grade Code Analysis Tool for the AI Era
@@ -224,7 +224,7 @@ Tree-sitter Analyzer is an enterprise-grade code analysis tool designed for the
224
224
  - **More Languages** - Basic support for C/C++, Rust, Go
225
225
 
226
226
  ### 🏆 Production Ready
227
- - **1893 Tests** - Comprehensive test coverage, enterprise-grade quality assurance
227
+ - **1980 Tests** - Comprehensive test coverage, enterprise-grade quality assurance
228
228
  - **71.48% Coverage** - Comprehensive test suite
229
229
  - **Cross-Platform Support** - Full compatibility with Windows, macOS, Linux
230
230
  - **Continuous Maintenance** - Active development and community support
@@ -731,7 +731,7 @@ Powerful file discovery and content search based on fd and ripgrep:
731
731
  ## 🏆 Quality Assurance
732
732
 
733
733
  ### 📊 Quality Metrics
734
- - **1893 Tests** - Comprehensive test coverage ✅
734
+ - **1980 Tests** - Comprehensive test coverage ✅
735
735
  - **71.48% Code Coverage** - Comprehensive test suite
736
736
  - **Zero Test Failures** - Production ready
737
737
  - **Cross-Platform Support** - Windows, macOS, Linux
@@ -784,7 +784,7 @@ uv run pytest tests/test_mcp_server_initialization.py -v
784
784
  **Verification Environment:**
785
785
  - Operating Systems: Windows 10, macOS, Linux
786
786
  - Python Version: 3.10+
787
- - Project Version: tree-sitter-analyzer v1.6.1.3
787
+ - Project Version: tree-sitter-analyzer v1.6.1.4
788
788
  - Test Files: BigService.java (1419 lines), sample.py (256 lines), MultiClass.java (54 lines)
789
789
 
790
790
  ---
@@ -1,11 +1,11 @@
1
- tree_sitter_analyzer/__init__.py,sha256=GnE09UdDRFn4KIFZSjDA_KKrsE8qmAyHvZf0IG5rf5Y,3069
1
+ tree_sitter_analyzer/__init__.py,sha256=uQLp3KXeuJDq1B5eHowray1HngjGdDoPOJu3Qf3gmiM,3069
2
2
  tree_sitter_analyzer/__main__.py,sha256=Zl79tpe4UaMu-7yeztc06tgP0CVMRnvGgas4ZQP5SCs,228
3
3
  tree_sitter_analyzer/api.py,sha256=jzwID6fJNdhQkJP3D0lzBVPhOnGIN4tyyMtmRYdK9zI,22753
4
4
  tree_sitter_analyzer/cli_main.py,sha256=BuaM-L-Jx3G49qvAUOQVsw0wEM-X0UzPaRszRZBist4,10374
5
5
  tree_sitter_analyzer/constants.py,sha256=7w3sLFt_6vPaKsxzrc21K1rOKpLGMyyA1203nu3pDOQ,1889
6
- tree_sitter_analyzer/encoding_utils.py,sha256=BgdBKnW20EueEFJT-aLrQI38bTOcR5rWQ3Dpa-ALszA,14805
6
+ tree_sitter_analyzer/encoding_utils.py,sha256=hPPoRzMHHYZ2hLREjp3OHWkmmVmjC6H0TX3SxyBXcGg,16704
7
7
  tree_sitter_analyzer/exceptions.py,sha256=AZryCQyKXekAg8lQZd3zqULnjhCKovBNNpnUlNGDhcI,11615
8
- tree_sitter_analyzer/file_handler.py,sha256=mtWz-DE4yfmak347s0e20xFNy3qddcek58Enom5GlZQ,6689
8
+ tree_sitter_analyzer/file_handler.py,sha256=f89N0CcnxfZxphu4QDpormc5AXoUko132EYK-kFoTx0,7753
9
9
  tree_sitter_analyzer/language_detector.py,sha256=pn3nQClo8b_Ar8dS5X3hq9_t5IIlIcizIC0twMaowU4,11693
10
10
  tree_sitter_analyzer/language_loader.py,sha256=gBUXGPTv91bRNs_urH23wzNKgh7ki6KkvpQ7iNPe3Rw,8922
11
11
  tree_sitter_analyzer/logging_manager.py,sha256=pQYQAQi1RheWokGsokNuF9Ik466jQK5UQC8PSVOxpEU,12669
@@ -89,7 +89,7 @@ tree_sitter_analyzer/security/__init__.py,sha256=ZTqTt24hsljCpTXAZpJC57L7MU5lJLT
89
89
  tree_sitter_analyzer/security/boundary_manager.py,sha256=3eeENRKWtz2pyZHzd8DiVaq8fdeC6s1eVOuBylSmQPg,9347
90
90
  tree_sitter_analyzer/security/regex_checker.py,sha256=jWK6H8PTPgzbwRPfK_RZ8bBTS6rtEbgjY5vr3YWjQ_U,9616
91
91
  tree_sitter_analyzer/security/validator.py,sha256=yR4qTWEcXpR--bSFwtWvSgY0AzqujOFAqlc1Z7dlTdk,9809
92
- tree_sitter_analyzer-1.6.1.3.dist-info/METADATA,sha256=8BOPv3ykHXzGMhNJMBEiu0qiAogfUce1q55UYrrHmAY,32236
93
- tree_sitter_analyzer-1.6.1.3.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
94
- tree_sitter_analyzer-1.6.1.3.dist-info/entry_points.txt,sha256=dEQkGMGmGGBzssEKlXW9F0-VlO3XJW2fJUv9i7898Ho,701
95
- tree_sitter_analyzer-1.6.1.3.dist-info/RECORD,,
92
+ tree_sitter_analyzer-1.6.1.4.dist-info/METADATA,sha256=pjEnX5EfNgtmFlaQeQLjR_KUYp1olwOZHHAK32S49MQ,32236
93
+ tree_sitter_analyzer-1.6.1.4.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
94
+ tree_sitter_analyzer-1.6.1.4.dist-info/entry_points.txt,sha256=dEQkGMGmGGBzssEKlXW9F0-VlO3XJW2fJUv9i7898Ho,701
95
+ tree_sitter_analyzer-1.6.1.4.dist-info/RECORD,,