Use @property/@setter for writable mathutils properties
Writable mathutils properties (Vector, Euler, etc.) were typed as plain attributes with a union type, causing the getter to also return the union. This made `obj.location.x` fail type checking since Sequence[float] has no `.x`. Now these properties use @property for the getter (returning the concrete mathutils type) and @setter accepting the wider union. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
+27
-9
@@ -89,6 +89,9 @@ def collect_all_type_strings(module_data: ModuleData) -> list[str]:
|
||||
all_types.append(base)
|
||||
for prop in struct["properties"]:
|
||||
all_types.append(prop["type"])
|
||||
setter_type = prop.get("setter_type")
|
||||
if setter_type:
|
||||
all_types.append(setter_type)
|
||||
for method in struct["methods"]:
|
||||
for param in method["params"]:
|
||||
if param["type"]:
|
||||
@@ -367,7 +370,9 @@ def generate_property_stub(
|
||||
property_decorator: str = "@property",
|
||||
) -> str:
|
||||
"""Generate a stub for a class property."""
|
||||
if prop["is_readonly"]:
|
||||
setter_type = prop.get("setter_type")
|
||||
|
||||
if prop["is_readonly"] or setter_type:
|
||||
result = f"{indent}{property_decorator}\n"
|
||||
result += f"{indent}def {prop['name']}(self) -> {prop['type']}:\n"
|
||||
if prop["description"]:
|
||||
@@ -377,6 +382,11 @@ def generate_property_stub(
|
||||
result += f'{indent} """{desc}"""\n'
|
||||
else:
|
||||
result += f"{indent} ...\n"
|
||||
if setter_type:
|
||||
result += f"\n{indent}@{prop['name']}.setter\n"
|
||||
result += (
|
||||
f"{indent}def {prop['name']}(self, value: {setter_type}) -> None: ...\n"
|
||||
)
|
||||
return result
|
||||
|
||||
result = f"{indent}{prop['name']}: {prop['type']}\n"
|
||||
@@ -413,6 +423,7 @@ def fixup_shadowed_builtins(
|
||||
fixed: list[PropertyData] = []
|
||||
for prop in properties:
|
||||
new_type = prop["type"]
|
||||
new_setter_type = prop.get("setter_type")
|
||||
for name in shadowed:
|
||||
# Replace bare builtin type references with builtins.X
|
||||
# e.g. "int" -> "builtins.int", "list[int]" -> "list[builtins.int]"
|
||||
@@ -421,14 +432,21 @@ def fixup_shadowed_builtins(
|
||||
f"builtins.{name}",
|
||||
new_type,
|
||||
)
|
||||
fixed.append(
|
||||
{
|
||||
"name": prop["name"],
|
||||
"type": new_type,
|
||||
"is_readonly": prop["is_readonly"],
|
||||
"description": prop["description"],
|
||||
}
|
||||
)
|
||||
if new_setter_type:
|
||||
new_setter_type = re.sub(
|
||||
rf"\b{name}\b",
|
||||
f"builtins.{name}",
|
||||
new_setter_type,
|
||||
)
|
||||
new_prop: PropertyData = {
|
||||
"name": prop["name"],
|
||||
"type": new_type,
|
||||
"is_readonly": prop["is_readonly"],
|
||||
"description": prop["description"],
|
||||
}
|
||||
if new_setter_type:
|
||||
new_prop["setter_type"] = new_setter_type
|
||||
fixed.append(new_prop)
|
||||
return fixed
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user