Files
python-sdk/pkg/hanzo-aci/dev_aci/linter/impl/python.py
T
zeekay ea3116aac9 Fix all test issues and achieve 100% test pass rate
- Remove all unconditional pytest.skip() calls
- Fix file content tests to handle both strict/non-strict modes
- Fix missing device_capabilities module in hanzo-network
- Fix HanzoNetProvider imports and exports
- Fix local_llm.py import errors
- Create test helper classes for pagination tests
- Fix FastMCP paginator test constructor args
- Configure all API keys from ~/.zsh/after.zsh
- All tests now pass or skip conditionally based on actual requirements
2025-08-12 16:19:34 -05:00

100 lines
3.0 KiB
Python

from typing import List
from dev_aci.utils.logger import oh_aci_logger as logger
from dev_aci.utils.shell import run_shell_cmd
from ..base import BaseLinter, LintResult
def python_compile_lint(fname: str) -> list[LintResult]:
try:
with open(fname, "r") as f:
code = f.read()
compile(code, fname, "exec") # USE TRACEBACK BELOW HERE
return []
except SyntaxError as err:
err_lineno = getattr(err, "end_lineno", err.lineno)
err_offset = getattr(err, "end_offset", err.offset)
if err_offset and err_offset < 0:
err_offset = err.offset
return [
LintResult(
file=fname, line=err_lineno, column=err_offset or 1, message=err.msg
)
]
def flake_lint(filepath: str) -> list[LintResult]:
fatal = "F821,F822,F831,E112,E113,E999,E902"
flake8_cmd = f"flake8 --select={fatal} --isolated {filepath}"
try:
cmd_outputs = run_shell_cmd(flake8_cmd, truncate_after=None)[1]
except FileNotFoundError:
return []
results: list[LintResult] = []
if not cmd_outputs:
return results
for line in cmd_outputs.splitlines():
parts = line.split(":")
if len(parts) >= 4:
_msg = parts[3].strip()
if len(parts) > 4:
_msg += ": " + parts[4].strip()
try:
line_num = int(parts[1])
except ValueError as e:
logger.warning(
f"Error parsing flake8 output for line: {e}. Parsed parts: {parts}. Skipping..."
)
continue
try:
column_num = int(parts[2])
except ValueError as e:
column_num = 1
_msg = (
parts[2].strip() + " " + _msg
) # add the unparsed message to the original message
logger.warning(
f"Error parsing flake8 output for column: {e}. Parsed parts: {parts}. Using default column 1."
)
results.append(
LintResult(
file=filepath,
line=line_num,
column=column_num,
message=_msg,
)
)
return results
class PythonLinter(BaseLinter):
@property
def supported_extensions(self) -> List[str]:
return [".py"]
def lint(self, file_path: str) -> list[LintResult]:
error = flake_lint(file_path)
if not error:
error = python_compile_lint(file_path)
return error
def compile_lint(self, file_path: str, code: str) -> List[LintResult]:
try:
compile(code, file_path, "exec")
return []
except SyntaxError as e:
return [
LintResult(
file=file_path,
line=e.lineno,
column=e.offset,
message=str(e),
rule="SyntaxError",
)
]