mirror of
https://github.com/hanzoai/python-sdk.git
synced 2026-10-23 20:23:00 +00:00
- 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
100 lines
3.0 KiB
Python
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",
|
|
)
|
|
]
|