error-translator-cli-v2 0.1.0__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.
- error_translator_cli_v2-0.1.0/PKG-INFO +7 -0
- error_translator_cli_v2-0.1.0/error_translator/__init__.py +0 -0
- error_translator_cli_v2-0.1.0/error_translator/cli.py +61 -0
- error_translator_cli_v2-0.1.0/error_translator/core.py +46 -0
- error_translator_cli_v2-0.1.0/error_translator/rules.py +50 -0
- error_translator_cli_v2-0.1.0/error_translator_cli_v2.egg-info/PKG-INFO +7 -0
- error_translator_cli_v2-0.1.0/error_translator_cli_v2.egg-info/SOURCES.txt +11 -0
- error_translator_cli_v2-0.1.0/error_translator_cli_v2.egg-info/dependency_links.txt +1 -0
- error_translator_cli_v2-0.1.0/error_translator_cli_v2.egg-info/entry_points.txt +2 -0
- error_translator_cli_v2-0.1.0/error_translator_cli_v2.egg-info/top_level.txt +1 -0
- error_translator_cli_v2-0.1.0/pyproject.toml +20 -0
- error_translator_cli_v2-0.1.0/setup.cfg +4 -0
- error_translator_cli_v2-0.1.0/tests/test_core.py +13 -0
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: error-translator-cli-v2
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A CLI tool that explains Python errors in simple human language.
|
|
5
|
+
Author-email: Gourabananda Datta <gourabanandadatta@zohomail.com>
|
|
6
|
+
Requires-Python: >=3.7
|
|
7
|
+
Description-Content-Type: text/markdown
|
|
File without changes
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
import argparse
|
|
3
|
+
|
|
4
|
+
from cv2 import line
|
|
5
|
+
from .core import translate_error
|
|
6
|
+
|
|
7
|
+
# ANSI Color Codes for terminal formatting
|
|
8
|
+
class Colors:
|
|
9
|
+
RED = '\033[91m'
|
|
10
|
+
GREEN = '\033[92m'
|
|
11
|
+
YELLOW = '\033[93m'
|
|
12
|
+
CYAN = '\033[96m'
|
|
13
|
+
BOLD = '\033[1m'
|
|
14
|
+
RESET = '\033[0m'
|
|
15
|
+
|
|
16
|
+
def print_result(result: dict):
|
|
17
|
+
"""Prints the translated error to the terminal with colors."""
|
|
18
|
+
print(f"\n{Colors.RED}{Colors.BOLD}🚨 Error Detected:{Colors.RESET}")
|
|
19
|
+
print(f"{result.get('matched_error', 'N/A')}\n")
|
|
20
|
+
|
|
21
|
+
# If file and line info is available, print it
|
|
22
|
+
if "file" in result:
|
|
23
|
+
print(f"{Colors.YELLOW}📍 Location: {result['file']} (Line {result['line']}){Colors.RESET}\n")
|
|
24
|
+
else:
|
|
25
|
+
print() # Just a newline
|
|
26
|
+
|
|
27
|
+
print(f"{Colors.CYAN}{Colors.BOLD}🧠 Explanation:{Colors.RESET}")
|
|
28
|
+
print(f"{result['explanation']}\n")
|
|
29
|
+
|
|
30
|
+
print(f"{Colors.GREEN}{Colors.BOLD}🛠️ Suggested Fix:{Colors.RESET}")
|
|
31
|
+
print(f"{result['fix']}\n")
|
|
32
|
+
|
|
33
|
+
def main():
|
|
34
|
+
parser = argparse.ArgumentParser(
|
|
35
|
+
description="Translate Python error messages into simple English."
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
parser.add_argument(
|
|
39
|
+
"error_text",
|
|
40
|
+
nargs="?",
|
|
41
|
+
help="The error message or traceback string to translate."
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
args = parser.parse_args()
|
|
45
|
+
|
|
46
|
+
# Read from positional argument OR standard input (piping)
|
|
47
|
+
error_input = args.error_text
|
|
48
|
+
|
|
49
|
+
if not error_input and not sys.stdin.isatty():
|
|
50
|
+
# Allows usage like: cat error.log | explain-error
|
|
51
|
+
error_input = sys.stdin.read()
|
|
52
|
+
|
|
53
|
+
if not error_input:
|
|
54
|
+
parser.print_help()
|
|
55
|
+
sys.exit(1)
|
|
56
|
+
|
|
57
|
+
result = translate_error(error_input)
|
|
58
|
+
print_result(result)
|
|
59
|
+
|
|
60
|
+
if __name__ == "__main__":
|
|
61
|
+
main()
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
from .rules import ERROR_RULES, DEFAULT_ERROR
|
|
2
|
+
import re
|
|
3
|
+
|
|
4
|
+
def translate_error(traceback_text: str) -> dict:
|
|
5
|
+
"""
|
|
6
|
+
Parses traceback text and returns a human-readable explanation and fix.
|
|
7
|
+
"""
|
|
8
|
+
location_match = re.search(r'File "(.*?)", line (\d+), in (.+)', traceback_text)
|
|
9
|
+
file_name = location_match.group(1) if location_match else "unknown file"
|
|
10
|
+
line_number = location_match.group(2) if location_match else "unknown line"
|
|
11
|
+
in_function = location_match.group(3) if location_match else "unknown function"
|
|
12
|
+
# Grab the last non-empty line of the traceback, which usually contains the actual error
|
|
13
|
+
lines = [line.strip() for line in traceback_text.strip().split('\n') if line.strip()]
|
|
14
|
+
if not lines:
|
|
15
|
+
return {"explanation": "No error text provided.", "fix": "Provide a valid Python error."}
|
|
16
|
+
|
|
17
|
+
actual_error_line = lines[-1]
|
|
18
|
+
|
|
19
|
+
for rule in ERROR_RULES:
|
|
20
|
+
match = rule["pattern"].search(actual_error_line)
|
|
21
|
+
if match:
|
|
22
|
+
# Extract the captured regex groups (e.g., the variable name)
|
|
23
|
+
extracted_values = match.groups()
|
|
24
|
+
|
|
25
|
+
# Format the explanation and fix using the extracted values
|
|
26
|
+
explanation = rule["explanation"].format(*extracted_values)
|
|
27
|
+
fix = rule["fix"].format(*extracted_values)
|
|
28
|
+
|
|
29
|
+
return {
|
|
30
|
+
"explanation": explanation,
|
|
31
|
+
"fix": fix,
|
|
32
|
+
"matched_error": actual_error_line,
|
|
33
|
+
"file": file_name,
|
|
34
|
+
"line": line_number,
|
|
35
|
+
"function": in_function
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
# If no rules match, return the default payload
|
|
39
|
+
return {
|
|
40
|
+
"explanation": DEFAULT_ERROR["explanation"],
|
|
41
|
+
"fix": DEFAULT_ERROR["fix"],
|
|
42
|
+
"matched_error": actual_error_line,
|
|
43
|
+
"file": file_name,
|
|
44
|
+
"line": line_number,
|
|
45
|
+
"function": in_function
|
|
46
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import re
|
|
2
|
+
|
|
3
|
+
# We compile the regex patterns upfront for performance.
|
|
4
|
+
ERROR_RULES = [
|
|
5
|
+
{
|
|
6
|
+
"pattern": re.compile(r"NameError: name '(.*)' is not defined"),
|
|
7
|
+
"explanation": "You tried to use a variable or function named '{0}', but Python doesn't recognize it.",
|
|
8
|
+
"fix": "Check if '{0}' is spelled correctly, or ensure you defined/imported it before using it."
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
"pattern": re.compile(r"TypeError: can only concatenate str \(not \"(.*)\"\) to str"),
|
|
12
|
+
"explanation": "You are trying to add a string to a {0}, which Python cannot do.",
|
|
13
|
+
"fix": "Convert the {0} to a string first using str() before concatenating."
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
"pattern": re.compile(r"TypeError: unsupported operand type\(s\) for \+: '(.*)' and '(.*)'"),
|
|
17
|
+
"explanation": "You are trying to add two incompatible types: a {0} and a {1}.",
|
|
18
|
+
"fix": "Ensure both sides of the '+' are the same type (e.g., both numbers or both strings)."
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"pattern": re.compile(r"IndexError: list index out of range"),
|
|
22
|
+
"explanation": "You are trying to access an item in a list at a position that doesn't exist.",
|
|
23
|
+
"fix": "Check the length of your list using len(). Remember, Python lists start counting at 0!"
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
"pattern": re.compile(r"KeyError: '(.*)'"),
|
|
27
|
+
"explanation": "You tried to look up a key named '{0}' in a dictionary, but that key doesn't exist.",
|
|
28
|
+
"fix": "Check for typos in the key name, or use the .get('{0}') method to safely access dictionary values."
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"pattern": re.compile(r"ZeroDivisionError: division by zero"),
|
|
32
|
+
"explanation": "You are trying to divide a number by zero, which is mathematically impossible.",
|
|
33
|
+
"fix": "Add an if-statement before the division to check if the denominator is 0."
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"pattern": re.compile(r"ModuleNotFoundError: No module named '(.*)'"),
|
|
37
|
+
"explanation": "Python is trying to import a package named '{0}', but it isn't installed in your current environment.",
|
|
38
|
+
"fix": "Open your terminal and run: pip install {0}"
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
"pattern": re.compile(r"AttributeError: '(.*)' object has no attribute '(.*)'"),
|
|
42
|
+
"explanation": "You are trying to use a method or property named '{1}' on a {0} object, but {0}s don't have that capability.",
|
|
43
|
+
"fix": "Check the spelling of '{1}'. If it's correct, verify that your variable is actually the data type you think it is."
|
|
44
|
+
},
|
|
45
|
+
]
|
|
46
|
+
|
|
47
|
+
DEFAULT_ERROR = {
|
|
48
|
+
"explanation": "This is an unknown error. The tool couldn't find a specific match.",
|
|
49
|
+
"fix": "Try copying the last line of the error into a search engine or StackOverflow."
|
|
50
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: error-translator-cli-v2
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A CLI tool that explains Python errors in simple human language.
|
|
5
|
+
Author-email: Gourabananda Datta <gourabanandadatta@zohomail.com>
|
|
6
|
+
Requires-Python: >=3.7
|
|
7
|
+
Description-Content-Type: text/markdown
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
pyproject.toml
|
|
2
|
+
error_translator/__init__.py
|
|
3
|
+
error_translator/cli.py
|
|
4
|
+
error_translator/core.py
|
|
5
|
+
error_translator/rules.py
|
|
6
|
+
error_translator_cli_v2.egg-info/PKG-INFO
|
|
7
|
+
error_translator_cli_v2.egg-info/SOURCES.txt
|
|
8
|
+
error_translator_cli_v2.egg-info/dependency_links.txt
|
|
9
|
+
error_translator_cli_v2.egg-info/entry_points.txt
|
|
10
|
+
error_translator_cli_v2.egg-info/top_level.txt
|
|
11
|
+
tests/test_core.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
error_translator
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61.0"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "error-translator-cli-v2"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "A CLI tool that explains Python errors in simple human language."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.7"
|
|
11
|
+
authors = [
|
|
12
|
+
{ name = "Gourabananda Datta", email = "gourabanandadatta@zohomail.com" }
|
|
13
|
+
]
|
|
14
|
+
|
|
15
|
+
[project.scripts]
|
|
16
|
+
explain-error = "error_translator.cli:main"
|
|
17
|
+
|
|
18
|
+
# --- NEW LINES BELOW ---
|
|
19
|
+
[tool.setuptools]
|
|
20
|
+
packages = ["error_translator"]
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
from error_translator.core import translate_error
|
|
2
|
+
|
|
3
|
+
def test_name_error_translation():
|
|
4
|
+
mock_traceback = """Traceback (most recent call last):
|
|
5
|
+
File "main.py", line 3, in <module>
|
|
6
|
+
print(x)
|
|
7
|
+
NameError: name 'x' is not defined"""
|
|
8
|
+
|
|
9
|
+
result = translate_error(mock_traceback)
|
|
10
|
+
|
|
11
|
+
assert "x" in result["explanation"]
|
|
12
|
+
assert result["file"] == "main.py"
|
|
13
|
+
assert result["line"] == "3"
|