API Reference

attrs works by decorating a class using attr.s and then optionally defining attributes on the class using attr.ib.

Note

When this documentation speaks about “attrs attributes” it means those attributes that are defined using attr.ib in the class body.

What follows is the API explanation, if you’d like a more hands-on introduction, have a look at attrs by Example.

Core

Warning

As of attrs 20.1.0, it also ships with a bunch of provisional APIs that are intended to become the main way of defining classes in the future.

Please have a look at Provisional APIs.

attr.NOTHING = NOTHING

Sentinel class to indicate the lack of a value when None is ambiguous.

_Nothing is a singleton. There is only ever one of it.

attr.s(these=None, repr_ns=None, repr=None, cmp=None, hash=None, init=None, slots=False, frozen=False, weakref_slot=True, str=False, auto_attribs=False, kw_only=False, cache_hash=False, auto_exc=False, eq=None, order=None, auto_detect=False, collect_by_mro=False, getstate_setstate=None, on_setattr=None)

A class decorator that adds dunder-methods according to the specified attributes using attr.ib or the these argument.

Parameters
  • these (dict of str to attr.ib) –

    A dictionary of name to attr.ib mappings. This is useful to avoid the definition of your attributes within the class body because you can’t (e.g. if you want to add __repr__ methods to Django models) or don’t want to.

    If these is not None, attrs will not search the class body for attributes and will not remove any attributes from it.

    If these is an ordered dict (dict on Python 3.6+, collections.OrderedDict otherwise), the order is deduced from the order of the attributes inside these. Otherwise the order of the definition of the attributes is used.

  • repr_ns (str) – When using nested classes, there’s no way in Python 2 to automatically detect that. Therefore it’s possible to set the namespace explicitly for a more meaningful repr output.

  • auto_detect (bool) –

    Instead of setting the init, repr, eq, order, and hash arguments explicitly, assume they are set to True unless any of the involved methods for one of the arguments is implemented in the current class (i.e. it is not inherited from some base class).

    So for example by implementing __eq__ on a class yourself, attrs will deduce eq=False and won’t create neither __eq__ nor __ne__ (but Python classes come with a sensible __ne__ by default, so it should be enough to only implement __eq__ in most cases).

    Warning

    If you prevent attrs from creating the ordering methods for you (order=False, e.g. by implementing __le__), it becomes your responsibility to make sure its ordering is sound. The best way is to use the functools.total_ordering decorator.

    Passing True or False to init, repr, eq, order, cmp, or hash overrides whatever auto_detect would determine.

    auto_detect requires Python 3. Setting it True on Python 2 raises a PythonTooOldError.

  • repr (bool) – Create a __repr__ method with a human readable representation of attrs attributes..

  • str (bool) – Create a __str__ method that is identical to __repr__. This is usually not necessary except for Exceptions.

  • eq (Optional[bool]) –

    If True or None (default), add __eq__ and __ne__ methods that check two instances for equality.

    They compare the instances as if they were tuples of their attrs attributes if and only if the types of both classes are identical!

  • order (Optional[bool]) – If True, add __lt__, __le__, __gt__, and __ge__ methods that behave like eq above and allow instances to be ordered. If None (default) mirror value of eq.

  • cmp (Optional[bool]) – Setting to True is equivalent to setting eq=True, order=True. Deprecated in favor of eq and order, has precedence over them for backward-compatibility though. Must not be mixed with eq or order.

  • hash (Optional[bool]) –

    If None (default), the __hash__ method is generated according how eq and frozen are set.

    1. If both are True, attrs will generate a __hash__ for you.

    2. If eq is True and frozen is False, __hash__ will be set to None, marking it unhashable (which it is).

    3. If eq is False, __hash__ will be left untouched meaning the __hash__ method of the base class will be used (if base class is object, this means it will fall back to id-based hashing.).

    Although not recommended, you can decide for yourself and force attrs to create one (e.g. if the class is immutable even though you didn’t freeze it programmatically) by passing True or not. Both of these cases are rather special and should be used carefully.

    See our documentation on Hashing, Python’s documentation on object.__hash__, and the GitHub issue that led to the default behavior for more details.

  • init (bool) – Create a __init__ method that initializes the attrs attributes. Leading underscores are stripped for the argument name. If a __attrs_post_init__ method exists on the class, it will be called after the class is fully initialized.

  • slots (bool) – Create a slotted class that’s more memory-efficient.

  • frozen (bool) –

    Make instances immutable after initialization. If someone attempts to modify a frozen instance, attr.exceptions.FrozenInstanceError is raised.

    Please note:

    1. This is achieved by installing a custom __setattr__ method on your class, so you can’t implement your own.

    2. True immutability is impossible in Python.

    3. This does have a minor a runtime performance impact when initializing new instances. In other words: __init__ is slightly slower with frozen=True.

    4. If a class is frozen, you cannot modify self in __attrs_post_init__ or a self-written __init__. You can circumvent that limitation by using object.__setattr__(self, "attribute_name", value).

    5. Subclasses of a frozen class are frozen too.

  • weakref_slot (bool) – Make instances weak-referenceable. This has no effect unless slots is also enabled.

  • auto_attribs (bool) –

    If True, collect PEP 526-annotated attributes (Python 3.6 and later only) from the class body.

    In this case, you must annotate every field. If attrs encounters a field that is set to an attr.ib but lacks a type annotation, an attr.exceptions.UnannotatedAttributeError is raised. Use field_name: typing.Any = attr.ib(...) if you don’t want to set a type.

    If you assign a value to those attributes (e.g. x: int = 42), that value becomes the default value like if it were passed using attr.ib(default=42). Passing an instance of Factory also works as expected.

    Attributes annotated as typing.ClassVar, and attributes that are neither annotated nor set to an attr.ib are ignored.

  • kw_only (bool) – Make all attributes keyword-only (Python 3+) in the generated __init__ (if init is False, this parameter is ignored).

  • cache_hash (bool) – Ensure that the object’s hash code is computed only once and stored on the object. If this is set to True, hashing must be either explicitly or implicitly enabled for this class. If the hash code is cached, avoid any reassignments of fields involved in hash code computation or mutations of the objects those fields point to after object creation. If such changes occur, the behavior of the object’s hash code is undefined.

  • auto_exc (bool) –

    If the class subclasses BaseException (which implicitly includes any subclass of any exception), the following happens to behave like a well-behaved Python exceptions class:

    • the values for eq, order, and hash are ignored and the instances compare and hash by the instance’s ids (N.B. attrs will not remove existing implementations of __hash__ or the equality methods. It just won’t add own ones.),

    • all attributes that are either passed into __init__ or have a default value are additionally available as a tuple in the args attribute,

    • the value of str is ignored leaving __str__ to base classes.

  • collect_by_mro (bool) –

    Setting this to True fixes the way attrs collects attributes from base classes. The default behavior is incorrect in certain cases of multiple inheritance. It should be on by default but is kept off for backward-compatability.

    See issue #428 for more details.

  • getstate_setstate (Optional[bool]) –

    Note

    This is usually only interesting for slotted classes and you should probably just set auto_detect to True.

    If True, __getstate__ and __setstate__ are generated and attached to the class. This is necessary for slotted classes to be pickleable. If left None, it’s True by default for slotted classes and False for dict classes.

    If auto_detect is True, and getstate_setstate is left None, and either __getstate__ or __setstate__ is detected directly on the class (i.e. not inherited), it is set to False (this is usually what you want).

  • on_setattr

    A callable that is run whenever the user attempts to set an attribute (either by assignment like i.x = 42 or by using setattr like setattr(i, "x", 42)). It receives the same argument as validators: the instance, the attribute that is being modified, and the new value.

    If no exception is raised, the attribute is set to the return value of the callable.

    If a list of callables is passed, they’re automatically wrapped in an attr.setters.pipe.

New in version 16.0.0: slots

New in version 16.1.0: frozen

New in version 16.3.0: str

New in version 16.3.0: Support for __attrs_post_init__.

Changed in version 17.1.0: hash supports None as value which is also the default now.

New in version 17.3.0: auto_attribs

Changed in version 18.1.0: If these is passed, no attributes are deleted from the class body.

Changed in version 18.1.0: If these is ordered, the order is retained.

New in version 18.2.0: weakref_slot

Deprecated since version 18.2.0: __lt__, __le__, __gt__, and __ge__ now raise a DeprecationWarning if the classes compared are subclasses of each other. __eq and __ne__ never tried to compared subclasses to each other.

Changed in version 19.2.0: __lt__, __le__, __gt__, and __ge__ now do not consider subclasses comparable anymore.

New in version 18.2.0: kw_only

New in version 18.2.0: cache_hash

New in version 19.1.0: auto_exc

Deprecated since version 19.2.0: cmp Removal on or after 2021-06-01.

New in version 19.2.0: eq and order

New in version 20.1.0: auto_detect

New in version 20.1.0: collect_by_mro

New in version 20.1.0: getstate_setstate

New in version 20.1.0: on_setattr

Note

attrs also comes with a serious business alias attr.attrs.

For example:

>>> import attr
>>> @attr.s
... class C(object):
...     _private = attr.ib()
>>> C(private=42)
C(_private=42)
>>> class D(object):
...     def __init__(self, x):
...         self.x = x
>>> D(1)
<D object at ...>
>>> D = attr.s(these={"x": attr.ib()}, init=False)(D)
>>> D(1)
D(x=1)
>>> @attr.s(auto_exc=True)
... class Error(Exception):
...     x = attr.ib()
...     y = attr.ib(default=42, init=False)
>>> Error("foo")
Error(x='foo', y=42)
>>> raise Error("foo")
Traceback (most recent call last):
   ...
Error: ('foo', 42)
>>> raise ValueError("foo", 42)   # for comparison
Traceback (most recent call last):
   ...
ValueError: ('foo', 42)
attr.ib(default=NOTHING, validator=None, repr=True, cmp=None, hash=None, init=True, metadata=None, type=None, converter=None, factory=None, kw_only=False, eq=None, order=None, on_setattr=None)

Create a new attribute on a class.

Warning

Does not do anything unless the class is also decorated with attr.s!

Parameters
  • default (Any value) –

    A value that is used if an attrs-generated __init__ is used and no value is passed while instantiating or the attribute is excluded using init=False.

    If the value is an instance of Factory, its callable will be used to construct a new value (useful for mutable data types like lists or dicts).

    If a default is not set (or set manually to attr.NOTHING), a value must be supplied when instantiating; otherwise a TypeError will be raised.

    The default can also be set using decorator notation as shown below.

  • factory (callable) – Syntactic sugar for default=attr.Factory(factory).

  • validator (callable or a list of callables.) –

    callable that is called by attrs-generated __init__ methods after the instance has been initialized. They receive the initialized instance, the Attribute, and the passed value.

    The return value is not inspected so the validator has to throw an exception itself.

    If a list is passed, its items are treated as validators and must all pass.

    Validators can be globally disabled and re-enabled using get_run_validators.

    The validator can also be set using decorator notation as shown below.

  • repr (a bool or a callable to use a custom function.) – Include this attribute in the generated __repr__ method. If True, include the attribute; if False, omit it. By default, the built-in repr() function is used. To override how the attribute value is formatted, pass a callable that takes a single value and returns a string. Note that the resulting string is used as-is, i.e. it will be used directly instead of calling repr() (the default).

  • eq (bool) – If True (default), include this attribute in the generated __eq__ and __ne__ methods that check two instances for equality.

  • order (bool) – If True (default), include this attributes in the generated __lt__, __le__, __gt__ and __ge__ methods.

  • cmp (bool) – Setting to True is equivalent to setting eq=True, order=True. Deprecated in favor of eq and order.

  • hash (Optional[bool]) – Include this attribute in the generated __hash__ method. If None (default), mirror eq’s value. This is the correct behavior according the Python spec. Setting this value to anything else than None is discouraged.

  • init (bool) – Include this attribute in the generated __init__ method. It is possible to set this to False and set a default value. In that case this attributed is unconditionally initialized with the specified default value or factory.

  • converter (callable) – callable that is called by attrs-generated __init__ methods to convert attribute’s value to the desired format. It is given the passed-in value, and the returned value will be used as the new value of the attribute. The value is converted before being passed to the validator, if any.

  • metadata – An arbitrary mapping, to be used by third-party components. See Metadata.

  • type

    The type of the attribute. In Python 3.6 or greater, the preferred method to specify the type is using a variable annotation (see PEP 526). This argument is provided for backward compatibility. Regardless of the approach used, the type will be stored on Attribute.type.

    Please note that attrs doesn’t do anything with this metadata by itself. You can use it as part of your own code or for static type checking.

  • kw_only – Make this attribute keyword-only (Python 3+) in the generated __init__ (if init is False, this parameter is ignored).

  • on_setattr (callable, or a list of callables, or None, or attr.setters.NO_OP) – Allows to overwrite the on_setattr setting from attr.s. If left None, the on_setattr value from attr.s is used. Set to attr.setters.NO_OP to run no setattr hooks for this attribute – regardless of the setting in attr.s.

New in version 15.2.0: convert

New in version 16.3.0: metadata

Changed in version 17.1.0: validator can be a list now.

Changed in version 17.1.0: hash is None and therefore mirrors eq by default.

New in version 17.3.0: type

Deprecated since version 17.4.0: convert

New in version 17.4.0: converter as a replacement for the deprecated convert to achieve consistency with other noun-based arguments.

New in version 18.1.0: factory=f is syntactic sugar for default=attr.Factory(f).

New in version 18.2.0: kw_only

Changed in version 19.2.0: convert keyword argument removed

Changed in version 19.2.0: repr also accepts a custom callable.

Deprecated since version 19.2.0: cmp Removal on or after 2021-06-01.

New in version 19.2.0: eq and order

New in version 20.1.0: on_setattr

Note

attrs also comes with a serious business alias attr.attrib.

The object returned by attr.ib also allows for setting the default and the validator using decorators:

>>> @attr.s
... class C(object):
...     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
class attr.Attribute(name, default, validator, repr, cmp, hash, init, inherited, metadata=None, type=None, converter=None, kw_only=False, eq=None, order=None, on_setattr=None)

Read-only representation of an attribute.

Attribute name

The name of the attribute.

Attribute inherited

Whether or not that attribute has been inherited from a base class.

Plus all arguments of attr.ib (except for factory which is only syntactic sugar for default=Factory(...).

New in version 20.1.0: inherited

New in version 20.1.0: on_setattr

Changed in version 20.2.0: inherited is not taken into account for equality checks and hashing anymore.

For the full version history of the fields, see attr.ib.

Instances of this class are frequently used for introspection purposes like:

  • fields returns a tuple of them.

  • Validators get them passed as the first argument.

Warning

You should never instantiate this class yourself!

>>> import attr
>>> @attr.s
... class C(object):
...     x = attr.ib()
>>> attr.fields(C).x
Attribute(name='x', default=NOTHING, validator=None, repr=True, eq=True, order=True, hash=None, init=True, metadata=mappingproxy({}), type=None, converter=None, kw_only=False, inherited=False, on_setattr=None)
attr.make_class(name, attrs, bases=(<class 'object'>, ), **attributes_arguments)

A quick way to create a new class called name with attrs.

Parameters
  • name (str) – The name for the new class.

  • attrs (list or dict) –

    A list of names or a dictionary of mappings of names to attributes.

    If attrs is a list or an ordered dict (dict on Python 3.6+, collections.OrderedDict otherwise), the order is deduced from the order of the names or attributes inside attrs. Otherwise the order of the definition of the attributes is used.

  • bases (tuple) – Classes that the new class will subclass.

  • attributes_arguments – Passed unmodified to attr.s.

Returns

A new class with attrs.

Return type

type

New in version 17.1.0: bases

Changed in version 18.1.0: If attrs is ordered, the order is retained.

This is handy if you want to programmatically create classes.

For example:

>>> C1 = attr.make_class("C1", ["x", "y"])
>>> C1(1, 2)
C1(x=1, y=2)
>>> C2 = attr.make_class("C2", {"x": attr.ib(default=42),
...                             "y": attr.ib(default=attr.Factory(list))})
>>> C2()
C2(x=42, y=[])
class attr.Factory(factory, takes_self=False)

Stores a factory callable.

If passed as the default value to attr.ib, the factory is used to generate a new value.

Parameters
  • factory (callable) – A callable that takes either none or exactly one mandatory positional argument depending on takes_self.

  • takes_self (bool) – Pass the partially initialized instance that is being initialized as a positional argument.

New in version 17.1.0: takes_self

For example:

>>> @attr.s
... class C(object):
...     x = attr.ib(default=attr.Factory(list))
...     y = attr.ib(default=attr.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})

Exceptions

exception attr.exceptions.PythonTooOldError

It was attempted to use an attrs feature that requires a newer Python version.

New in version 18.2.0.

exception attr.exceptions.FrozenError

A frozen/immutable instance or attribute haave been attempted to be modified.

It mirrors the behavior of namedtuples by using the same error message and subclassing AttributeError.

New in version 20.1.0.

exception attr.exceptions.FrozenInstanceError

A frozen instance has been attempted to be modified.

New in version 16.1.0.

exception attr.exceptions.FrozenAttributeError

A frozen attribute has been attempted to be modified.

New in version 20.1.0.

exception attr.exceptions.AttrsAttributeNotFoundError

An attrs function couldn’t find an attribute that the user asked for.

New in version 16.2.0.

exception attr.exceptions.NotAnAttrsClassError

A non-attrs class has been passed into an attrs function.

New in version 16.2.0.

exception attr.exceptions.DefaultAlreadySetError

A default has been set using attr.ib() and is attempted to be reset using the decorator.

New in version 17.1.0.

exception attr.exceptions.UnannotatedAttributeError

A class with auto_attribs=True has an attr.ib() without a type annotation.

New in version 17.3.0.

exception attr.exceptions.NotCallableError(msg, value)

A attr.ib() requiring a callable has been set with a value that is not callable.

New in version 19.2.0.

For example:

@attr.s(auto_attribs=True)
class C:
    x: int
    y = attr.ib()  # <- ERROR!

Helpers

attrs comes with a bunch of helper methods that make working with it easier:

attr.fields(cls)

Return the tuple of attrs attributes for a class.

The tuple also allows accessing the fields by their names (see below for examples).

Parameters

cls (type) – Class to introspect.

Raises
Return type

tuple (with name accessors) of attr.Attribute

Changed in version 16.2.0: Returned tuple allows accessing the fields by name.

For example:

>>> @attr.s
... class C(object):
...     x = attr.ib()
...     y = attr.ib()
>>> attr.fields(C)
(Attribute(name='x', default=NOTHING, validator=None, repr=True, eq=True, order=True, hash=None, init=True, metadata=mappingproxy({}), type=None, converter=None, kw_only=False, inherited=False, on_setattr=None), Attribute(name='y', default=NOTHING, validator=None, repr=True, eq=True, order=True, hash=None, init=True, metadata=mappingproxy({}), type=None, converter=None, kw_only=False, inherited=False, on_setattr=None))
>>> attr.fields(C)[1]
Attribute(name='y', default=NOTHING, validator=None, repr=True, eq=True, order=True, hash=None, init=True, metadata=mappingproxy({}), type=None, converter=None, kw_only=False, inherited=False, on_setattr=None)
>>> attr.fields(C).y is attr.fields(C)[1]
True
attr.fields_dict(cls)

Return an ordered dictionary of attrs attributes for a class, whose keys are the attribute names.

Parameters

cls (type) – Class to introspect.

Raises
Return type

an ordered dict where keys are attribute names and values are attr.Attributes. This will be a dict if it’s naturally ordered like on Python 3.6+ or an OrderedDict otherwise.

New in version 18.1.0.

For example:

>>> @attr.s
... class C(object):
...     x = attr.ib()
...     y = attr.ib()
>>> attr.fields_dict(C)
{'x': Attribute(name='x', default=NOTHING, validator=None, repr=True, eq=True, order=True, hash=None, init=True, metadata=mappingproxy({}), type=None, converter=None, kw_only=False, inherited=False, on_setattr=None), 'y': Attribute(name='y', default=NOTHING, validator=None, repr=True, eq=True, order=True, hash=None, init=True, metadata=mappingproxy({}), type=None, converter=None, kw_only=False, inherited=False, on_setattr=None)}
>>> attr.fields_dict(C)['y']
Attribute(name='y', default=NOTHING, validator=None, repr=True, eq=True, order=True, hash=None, init=True, metadata=mappingproxy({}), type=None, converter=None, kw_only=False, inherited=False, on_setattr=None)
>>> attr.fields_dict(C)['y'] is attr.fields(C).y
True
attr.has(cls)

Check whether cls is a class with attrs attributes.

Parameters

cls (type) – Class to introspect.

Raises

TypeError – If cls is not a class.

Return type

bool

For example:

>>> @attr.s
... class C(object):
...     pass
>>> attr.has(C)
True
>>> attr.has(object)
False
attr.resolve_types(cls, globalns=None, localns=None)

Resolve any strings and forward annotations in type annotations.

This is only required if you need concrete types in Attribute’s type field. In other words, you don’t need to resolve your types if you only use them for static type checking.

With no arguments, names will be looked up in the module in which the class was created. If this is not what you want, e.g. if the name only exists inside a method, you may pass globalns or localns to specify other dictionaries in which to look up these names. See the docs of typing.get_type_hints for more details.

Parameters
  • cls (type) – Class to resolve.

  • globalns (Optional[dict]) – Dictionary containing global variables.

  • localns (Optional[dict]) – Dictionary containing local variables.

Raises
Returns

cls so you can use this function also as a class decorator. Please note that you have to apply it after attr.s. That means the decorator has to come in the line before attr.s.

New in version 20.1.0.

For example:

>>> import typing
>>> @attr.s(auto_attribs=True)
... class A:
...     a: typing.List['A']
...     b: 'B'
...
>>> @attr.s(auto_attribs=True)
... class B:
...     a: A
...
>>> attr.fields(A).a.type
typing.List[ForwardRef('A')]
>>> attr.fields(A).b.type
'B'
>>> attr.resolve_types(A, globals(), locals())
<class 'A'>
>>> attr.fields(A).a.type
typing.List[A]
>>> attr.fields(A).b.type
<class 'B'>
attr.asdict(inst, recurse=True, filter=None, dict_factory=<class 'dict'>, retain_collection_types=False)

Return the attrs attribute values of inst as a dict.

Optionally recurse into other attrs-decorated classes.

Parameters
  • inst – Instance of an attrs-decorated class.

  • recurse (bool) – Recurse into classes that are also attrs-decorated.

  • filter (callable) – A callable whose return code determines whether an attribute or element is included (True) or dropped (False). Is called with the attr.Attribute as the first argument and the value as the second argument.

  • dict_factory (callable) – A callable to produce dictionaries from. For example, to produce ordered dictionaries instead of normal Python dictionaries, pass in collections.OrderedDict.

  • retain_collection_types (bool) – Do not convert to list when encountering an attribute whose type is tuple or set. Only meaningful if recurse is True.

Return type

return type of dict_factory

Raises

attr.exceptions.NotAnAttrsClassError – If cls is not an attrs class.

New in version 16.0.0: dict_factory

New in version 16.1.0: retain_collection_types

For example:

>>> @attr.s
... class C(object):
...     x = attr.ib()
...     y = attr.ib()
>>> attr.asdict(C(1, C(2, 3)))
{'x': 1, 'y': {'x': 2, 'y': 3}}
attr.astuple(inst, recurse=True, filter=None, tuple_factory=<class 'tuple'>, retain_collection_types=False)

Return the attrs attribute values of inst as a tuple.

Optionally recurse into other attrs-decorated classes.

Parameters
  • inst – Instance of an attrs-decorated class.

  • recurse (bool) – Recurse into classes that are also attrs-decorated.

  • filter (callable) – A callable whose return code determines whether an attribute or element is included (True) or dropped (False). Is called with the attr.Attribute as the first argument and the value as the second argument.

  • tuple_factory (callable) – A callable to produce tuples from. For example, to produce lists instead of tuples.

  • retain_collection_types (bool) – Do not convert to list or dict when encountering an attribute which type is tuple, dict or set. Only meaningful if recurse is True.

Return type

return type of tuple_factory

Raises

attr.exceptions.NotAnAttrsClassError – If cls is not an attrs class.

New in version 16.2.0.

For example:

>>> @attr.s
... class C(object):
...     x = attr.ib()
...     y = attr.ib()
>>> attr.astuple(C(1,2))
(1, 2)

attrs includes some handy helpers for filtering the attributes in attr.asdict and attr.astuple:

attr.filters.include(*what)

Whitelist what.

Parameters

what (list of type or attr.Attributes) – What to whitelist.

Return type

callable

attr.filters.exclude(*what)

Blacklist what.

Parameters

what (list of classes or attr.Attributes.) – What to blacklist.

Return type

callable

See asdict() for examples.

attr.evolve(inst, **changes)

Create a new instance, based on inst with changes applied.

Parameters
  • inst – Instance of a class with attrs attributes.

  • changes – Keyword changes in the new copy.

Returns

A copy of inst with changes incorporated.

Raises

New in version 17.1.0.

For example:

>>> @attr.s
... class C(object):
...     x = attr.ib()
...     y = attr.ib()
>>> i1 = C(1, 2)
>>> i1
C(x=1, y=2)
>>> i2 = attr.evolve(i1, y=3)
>>> i2
C(x=1, y=3)
>>> i1 == i2
False

evolve creates a new instance using __init__. This fact has several implications:

  • private attributes should be specified without the leading underscore, just like in __init__.

  • attributes with init=False can’t be set with evolve.

  • the usual __init__ validators will validate the new values.

attr.validate(inst)

Validate all attributes on inst that have a validator.

Leaves all exceptions through.

Parameters

inst – Instance of a class with attrs attributes.

For example:

>>> @attr.s
... class C(object):
...     x = attr.ib(validator=attr.validators.instance_of(int))
>>> i = C(1)
>>> i.x = "1"
>>> attr.validate(i)
Traceback (most recent call last):
   ...
TypeError: ("'x' must be <class 'int'> (got '1' that is a <class 'str'>).", ...)

Validators can be globally disabled if you want to run them only in development and tests but not in production because you fear their performance impact:

attr.set_run_validators(run)

Set whether or not validators are run. By default, they are run.

attr.get_run_validators()

Return whether or not validators are run.

Validators

attrs comes with some common validators in the attrs.validators module:

attr.validators.instance_of(type)

A validator that raises a TypeError if the initializer is called with a wrong type for this particular attribute (checks are performed using isinstance therefore it’s also valid to pass a tuple of types).

Parameters

type (type or tuple of types) – The type to check for.

Raises

TypeError – With a human readable error message, the attribute (of type attr.Attribute), the expected type, and the value it got.

For example:

>>> @attr.s
... class C(object):
...     x = attr.ib(validator=attr.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, validator=<instance_of validator for type <type 'int'>>, type=None, kw_only=False), <type 'int'>, '42')
>>> C(None)
Traceback (most recent call last):
   ...
TypeError: ("'x' must be <type 'int'> (got None that is a <type 'NoneType'>).", Attribute(name='x', default=NOTHING, validator=<instance_of validator for type <type 'int'>>, repr=True, cmp=True, hash=None, init=True, type=None, kw_only=False), <type 'int'>, None)
attr.validators.in_(options)

A validator that raises a ValueError if the initializer is called with a value that does not belong in the options provided. The check is performed using value in options.

Parameters

options (list, tuple, enum.Enum, …) – Allowed options.

Raises

ValueError – With a human readable error message, the attribute (of type attr.Attribute), the expected options, and the value it got.

New in version 17.1.0.

For example:

>>> import enum
>>> class State(enum.Enum):
...     ON = "on"
...     OFF = "off"
>>> @attr.s
... class C(object):
...     state = attr.ib(validator=attr.validators.in_(State))
...     val = attr.ib(validator=attr.validators.in_([1, 2, 3]))
>>> C(State.ON, 1)
C(state=<State.ON: 'on'>, val=1)
>>> C("on", 1)
Traceback (most recent call last):
   ...
ValueError: 'state' must be in <enum 'State'> (got 'on')
>>> C(State.ON, 4)
Traceback (most recent call last):
   ...
ValueError: 'val' must be in [1, 2, 3] (got 4)
attr.validators.provides(interface)

A validator that raises a TypeError if the initializer is called with an object that does not provide the requested interface (checks are performed using interface.providedBy(value) (see zope.interface).

Parameters

interface (zope.interface.Interface) – The interface to check for.

Raises

TypeError – With a human readable error message, the attribute (of type attr.Attribute), the expected interface, and the value it got.

attr.validators.and_(*validators)

A validator that composes multiple validators into one.

When called on a value, it runs all wrapped validators.

Parameters

validators (callables) – Arbitrary number of validators.

New in version 17.1.0.

For convenience, it’s also possible to pass a list to attr.ib’s validator argument.

Thus the following two statements are equivalent:

x = attr.ib(validator=attr.validators.and_(v1, v2, v3))
x = attr.ib(validator=[v1, v2, v3])
attr.validators.optional(validator)

A validator that makes an attribute optional. An optional attribute is one which can be set to None in addition to satisfying the requirements of the sub-validator.

Parameters

validator (callable or list of callables.) – A validator (or a list of validators) that is used for non-None values.

New in version 15.1.0.

Changed in version 17.1.0: validator can be a list of validators.

For example:

>>> @attr.s
... class C(object):
...     x = attr.ib(validator=attr.validators.optional(attr.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, validator=<instance_of validator for type <type 'int'>>, type=None, kw_only=False), <type 'int'>, '42')
>>> C(None)
C(x=None)
attr.validators.is_callable()

A validator that raises a attr.exceptions.NotCallableError if the initializer is called with a value for this particular attribute that is not callable.

New in version 19.1.0.

Raises

attr.exceptions.NotCallableError – With a human readable error message containing the attribute (attr.Attribute) name, and the value it got.

For example:

>>> @attr.s
... class C(object):
...     x = attr.ib(validator=attr.validators.is_callable())
>>> C(isinstance)
C(x=<built-in function isinstance>)
>>> C("not a callable")
Traceback (most recent call last):
    ...
attr.exceptions.NotCallableError: 'x' must be callable (got 'not a callable' that is a <class 'str'>).
attr.validators.matches_re(regex, flags=0, func=None)

A validator that raises ValueError if the initializer is called with a string that doesn’t match regex.

Parameters
  • regex (str) – a regex string to match against

  • flags (int) – flags that will be passed to the underlying re function (default 0)

  • func (callable) – which underlying re function to call (options are re.fullmatch, re.search, re.match, default is None which means either re.fullmatch or an emulation of it on Python 2). For performance reasons, they won’t be used directly but on a pre-re.compileed pattern.

New in version 19.2.0.

For example:

>>> @attr.s
... class User(object):
...     email = attr.ib(validator=attr.validators.matches_re(
...         "(^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$)"))
>>> User(email="user@example.com")
User(email='user@example.com')
>>> User(email="user@example.com@test.com")
Traceback (most recent call last):
    ...
ValueError: ("'email' must match regex '(^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\\\\.[a-zA-Z0-9-.]+$)' ('user@example.com@test.com' doesn't)", Attribute(name='email', default=NOTHING, validator=<matches_re validator for pattern re.compile('(^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\\.[a-zA-Z0-9-.]+$)')>, repr=True, cmp=True, hash=None, init=True, metadata=mappingproxy({}), type=None, converter=None, kw_only=False), re.compile('(^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\\.[a-zA-Z0-9-.]+$)'), 'user@example.com@test.com')
attr.validators.deep_iterable(member_validator, iterable_validator=None)

A validator that performs deep validation of an iterable.

Parameters
  • member_validator – Validator to apply to iterable members

  • iterable_validator – Validator to apply to iterable itself (optional)

New in version 19.1.0.

Raises

TypeError – if any sub-validators fail

For example:

>>> @attr.s
... class C(object):
...     x = attr.ib(validator=attr.validators.deep_iterable(
...     member_validator=attr.validators.instance_of(int),
...     iterable_validator=attr.validators.instance_of(list)
...     ))
>>> C(x=[1, 2, 3])
C(x=[1, 2, 3])
>>> C(x=set([1, 2, 3]))
Traceback (most recent call last):
    ...
TypeError: ("'x' must be <class 'list'> (got {1, 2, 3} that is a <class 'set'>).", Attribute(name='x', default=NOTHING, validator=<deep_iterable validator for <instance_of validator for type <class 'list'>> iterables of <instance_of validator for type <class 'int'>>>, repr=True, cmp=True, hash=None, init=True, metadata=mappingproxy({}), type=None, converter=None, kw_only=False), <class 'list'>, {1, 2, 3})
>>> C(x=[1, 2, "3"])
Traceback (most recent call last):
    ...
TypeError: ("'x' must be <class 'int'> (got '3' that is a <class 'str'>).", Attribute(name='x', default=NOTHING, validator=<deep_iterable validator for <instance_of validator for type <class 'list'>> iterables of <instance_of validator for type <class 'int'>>>, repr=True, cmp=True, hash=None, init=True, metadata=mappingproxy({}), type=None, converter=None, kw_only=False), <class 'int'>, '3')
attr.validators.deep_mapping(key_validator, value_validator, mapping_validator=None)

A validator that performs deep validation of a dictionary.

Parameters
  • key_validator – Validator to apply to dictionary keys

  • value_validator – Validator to apply to dictionary values

  • mapping_validator – Validator to apply to top-level mapping attribute (optional)

New in version 19.1.0.

Raises

TypeError – if any sub-validators fail

For example:

>>> @attr.s
... class C(object):
...     x = attr.ib(validator=attr.validators.deep_mapping(
...         key_validator=attr.validators.instance_of(str),
...         value_validator=attr.validators.instance_of(int),
...         mapping_validator=attr.validators.instance_of(dict)
...     ))
>>> C(x={"a": 1, "b": 2})
C(x={'a': 1, 'b': 2})
>>> C(x=None)
Traceback (most recent call last):
    ...
TypeError: ("'x' must be <class 'dict'> (got None that is a <class 'NoneType'>).", Attribute(name='x', default=NOTHING, validator=<deep_mapping validator for objects mapping <instance_of validator for type <class 'str'>> to <instance_of validator for type <class 'int'>>>, repr=True, cmp=True, hash=None, init=True, metadata=mappingproxy({}), type=None, converter=None, kw_only=False), <class 'dict'>, None)
>>> C(x={"a": 1.0, "b": 2})
Traceback (most recent call last):
    ...
TypeError: ("'x' must be <class 'int'> (got 1.0 that is a <class 'float'>).", Attribute(name='x', default=NOTHING, validator=<deep_mapping validator for objects mapping <instance_of validator for type <class 'str'>> to <instance_of validator for type <class 'int'>>>, repr=True, cmp=True, hash=None, init=True, metadata=mappingproxy({}), type=None, converter=None, kw_only=False), <class 'int'>, 1.0)
>>> C(x={"a": 1, 7: 2})
Traceback (most recent call last):
    ...
TypeError: ("'x' must be <class 'str'> (got 7 that is a <class 'int'>).", Attribute(name='x', default=NOTHING, validator=<deep_mapping validator for objects mapping <instance_of validator for type <class 'str'>> to <instance_of validator for type <class 'int'>>>, repr=True, cmp=True, hash=None, init=True, metadata=mappingproxy({}), type=None, converter=None, kw_only=False), <class 'str'>, 7)

Converters

attr.converters.pipe(*converters)

A converter that composes multiple converters into one.

When called on a value, it runs all wrapped converters, returning the last value.

Parameters

converters (callables) – Arbitrary number of converters.

New in version 20.1.0.

For convenience, it’s also possible to pass a list to attr.ib’s converter argument.

Thus the following two statements are equivalent:

x = attr.ib(converter=attr.converter.pipe(c1, c2, c3))
x = attr.ib(converter=[c1, c2, c3])
attr.converters.optional(converter)

A converter that allows an attribute to be optional. An optional attribute is one which can be set to None.

Parameters

converter (callable) – the converter that is used for non-None values.

New in version 17.1.0.

For example:

>>> @attr.s
... class C(object):
...     x = attr.ib(converter=attr.converters.optional(int))
>>> C(None)
C(x=None)
>>> C(42)
C(x=42)
attr.converters.default_if_none(default=NOTHING, factory=None)

A converter that allows to replace None values by default or the result of factory.

Parameters
  • default – Value to be used if None is passed. Passing an instance of attr.Factory is supported, however the takes_self option is not.

  • factory (callable) – A callable that takes not parameters whose result is used if None is passed.

Raises

New in version 18.2.0.

For example:

>>> @attr.s
... class C(object):
...     x = attr.ib(
...         converter=attr.converters.default_if_none("")
...     )
>>> C(None)
C(x='')

Setters

These are helpers that you can use together with attr.s’s and attr.ib’s on_setattr arguments.

attr.setters.frozen(_, __, ___)

Prevent an attribute to be modified.

New in version 20.1.0.

attr.setters.validate(instance, attrib, new_value)

Run attrib’s validator on new_value if it has one.

New in version 20.1.0.

attr.setters.convert(instance, attrib, new_value)

Run attrib’s converter – if it has one – on new_value and return the result.

New in version 20.1.0.

attr.setters.pipe(*setters)

Run all setters and return the return value of the last one.

New in version 20.1.0.

attr.setters.NO_OP = <object object>

Sentinel for disabling class-wide on_setattr hooks for certain attributes.

Does not work in pipe or within lists.

New in version 20.1.0.

For example, only x is frozen here:

>>> @attr.s(on_setattr=attr.setters.frozen)
... class C(object):
...     x = attr.ib()
...     y = attr.ib(on_setattr=attr.setters.NO_OP)
>>> c = C(1, 2)
>>> c.y = 3
>>> c.y
3
>>> c.x = 4
Traceback (most recent call last):
    ...
attr.exceptions.FrozenAttributeError: ()

N.B. Please use attr.s’s frozen argument to freeze whole classes; it is more efficient.

Provisional APIs

These are Python 3.6 and later-only, keyword-only, and provisional APIs that call attr.s with different default values.

The most notable differences are:

  • automatically detect whether or not auto_attribs should be True

  • slots=True (see slotted classes)

  • auto_exc=True

  • auto_detect=True

  • eq=True, but order=False

  • Validators run when you set an attribute (on_setattr=attr.setters.validate).

  • Some options that aren’t relevant to Python 3 have been dropped.

Please note that these are defaults and you’re free to override them, just like before.


Their behavior is scheduled to become part of the upcoming import attrs that will introduce a new namespace with nicer names and nicer defaults (see #408 and #487).

Therefore your constructive feedback in the linked issues above is strongly encouraged!

Note

Provisional doesn’t mean we will remove it (although it will be deprecated once the final form is released), but that it might change if we receive relevant feedback.

attr.s and attr.ib (and their serious business cousins) aren’t going anywhere. The new APIs build on top of them.

attr.define(maybe_cls=None, *, these=None, repr=None, hash=None, init=None, slots=True, frozen=False, weakref_slot=True, str=False, auto_attribs=None, kw_only=False, cache_hash=False, auto_exc=True, eq=None, order=False, auto_detect=True, getstate_setstate=None, on_setattr=None)

The only behavioral differences are the handling of the auto_attribs option:

Parameters

auto_attribs (Optional[bool]) –

If set to True or False, it behaves exactly like attr.s. If left None, attr.s will try to guess:

  1. If all attributes are annotated and no attr.ib is found, it assumes auto_attribs=True.

  2. Otherwise it assumes auto_attribs=False and tries to collect attr.ibs.

and that mutable classes (frozen=False) validate on __setattr__.

New in version 20.1.0.

attr.mutable(same_as_define)

Alias for attr.define.

New in version 20.1.0.

attr.frozen(same_as_define)

Behaves the same as attr.define but sets frozen=True and on_setattr=None.

New in version 20.1.0.

attr.field(*, default=NOTHING, validator=None, repr=True, hash=None, init=True, metadata=None, converter=None, factory=None, kw_only=False, eq=None, order=None, on_setattr=None)

Identical to attr.ib, except keyword-only and with some arguments removed.

New in version 20.1.0.

Deprecated APIs

To help you write backward compatible code that doesn’t throw warnings on modern releases, the attr module has an __version_info__ attribute as of version 19.2.0. It behaves similarly to sys.version_info and is an instance of VersionInfo:

class attr.VersionInfo(year: int, minor: int, micro: int, releaselevel: str)

A version object that can be compared to tuple of length 1–4:

>>> attr.VersionInfo(19, 1, 0, "final")  <= (19, 2)
True
>>> attr.VersionInfo(19, 1, 0, "final") < (19, 1, 1)
True
>>> vi = attr.VersionInfo(19, 2, 0, "final")
>>> vi < (19, 1, 1)
False
>>> vi < (19,)
False
>>> vi == (19, 2,)
True
>>> vi == (19, 2, 1)
False

New in version 19.2.

With its help you can write code like this:

>>> 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)
... class C(object):
...     pass

The serious business aliases used to be called attr.attributes and attr.attr. There are no plans to remove them but they shouldn’t be used in new code.

The cmp argument to both attr.s and attr.ib has been deprecated in 19.2 and shouldn’t be used.

attr.assoc(inst, **changes)

Copy inst and apply changes.

Parameters
  • inst – Instance of a class with attrs attributes.

  • changes – Keyword changes in the new copy.

Returns

A copy of inst with changes incorporated.

Raises

Deprecated since version 17.1.0: Use evolve instead.