Add overrides to all versions and fix 4.3 temp_override hang

- Copy gpu.state, bpy.path, gpu.types overrides to 4.0-4.5
- Add bpy.msgbus override for 4.5
- Skip temp_override probe on Blender < 4.4 (hangs on 4.3)
- Fix _is_getset_writable to use docstring hints instead of __set__ probe

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Joseph HENRY 2026-04-02 10:41:25 +02:00
parent a6f70f776f
commit fe6deadfc7
19 changed files with 237 additions and 23 deletions

View File

@ -1433,25 +1433,15 @@ def _fix_dunder_signatures(
def _is_getset_writable(cls: type[object], attr_name: str) -> bool: def _is_getset_writable(cls: type[object], attr_name: str) -> bool:
"""Test if a C getset_descriptor property is writable. """Test if a C getset_descriptor property is writable.
C getset_descriptors that have a setter implement __set__. We check the docstring for "(read-only)" or "(readonly)" hints.
Those without a setter raise AttributeError on __set__ calls. If no hint is found, assume writable (most C getset_descriptors are).
We test this by checking if __set__ raises on a dummy call.
""" """
descriptor = cls.__dict__.get(attr_name) descriptor = cls.__dict__.get(attr_name)
if descriptor is None: if descriptor is None:
return False return False
# If the descriptor doesn't implement __set__ at all, it's read-only doc = getattr(descriptor, "__doc__", "") or ""
if not hasattr(descriptor, "__set__"): if "read-only" in doc.lower() or "readonly" in doc.lower():
return False return False
# Try calling __set__ with None — a writable descriptor will attempt
# the set (and fail on None), while a read-only one raises AttributeError
try:
descriptor.__set__(None, None)
except AttributeError:
return False
except Exception:
# Any other error means __set__ exists (it just didn't like our args)
return True
return True return True
@ -2720,20 +2710,22 @@ def introspect_rna_types() -> ModuleData:
known = {s["name"] for s in structs} known = {s["name"] for s in structs}
bpy = importlib.import_module("bpy") bpy = importlib.import_module("bpy")
ctx = getattr(bpy, "context") ctx = getattr(bpy, "context")
_HIDDEN_TYPE_PROBES: list[tuple[object, str]] = [ # Probe temp_override to discover ContextTempOverride.
(ctx, "temp_override"), # Skip on Blender < 4.4 where this call hangs.
] bpy_app = importlib.import_module("bpy.app")
for obj, method_name in _HIDDEN_TYPE_PROBES: blender_version: tuple[int, ...] = getattr(bpy_app, "version", (0, 0, 0))
func = getattr(obj, method_name, None) temp_override = ctx.__class__.__dict__.get("temp_override")
if func is None or not callable(func): if (
continue temp_override is not None
and type(temp_override).__name__ == "method_descriptor"
and blender_version >= (4, 4, 0)
):
try: try:
result = func() result = ctx.temp_override()
result_cls = result.__class__ result_cls = result.__class__
if result_cls.__name__ not in known: if result_cls.__name__ not in known:
structs.append(introspect_class(result_cls, "bpy.types")) structs.append(introspect_class(result_cls, "bpy.types"))
known.add(result_cls.__name__) known.add(result_cls.__name__)
# Clean up context manager if applicable
exit_fn = getattr(result, "__exit__", None) exit_fn = getattr(result, "__exit__", None)
if exit_fn is not None: if exit_fn is not None:
exit_fn(None, None, None) exit_fn(None, None, None)

View File

@ -0,0 +1,22 @@
{
"abspath": {
"params": {
"path": "str | bytes"
}
},
"basename": {
"params": {
"path": "str | bytes"
}
},
"is_subdir": {
"params": {
"directory": "str | bytes"
}
},
"native_pathsep": {
"params": {
"path": "str | bytes"
}
}
}

View File

@ -0,0 +1,8 @@
{
"active_framebuffer_get": {
"return_type": "gpu.types.GPUFrameBuffer"
},
"viewport_get": {
"return_type": "tuple[int, int, int, int]"
}
}

View File

@ -0,0 +1,7 @@
{
"GPUShader.uniform_float": {
"params": {
"value": "float | int | Sequence[float] | mathutils.Matrix | mathutils.Vector | mathutils.Euler | mathutils.Quaternion | mathutils.Color"
}
}
}

View File

@ -0,0 +1,22 @@
{
"abspath": {
"params": {
"path": "str | bytes"
}
},
"basename": {
"params": {
"path": "str | bytes"
}
},
"is_subdir": {
"params": {
"directory": "str | bytes"
}
},
"native_pathsep": {
"params": {
"path": "str | bytes"
}
}
}

View File

@ -0,0 +1,8 @@
{
"active_framebuffer_get": {
"return_type": "gpu.types.GPUFrameBuffer"
},
"viewport_get": {
"return_type": "tuple[int, int, int, int]"
}
}

View File

@ -0,0 +1,7 @@
{
"GPUShader.uniform_float": {
"params": {
"value": "float | int | Sequence[float] | mathutils.Matrix | mathutils.Vector | mathutils.Euler | mathutils.Quaternion | mathutils.Color"
}
}
}

View File

@ -0,0 +1,22 @@
{
"abspath": {
"params": {
"path": "str | bytes"
}
},
"basename": {
"params": {
"path": "str | bytes"
}
},
"is_subdir": {
"params": {
"directory": "str | bytes"
}
},
"native_pathsep": {
"params": {
"path": "str | bytes"
}
}
}

View File

@ -0,0 +1,8 @@
{
"active_framebuffer_get": {
"return_type": "gpu.types.GPUFrameBuffer"
},
"viewport_get": {
"return_type": "tuple[int, int, int, int]"
}
}

View File

@ -0,0 +1,7 @@
{
"GPUShader.uniform_float": {
"params": {
"value": "float | int | Sequence[float] | mathutils.Matrix | mathutils.Vector | mathutils.Euler | mathutils.Quaternion | mathutils.Color"
}
}
}

View File

@ -0,0 +1,22 @@
{
"abspath": {
"params": {
"path": "str | bytes"
}
},
"basename": {
"params": {
"path": "str | bytes"
}
},
"is_subdir": {
"params": {
"directory": "str | bytes"
}
},
"native_pathsep": {
"params": {
"path": "str | bytes"
}
}
}

View File

@ -0,0 +1,8 @@
{
"active_framebuffer_get": {
"return_type": "gpu.types.GPUFrameBuffer"
},
"viewport_get": {
"return_type": "tuple[int, int, int, int]"
}
}

View File

@ -0,0 +1,7 @@
{
"GPUShader.uniform_float": {
"params": {
"value": "float | int | Sequence[float] | mathutils.Matrix | mathutils.Vector | mathutils.Euler | mathutils.Quaternion | mathutils.Color"
}
}
}

View File

@ -0,0 +1,22 @@
{
"abspath": {
"params": {
"path": "str | bytes"
}
},
"basename": {
"params": {
"path": "str | bytes"
}
},
"is_subdir": {
"params": {
"directory": "str | bytes"
}
},
"native_pathsep": {
"params": {
"path": "str | bytes"
}
}
}

View File

@ -0,0 +1,8 @@
{
"active_framebuffer_get": {
"return_type": "gpu.types.GPUFrameBuffer"
},
"viewport_get": {
"return_type": "tuple[int, int, int, int]"
}
}

View File

@ -0,0 +1,7 @@
{
"GPUShader.uniform_float": {
"params": {
"value": "float | int | Sequence[float] | mathutils.Matrix | mathutils.Vector | mathutils.Euler | mathutils.Quaternion | mathutils.Color"
}
}
}

View File

@ -0,0 +1,22 @@
{
"abspath": {
"params": {
"path": "str | bytes"
}
},
"basename": {
"params": {
"path": "str | bytes"
}
},
"is_subdir": {
"params": {
"directory": "str | bytes"
}
},
"native_pathsep": {
"params": {
"path": "str | bytes"
}
}
}

View File

@ -0,0 +1,8 @@
{
"active_framebuffer_get": {
"return_type": "gpu.types.GPUFrameBuffer"
},
"viewport_get": {
"return_type": "tuple[int, int, int, int]"
}
}

View File

@ -0,0 +1,7 @@
{
"GPUShader.uniform_float": {
"params": {
"value": "float | int | Sequence[float] | mathutils.Matrix | mathutils.Vector | mathutils.Euler | mathutils.Quaternion | mathutils.Color"
}
}
}