Add conformance tests and fix introspection issues
- Add conformance test framework with poe conformance task - Add test files for mathutils, bpy, and gpu API patterns - Fix self param leaking into signatures from C method_descriptors - Synthesize __iter__ for classes with __getitem__ but no explicit __iter__ - Add __iter__ runtime probing to discover Iterator[element_type] - Add :raises to directive lookahead to fix rtype parsing - Add 5.1 override for Matrix.Translation to accept Vector Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
+30
-1
@@ -959,7 +959,9 @@ def introspect_callable(func: Callable[..., object], name: str) -> FunctionData
|
||||
# C functions often use generic names like "object" in __text_signature__
|
||||
# while docstrings use descriptive names like "string", "cls", etc.
|
||||
doc_param_list = list(param_types.items())
|
||||
sig_param_list = list(sig.parameters.items())
|
||||
sig_param_list = [
|
||||
(n, p) for n, p in sig.parameters.items() if n != "self"
|
||||
]
|
||||
|
||||
params = []
|
||||
for i, (pname, param) in enumerate(sig_param_list):
|
||||
@@ -1223,6 +1225,17 @@ def _fix_dunder_signatures(
|
||||
pass
|
||||
continue
|
||||
|
||||
# __iter__: return Iterator[element_type] based on __getitem__
|
||||
if name == "__iter__":
|
||||
try:
|
||||
result = instance[0]
|
||||
etype = _type_name(result)
|
||||
method["return_type"] = f"Iterator[{etype}]"
|
||||
method["params"] = []
|
||||
except Exception:
|
||||
pass
|
||||
continue
|
||||
|
||||
# __setitem__: refine value type from __getitem__ return type
|
||||
if name == "__setitem__":
|
||||
try:
|
||||
@@ -1381,6 +1394,22 @@ def introspect_class(cls: type[object], module_name: str) -> StructData:
|
||||
if dunder_methods:
|
||||
_fix_dunder_signatures(cls, dunder_methods)
|
||||
|
||||
# Synthesize __iter__ if the class supports iteration via __getitem__
|
||||
# but doesn't define __iter__ explicitly (old-style C iteration protocol).
|
||||
method_names = {m["name"] for m in methods}
|
||||
if "__getitem__" in method_names and "__iter__" not in method_names:
|
||||
getitem = next(m for m in methods if m["name"] == "__getitem__")
|
||||
elem_type = getitem["return_type"] or "object"
|
||||
methods.append(
|
||||
{
|
||||
"name": "__iter__",
|
||||
"doc": "",
|
||||
"params": [],
|
||||
"return_type": f"Iterator[{elem_type}]",
|
||||
"is_classmethod": False,
|
||||
}
|
||||
)
|
||||
|
||||
return {
|
||||
"name": cls.__name__,
|
||||
"doc": class_doc,
|
||||
|
||||
Reference in New Issue
Block a user