| 95 | self.blender_panel.draw(self, bpy.context) |
| 96 | |
| 97 | def __getattr__(self, attr: str) -> PanelSpy | Any: |
| 98 | self.spied_attr = attr |
| 99 | try: |
| 100 | annotations = self.blender_panel.__annotations__ |
| 101 | except AttributeError: |
| 102 | annotations = type(self.blender_panel).__annotations__ |
| 103 | if annotation := annotations.get(attr, None): |
| 104 | return annotation.keywords.get("default", None) # An operator property |
| 105 | if attr == "layout": |
| 106 | return self |
| 107 | sentinel = object() |
| 108 | attr_value = getattr(self.blender_panel, attr, sentinel) |
| 109 | # Don't use `callable`, because we might have `Data` classes as panel attributes. |
| 110 | if attr_value is not sentinel and not isinstance(attr_value, types.FunctionType): |
| 111 | return attr_value |
| 112 | return self |
| 113 | |
| 114 | def __call__(self, *args: Any, **kwargs: Any) -> PanelSpy | TemplateListSpy | OperatorSpy | Any: |
| 115 | if self.spied_attr in ("row", "column", "box", "separator", "menu", "operator_menu_enum", "split"): |