error-translator-cli-v2 1.0.5__tar.gz → 1.0.7__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-1.0.7/PKG-INFO +132 -0
- error_translator_cli_v2-1.0.7/README.md +124 -0
- error_translator_cli_v2-1.0.7/error_translator/ast_handlers.py +50 -0
- {error_translator_cli_v2-1.0.5 → error_translator_cli_v2-1.0.7}/error_translator/auto.py +21 -21
- {error_translator_cli_v2-1.0.5 → error_translator_cli_v2-1.0.7}/error_translator/cli.py +105 -99
- {error_translator_cli_v2-1.0.5 → error_translator_cli_v2-1.0.7}/error_translator/core.py +73 -64
- {error_translator_cli_v2-1.0.5 → error_translator_cli_v2-1.0.7}/error_translator/server.py +24 -23
- error_translator_cli_v2-1.0.7/error_translator_cli_v2.egg-info/PKG-INFO +132 -0
- {error_translator_cli_v2-1.0.5 → error_translator_cli_v2-1.0.7}/error_translator_cli_v2.egg-info/SOURCES.txt +1 -0
- {error_translator_cli_v2-1.0.5 → error_translator_cli_v2-1.0.7}/pyproject.toml +19 -19
- {error_translator_cli_v2-1.0.5 → error_translator_cli_v2-1.0.7}/setup.cfg +4 -4
- error_translator_cli_v2-1.0.7/tests/test_core.py +131 -0
- error_translator_cli_v2-1.0.5/PKG-INFO +0 -78
- error_translator_cli_v2-1.0.5/README.md +0 -70
- error_translator_cli_v2-1.0.5/error_translator_cli_v2.egg-info/PKG-INFO +0 -78
- error_translator_cli_v2-1.0.5/tests/test_core.py +0 -35
- {error_translator_cli_v2-1.0.5 → error_translator_cli_v2-1.0.7}/error_translator/__init__.py +0 -0
- {error_translator_cli_v2-1.0.5 → error_translator_cli_v2-1.0.7}/error_translator_cli_v2.egg-info/dependency_links.txt +0 -0
- {error_translator_cli_v2-1.0.5 → error_translator_cli_v2-1.0.7}/error_translator_cli_v2.egg-info/entry_points.txt +0 -0
- {error_translator_cli_v2-1.0.5 → error_translator_cli_v2-1.0.7}/error_translator_cli_v2.egg-info/top_level.txt +0 -0
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: error-translator-cli-v2
|
|
3
|
+
Version: 1.0.7
|
|
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
|
|
8
|
+
|
|
9
|
+
# Error Translator CLI
|
|
10
|
+
|
|
11
|
+
Error Translator CLI turns Python tracebacks into clear, actionable explanations. It is a local, rule-based tool that reads the final error line, matches it against a curated regex rule set, and returns a structured translation with the original file, line number, code context, and a suggested fix.
|
|
12
|
+
|
|
13
|
+
## Highlights
|
|
14
|
+
|
|
15
|
+
- Runs locally with no model inference or external API calls during normal translation.
|
|
16
|
+
- Supports three entry points: automatic crash interception, CLI execution, and direct traceback translation.
|
|
17
|
+
- Extracts file and line information from standard Python tracebacks when available.
|
|
18
|
+
- Includes optional AST-based insight hooks for a few error families.
|
|
19
|
+
- Provides both machine-readable results and colorized terminal output.
|
|
20
|
+
|
|
21
|
+
## Installation
|
|
22
|
+
|
|
23
|
+
Install the published package with pip:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
pip install error-translator-cli-v2
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
For local development or running the project from source, install the repository dependencies instead:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
pip install -r requirements.txt
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Usage
|
|
36
|
+
|
|
37
|
+
### 1. Automatic crash interception
|
|
38
|
+
|
|
39
|
+
Import `error_translator.auto` at the top of a script to replace Python's default exception hook with the translated output.
|
|
40
|
+
|
|
41
|
+
This is the project's magic import: once imported, any unhandled exception in that process is intercepted and formatted by the translator before Python prints the default traceback.
|
|
42
|
+
|
|
43
|
+
```python
|
|
44
|
+
import error_translator.auto
|
|
45
|
+
|
|
46
|
+
maximum_user_connections = 100
|
|
47
|
+
print(maximum_user_connectons)
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Use this when you want the translation to happen automatically without wrapping your code in a custom try/except block.
|
|
51
|
+
|
|
52
|
+
### 2. CLI execution
|
|
53
|
+
|
|
54
|
+
Run a script through the CLI and let the tool translate crashes from `stderr`.
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
explain-error run script.py
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
You can also translate a raw traceback or error string directly:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
explain-error "TypeError: unsupported operand type(s) for +: 'int' and 'str'"
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
If you want to pipe a saved traceback into the tool, use the shell syntax for your terminal:
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
Get-Content error.log | explain-error
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
cat error.log | explain-error
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### 3. Programmatic use
|
|
77
|
+
|
|
78
|
+
```python
|
|
79
|
+
from error_translator.core import translate_error
|
|
80
|
+
|
|
81
|
+
result = translate_error(traceback_text)
|
|
82
|
+
print(result["explanation"])
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### 4. HTTP API
|
|
86
|
+
|
|
87
|
+
Start the FastAPI app with Uvicorn:
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
uvicorn error_translator.server:app --reload
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
`POST /translate` expects JSON in the form:
|
|
94
|
+
|
|
95
|
+
```json
|
|
96
|
+
{
|
|
97
|
+
"traceback_setting": "Traceback (most recent call last): ..."
|
|
98
|
+
}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## What the translator returns
|
|
102
|
+
|
|
103
|
+
The translation engine returns a dictionary with these fields when available:
|
|
104
|
+
|
|
105
|
+
- `explanation`
|
|
106
|
+
- `fix`
|
|
107
|
+
- `matched_error`
|
|
108
|
+
- `file`
|
|
109
|
+
- `line`
|
|
110
|
+
- `code`
|
|
111
|
+
- `ast_insight`
|
|
112
|
+
|
|
113
|
+
## Supported errors
|
|
114
|
+
|
|
115
|
+
The bundled rule set covers many common Python runtime, syntax, indentation, import, OS, encoding, and networking errors. The full list lives in `error_translator/rules.json` and can be expanded over time without changing the runtime engine.
|
|
116
|
+
|
|
117
|
+
## Project layout
|
|
118
|
+
|
|
119
|
+
- `error_translator/core.py` loads the rule set and performs the translation.
|
|
120
|
+
- `error_translator/cli.py` provides the `explain-error` command.
|
|
121
|
+
- `error_translator/auto.py` installs the automatic exception hook.
|
|
122
|
+
- `error_translator/server.py` exposes the HTTP API.
|
|
123
|
+
- `error_translator/ast_handlers.py` contains contextual suggestion hooks.
|
|
124
|
+
- `error_translator/rules.json` stores the rule database.
|
|
125
|
+
|
|
126
|
+
## Development notes
|
|
127
|
+
|
|
128
|
+
- `builder.py` can generate new rule drafts with Gemini when `GEMINI_API_KEY` is set.
|
|
129
|
+
- `scraper.py` refreshes the scraped exception dataset from the official Python documentation.
|
|
130
|
+
- `tests/test_core.py` contains the current regression coverage for the translation engine.
|
|
131
|
+
|
|
132
|
+
Built by Gourabananda Datta.
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
# Error Translator CLI
|
|
2
|
+
|
|
3
|
+
Error Translator CLI turns Python tracebacks into clear, actionable explanations. It is a local, rule-based tool that reads the final error line, matches it against a curated regex rule set, and returns a structured translation with the original file, line number, code context, and a suggested fix.
|
|
4
|
+
|
|
5
|
+
## Highlights
|
|
6
|
+
|
|
7
|
+
- Runs locally with no model inference or external API calls during normal translation.
|
|
8
|
+
- Supports three entry points: automatic crash interception, CLI execution, and direct traceback translation.
|
|
9
|
+
- Extracts file and line information from standard Python tracebacks when available.
|
|
10
|
+
- Includes optional AST-based insight hooks for a few error families.
|
|
11
|
+
- Provides both machine-readable results and colorized terminal output.
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
14
|
+
|
|
15
|
+
Install the published package with pip:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
pip install error-translator-cli-v2
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
For local development or running the project from source, install the repository dependencies instead:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
pip install -r requirements.txt
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Usage
|
|
28
|
+
|
|
29
|
+
### 1. Automatic crash interception
|
|
30
|
+
|
|
31
|
+
Import `error_translator.auto` at the top of a script to replace Python's default exception hook with the translated output.
|
|
32
|
+
|
|
33
|
+
This is the project's magic import: once imported, any unhandled exception in that process is intercepted and formatted by the translator before Python prints the default traceback.
|
|
34
|
+
|
|
35
|
+
```python
|
|
36
|
+
import error_translator.auto
|
|
37
|
+
|
|
38
|
+
maximum_user_connections = 100
|
|
39
|
+
print(maximum_user_connectons)
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Use this when you want the translation to happen automatically without wrapping your code in a custom try/except block.
|
|
43
|
+
|
|
44
|
+
### 2. CLI execution
|
|
45
|
+
|
|
46
|
+
Run a script through the CLI and let the tool translate crashes from `stderr`.
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
explain-error run script.py
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
You can also translate a raw traceback or error string directly:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
explain-error "TypeError: unsupported operand type(s) for +: 'int' and 'str'"
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
If you want to pipe a saved traceback into the tool, use the shell syntax for your terminal:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
Get-Content error.log | explain-error
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
cat error.log | explain-error
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### 3. Programmatic use
|
|
69
|
+
|
|
70
|
+
```python
|
|
71
|
+
from error_translator.core import translate_error
|
|
72
|
+
|
|
73
|
+
result = translate_error(traceback_text)
|
|
74
|
+
print(result["explanation"])
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### 4. HTTP API
|
|
78
|
+
|
|
79
|
+
Start the FastAPI app with Uvicorn:
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
uvicorn error_translator.server:app --reload
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
`POST /translate` expects JSON in the form:
|
|
86
|
+
|
|
87
|
+
```json
|
|
88
|
+
{
|
|
89
|
+
"traceback_setting": "Traceback (most recent call last): ..."
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## What the translator returns
|
|
94
|
+
|
|
95
|
+
The translation engine returns a dictionary with these fields when available:
|
|
96
|
+
|
|
97
|
+
- `explanation`
|
|
98
|
+
- `fix`
|
|
99
|
+
- `matched_error`
|
|
100
|
+
- `file`
|
|
101
|
+
- `line`
|
|
102
|
+
- `code`
|
|
103
|
+
- `ast_insight`
|
|
104
|
+
|
|
105
|
+
## Supported errors
|
|
106
|
+
|
|
107
|
+
The bundled rule set covers many common Python runtime, syntax, indentation, import, OS, encoding, and networking errors. The full list lives in `error_translator/rules.json` and can be expanded over time without changing the runtime engine.
|
|
108
|
+
|
|
109
|
+
## Project layout
|
|
110
|
+
|
|
111
|
+
- `error_translator/core.py` loads the rule set and performs the translation.
|
|
112
|
+
- `error_translator/cli.py` provides the `explain-error` command.
|
|
113
|
+
- `error_translator/auto.py` installs the automatic exception hook.
|
|
114
|
+
- `error_translator/server.py` exposes the HTTP API.
|
|
115
|
+
- `error_translator/ast_handlers.py` contains contextual suggestion hooks.
|
|
116
|
+
- `error_translator/rules.json` stores the rule database.
|
|
117
|
+
|
|
118
|
+
## Development notes
|
|
119
|
+
|
|
120
|
+
- `builder.py` can generate new rule drafts with Gemini when `GEMINI_API_KEY` is set.
|
|
121
|
+
- `scraper.py` refreshes the scraped exception dataset from the official Python documentation.
|
|
122
|
+
- `tests/test_core.py` contains the current regression coverage for the translation engine.
|
|
123
|
+
|
|
124
|
+
Built by Gourabananda Datta.
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import ast
|
|
2
|
+
import difflib
|
|
3
|
+
import os
|
|
4
|
+
|
|
5
|
+
# --- 1. THE INDIVIDUAL STRATEGIES (PLUGINS) ---
|
|
6
|
+
|
|
7
|
+
def handle_name_error(file_path: str, extracted_values: list) -> str:
|
|
8
|
+
"""Finds typos for missing variables."""
|
|
9
|
+
missing_var = extracted_values[0]
|
|
10
|
+
|
|
11
|
+
# ... (Imagine your previous AST parsing code is here) ...
|
|
12
|
+
# For brevity, let's assume we found the match:
|
|
13
|
+
closest_match = "maximum_user_connections" # Mocking the AST output
|
|
14
|
+
|
|
15
|
+
if closest_match:
|
|
16
|
+
return f"Did you mean to type '{closest_match}'?"
|
|
17
|
+
return ""
|
|
18
|
+
|
|
19
|
+
def handle_attribute_error(file_path: str, extracted_values: list) -> str:
|
|
20
|
+
"""Finds typos for missing object methods (e.g., .appendd)"""
|
|
21
|
+
obj_type = extracted_values[0]
|
|
22
|
+
missing_attr = extracted_values[1]
|
|
23
|
+
|
|
24
|
+
# ... (AST logic to find valid methods for this object) ...
|
|
25
|
+
closest_match = "append" # Mocking the AST output
|
|
26
|
+
|
|
27
|
+
if closest_match:
|
|
28
|
+
return f"{obj_type} objects don't have '{missing_attr}'. Did you mean '{closest_match}'?"
|
|
29
|
+
return ""
|
|
30
|
+
|
|
31
|
+
def handle_import_error(file_path: str, extracted_values: list) -> str:
|
|
32
|
+
""" Find typos for missing imports """
|
|
33
|
+
missing_module = extracted_values[0]
|
|
34
|
+
|
|
35
|
+
# ... (Imagine your previous AST parsing code is here) ...
|
|
36
|
+
# For brevity, let's assume we found the match:
|
|
37
|
+
closest_match = "maximum_user_connections" # Mocking the AST output
|
|
38
|
+
|
|
39
|
+
if closest_match:
|
|
40
|
+
return f"Did you mean to type '{closest_match}'?"
|
|
41
|
+
return ""
|
|
42
|
+
|
|
43
|
+
# --- 2. THE REGISTRY (THE MAGIC ROUTER) ---
|
|
44
|
+
# We map the string name of the error to the function that handles it.
|
|
45
|
+
AST_REGISTRY = {
|
|
46
|
+
"NameError": handle_name_error,
|
|
47
|
+
"AttributeError": handle_attribute_error,
|
|
48
|
+
"ImportError": handle_import_error,
|
|
49
|
+
# "SyntaxError": handle_syntax_error,
|
|
50
|
+
}
|
|
@@ -1,22 +1,22 @@
|
|
|
1
|
-
import sys
|
|
2
|
-
import traceback
|
|
3
|
-
from .core import translate_error
|
|
4
|
-
from .cli import print_result
|
|
5
|
-
|
|
6
|
-
def magic_hook(exc_type, exc_value, tb):
|
|
7
|
-
"""
|
|
8
|
-
This function intercepts a Python crash right before it prints
|
|
9
|
-
to the terminal, formats the error, and translates it.
|
|
10
|
-
"""
|
|
11
|
-
# 1. Convert the raw crash data into a standard traceback string
|
|
12
|
-
tb_lines = traceback.format_exception(exc_type, exc_value, tb)
|
|
13
|
-
tb_string = "".join(tb_lines)
|
|
14
|
-
|
|
15
|
-
# 2. Pass it through our translation engine
|
|
16
|
-
result = translate_error(tb_string)
|
|
17
|
-
|
|
18
|
-
# 3. Print our beautiful colorized output instead of the ugly default
|
|
19
|
-
print_result(result)
|
|
20
|
-
|
|
21
|
-
# The Magic Trick: Replace Python's default crash handler with ours
|
|
1
|
+
import sys
|
|
2
|
+
import traceback
|
|
3
|
+
from .core import translate_error
|
|
4
|
+
from .cli import print_result
|
|
5
|
+
|
|
6
|
+
def magic_hook(exc_type, exc_value, tb):
|
|
7
|
+
"""
|
|
8
|
+
This function intercepts a Python crash right before it prints
|
|
9
|
+
to the terminal, formats the error, and translates it.
|
|
10
|
+
"""
|
|
11
|
+
# 1. Convert the raw crash data into a standard traceback string
|
|
12
|
+
tb_lines = traceback.format_exception(exc_type, exc_value, tb)
|
|
13
|
+
tb_string = "".join(tb_lines)
|
|
14
|
+
|
|
15
|
+
# 2. Pass it through our translation engine
|
|
16
|
+
result = translate_error(tb_string)
|
|
17
|
+
|
|
18
|
+
# 3. Print our beautiful colorized output instead of the ugly default
|
|
19
|
+
print_result(result)
|
|
20
|
+
|
|
21
|
+
# The Magic Trick: Replace Python's default crash handler with ours
|
|
22
22
|
sys.excepthook = magic_hook
|
|
@@ -1,100 +1,106 @@
|
|
|
1
|
-
import sys
|
|
2
|
-
import argparse
|
|
3
|
-
from .core import translate_error
|
|
4
|
-
|
|
5
|
-
# ANSI Color Codes
|
|
6
|
-
class Colors:
|
|
7
|
-
RED = '\033[91m'
|
|
8
|
-
GREEN = '\033[92m'
|
|
9
|
-
YELLOW = '\033[93m'
|
|
10
|
-
CYAN = '\033[96m'
|
|
11
|
-
BOLD = '\033[1m'
|
|
12
|
-
RESET = '\033[0m'
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
print(f"{
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
print(f"{Colors.RESET} |
|
|
24
|
-
print(f"{Colors.RESET}
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
print(f"{
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
print(f"{
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
1
|
+
import sys
|
|
2
|
+
import argparse
|
|
3
|
+
from .core import translate_error
|
|
4
|
+
|
|
5
|
+
# ANSI Color Codes
|
|
6
|
+
class Colors:
|
|
7
|
+
RED = '\033[91m'
|
|
8
|
+
GREEN = '\033[92m'
|
|
9
|
+
YELLOW = '\033[93m'
|
|
10
|
+
CYAN = '\033[96m'
|
|
11
|
+
BOLD = '\033[1m'
|
|
12
|
+
RESET = '\033[0m'
|
|
13
|
+
MAGENTA = '\033[95m'
|
|
14
|
+
|
|
15
|
+
def print_result(result: dict):
|
|
16
|
+
"""Prints the translated error to the terminal with colors."""
|
|
17
|
+
print(f"\n{Colors.RED}{Colors.BOLD} Error Detected:{Colors.RESET}")
|
|
18
|
+
print(f"{result.get('matched_error', 'N/A')}")
|
|
19
|
+
|
|
20
|
+
if "file" in result:
|
|
21
|
+
print(f"{Colors.YELLOW} Location: {result['file']} (Line {result['line']}){Colors.RESET}\n")
|
|
22
|
+
if result.get("code"):
|
|
23
|
+
print(f"{Colors.RESET} |")
|
|
24
|
+
print(f"{Colors.RESET} | {Colors.RED}{result['code']}{Colors.RESET}")
|
|
25
|
+
print(f"{Colors.RESET} |\n")
|
|
26
|
+
else:
|
|
27
|
+
print("\n")
|
|
28
|
+
|
|
29
|
+
else:
|
|
30
|
+
print()
|
|
31
|
+
|
|
32
|
+
print(f"{Colors.CYAN}{Colors.BOLD} Explanation:{Colors.RESET}")
|
|
33
|
+
print(f"{result['explanation']}\n")
|
|
34
|
+
|
|
35
|
+
print(f"{Colors.GREEN}{Colors.BOLD} Suggested Fix:{Colors.RESET}")
|
|
36
|
+
print(f"{result['fix']}\n")
|
|
37
|
+
|
|
38
|
+
if result.get("ast_insight"):
|
|
39
|
+
print(f"{Colors.MAGENTA}{Colors.BOLD} AST Insight:{Colors.RESET}")
|
|
40
|
+
print(f"{result['ast_insight']}\n")
|
|
41
|
+
|
|
42
|
+
def run_script(script_name: str):
|
|
43
|
+
"""Runs a python script in the background and catches its errors."""
|
|
44
|
+
import subprocess
|
|
45
|
+
try:
|
|
46
|
+
# Run the script using the current Python environment
|
|
47
|
+
result = subprocess.run(
|
|
48
|
+
[sys.executable, script_name],
|
|
49
|
+
capture_output=True,
|
|
50
|
+
text=True
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
# If the script ran perfectly (Return Code 0), print standard output
|
|
54
|
+
if result.returncode == 0:
|
|
55
|
+
print(result.stdout, end="")
|
|
56
|
+
|
|
57
|
+
# If the script crashed, print whatever succeeded, THEN translate the error
|
|
58
|
+
else:
|
|
59
|
+
if result.stdout:
|
|
60
|
+
print(result.stdout, end="")
|
|
61
|
+
|
|
62
|
+
translation = translate_error(result.stderr)
|
|
63
|
+
print_result(translation)
|
|
64
|
+
|
|
65
|
+
except FileNotFoundError:
|
|
66
|
+
print(f"{Colors.RED}Error: Could not find script '{script_name}'{Colors.RESET}")
|
|
67
|
+
|
|
68
|
+
# Entry point of the program
|
|
69
|
+
def main():
|
|
70
|
+
parser = argparse.ArgumentParser(
|
|
71
|
+
description="Translate Python error messages into simple English."
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
# Allow multiple arguments so we can accept "run script.py" or a long error string
|
|
75
|
+
parser.add_argument(
|
|
76
|
+
"args",
|
|
77
|
+
nargs="*",
|
|
78
|
+
help="Use 'run <script.py>' to execute a file, or pass an error string."
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
parsed_args = parser.parse_args()
|
|
82
|
+
|
|
83
|
+
# 1. Handle Piped Input (e.g., cat error.log | explain-error)
|
|
84
|
+
if not sys.stdin.isatty():
|
|
85
|
+
error_input = sys.stdin.read()
|
|
86
|
+
if error_input.strip():
|
|
87
|
+
print_result(translate_error(error_input))
|
|
88
|
+
return
|
|
89
|
+
|
|
90
|
+
# 2. Print help if no arguments
|
|
91
|
+
if not parsed_args.args:
|
|
92
|
+
parser.print_help()
|
|
93
|
+
sys.exit(1)
|
|
94
|
+
|
|
95
|
+
# 3. Check if the user used the "run" command
|
|
96
|
+
if parsed_args.args[0] == "run" and len(parsed_args.args) > 1:
|
|
97
|
+
script_name = parsed_args.args[1]
|
|
98
|
+
run_script(script_name)
|
|
99
|
+
|
|
100
|
+
# 4. Fallback: Treat the input as a raw error string
|
|
101
|
+
else:
|
|
102
|
+
error_input = " ".join(parsed_args.args)
|
|
103
|
+
print_result(translate_error(error_input))
|
|
104
|
+
|
|
105
|
+
if __name__ == "__main__":
|
|
100
106
|
main()
|