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:
2026-03-26 17:45:01 +01:00
co-authored by Claude Opus 4.6
parent e4739448c2
commit 9fa2f1c200
5 changed files with 126 additions and 2 deletions
+30 -1
View File
@@ -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,