# *attrs* by Example

## Basics

The simplest possible usage is:

```{doctest}
>>> from attrs import define, field
>>> @define
... class Empty:
...     pass
>>> Empty()
Empty()
>>> Empty() == Empty()
True
>>> Empty() is Empty()
False
```

So in other words: *attrs* is useful even without actual {term}`fields <field>`!

But you'll usually want some data on your classes, so let's add some:

```{doctest}
>>> @define
... class Coordinates:
...     x: int
...     y: int
```

By default, all features are added, so you immediately have a fully functional data class with a nice `repr` string and comparison methods.

```{doctest}
>>> c1 = Coordinates(1, 2)
>>> c1
Coordinates(x=1, y=2)
>>> c2 = Coordinates(x=2, y=1)
>>> c2
Coordinates(x=2, y=1)
>>> c1 == c2
False
```

As shown, the generated `__init__` method allows for both positional and keyword arguments.

---

Unlike Data Classes, *attrs* doesn't force you to use type annotations.
So, the previous example could also have been written as:

```{doctest}
>>> @define
... class Coordinates:
...     x = field()
...     y = field()
>>> Coordinates(1, 2)
Coordinates(x=1, y=2)
```

:::{caution}
If a class body contains a field that is defined using {func}`attrs.field` (or {func}`attr.ib`), but **lacks a type annotation**, *attrs* switches to a no-typing mode and ignores fields that have type annotations but are not defined using {func}`attrs.field` (or {func}`attr.ib`).
:::

---

For private attributes, *attrs* will strip the leading underscores for keyword arguments:

```{doctest}
>>> @define
... class C:
...     _x: int
>>> C(x=1)
C(_x=1)
```

If you want to initialize your private attributes yourself, you can do that too:

```{doctest}
>>> @define
... class C:
...     _x: int = field(init=False, default=42)
>>> C()
C(_x=42)
>>> C(23)
Traceback (most recent call last):
   ...
TypeError: __init__() takes exactly 1 argument (2 given)
```

If you prefer to expose your privates, you can use keyword argument aliases:

```{doctest}
>>> @define
... class C:
...     _x: int = field(alias="_x")
>>> C(_x=1)
C(_x=1)
```

An additional way of defining attributes is supported too.
This is useful in times when you want to enhance classes that are not yours (nice `__repr__` for Django models anyone?):

```{doctest}
>>> class SomethingFromSomeoneElse:
...     def __init__(self, x):
...         self.x = x
>>> SomethingFromSomeoneElse = define(
...     these={
...         "x": field()
...     }, init=False)(SomethingFromSomeoneElse)
>>> SomethingFromSomeoneElse(1)
SomethingFromSomeoneElse(x=1)
```

[Subclassing is bad for you](https://www.youtube.com/watch?v=3MNVP9-hglc) (except when doing [strict specialization](https://hynek.me/articles/python-subclassing-redux/)), but *attrs* will still do what you'd hope for:

```{doctest}
>>> @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
>>> i = C(1, 2, 3)
>>> i
C(a=1, b=2, c=3)
>>> i == C(1, 2, 3)
True
>>> i.get_a()
1
```

{term}`Slotted classes <slotted classes>`, which are the default for the new APIs, don't play well with multiple inheritance so we don't use them in the example.

The order of the attributes is defined by the [MRO](https://www.python.org/download/releases/2.3/mro/).


### Keyword-only Attributes

You can also add [keyword-only](https://docs.python.org/3/glossary.html#keyword-only-parameter) attributes:

```{doctest}
>>> @define
... class A:
...     a: int = field(kw_only=True)
>>> A()
Traceback (most recent call last):
...
TypeError: A() missing 1 required keyword-only argument: 'a'
>>> A(a=1)
A(a=1)
```

`kw_only` may also be specified at decorator level, and will apply to all attributes:

```{doctest}
>>> @define(kw_only=True)
... class A:
...     a: int
...     b: int
>>> A(1, 2)
Traceback (most recent call last):
...
TypeError: __init__() takes 1 positional argument but 3 were given
>>> A(a=1, b=2)
A(a=1, b=2)
```

If you create an attribute with `init=False`, the `kw_only` argument is ignored.

Keyword-only attributes allow subclasses to add attributes without default values, even if the base class defines attributes with default values:

```{doctest}
>>> @define
... class A:
...     a: int = 0
>>> @define
... class B(A):
...     b: int = field(kw_only=True)
>>> B(b=1)
B(a=0, b=1)
>>> B()
Traceback (most recent call last):
...
TypeError: B() missing 1 required keyword-only argument: 'b'
```

If you don't set `kw_only=True`, then there is no valid attribute ordering, and you'll get an error:

```{doctest}
>>> @define
... class A:
...     a: int = 0
>>> @define
... class B(A):
...     b: int
Traceback (most recent call last):
...
ValueError: No mandatory attributes allowed after an attribute with a default value or factory.  Attribute in question: Attribute(name='b', default=NOTHING, validator=None, repr=True, cmp=True, hash=None, init=True, converter=None, metadata=mappingproxy({}), type=int, kw_only=False)
```

(asdict)=

## Converting to Collections Types

When you have a class with data, it often is very convenient to transform that class into a {class}`dict` (for example if you want to serialize it to JSON):

```{doctest}
>>> from attrs import asdict
>>> asdict(Coordinates(x=1, y=2))
{'x': 1, 'y': 2}
```

Some fields cannot or should not be transformed.
For that, {func}`attrs.asdict` offers a callback that decides whether an attribute should be included:

```{doctest}
>>> @define
... class User:
...     email: str
...     password: str

>>> @define
... class UserList:
...     users: list[User]

>>> asdict(UserList([User("jane@doe.invalid", "s33kred"),
...                  User("joe@doe.invalid", "p4ssw0rd")]),
...        filter=lambda attr, value: attr.name != "password")
{'users': [{'email': 'jane@doe.invalid'}, {'email': 'joe@doe.invalid'}]}
```

For the common case where you want to [`include`](attrs.filters.include) or [`exclude`](attrs.filters.exclude) certain types, string name or attributes, *attrs* ships with a few helpers:

```{doctest}
>>> from attrs import asdict, filters, fields

>>> @define
... class User:
...     login: str
...     password: str
...     email: str
...     id: int

>>> asdict(
...     User("jane", "s33kred", "jane@example.com", 42),
...     filter=filters.exclude(fields(User).password, "email", int))
{'login': 'jane'}

>>> @define
... class C:
...     x: str
...     y: str
...     z: int

>>> asdict(C("foo", "2", 3),
...        filter=filters.include(int, fields(C).x))
{'x': 'foo', 'z': 3}

>>> asdict(C("foo", "2", 3),
...        filter=filters.include(fields(C).x, "z"))
{'x': 'foo', 'z': 3}
```

:::{note}
Though using string names directly is convenient, mistyping attribute names will silently do the wrong thing and neither Python nor your type checker can help you.
{func}`attrs.fields()` will raise an `AttributeError` when the field doesn't exist while literal string names won't.
Using {func}`attrs.fields()` to get attributes is worth being recommended in most cases.

```{doctest}
>>> asdict(
...     User("jane", "s33kred", "jane@example.com", 42),
...     filter=filters.exclude("passwd")
... )
{'login': 'jane', 'password': 's33kred', 'email': 'jane@example.com', 'id': 42}

>>> asdict(
...     User("jane", "s33kred", "jane@example.com", 42),
...     filter=fields(User).passwd
... )
Traceback (most recent call last):
...
AttributeError: 'UserAttributes' object has no attribute 'passwd'. Did you mean: 'password'?
```
:::

Other times, all you want is a tuple and *attrs* won't let you down:

```{doctest}
>>> import sqlite3
>>> from attrs import 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)") #doctest: +ELLIPSIS
...    c.execute("INSERT INTO foo VALUES (?, ?)", astuple(foo)) #doctest: +ELLIPSIS
...    foo2 = Foo(*c.execute("SELECT x, y FROM foo").fetchone())
<sqlite3.Cursor object at ...>
<sqlite3.Cursor object at ...>
>>> foo == foo2
True
```

For more advanced transformations and conversions, we recommend you look at a companion library (such as [*cattrs*](https://catt.rs/)).


## Defaults

Sometimes you want to have default values for your initializer.
And sometimes you even want mutable objects as default values (ever accidentally used `def f(arg=[])`?).
*attrs* has you covered in both cases:

```{doctest}
>>> 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)
```

More information on why class methods for constructing objects are awesome can be found in this insightful [blog post](https://web.archive.org/web/20210130220433/http://as.ynchrono.us/2014/12/asynchronous-object-initialization.html).

Default factories can also be set using the `factory` argument to {func}`~attrs.field`, and using a decorator.
The method receives the partially initialized instance which enables you to base a default value on other attributes:

```{doctest}
>>> @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=[])
```

Please keep in mind that the decorator approach *only* works if the attribute in question has a {func}`~attrs.field` assigned to it.
As a result, annotating an attribute with a type is *not* enough if you use `@default`.

(examples-validators)=

## Validators

Although your initializers should do as little as possible (ideally: just initialize your instance according to the arguments!), it can come in handy to do some kind of validation on the arguments.

*attrs* offers two ways to define validators for each attribute and it's up to you to choose which one suits your style and project better.

You can use a decorator:

```{doctest}
>>> @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")
>>> C(42)
C(x=42)
>>> C(43)
Traceback (most recent call last):
   ...
ValueError: x must be smaller or equal to 42
```

...or a callable...

```{doctest}
>>> from attrs import 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
>>> C(x=3, y=4)
C(x=3, y=4)
>>> C(x=4, y=3)
Traceback (most recent call last):
   ...
ValueError: 'x' has to be smaller than 'y'!
```

...or both at once:

```{doctest}
>>> @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")
>>> C(128)
C(x=128)
>>> C("128")
Traceback (most recent call last):
   ...
TypeError: ("'x' must be <class 'int'> (got '128' that is a <class 'str'>).", Attribute(name='x', default=NOTHING, validator=[<instance_of validator for type <class 'int'>>, <function fits_byte at 0x10fd7a0d0>], repr=True, cmp=True, hash=True, init=True, metadata=mappingproxy({}), type=int, converter=None, kw_only=False), <class 'int'>, '128')
>>> C(256)
Traceback (most recent call last):
   ...
ValueError: value out of bounds
```

Please note that the decorator approach only works if -- and only if! -- the attribute in question has a {func}`~attrs.field` assigned.
Therefore if you use `@validator`, it is *not* enough to annotate said attribute with a type.

*attrs* ships with a bunch of validators, make sure to [check them out](api-validators) before writing your own:

```{doctest}
>>> @define
... class C:
...     x: int = field(validator=validators.instance_of(int))
>>> C(42)
C(x=42)
>>> C("42")
Traceback (most recent call last):
   ...
TypeError: ("'x' must be <type 'int'> (got '42' that is a <type 'str'>).", Attribute(name='x', default=NOTHING, factory=NOTHING, validator=<instance_of validator for type <type 'int'>>, type=None, kw_only=False), <type 'int'>, '42')
```

If using the old-school {func}`attr.s` decorator, validators only run on initialization by default.
If using the newer {func}`attrs.define` and friends, validators run on initialization *and* on attribute setting.
This behavior can be changed using the *on_setattr* argument.

Check out {ref}`validators` for more details.


## Conversion

Attributes can have a `converter` function specified, which will be called with the attribute's passed-in value to get a new value to use.
This can be useful for doing type-conversions on values that you don't want to force your callers to do.

```{doctest}
>>> @define
... class C:
...     x: int = field(converter=int)
>>> o = C("1")
>>> o.x
1
>>> o.x = "2"
>>> o.x
2
```

If using the old-school {func}`attr.s` decorator, converters only run on initialization by default.
If using the newer {func}`attrs.define` and friends, converters run on initialization *and* on attribute setting.
This behavior can be changed using the *on_setattr* argument.

Check out {ref}`converters` for more details.

(metadata)=

## Metadata

All *attrs* attributes may include arbitrary metadata in the form of a read-only dictionary.

```{doctest}
>>> from attrs import fields

>>> @define
... class C:
...    x = field(metadata={'my_metadata': 1})
>>> fields(C).x.metadata
mappingproxy({'my_metadata': 1})
>>> fields(C).x.metadata['my_metadata']
1
```

Metadata is not used by *attrs*, and is meant to enable rich functionality in third-party libraries.
The metadata dictionary follows the normal dictionary rules:
Keys need to be hashable, and both keys and values are recommended to be immutable.

If you're the author of a third-party library with *attrs* integration, please see [*Extending Metadata*](extending-metadata).


## Types

*attrs* also allows you to associate a type with an attribute using either the *type* argument to using {pep}`526`-annotations or {func}`attrs.field`/{func}`attr.ib`:

```{doctest}
>>> @define
... class C:
...     x: int
>>> fields(C).x.type
<class 'int'>

>>> import attr
>>> @attr.s
... class C:
...     x = attr.ib(type=int)
>>> fields(C).x.type
<class 'int'>
```

If you don't mind annotating *all* attributes, you can even drop the `attrs.field` and assign default values instead:

```{doctest}
>>> 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
<class 'int'>
>>> fields(AutoC).foo.type
<class 'str'>
>>> 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
```

The generated `__init__` method will have an attribute called `__annotations__` that contains this type information.

If your annotations contain strings (for example, forward references),
you can resolve these after all references have been defined by using {func}`attrs.resolve_types`.
This will replace the *type* attribute in the respective fields.

```{doctest}
>>> 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())
<class 'A'>
>>> fields(A).a.type
list[A]
>>> fields(A).b.type
<class 'B'>
```

:::{note}
If you find yourself using string type annotations to handle forward references, wrap the entire type annotation in quotes instead of only the type you need a forward reference to (so `'list[A]'` instead of `list['A']`).
This is a limitation of the Python typing system.
:::

:::{warning}
*attrs* itself doesn't have any features that work on top of type metadata.
However it's useful for writing your own validators or serialization frameworks.
:::


## Slots

{term}`Slotted classes <slotted classes>` have several advantages on CPython.
Defining `__slots__` by hand is tedious, in *attrs* it's just a matter of using {func}`attrs.define` or passing `slots=True` to {func}`attr.s`:

```{doctest}
>>> @define
... class Coordinates:
...     x: int
...     y: int

>>> import attr

>>> @attr.s(slots=True)
... class Coordinates:
...     x: int
...     y: int
```

{func}`~attrs.define` sets `slots=True` by default.


## Immutability

Sometimes you have instances that shouldn't be changed after instantiation.
Immutability is especially popular in functional programming and is generally a very good thing.
If you'd like to enforce it, *attrs* will try to help:

```{doctest}
>>> 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
```

Please note that true immutability is impossible in Python but it will [get](how-frozen) you 99% there.
By themselves, immutable classes are useful for long-lived objects that should never change; like configurations for example.

In order to use them in regular program flow, you'll need a way to easily create new instances with changed attributes.
In Clojure that function is called [*assoc*](https://clojuredocs.org/clojure.core/assoc) and *attrs* shamelessly imitates it: {func}`attrs.evolve`:

```{doctest}
>>> 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
```

On Python 3.13 and later, you can also use {func}`copy.replace` from the standard library:

```{doctest}
>>> import copy
>>> @frozen
... class C:
...     x: int
...     y: int
>>> i = C(1, 2)
>>> copy.replace(i, y=3)
C(x=1, y=3)
```


## Other Goodies

When building systems that have something resembling a plugin interface, you may want to have a registry of all classes that implement a certain interface:

```{doctest}
>>> REGISTRY = []
>>> class Base:  # does NOT have to be an attrs class!
...     @classmethod
...     def __attrs_init_subclass__(cls):
...         REGISTRY.append(cls)
>>> @define
... class Impl(Base):
...     pass
>>> REGISTRY
[<class 'Impl'>]
```

Sometimes you may want to create a class programmatically.
*attrs* gives you {func}`attrs.make_class` for that:

```{doctest}
>>> from attrs import make_class
>>> @define
... class C1:
...     x = field(type=int)
...     y = field()
>>> C2 = make_class("C2", {"x": field(type=int), "y": field()})
>>> fields(C1) == fields(C2)
True
>>> fields(C2).x.type
<class 'int'>
```

You can still have power over the attributes if you pass a dictionary of name: {func}`~attrs.field` mappings and can pass the same arguments as you can to `@attrs.define`:

```{doctest}
>>> C = make_class("C", {"x": field(default=42),
...                      "y": field(default=Factory(list))},
...                repr=False)
>>> i = C()
>>> i  # no repr added!
<__main__.C object at ...>
>>> i.x
42
>>> i.y
[]
```

If you need to dynamically make a class with {func}`~attrs.make_class` and it needs to be a subclass of something else than {class}`object`, use the `bases` argument:

```{doctest}
>>> class D:
...    def __eq__(self, other):
...        return True  # arbitrary example
>>> C = make_class("C", {}, bases=(D,), cmp=False)
>>> isinstance(C(), D)
True
```

Sometimes, you want to have your class's `__init__` method do more than just
the initialization, validation, etc. that gets done for you automatically when
using `@define`.
To do this, just define a `__attrs_post_init__` method in your class.
It will get called at the end of the generated `__init__` method.

```{doctest}
>>> @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)
>>> obj
C(x=1, y=2, z=3)
```

You can exclude single attributes from certain methods:

```{doctest}
>>> @define
... class C:
...     user: str
...     password: str = field(repr=False)
>>> C("me", "s3kr3t")
C(user='me')
```

Alternatively, to influence how the generated `__repr__()` method formats a specific attribute, specify a custom callable to be used instead of the `repr()` built-in function:

```{doctest}
>>> @define
... class C:
...     user: str
...     password: str = field(repr=lambda value: '***')
>>> C("me", "s3kr3t")
C(user='me', password=***)
```
