error-translator-cli-v2 1.0.7__tar.gz → 1.0.8__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 (16) hide show
  1. {error_translator_cli_v2-1.0.7 → error_translator_cli_v2-1.0.8}/PKG-INFO +1 -1
  2. {error_translator_cli_v2-1.0.7 → error_translator_cli_v2-1.0.8}/error_translator/core.py +37 -25
  3. {error_translator_cli_v2-1.0.7 → error_translator_cli_v2-1.0.8}/error_translator_cli_v2.egg-info/PKG-INFO +1 -1
  4. {error_translator_cli_v2-1.0.7 → error_translator_cli_v2-1.0.8}/pyproject.toml +1 -1
  5. {error_translator_cli_v2-1.0.7 → error_translator_cli_v2-1.0.8}/tests/test_core.py +20 -2
  6. {error_translator_cli_v2-1.0.7 → error_translator_cli_v2-1.0.8}/README.md +0 -0
  7. {error_translator_cli_v2-1.0.7 → error_translator_cli_v2-1.0.8}/error_translator/__init__.py +0 -0
  8. {error_translator_cli_v2-1.0.7 → error_translator_cli_v2-1.0.8}/error_translator/ast_handlers.py +0 -0
  9. {error_translator_cli_v2-1.0.7 → error_translator_cli_v2-1.0.8}/error_translator/auto.py +0 -0
  10. {error_translator_cli_v2-1.0.7 → error_translator_cli_v2-1.0.8}/error_translator/cli.py +0 -0
  11. {error_translator_cli_v2-1.0.7 → error_translator_cli_v2-1.0.8}/error_translator/server.py +0 -0
  12. {error_translator_cli_v2-1.0.7 → error_translator_cli_v2-1.0.8}/error_translator_cli_v2.egg-info/SOURCES.txt +0 -0
  13. {error_translator_cli_v2-1.0.7 → error_translator_cli_v2-1.0.8}/error_translator_cli_v2.egg-info/dependency_links.txt +0 -0
  14. {error_translator_cli_v2-1.0.7 → error_translator_cli_v2-1.0.8}/error_translator_cli_v2.egg-info/entry_points.txt +0 -0
  15. {error_translator_cli_v2-1.0.7 → error_translator_cli_v2-1.0.8}/error_translator_cli_v2.egg-info/top_level.txt +0 -0
  16. {error_translator_cli_v2-1.0.7 → error_translator_cli_v2-1.0.8}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: error-translator-cli-v2
3
- Version: 1.0.7
3
+ Version: 1.0.8
4
4
  Summary: A CLI tool that explains Python errors in simple human language.
5
5
  Author-email: Gourabananda Datta <gourabanandadatta@zohomail.com>
6
6
  Requires-Python: >=3.7
@@ -1,50 +1,62 @@
1
1
  import json
2
2
  import os
3
+ import re
4
+ import linecache
5
+ from functools import lru_cache
3
6
  from .ast_handlers import AST_REGISTRY
4
7
 
8
+
9
+ @lru_cache(maxsize=1)
5
10
  def load_rules():
6
- """Loads the error rules from the JSON file."""
7
- # Find the absolute path to the json file next to this script
11
+ """Load the error rules from disk once and cache them."""
8
12
  current_dir = os.path.dirname(os.path.abspath(__file__))
9
- json_path = os.path.join(current_dir, 'rules.json')
10
-
11
- with open(json_path, 'r') as file:
13
+ json_path = os.path.join(current_dir, "rules.json")
14
+
15
+ with open(json_path, "r", encoding="utf-8") as file:
12
16
  return json.load(file)
13
17
 
18
+
19
+ @lru_cache(maxsize=1)
20
+ def compiled_rules():
21
+ """Compile regex patterns once to avoid repeated work per translation."""
22
+ data = load_rules()
23
+ compiled = []
24
+ for rule in data["rules"]:
25
+ compiled.append((re.compile(rule["pattern"]), rule))
26
+ return compiled
27
+
28
+
29
+ def _extract_location(traceback_text: str) -> tuple[str, str]:
30
+ location_match = re.search(r'File\s+[\'"]?(.*?)[\'"]?,\s+line\s+(\d+)', traceback_text)
31
+ if not location_match:
32
+ return "Unknown File", "Unknown Line"
33
+ return location_match.group(1), location_match.group(2)
34
+
35
+
14
36
  def translate_error(traceback_text: str) -> dict:
15
- import re
16
- import linecache # <-- NEW: Lazy import the linecache module
17
-
18
37
  data = load_rules()
19
- rules = data["rules"]
38
+ rules = compiled_rules()
20
39
  default_error = data["default"]
21
40
 
22
- lines = [line.strip() for line in traceback_text.strip().split('\n') if line.strip()]
41
+ lines = [line.strip() for line in traceback_text.strip().split("\n") if line.strip()]
23
42
  if not lines:
24
43
  return {"explanation": "No error text provided.", "fix": "Provide a valid Python error."}
25
-
44
+
26
45
  actual_error_line = lines[-1]
27
46
 
28
- location_match = re.search(r'File\s+[\'"]?(.*?)[\'"]?,\s+line\s+(\d+)', traceback_text)
29
- file_name = location_match.group(1) if location_match else "Unknown File"
30
- line_number = location_match.group(2) if location_match else "Unknown Line"
47
+ file_name, line_number = _extract_location(traceback_text)
31
48
 
32
- # --- NEW CONTEXT ENGINE LOGIC ---
33
49
  code_context = ""
34
50
  if file_name != "Unknown File" and line_number != "Unknown Line":
35
51
  try:
36
- # linecache safely fetches the exact line of code as a string
37
52
  raw_line = linecache.getline(file_name, int(line_number))
38
53
  if raw_line:
39
- code_context = raw_line.strip() # Remove extra spaces/newlines
54
+ code_context = raw_line.strip()
40
55
  except Exception:
41
- pass # If the file can't be read for any reason, fail silently
42
- # --------------------------------
56
+ pass
43
57
 
44
- for rule in rules:
45
- pattern = re.compile(rule["pattern"])
58
+ for pattern, rule in rules:
46
59
  match = pattern.search(actual_error_line)
47
-
48
60
  if match:
49
61
  extracted_values = list(match.groups())
50
62
  fix_text = rule["fix"].format(*extracted_values)
@@ -61,7 +73,7 @@ def translate_error(traceback_text: str) -> dict:
61
73
  "matched_error": actual_error_line,
62
74
  "file": file_name,
63
75
  "line": line_number,
64
- "code": code_context
76
+ "code": code_context,
65
77
  }
66
78
 
67
79
  return {
@@ -70,5 +82,5 @@ def translate_error(traceback_text: str) -> dict:
70
82
  "matched_error": actual_error_line,
71
83
  "file": file_name,
72
84
  "line": line_number,
73
- "code": code_context
74
- }
85
+ "code": code_context,
86
+ }
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: error-translator-cli-v2
3
- Version: 1.0.7
3
+ Version: 1.0.8
4
4
  Summary: A CLI tool that explains Python errors in simple human language.
5
5
  Author-email: Gourabananda Datta <gourabanandadatta@zohomail.com>
6
6
  Requires-Python: >=3.7
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "error-translator-cli-v2"
7
- version = "1.0.7"
7
+ version = "1.0.8"
8
8
  description = "A CLI tool that explains Python errors in simple human language."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.7"
@@ -1,5 +1,5 @@
1
1
  import pytest
2
- from error_translator.core import translate_error
2
+ from error_translator.core import translate_error, load_rules, compiled_rules
3
3
 
4
4
  # --- 1. EDGE CASE TESTS ---
5
5
 
@@ -35,6 +35,24 @@ def test_unknown_error_fallback():
35
35
  assert result["matched_error"] == "Something completely random went wrong here."
36
36
 
37
37
 
38
+ def test_empty_input_returns_helpful_message():
39
+ result = translate_error(" \n ")
40
+ assert result["explanation"] == "No error text provided."
41
+ assert result["fix"] == "Provide a valid Python error."
42
+
43
+
44
+ def test_rule_loading_is_cached():
45
+ first = load_rules()
46
+ second = load_rules()
47
+ assert first is second
48
+
49
+
50
+ def test_compiled_rules_are_cached():
51
+ first = compiled_rules()
52
+ second = compiled_rules()
53
+ assert first is second
54
+
55
+
38
56
  # --- 2. THE PARAMETERIZED ENGINE FOR ALL ERRORS ---
39
57
 
40
58
  @pytest.mark.parametrize("mock_traceback, expected_in_explanation", [
@@ -128,4 +146,4 @@ def test_regex_extraction_for_supported_errors(mock_traceback, expected_in_expla
128
146
 
129
147
  # 2. Prove the Context Engine successfully parsed the file location
130
148
  assert result["file"] == "script.py"
131
- assert result["line"] == "5"
149
+ assert result["line"] == "5"