Communicating to static analysis tools that a type is dynamically generated and informing them of how (original) (raw)
Hello,
I’m writing a package to generate classes via a mixin/transformer model, (to simplify it, think Pydantic but geared more toward behavior rather than data storage), and I’m running up against the limitations of static tooling and my own incompetence.
I want a reliable way to essentially tell SA “this class has a method named foo
with such and such signature, now” without manually outlining a protocol or abstract base class, as that would serve as a stumbling block in terms of efficiency.
I found, for lack of a better term, a godforsaken hack that works at runtime by generating actual type classes from parameters, but it’s kind of pointless without integration into static analysis tools.
import types
from collections.abc import Callable
from typing import Any, Self
class FakeType(type):
_instancecheck: Callable[[Self, Any], bool]
def __instancecheck__(cls, instance: Any) -> bool:
if cls._instancecheck is None:
raise TypeError(f"{cls.__name__}.__instancecheck__ is None")
return cls._instancecheck(cls, instance)
class HasAttributeMeta(type):
def __getitem__[T](cls, item: tuple[str, type[T]]):
name, type_ = item
type_name = f"HasAttribute_{name}"
def exec_body(ns: dict[str, Any]) -> None:
ns["_instancecheck"] = cls.has_attribute_inst_check(name, type_)
new_type = types.new_class(
type_name,
(),
{"metaclass": FakeType},
exec_body=exec_body
)
return new_type
@classmethod
def has_attribute_inst_check(cls, name: str, type_: type) -> Callable[[Self, Any], bool]:
def _instancecheck(_cls: Self, instance: Any) -> bool:
if not hasattr(instance, name):
return False
return isinstance(getattr(instance, name), type_)
_instancecheck.__name__ = "__instancecheck__"
return _instancecheck
class HasAttribute(metaclass=HasAttributeMeta):
...
I am fully aware that what I’m doing is potentially suboptimal, but I would really like to know how I can make this work, or if I’m missing something.