Compare commits
4 Commits
c062361ef9
...
db069abe83
| Author | SHA1 | Date | |
|---|---|---|---|
| db069abe83 | |||
| 196d9f12f3 | |||
| 866b3f0fe7 | |||
| 87df32c32c |
22
scripts/check_hints.py
Normal file
22
scripts/check_hints.py
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
import re
|
||||||
|
import sys
|
||||||
|
|
||||||
|
files = ['ai_client.py', 'aggregate.py', 'mcp_client.py', 'shell_runner.py']
|
||||||
|
for file_path in files:
|
||||||
|
print(f"Checking {file_path}...")
|
||||||
|
with open(file_path, 'r', encoding='utf-8') as f:
|
||||||
|
lines = f.readlines()
|
||||||
|
for i, line in enumerate(lines):
|
||||||
|
if line.strip().startswith('def '):
|
||||||
|
if '->' not in line:
|
||||||
|
# Check next line if it's a multiline def
|
||||||
|
if '):' not in line:
|
||||||
|
full_def = line
|
||||||
|
j = i + 1
|
||||||
|
while j < len(lines) and '):' not in lines[j-1]:
|
||||||
|
full_def += lines[j]
|
||||||
|
j += 1
|
||||||
|
if '->' not in full_def:
|
||||||
|
print(f" Missing hint at line {i+1}: {line.strip()}")
|
||||||
|
else:
|
||||||
|
print(f" Missing hint at line {i+1}: {line.strip()}")
|
||||||
31
scripts/check_hints_v2.py
Normal file
31
scripts/check_hints_v2.py
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
import re
|
||||||
|
import sys
|
||||||
|
|
||||||
|
files = ['ai_client.py', 'aggregate.py', 'mcp_client.py', 'shell_runner.py']
|
||||||
|
for file_path in files:
|
||||||
|
print(f"Checking {file_path}...")
|
||||||
|
with open(file_path, 'r', encoding='utf-8') as f:
|
||||||
|
content = f.read()
|
||||||
|
# Find all function definitions
|
||||||
|
# This regex is simplified and might miss some edge cases (like multi-line defs)
|
||||||
|
# But it's better than nothing.
|
||||||
|
defs = re.finditer(r'def\s+([a-zA-Z_][a-zA-Z0-9_]*)\s*\((.*?)\)\s*(->\s*.*?)?:', content, re.DOTALL)
|
||||||
|
for m in defs:
|
||||||
|
name = m.group(1)
|
||||||
|
args = m.group(2).strip()
|
||||||
|
ret = m.group(3)
|
||||||
|
|
||||||
|
if not ret:
|
||||||
|
print(f" Missing return type: {name}({args})")
|
||||||
|
|
||||||
|
# Check arguments
|
||||||
|
if args:
|
||||||
|
arg_list = [a.strip() for a in args.split(',')]
|
||||||
|
for arg in arg_list:
|
||||||
|
if not arg or arg == 'self' or arg == 'cls':
|
||||||
|
continue
|
||||||
|
if ':' not in arg and '=' not in arg:
|
||||||
|
print(f" Missing arg type: {name} -> {arg}")
|
||||||
|
elif ':' not in arg and '=' in arg:
|
||||||
|
# arg=val (missing type)
|
||||||
|
print(f" Missing arg type: {name} -> {arg}")
|
||||||
24
scripts/type_hint_scanner.py
Normal file
24
scripts/type_hint_scanner.py
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
import ast
|
||||||
|
import sys
|
||||||
|
|
||||||
|
def get_missing_hints(file_path: str):
|
||||||
|
with open(file_path, "r", encoding="utf-8") as f:
|
||||||
|
tree = ast.parse(f.read())
|
||||||
|
|
||||||
|
missing = []
|
||||||
|
for node in ast.walk(tree):
|
||||||
|
if isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef)):
|
||||||
|
has_return = node.returns is not None
|
||||||
|
args_missing = any(arg.annotation is None for arg in node.args.args if arg.arg != "self")
|
||||||
|
if not has_return or args_missing:
|
||||||
|
missing.append({
|
||||||
|
"name": node.name,
|
||||||
|
"lineno": node.lineno,
|
||||||
|
"col_offset": node.col_offset
|
||||||
|
})
|
||||||
|
return missing
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
if len(sys.argv) > 1:
|
||||||
|
for m in get_missing_hints(sys.argv[1]):
|
||||||
|
print(f"Line {m['lineno']}: {m['name']}")
|
||||||
BIN
test_output.log
BIN
test_output.log
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
tests_sweep.log
BIN
tests_sweep.log
Binary file not shown.
Reference in New Issue
Block a user