### Post-Initialization Attribute Setup with attrs Source: https://github.com/fahreddinozcan/attrs/blob/main/docs/init.md Demonstrates how to use the __attrs_post_init__ method to set attributes after a class instance has been initialized. This is useful for attributes that depend on other initialized attributes or have complex initialization logic. It shows a basic example and how to handle frozen classes. ```python from attrs import define, field, frozen @define class C: x: int y: int = field(init=False) def __attrs_post_init__(self): self.y = self.x + 1 @frozen class FrozenBroken: x: int y: int = field(init=False) def __attrs_post_init__(self): self.y = self.x + 1 @frozen class Frozen: x: int y: int = field(init=False) def __attrs_post_init__(self): object.__setattr__(self, "y", self.x + 1) ``` -------------------------------- ### Decorate an Existing Class with attrs Fields Source: https://github.com/fahreddinozcan/attrs/blob/main/docs/examples.md Demonstrates how to use `attrs.define` as a decorator on an existing class to add fields. This is useful for enhancing classes that are not defined by attrs itself. ```python class SomethingFromSomeoneElse: def __init__(self, x): self.x = x SomethingFromSomeoneElse = define( these={ "x": field() }, init=False )(SomethingFromSomeoneElse) # Example usage: print(SomethingFromSomeoneElse(1)) ``` -------------------------------- ### Programmatically Creating Classes with attrs.make_class Source: https://github.com/fahreddinozcan/attrs/blob/main/docs/examples.md Shows how to dynamically create classes using `attrs.make_class`. This function allows defining class attributes and arguments similar to `@attrs.define`. It's useful when class structure is determined at runtime. ```python from attrs import make_class, define, field, fields @define class C1: x = field(type=int) y = field() C2 = make_class("C2", {"x": field(type=int), "y": field()}) print(fields(C1) == fields(C2)) print(fields(C2).x.type) ``` ```python from attrs import make_class, define, field, Factory C = make_class("C", {"x": field(default=42), "y": field(default=Factory(list))}, repr=False) i = C() print(i) print(i.x) print(i.y) ``` ```python from attrs import make_class class D: def __eq__(self, other): return True C = make_class("C", {{}}, bases=(D,), cmp=False) print(isinstance(C(), D)) ``` -------------------------------- ### Customizing Initialization with __attrs_post_init__ in attrs Source: https://github.com/fahreddinozcan/attrs/blob/main/docs/examples.md Explains how to add custom logic to the end of the generated `__init__` method in attrs classes by defining `__attrs_post_init__`. This method is called after standard initialization and validation. ```python from attrs import define, field @define class C: x: int y: int z: int = field(init=False) def __attrs_post_init__(self): self.z = self.x + self.y obj = C(x=1, y=2) print(obj) ``` -------------------------------- ### Registering Classes Implementing an Interface with attrs Source: https://github.com/fahreddinozcan/attrs/blob/main/docs/examples.md Demonstrates how to create a registry of classes that implement a specific interface using a class decorator. This pattern is useful for plugin systems. It relies on `__attrs_init_subclass__` hook provided by attrs. ```python REGISTRY = [] class Base: @classmethod def __attrs_init_subclass__(cls): REGISTRY.append(cls) from attrs import define, field @define class Impl(Base): pass print(REGISTRY) ``` -------------------------------- ### Creating Immutable Classes with `frozen` Source: https://github.com/fahreddinozcan/attrs/blob/main/docs/examples.md Defines classes where instances cannot be modified after initialization, providing a form of immutability. This is useful for configuration objects or any data that should remain constant. ```python >>> from attrs import frozen >>> @frozen ... class C: ... x: int >>> i = C(1) >>> i.x = 2 Traceback (most recent call last): ... attrs.exceptions.FrozenInstanceError: can't set attribute >>> i.x 1 ``` -------------------------------- ### Define a Class with an Initialized Private Attribute using attrs Source: https://github.com/fahreddinozcan/attrs/blob/main/docs/examples.md Shows how to define a private attribute with `init=False` and a default value. This prevents the attribute from being passed during initialization, and it's initialized with its default value. ```python @define class C: _x: int = field(init=False, default=42) # Example usage: print(C()) # Calling C(23) would raise a TypeError ``` -------------------------------- ### Define an Empty Class with attrs Source: https://github.com/fahreddinozcan/attrs/blob/main/docs/examples.md Demonstrates the simplest usage of attrs to define an empty class. This showcases that attrs is useful even without explicitly defined fields, providing default `__init__` and comparison methods. ```python from attrs import define, field @define class Empty: pass # Example usage: print(Empty()) print(Empty() == Empty()) print(Empty() is Empty()) ``` -------------------------------- ### Define a Class with a Private Attribute using attrs Source: https://github.com/fahreddinozcan/attrs/blob/main/docs/examples.md Demonstrates how attrs handles private attributes (prefixed with an underscore). By default, attrs strips leading underscores for keyword arguments in the generated `__init__` method. ```python @define class C: _x: int # Example usage: print(C(x=1)) ``` -------------------------------- ### Define a Class with Integer Fields using attrs Source: https://github.com/fahreddinozcan/attrs/blob/main/docs/examples.md Shows how to define a class with typed integer fields 'x' and 'y' using attrs. This automatically generates a `__repr__` string and comparison methods, allowing both positional and keyword argument initialization. ```python @define class Coordinates: x: int y: int # Example usage: c1 = Coordinates(1, 2) print(c1) c2 = Coordinates(x=2, y=1) print(c2) print(c1 == c2) ``` -------------------------------- ### Define a Class with a Private Attribute Alias using attrs Source: https://github.com/fahreddinozcan/attrs/blob/main/docs/examples.md Illustrates using `field(alias=...)` to provide an alias for a private attribute. This allows initializing the private attribute using its alias as a keyword argument. ```python @define class C: _x: int = field(alias="_x") # Example usage: print(C(_x=1)) ``` -------------------------------- ### Defining Slotted Classes Source: https://github.com/fahreddinozcan/attrs/blob/main/docs/examples.md Creates classes that use `__slots__` for memory efficiency on CPython. This is achieved by using `attrs.define` (which sets `slots=True` by default) or by explicitly passing `slots=True` to `attr.s`. ```python >>> @define ... class Coordinates: ... x: int ... y: int ``` ```python >>> import attr >>> @attr.s(slots=True) ... class Coordinates: ... x: int ... y: int ``` -------------------------------- ### Attrs Converter with Validator Example (Python) Source: https://github.com/fahreddinozcan/attrs/blob/main/docs/init.md Shows how to combine an attrs field converter with a validator. The converter normalizes the input (e.g., to an integer), and the validator then checks the normalized value against business logic. ```python import attrs from attrs import define, field def validate_x(instance, attribute, value): if value < 0: raise ValueError("x must be at least 0.") @define class C: x = field(converter=int, validator=validate_x) o = C("0") print(o.x) try: C("-1") except ValueError as e: print(e) ``` -------------------------------- ### Excluding Attributes from Methods using attrs fields Source: https://github.com/fahreddinozcan/attrs/blob/main/docs/examples.md Demonstrates how to exclude specific attributes from methods like `__repr__` by setting the `repr` argument to `False` for the respective field. This allows for fine-grained control over generated method output. ```python from attrs import define, field @define class C: user: str password: str = field(repr=False) print(C("me", "s3kr3t")) ``` -------------------------------- ### Attrs Field Converter Example (Python) Source: https://github.com/fahreddinozcan/attrs/blob/main/docs/init.md Demonstrates how to use the 'converter' argument in attrs.field to automatically convert incoming values to the desired type. Converters are executed before validators, allowing for normalization before validation. ```python import attrs from attrs import define, field @define class C: x = field(converter=int) o = C("1") print(o.x) o.x = "2" print(o.x) ``` -------------------------------- ### Accessing Attribute Metadata in Python Source: https://github.com/fahreddinozcan/attrs/blob/main/docs/examples.md Demonstrates how to attach and retrieve arbitrary metadata associated with an attribute. Metadata is stored as a read-only dictionary and can be accessed via `attrs.fields(YourClass).attribute_name.metadata`. It's intended for third-party library integration. ```python from attrs import define, field, fields @define class C: x = field(metadata={'my_metadata': 1}) # Example Usage: # print(fields(C).x.metadata) # Output: mappingproxy({'my_metadata': 1}) # print(fields(C).x.metadata['my_metadata']) # Output: 1 ``` -------------------------------- ### Evolving Immutable Instances with `evolve` Source: https://github.com/fahreddinozcan/attrs/blob/main/docs/examples.md Creates a new instance of a frozen class with specified attributes changed, mimicking Clojure's `assoc` function. This allows for functional-style updates to immutable data structures without direct mutation. ```python >>> from attrs import evolve, frozen >>> @frozen ... class C: ... x: int ... y: int >>> i1 = C(1, 2) >>> i1 C(x=1, y=2) >>> i2 = evolve(i1, y=3) >>> i2 C(x=1, y=3) >>> i1 == i2 False ``` -------------------------------- ### Combined Validation Approaches in Python Source: https://github.com/fahreddinozcan/attrs/blob/main/docs/examples.md Illustrates using both a decorator and a callable validator for the same attribute. This allows for multi-faceted validation, such as type checking and custom range checks. The validator functions receive the instance, attribute, and value. ```python from attrs import define, field, validators @define class C: x: int = field(validator=validators.instance_of(int)) @x.validator def fits_byte(self, attribute, value): if not 0 <= value < 256: raise ValueError("value out of bounds") # Example Usage: # C(128) # Valid # C("128") # Raises TypeError # C(256) # Raises ValueError ``` -------------------------------- ### Customizing Attribute Representation in attrs __repr__ Source: https://github.com/fahreddinozcan/attrs/blob/main/docs/examples.md Shows how to provide a custom callable (like a lambda function) to the `repr` argument of `attrs.field` to control how a specific attribute is represented in the generated `__repr__` method. This allows for more flexible output formatting. ```python from attrs import define, field @define class C: user: str password: str = field(repr=lambda value: '***') print(C("me", "s3kr3t")) ``` -------------------------------- ### Attrs Custom __init__ with __attrs_init__ Example (Python) Source: https://github.com/fahreddinozcan/attrs/blob/main/docs/init.md Demonstrates how to provide a custom `__init__` method and call `self.__attrs_init__(...)` to leverage attrs' generated initialization logic. This is useful for adding default values or performing logic before attrs sets attributes. ```python import attrs from attrs import define @define class C: x: int def __init__(self, x: int = 42): # Call the attrs-generated initialization logic self.__attrs_init__(x) # Example usage: o = C() print(o) o2 = C(10) print(o2) ``` -------------------------------- ### Define Subclassed Classes with Multiple Inheritance using attrs Source: https://github.com/fahreddinozcan/attrs/blob/main/docs/examples.md Shows how attrs handles multiple inheritance. When `slots=False`, attrs supports multiple inheritance, generating `__init__` and comparison methods correctly based on the Method Resolution Order (MRO). ```python @define(slots=False) class A: a: int def get_a(self): return self.a @define(slots=False) class B: b: int @define(slots=False) class C(B, A): c: int # Example usage: i = C(1, 2, 3) print(i) print(i == C(1, 2, 3)) print(i.get_a()) ``` -------------------------------- ### Python: Define Keyword-Only Attributes with attrs Source: https://github.com/fahreddinozcan/attrs/blob/main/docs/examples.md Demonstrates how to define keyword-only attributes using `attrs.define` and `attrs.field(kw_only=True)`. Keyword-only arguments enforce that these attributes must be passed by keyword during instantiation, improving clarity and preventing ordering issues, especially in subclassing scenarios. ```python from attrs import define, field @define class A: a: int = field(kw_only=True) # Example usage: # A() # Raises TypeError: missing 1 required keyword-only argument: 'a' # A(a=1) # Creates an instance A(a=1) @define(kw_only=True) class B: a: int b: int # Example usage: # B(1, 2) # Raises TypeError: __init__() takes 1 positional argument but 3 were given # B(a=1, b=2) # Creates an instance B(a=1, b=2) @define class A_base: a: int = 0 @define class B_sub(A_base): b: int = field(kw_only=True) # Example usage: # B_sub(b=1) # Creates an instance B(a=0, b=1) # B_sub() # Raises TypeError: missing 1 required keyword-only argument: 'b' @define class A_err: a: int = 0 @define class B_err(A_err): b: int # This will raise ValueError due to ordering # Example usage: # Raises ValueError: No mandatory attributes allowed after an attribute with a default value or factory. ``` -------------------------------- ### Attribute Conversion with `converter` in Python Source: https://github.com/fahreddinozcan/attrs/blob/main/docs/examples.md Shows how to use the `converter` argument in `attrs.field` to automatically transform attribute values. The specified callable (e.g., `int`) is applied to the value upon initialization and attribute setting. This is useful for type coercion. ```python from attrs import define, field @define class C: x: int = field(converter=int) # Example Usage: o = C("1") print(o.x) # Output: 1 o.x = "2" print(o.x) # Output: 2 ``` -------------------------------- ### Use Factory for Default Collections in attrs Source: https://github.com/fahreddinozcan/attrs/blob/main/docs/examples.md Demonstrates using `attrs.Factory` to provide a default mutable object, `collections.deque`, for an attribute in `ConnectionPool`. This prevents shared default mutable objects across instances. It also shows how to use a class method to create instances and manage a pool of connections. ```python >>> import collections >>> @define ... class Connection: ... socket: int ... @classmethod ... def connect(cls, db_string): ... # ... connect somehow to db_string ... ... return cls(socket=42) >>> @define ... class ConnectionPool: ... db_string: str ... pool: collections.deque = Factory(collections.deque) ... debug: bool = False ... def get_connection(self): ... try: ... return self.pool.pop() ... except IndexError: ... if self.debug: ... print("New connection!") ... return Connection.connect(self.db_string) ... def free_connection(self, conn): ... if self.debug: ... print("Connection returned!") ... self.pool.appendleft(conn) ... >>> cp = ConnectionPool("postgres://localhost") >>> cp ConnectionPool(db_string='postgres://localhost', pool=deque([]), debug=False) >>> conn = cp.get_connection() >>> conn Connection(socket=42) >>> cp.free_connection(conn) >>> cp ConnectionPool(db_string='postgres://localhost', pool=deque([Connection(socket=42)]), debug=False) ``` -------------------------------- ### Python: Convert attrs Class to Dictionary with asdict Source: https://github.com/fahreddinozcan/attrs/blob/main/docs/examples.md Shows how to convert an attrs class instance into a dictionary using `attrs.asdict`. It demonstrates basic conversion and how to use a filter function to exclude specific attributes based on name or type, useful for serialization or selective data processing. ```python from attrs import define, asdict, fields, filters @define class Coordinates: x: int y: int coords = Coordinates(x=1, y=2) print(asdict(coords)) # Output: {'x': 1, 'y': 2} @define class User: email: str password: str @define class UserList: users: list[User] user_list = UserList([User("jane@doe.invalid", "s33kred"), User("joe@doe.invalid", "p4ssw0rd")]) # Exclude password field using a lambda filter print(asdict(user_list, filter=lambda attr, value: attr.name != "password")) # Output: {'users': [{'email': 'jane@doe.invalid'}, {'email': 'joe@doe.invalid'}]} @define class UserComplex: login: str password: str email: str id: int user = UserComplex("jane", "s33kred", "jane@example.com", 42) # Exclude specific fields ('password', 'email') and type (int) print(asdict(user, filter=filters.exclude(fields(UserComplex).password, "email", int))) # Output: {'login': 'jane'} @define class C: x: str y: str z: int c_instance = C("foo", "2", 3) # Include specific types (int) and fields ('x') print(asdict(c_instance, filter=filters.include(int, fields(C).x))) # Output: {'x': 'foo', 'z': 3} # Include specific fields ('x') and type ('z' implicitly as int) print(asdict(c_instance, filter=filters.include(fields(C).x, "z"))) # Output: {'x': 'foo', 'z': 3} # Example demonstrating AttributeError with non-existent field name try: asdict(user, filter=fields(UserComplex).passwd) except AttributeError as e: print(e) # Output: 'UserAttributes' object has no attribute 'passwd'. Did you mean: 'password'? # Example of silent failure with string exclusion for non-existent field print(asdict(user, filter=filters.exclude("passwd"))) # Output: {'login': 'jane', 'password': 's33kred', 'email': 'jane@example.com', 'id': 42} ``` -------------------------------- ### Pyright Decorator Wrapping with dataclass_transform Source: https://github.com/fahreddinozcan/attrs/blob/main/docs/extending.md Illustrates how to support generic decorator wrapping in Pyright using `typing.dataclass_transform`. This example shows a custom `custom_define` decorator that wraps `attrs.define` and specifies `attr.attrib` and `attrs.field` as field specifiers. ```python import typing import attr import attrs @typing.dataclass_transform(field_specifiers=(attr.attrib, attrs.field)) def custom_define(f): return attrs.define(f) ``` -------------------------------- ### Callable Attribute Validation in Python Source: https://github.com/fahreddinozcan/attrs/blob/main/docs/examples.md Shows how to use a callable function as a validator for an attribute. Multiple validators, including built-in ones like instance_of and custom callables, can be provided in a list. The validator function receives the instance, attribute, and value. ```python from attrs import define, field, validators def x_smaller_than_y(instance, attribute, value): if value >= instance.y: raise ValueError("'x' has to be smaller than 'y'!") @define class C: x: int = field(validator=[validators.instance_of(int), x_smaller_than_y]) y: int # Example Usage: # C(x=3, y=4) # Valid # C(x=4, y=3) # Raises ValueError ``` -------------------------------- ### Python: Handling Private Attributes with Default Aliasing in attrs Source: https://github.com/fahreddinozcan/attrs/blob/main/docs/init.md Illustrates how attrs automatically strips leading underscores from attribute names to create __init__ method arguments. This example shows the default behavior and potential pitfalls. ```Python >>> import inspect >>> from attrs import define >>> @define ... class FileDescriptor: ... _fd: int >>> inspect.signature(FileDescriptor.__init__) None> ``` -------------------------------- ### Automatic Attribute Typing with Default Values Source: https://github.com/fahreddinozcan/attrs/blob/main/docs/examples.md When `auto_attribs=True` (the default for `@define`), you can drop `attrs.field` and assign default values to attributes, which will also serve as their type annotations. This simplifies class definition for attributes with predefined values or factory-created collections. ```python >>> import typing >>> @define ... class AutoC: ... cls_var: typing.ClassVar[int] = 5 # this one is ignored ... l: list[int] = Factory(list) ... x: int = 1 ... foo: str = "every attrib needs a type if auto_attribs=True" ... bar: typing.Any = None >>> fields(AutoC).l.type list[int] >>> fields(AutoC).x.type >>> fields(AutoC).foo.type >>> fields(AutoC).bar.type typing.Any >>> AutoC() AutoC(l=[], x=1, foo='every attrib needs a type if auto_attribs=True', bar=None) >>> AutoC.cls_var 5 ``` -------------------------------- ### Replacing Attributes in Frozen Instances (Python 3.13+) Source: https://github.com/fahreddinozcan/attrs/blob/main/docs/examples.md Utilizes the standard library's `copy.replace` function (available from Python 3.13 onwards) to create a new instance of a frozen class with updated attribute values. This provides an alternative to `attrs.evolve` for immutable object manipulation. ```python >>> import copy >>> @frozen ... class C: ... x: int ... y: int >>> i = C(1, 2) >>> copy.replace(i, y=3) C(x=1, y=3) ``` -------------------------------- ### Use Decorator for Attribute-Based Defaults in attrs Source: https://github.com/fahreddinozcan/attrs/blob/main/docs/examples.md Illustrates how to use a decorator (`@y.default`) to define a default value for an attribute (`y`) that depends on another attribute (`x`) within the same class (`C`). It also shows a simpler use of `factory=list` for a default list. ```python >>> @define ... class C: ... x: int = 1 ... y: int = field() ... @y.default ... def _any_name_except_a_name_of_an_attribute(self): ... return self.x + 1 ... z: list = field(factory=list) >>> C() C(x=1, y=2, z=[]) ``` -------------------------------- ### Derived Attributes using __attrs_post_init__ in attrs Source: https://github.com/fahreddinozcan/attrs/blob/main/docs/init.md Shows a common pattern for creating derived attributes where one attribute's value depends on another. This example uses the __attrs_post_init__ hook to initialize a 'client' attribute based on a 'token' attribute. ```python @define class APIClient: token: str client: WebClient = field(init=False) def __attrs_post_init__(self): self.client = WebClient(self.token) ``` -------------------------------- ### Define Class Fields without Type Annotations using attrs Source: https://github.com/fahreddinozcan/attrs/blob/main/docs/examples.md Illustrates defining class fields 'x' and 'y' using `attrs.field()` without type annotations. This approach is an alternative to type annotations and still provides a functional data class. ```python @define class Coordinates: x = field() y = field() # Example usage: print(Coordinates(1, 2)) ``` -------------------------------- ### Avoid Mutable Default Arguments with attrs Factories Source: https://github.com/fahreddinozcan/attrs/blob/main/docs/init.md Illustrates the problem with using mutable default arguments (like `[]` for a list) directly in class definitions. It shows how attrs' factory options prevent unintended shared state between instances by ensuring each instance gets a new mutable object. ```python @define class C: x = [] # Example demonstrating the issue: # i = C() # k = C() # i.x.append(42) # print(k.x) # Output: [42] (shared list) ``` -------------------------------- ### Monkeypatching Limitation and Workaround with Slotted Classes (Python) Source: https://github.com/fahreddinozcan/attrs/blob/main/docs/glossary.md Illustrates the inability to monkeypatch methods on slotted classes and provides a workaround by subclassing as a dict class. This example uses `unittest.mock` to show the `AttributeError` on a slotted class and successful patching on a dict class. ```python import unittest.mock from attr import define @define class Slotted: x: int def method(self): return self.x s = Slotted(42) with unittest.mock.patch.object(s, "method", return_value=23): pass @define(slots=False) class Dicted(Slotted): pass d = Dicted(42) with unittest.mock.patch.object(d, "method", return_value=23): assert 23 == d.method() ``` -------------------------------- ### attrs Converter with Custom Function Source: https://github.com/fahreddinozcan/attrs/blob/main/docs/api.rst Demonstrates how to use custom conversion functions with attrs fields. The example shows a `complicated` converter that performs arithmetic operations based on the instance's factor and field metadata. The converter can be configured to accept the instance (`self_`) and the field object itself. ```python >>> from attrs import define, field, Converter >>> def complicated(value, self_, field): ... return int(value) * self_.factor + field.metadata["offset"] >>> @define ... class C: ... factor = 5 # not an *attrs* field ... x = field( ... metadata={"offset": 200}, ... converter=Converter(complicated, takes_self=True, takes_field=True) ... ) >>> C("42") C(x=410) ``` -------------------------------- ### Python: Convert attrs Class to Tuple with astuple Source: https://github.com/fahreddinozcan/attrs/blob/main/docs/examples.md Illustrates the use of `attrs.astuple` to convert an attrs class instance into a tuple. This is useful for database operations or scenarios where a positional data structure is required. The example shows insertion into an SQLite database. ```python import sqlite3 from attrs import define, astuple @define class Foo: a: int b: int foo = Foo(2, 3) with sqlite3.connect(":memory:") as conn: c = conn.cursor() c.execute("CREATE TABLE foo (x INTEGER PRIMARY KEY ASC, y)") # Use astuple to insert values into the database c.execute("INSERT INTO foo VALUES (?, ?)", astuple(foo)) # Fetch data and reconstruct the Foo object foo2 = Foo(*c.execute("SELECT x, y FROM foo").fetchone()) print(foo == foo2) # Output: True ``` -------------------------------- ### attrs Class Definition vs. Manual Implementation Source: https://github.com/fahreddinozcan/attrs/blob/main/docs/why.md Demonstrates the concise way to define a class using attrs compared to a manually written equivalent. Shows how attrs automatically generates __repr__, __eq__, __ne__, and __hash__ methods, reducing boilerplate and potential errors. ```python >>> @attrs.define ... class SmartClass: ... a = attrs.field() ... b = attrs.field() >>> SmartClass(1, 2) SmartClass(a=1, b=2) ``` ```python >>> class ArtisanalClass: ... def __init__(self, a, b): ... self.a = a ... self.b = b ... ... def __repr__(self): ... return f"ArtisanalClass(a={self.a}, b={self.b})" ... ... def __eq__(self, other): ... if other.__class__ is self.__class__: ... return (self.a, self.b) == (other.a, other.b) ... else: ... return NotImplemented ... ... def __ne__(self, other): ... result = self.__eq__(other) ... if result is NotImplemented: ... return NotImplemented ... else: ... return not result ... ... def __hash__(self): ... return hash((self.__class__, self.a, self.b))) >>> ArtisanalClass(a=1, b=2) ArtisanalClass(a=1, b=2) ``` -------------------------------- ### attrs Class with Type Hinting and Custom __repr__ Source: https://github.com/fahreddinozcan/attrs/blob/main/docs/why.md Illustrates how attrs can be used with type hints for better code clarity and how to override default methods like __repr__ for custom string representations. This shows the flexibility of attrs beyond its automatic generation capabilities. ```python >>> @attrs.define ... class SmartClass: ... a: int ... b: int ... ... def __repr__(self): ... return f"" >>> SmartClass(1, 2) ``` -------------------------------- ### Get class attributes with attrs.fields Source: https://github.com/fahreddinozcan/attrs/blob/main/docs/api.rst Explains how to retrieve information about the attributes of an attrs-defined class using the `attrs.fields` function. It returns a tuple of `Attribute` objects. ```python >>> @define ... class C: ... x = field() ... y = field() >>> attrs.fields(C) (Attribute(name='x', default=NOTHING, validator=None, repr=True, eq=True, eq_key=None, order=True, order_key=None, hash=None, init=True, metadata=mappingproxy({}), type=None, converter=None, kw_only=False, inherited=False, on_setattr=None, alias='x'), Attribute(name='y', default=NOTHING, validator=None, repr=True, eq=True, eq_key=None, order=True, order_key=None, hash=None, init=True, metadata=mappingproxy({}), type=None, converter=None, kw_only=False, inherited=False, on_setattr=None, alias='y')) >>> attrs.fields(C)[1] Attribute(name='y', default=NOTHING, validator=None, repr=True, eq=True, eq_key=None, order=True, order_key=None, hash=None, init=True, metadata=mappingproxy({}), type=None, converter=None, kw_only=False, inherited=False, on_setattr=None, alias='y') >>> attrs.fields(C).y is attrs.fields(C)[1] True ``` -------------------------------- ### Using attrs.fields_dict to inspect class fields Source: https://github.com/fahreddinozcan/attrs/blob/main/docs/api.rst Demonstrates how to use `attrs.fields_dict` to get a dictionary of attributes for an attrs-defined class. This function is useful for introspection and understanding the structure of your classes. ```python >>> import attr >>> @attr.s ... class C: ... x = attr.ib() ... y = attr.ib() >>> attrs.fields_dict(C) {'x': Attribute(name='x', default=NOTHING, validator=None, repr=True, eq=True, eq_key=None, order=True, order_key=None, hash=None, init=True, metadata=mappingproxy({}), type=None, converter=None, kw_only=False, inherited=False, on_setattr=None, alias='x'), 'y': Attribute(name='y', default=NOTHING, validator=None, repr=True, eq=True, eq_key=None, order=True, order_key=None, hash=None, init=True, metadata=mappingproxy({}), type=None, converter=None, kw_only=False, inherited=False, on_setattr=None, alias='y')} >>> attr.fields_dict(C)['y'] Attribute(name='y', default=NOTHING, validator=None, repr=True, eq=True, eq_key=None, order=True, order_key=None, hash=None, init=True, metadata=mappingproxy({}), type=None, converter=None, kw_only=False, inherited=False, on_setattr=None, alias='y') >>> attrs.fields_dict(C)['y'] is attrs.fields(C).y True ``` -------------------------------- ### attrs Setters: NO_OP Sentinel Source: https://github.com/fahreddinozcan/attrs/blob/main/docs/api.rst Illustrates the use of `attrs.setters.NO_OP` as a sentinel value to disable class-wide `on_setattr` hooks for specific attributes. This example shows how to freeze a class but exclude one attribute from being frozen. ```python >>> from attrs import define, field, setters >>> @define(on_setattr=setters.frozen) ... class C: ... x = field() ... y = field(on_setattr=setters.NO_OP) >>> c = C(1, 2) >>> c.y = 3 >>> c.y 3 >>> c.x = 4 Traceback (most recent call last): ... attrs.exceptions.FrozenAttributeError: () ``` -------------------------------- ### Programmatically create classes with attrs.make_class Source: https://github.com/fahreddinozcan/attrs/blob/main/docs/api.rst Illustrates how to create classes dynamically using `attrs.make_class`. It shows creating a class with simple attribute names and another with fields having defaults and factories. ```python >>> C1 = attrs.make_class("C1", ["x", "y"]) >>> C1(1, 2) C1(x=1, y=2) >>> C2 = attrs.make_class("C2", { ... "x": field(default=42), ... "y": field(factory=list) ... }) >>> C2() C2(x=42, y=[]) ``` -------------------------------- ### Slotted Class Attribute Limitation Example (Python) Source: https://github.com/fahreddinozcan/attrs/blob/main/docs/glossary.md Demonstrates that slotted classes, created using attrs, do not allow setting attributes not defined in `__slots__`. It shows an `AttributeError` when attempting to assign a new attribute. ```python from attr import define @define class Coordinates: x: int y: int c = Coordinates(x=1, y=2) c.z = 3 ``` -------------------------------- ### Python: SyntaxError due to Invalid Attribute Name Transformation in attrs Source: https://github.com/fahreddinozcan/attrs/blob/main/docs/init.md Demonstrates a potential SyntaxError when an attribute name starting with an underscore is transformed into an invalid Python identifier for the __init__ method argument. ```Python >>> @define ... class C: ... _1: int Traceback (most recent call last): ... # doctest:break SyntaxError: invalid syntax ``` -------------------------------- ### attrs: Validate attribute is callable Source: https://github.com/fahreddinozcan/attrs/blob/main/docs/api.rst This example demonstrates using `attrs.validators.is_callable` to ensure that an attribute is a callable object. It allows functions or methods but rejects non-callable types like strings, raising an `attr.exceptions.NotCallableError` for invalid inputs. ```python from attrs import define, field @define class C: x = field(validator=attrs.validators.is_callable()) # Example usage: # C(isinstance) # Valid # C("not a callable") # Raises attr.exceptions.NotCallableError ``` -------------------------------- ### Decorator-based Attribute Validation in Python Source: https://github.com/fahreddinozcan/attrs/blob/main/docs/examples.md Demonstrates using a decorator to define a validator for an attribute. This method requires the attribute to have an attrs.field assigned. The validator function receives the instance, attribute, and value, and should raise an error if the value is invalid. ```python from attrs import define, field @define class C: x: int = field() @x.validator def check(self, attribute, value): if value > 42: raise ValueError("x must be smaller or equal to 42") # Example Usage: # C(42) # Valid # C(43) # Raises ValueError ``` -------------------------------- ### Python: Factory Method for Class Initialization with attrs Source: https://github.com/fahreddinozcan/attrs/blob/main/docs/init.md Demonstrates using a classmethod to create instances from external data, promoting testability and decoupling. This avoids passing complex objects directly into __init__. ```Python @define class Point: x: float y: float @classmethod def from_row(cls, row): return cls(row.x, row.y) pt = Point.from_row(row) ``` -------------------------------- ### Using attr.ib for Attribute Definition and Validation (Python) Source: https://github.com/fahreddinozcan/attrs/blob/main/docs/api-attr.rst Illustrates the use of attr.ib to define class attributes, set defaults using decorators, and implement custom validators. Shows how to define validation logic for specific attributes. ```python >>> @attr.s ... class C: ... x = attr.ib() ... y = attr.ib() ... @x.validator ... def _any_name_except_a_name_of_an_attribute(self, attribute, value): ... if value < 0: ... raise ValueError("x must be positive") ... @y.default ... def _any_name_except_a_name_of_an_attribute(self): ... return self.x + 1 >>> C(1) C(x=1, y=2) >>> C(-1) Traceback (most recent call last): ... ValueError: x must be positive ``` -------------------------------- ### Use attrs.Factory for default values Source: https://github.com/fahreddinozcan/attrs/blob/main/docs/api.rst Shows how to use `attrs.Factory` to provide default values for attributes, including callable defaults and defaults that depend on the instance's state. ```python >>> @define ... class C: ... x = field(default=attrs.Factory(list)) ... y = field(default=attrs.Factory( ... lambda self: set(self.x), ... takes_self=True) ... ) >>> C() C(x=[], y=set()) >>> C([1, 2, 3]) C(x=[1, 2, 3], y={1, 2, 3}) ``` -------------------------------- ### Resolving String Type Annotations Source: https://github.com/fahreddinozcan/attrs/blob/main/docs/examples.md Resolves string-based type annotations (forward references) into actual type objects using `attrs.resolve_types`. This is crucial when dealing with mutually recursive class definitions or when types are not yet defined at the time of class creation. ```python >>> from attrs import resolve_types >>> @define ... class A: ... a: 'list[A]' ... b: 'B' ... >>> @define ... class B: ... a: A ... >>> fields(A).a.type 'list[A]' >>> fields(A).b.type 'B' >>> resolve_types(A, globals(), locals()) >>> fields(A).a.type list[A] >>> fields(A).b.type ``` -------------------------------- ### Python: Generate __init__ with attrs.define Source: https://github.com/fahreddinozcan/attrs/blob/main/docs/how-does-it-work.md Demonstrates how attrs automatically generates an __init__ method for a class decorated with @attrs.define. This generated method mirrors the expected signature based on the defined attributes, without runtime introspection. ```python import inspect from attrs import define @define class C: x: int print(inspect.getsource(C.__init__)) ``` -------------------------------- ### Built-in Instance Type Validation in Python Source: https://github.com/fahreddinozcan/attrs/blob/main/docs/examples.md Demonstrates the use of the built-in `validators.instance_of` to ensure an attribute is of a specific type. This is a common validation pattern to enforce data types. The validator raises a TypeError if the provided value does not match the expected type. ```python from attrs import define, field, validators @define class C: x: int = field(validator=validators.instance_of(int)) # Example Usage: # C(42) # Valid # C("42") # Raises TypeError ``` -------------------------------- ### Version Compatibility Check for attr (Python) Source: https://github.com/fahreddinozcan/attrs/blob/main/docs/api-attr.rst Provides a Python code snippet demonstrating how to check the version of the 'attr' library to ensure compatibility with newer features like 'eq' and 'cmp'. This helps in writing code that works across different versions. ```python >>> if getattr(attr, "__version_info__", (0,)) >= (19, 2): ... cmp_off = {"eq": False} ... else: ... cmp_off = {"cmp": False} >>> cmp_off == {"eq": False} True >>> @attr.s(**cmp_off) ``` -------------------------------- ### Combining Decorator and Field Validators Source: https://github.com/fahreddinozcan/attrs/blob/main/docs/init.md Illustrates how to define validators using both the attrs.field validator argument and the @.validator decorator. Both sets of validators are executed. ```python import attrs @attrs.define class C: x = attrs.field(validator=attrs.validators.instance_of(int)) @x.validator def fits_byte(self, attribute, value): if not 0 <= value < 256: raise ValueError("value out of bounds") # Example usage: # C(128) # Valid # C("128") # Raises TypeError # C(256) # Raises ValueError ``` -------------------------------- ### attrs: Deeply validate iterable members and type Source: https://github.com/fahreddinozcan/attrs/blob/main/docs/api.rst This example showcases `attrs.validators.deep_iterable`, which validates both the iterable itself (e.g., must be a list) and its members (e.g., must be integers). It raises a `TypeError` if the iterable type is incorrect or if any member does not meet the specified criteria. ```python from attrs import define, field @define class C: x = field(validator=attrs.validators.deep_iterable( member_validator=attrs.validators.instance_of(int), iterable_validator=attrs.validators.instance_of(list) )) # Example usage: # C(x=[1, 2, 3]) # Valid # C(x=set([1, 2, 3])) # Raises TypeError (iterable type) # C(x=[1, 2, "3"]) # Raises TypeError (member type) ``` -------------------------------- ### Core Functionality Source: https://github.com/fahreddinozcan/attrs/blob/main/docs/api-attr.rst Defines classes with attributes, similar to Python's dataclasses but with more customization options. Supports various configurations for initialization, representation, comparison, hashing, and more. ```APIDOC ## attr.s (Decorator) ### Description Decorates a class to automatically generate methods for initialization, representation, comparison, and hashing based on the class attributes. It offers extensive customization through its parameters. ### Method Decorator ### Endpoint N/A (Class Decorator) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```python import attr @attr.s class C: _private = attr.ib() # Example Usage: instance = C(private=42) print(instance) # Output: C(_private=42) ``` ### Response #### Success Response (200) N/A (Class definition) #### Response Example N/A ``` ```APIDOC ## attr.ib() ### Description Defines an attribute for a class decorated with `attr.s`. It can be used to configure attribute behavior like defaults, validators, and more. An alias `attr.attrib` is also available. ### Method Function ### Endpoint N/A (Used within class definitions) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```python import attr @attr.s class C: x = attr.ib() y = attr.ib(default=attr.Factory(lambda self: self.x + 1)) @x.validator def check_x(self, attribute, value): if value < 0: raise ValueError("x must be positive") # Example Usage: instance1 = C(1) print(instance1) # Output: C(x=1, y=2) try: C(-1) except ValueError as e: print(e) # Output: x must be positive ``` ### Response #### Success Response (200) N/A (Attribute definition) #### Response Example N/A ```