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
+69
View File
@@ -396,6 +396,68 @@ def typecheck_stubs(versions: list[str] | None = None) -> None:
sys.exit(1)
def conformance_check(versions: list[str] | None = None) -> None:
"""Type-check conformance test files against generated stubs."""
dist_dir = SCRIPT_DIR / "dist"
conformance_dir = SCRIPT_DIR / "conformance"
if not conformance_dir.exists():
print("No conformance/ directory found.")
sys.exit(1)
if versions:
missing = [v for v in versions if not (dist_dir / v).is_dir()]
if missing:
print(f"Missing stubs for: {', '.join(missing)}")
sys.exit(1)
else:
versions = sorted(
d.name
for d in dist_dir.iterdir()
if d.is_dir() and not d.name.startswith(".")
)
if not versions:
print("No generated stubs found in dist/.")
sys.exit(1)
failed = False
for version in versions:
version_dir = dist_dir / version
print(f"=== Conformance check against Blender {version} stubs ===")
python_version_file = version_dir / ".python-version"
python_version = (
python_version_file.read_text().strip()
if python_version_file.exists()
else "3.11"
)
config = version_dir / "pyrightconfig.conformance.json"
config.write_text(
json.dumps(
{
"include": [str(conformance_dir)],
"extraPaths": [str(version_dir)],
"typeCheckingMode": "strict",
"pythonVersion": python_version,
}
)
)
result = subprocess.run(
["basedpyright", "--project", str(config)],
)
config.unlink()
if result.returncode != 0:
failed = True
if failed:
sys.exit(1)
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Blender type stubs generator")
parser.add_argument(
@@ -403,6 +465,11 @@ if __name__ == "__main__":
action="store_true",
help="Type-check generated stubs instead of generating",
)
parser.add_argument(
"--conformance",
action="store_true",
help="Run conformance tests against generated stubs",
)
parser.add_argument(
"versions",
nargs="*",
@@ -412,6 +479,8 @@ if __name__ == "__main__":
if args.typecheck_stubs:
typecheck_stubs(args.versions or None)
elif args.conformance:
conformance_check(args.versions or None)
else:
if not args.versions:
parser.error("versions are required for generation")