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)