auto-code-fixer 0.3.1__tar.gz → 0.3.3__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.
- {auto_code_fixer-0.3.1 → auto_code_fixer-0.3.3}/PKG-INFO +1 -1
- auto_code_fixer-0.3.3/auto_code_fixer/__init__.py +1 -0
- {auto_code_fixer-0.3.1 → auto_code_fixer-0.3.3}/auto_code_fixer/cli.py +44 -7
- {auto_code_fixer-0.3.1 → auto_code_fixer-0.3.3}/auto_code_fixer/traceback_utils.py +13 -3
- {auto_code_fixer-0.3.1 → auto_code_fixer-0.3.3}/auto_code_fixer.egg-info/PKG-INFO +1 -1
- {auto_code_fixer-0.3.1 → auto_code_fixer-0.3.3}/pyproject.toml +1 -1
- auto_code_fixer-0.3.1/auto_code_fixer/__init__.py +0 -1
- {auto_code_fixer-0.3.1 → auto_code_fixer-0.3.3}/LICENSE +0 -0
- {auto_code_fixer-0.3.1 → auto_code_fixer-0.3.3}/README.md +0 -0
- {auto_code_fixer-0.3.1 → auto_code_fixer-0.3.3}/auto_code_fixer/command_runner.py +0 -0
- {auto_code_fixer-0.3.1 → auto_code_fixer-0.3.3}/auto_code_fixer/fixer.py +0 -0
- {auto_code_fixer-0.3.1 → auto_code_fixer-0.3.3}/auto_code_fixer/installer.py +0 -0
- {auto_code_fixer-0.3.1 → auto_code_fixer-0.3.3}/auto_code_fixer/models.py +0 -0
- {auto_code_fixer-0.3.1 → auto_code_fixer-0.3.3}/auto_code_fixer/patcher.py +0 -0
- {auto_code_fixer-0.3.1 → auto_code_fixer-0.3.3}/auto_code_fixer/plan.py +0 -0
- {auto_code_fixer-0.3.1 → auto_code_fixer-0.3.3}/auto_code_fixer/runner.py +0 -0
- {auto_code_fixer-0.3.1 → auto_code_fixer-0.3.3}/auto_code_fixer/sandbox.py +0 -0
- {auto_code_fixer-0.3.1 → auto_code_fixer-0.3.3}/auto_code_fixer/utils.py +0 -0
- {auto_code_fixer-0.3.1 → auto_code_fixer-0.3.3}/auto_code_fixer/venv_manager.py +0 -0
- {auto_code_fixer-0.3.1 → auto_code_fixer-0.3.3}/auto_code_fixer.egg-info/SOURCES.txt +0 -0
- {auto_code_fixer-0.3.1 → auto_code_fixer-0.3.3}/auto_code_fixer.egg-info/dependency_links.txt +0 -0
- {auto_code_fixer-0.3.1 → auto_code_fixer-0.3.3}/auto_code_fixer.egg-info/entry_points.txt +0 -0
- {auto_code_fixer-0.3.1 → auto_code_fixer-0.3.3}/auto_code_fixer.egg-info/requires.txt +0 -0
- {auto_code_fixer-0.3.1 → auto_code_fixer-0.3.3}/auto_code_fixer.egg-info/top_level.txt +0 -0
- {auto_code_fixer-0.3.1 → auto_code_fixer-0.3.3}/setup.cfg +0 -0
- {auto_code_fixer-0.3.1 → auto_code_fixer-0.3.3}/tests/test_fix_imported_file.py +0 -0
- {auto_code_fixer-0.3.1 → auto_code_fixer-0.3.3}/tests/test_internal_imports.py +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.3.3"
|
|
@@ -88,15 +88,43 @@ def fix_file(file_path, project_root, api_key, ask, verbose, *, dry_run: bool, m
|
|
|
88
88
|
if dry_run:
|
|
89
89
|
log("DRY RUN: would apply fixes:\n" + "\n".join(rel_changes), "WARN")
|
|
90
90
|
else:
|
|
91
|
+
sr = os.path.realpath(os.path.abspath(sandbox_root))
|
|
92
|
+
pr = os.path.realpath(os.path.abspath(project_root))
|
|
93
|
+
|
|
91
94
|
for p in sorted(changed_sandbox_files):
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
95
|
+
p_real = os.path.realpath(os.path.abspath(p))
|
|
96
|
+
|
|
97
|
+
# compute rel using real paths to avoid macOS /private path weirdness
|
|
98
|
+
rel = os.path.relpath(p_real, sr)
|
|
99
|
+
|
|
100
|
+
# Safety: never allow paths escaping the sandbox
|
|
101
|
+
if rel.startswith(".." + os.sep) or rel == "..":
|
|
102
|
+
log(f"Skipping suspicious path outside sandbox: {p}", "WARN")
|
|
103
|
+
continue
|
|
104
|
+
|
|
105
|
+
dst = os.path.join(pr, rel)
|
|
106
|
+
dst_real = os.path.realpath(os.path.abspath(dst))
|
|
107
|
+
|
|
108
|
+
# Safety: never write outside the project root
|
|
109
|
+
if not (dst_real.startswith(pr + os.sep) or dst_real == pr):
|
|
110
|
+
log(f"Skipping suspicious destination outside project: {dst}", "WARN")
|
|
111
|
+
continue
|
|
112
|
+
|
|
113
|
+
# Avoid shutil.SameFileError
|
|
114
|
+
try:
|
|
115
|
+
if os.path.exists(dst_real) and os.path.samefile(p_real, dst_real):
|
|
116
|
+
log(f"Skip copy (same file): {dst_real}", "DEBUG")
|
|
117
|
+
continue
|
|
118
|
+
except Exception:
|
|
119
|
+
pass
|
|
120
|
+
|
|
121
|
+
if os.path.exists(dst_real):
|
|
122
|
+
bak = backup_file(dst_real)
|
|
96
123
|
log(f"Backup created: {bak}", "DEBUG")
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
124
|
+
|
|
125
|
+
os.makedirs(os.path.dirname(dst_real), exist_ok=True)
|
|
126
|
+
shutil.copy(p_real, dst_real)
|
|
127
|
+
log(f"File updated: {dst_real}")
|
|
100
128
|
|
|
101
129
|
shutil.rmtree(sandbox_root)
|
|
102
130
|
log(f"Fix completed in {attempt + 1} attempt(s) 🎉")
|
|
@@ -115,6 +143,15 @@ def fix_file(file_path, project_root, api_key, ask, verbose, *, dry_run: bool, m
|
|
|
115
143
|
|
|
116
144
|
target_file = pick_relevant_file(stderr, sandbox_root=sandbox_root) or sandbox_entry
|
|
117
145
|
|
|
146
|
+
# Safety: ensure target_file is within sandbox
|
|
147
|
+
try:
|
|
148
|
+
sr = os.path.realpath(os.path.abspath(sandbox_root))
|
|
149
|
+
tf = os.path.realpath(os.path.abspath(target_file))
|
|
150
|
+
if not (tf.startswith(sr + os.sep) or tf == sr):
|
|
151
|
+
target_file = sandbox_entry
|
|
152
|
+
except Exception:
|
|
153
|
+
target_file = sandbox_entry
|
|
154
|
+
|
|
118
155
|
# Optional AI fix plan can override file selection
|
|
119
156
|
try:
|
|
120
157
|
from auto_code_fixer.plan import ask_ai_for_fix_plan
|
|
@@ -4,24 +4,34 @@ import re
|
|
|
4
4
|
_FILE_RE = re.compile(r"File \"([^\"]+)\", line (\d+)")
|
|
5
5
|
|
|
6
6
|
|
|
7
|
+
def _norm(p: str) -> str:
|
|
8
|
+
"""Normalize paths for comparison.
|
|
9
|
+
|
|
10
|
+
On macOS tracebacks often include /private prefix; realpath handles that.
|
|
11
|
+
"""
|
|
12
|
+
return os.path.realpath(os.path.abspath(p))
|
|
13
|
+
|
|
14
|
+
|
|
7
15
|
def pick_relevant_file(stderr: str, *, sandbox_root: str) -> str | None:
|
|
8
16
|
"""Pick the most relevant python file from a traceback.
|
|
9
17
|
|
|
10
18
|
Strategy: return the last file path that lives inside sandbox_root.
|
|
19
|
+
|
|
20
|
+
Uses realpath() to handle macOS '/private/var/...' vs '/var/...' differences.
|
|
11
21
|
"""
|
|
12
22
|
|
|
13
23
|
if not stderr:
|
|
14
24
|
return None
|
|
15
25
|
|
|
16
|
-
|
|
26
|
+
sandbox_root_n = _norm(sandbox_root)
|
|
17
27
|
matches = _FILE_RE.findall(stderr)
|
|
18
28
|
if not matches:
|
|
19
29
|
return None
|
|
20
30
|
|
|
21
31
|
chosen = None
|
|
22
32
|
for path, _lineno in matches:
|
|
23
|
-
ap =
|
|
24
|
-
if ap.startswith(
|
|
33
|
+
ap = _norm(path)
|
|
34
|
+
if ap.startswith(sandbox_root_n + os.sep) or ap == sandbox_root_n:
|
|
25
35
|
chosen = ap
|
|
26
36
|
|
|
27
37
|
return chosen
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.3.1"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{auto_code_fixer-0.3.1 → auto_code_fixer-0.3.3}/auto_code_fixer.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|