attrs
attrs copied to clipboard
Question: `make_class` equivalent of the "new API" - defining fields using type annotations
I have been trying to use attr.make_class
to create a class based on type annotations. This is exemplified by the following code:
import attr
import inspect
class Test:
a: int
b: str
aTest = attr.frozen(Test)
sig = inspect.get_annotations(Test)
print(sig) # {"a": int, "b": str}
# fails with AttributeError: type object 'int' has no attribute 'type'
bTest = attr.make_class("Test", sig, frozen=True, on_setattr=True, auto_attribs=True)
The intent were for bTest
to be equivalent to aTest
, but generated programatically. However, that doesn't seem to work. What is the standard way to create an attr class programmatically from type annotations?
import attr import inspect
Define a function to create an attr class from type annotations
def create_attr_class(cls_name, annotations, frozen=True): attr_fields = {} for attr_name, attr_type in annotations.items(): attr_fields[attr_name] = attr.ib(type=attr_type)
return attr.define(cls_name, **attr_fields, frozen=frozen)
Define your class with type annotations
class Test: a: int b: str
Get the annotations from the class
annotations = inspect.get_type_hints(Test)
Create an attr class programmatically
GeneratedTestClass = create_attr_class("GeneratedTest", annotations, frozen=True)
Create instances of the generated class
test_instance = GeneratedTestClass(a=42, b="Hello")
Verify that it's frozen
try: test_instance.a = 10 # This should raise an AttributeError except AttributeError as e: print(e)
Print the instance
print(test_instance)