Fix all typecheck errors in source code

- Fix partially unknown types from empty set() literals with annotations
- Use getattr-based indexing for runtime probes on object-typed instances
- Fix val_type annotation for hidden type discovery
- Use raw_type string check instead of isinstance for classmethod detection
- Access classmethod.__func__ via getattr to avoid partial unknown types
- Fix struct base type narrowing in collect_all_type_strings

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-30 17:29:40 +02:00
co-authored by Claude Opus 4.6
parent b4158d8ca2
commit cfcb66620a
2 changed files with 34 additions and 33 deletions
+27 -24
View File
@@ -333,9 +333,7 @@ def clean_type_str(type_str: str) -> str:
type_str = type_str.rstrip(":.,")
# Convert "string in ['X', 'Y', ...]" to Literal["X", "Y", ...]
str_in_match = re.match(
r"str(?:ing)?\s+in\s+\[([^\]]+)\]", type_str, re.IGNORECASE
)
str_in_match = re.match(r"str(?:ing)?\s+in\s+\[([^\]]+)\]", type_str, re.IGNORECASE)
if str_in_match:
values = re.findall(r"'([^']+)'", str_in_match.group(1))
if values:
@@ -495,9 +493,7 @@ def clean_type_str(type_str: str) -> str:
# Use \b on both sides to avoid matching inside longer names (e.g. SequenceEntry).
type_str = re.sub(r"\bCallable\b(?!\[)", "Callable[..., object]", type_str)
# Fix Callable[[..., ...], X] or Callable[[object, ...], X] -> Callable[..., X]
type_str = re.sub(
r"Callable\[\[[^\]]*\.\.\.[^\]]*\]", "Callable[...", type_str
)
type_str = re.sub(r"Callable\[\[[^\]]*\.\.\.[^\]]*\]", "Callable[...", type_str)
type_str = re.sub(r"\bdict\b(?!\[)", "dict[str, object]", type_str)
type_str = re.sub(r"\blist\b(?!\[)", "list[object]", type_str)
type_str = re.sub(r"\btuple\b(?!\[)", "tuple[object, ...]", type_str)
@@ -1293,7 +1289,8 @@ def _fix_dunder_signatures(
# __getitem__: probe with int index to discover element type
if name == "__getitem__":
try:
result = instance[0]
getitem = getattr(instance, "__getitem__")
result = getitem(0)
rtype = _type_name(result)
method["return_type"] = rtype
method["params"] = [
@@ -1311,7 +1308,8 @@ def _fix_dunder_signatures(
# __iter__: return Iterator[element_type] based on __getitem__
if name == "__iter__":
try:
result = instance[0]
getitem = getattr(instance, "__getitem__")
result = getitem(0)
etype = _type_name(result)
method["return_type"] = f"Iterator[{etype}]"
method["params"] = []
@@ -1322,7 +1320,8 @@ def _fix_dunder_signatures(
# __setitem__: refine value type from __getitem__ return type
if name == "__setitem__":
try:
result = instance[0]
getitem = getattr(instance, "__getitem__")
result = getitem(0)
vtype = _type_name(result)
method["params"] = [
{
@@ -1839,13 +1838,13 @@ def introspect_module(module_name: str) -> ModuleData:
val = getattr(instance, prop["name"])
except Exception:
continue
val_type = type(val)
val_name = val_type.__name__
val_cls = val.__class__
val_name = val_cls.__name__
if hasattr(_builtins_mod, val_name) or val_name in _SKIP_PROP_TYPES:
continue
# Add the hidden type if not already known
if val_name not in known_struct_names:
hidden_struct = introspect_class(val_type, module_name)
hidden_struct = introspect_class(val_cls, module_name)
# Fix dunders using the live instance (since the type
# may not be directly constructible)
dunder_methods = [
@@ -2512,23 +2511,27 @@ def introspect_rna_types() -> ModuleData:
raw_type = type(raw).__name__
# Only pick up C-level methods, not Python-defined ones.
# classmethod wrapping a builtin is C-level (e.g. Space.draw_handler_add)
is_c_classmethod = raw_type == "classmethod_descriptor" or (
isinstance(raw, classmethod)
and not hasattr(getattr(raw, "__func__", None), "__code__")
)
is_c_classmethod = raw_type == "classmethod_descriptor"
if not is_c_classmethod and raw_type == "classmethod":
# classmethod wrapping a builtin (e.g. Space.draw_handler_add)
inner = getattr(raw, "__func__", None)
is_c_classmethod = inner is not None and not hasattr(inner, "__code__")
if is_c_classmethod:
obj = getattr(cls, attr_name)
func_data = introspect_callable(obj, attr_name)
if func_data:
func_data["is_classmethod"] = True
struct["methods"].append(func_data)
bound = getattr(cls, attr_name)
if callable(bound):
func_data = introspect_callable(bound, attr_name)
if func_data:
func_data["is_classmethod"] = True
struct["methods"].append(func_data)
elif raw_type in (
"method_descriptor",
"builtin_function_or_method",
):
func_data = introspect_callable(raw, attr_name)
if func_data:
struct["methods"].append(func_data)
obj = getattr(cls, attr_name)
if callable(obj):
func_data = introspect_callable(obj, attr_name)
if func_data:
struct["methods"].append(func_data)
return {
"module": "bpy.types",