API Reference#

attrs works by decorating a class using attrs.define or attr.s and then defining attributes on the class using attrs.field, attr.ib, or type annotations.

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

If you’re confused by the many names, please check out On The Core API Names for clarification, but the TL;DR is that as of version 21.3.0, attrs consists of two top-level package names:

  • The classic attr that powers the venerable attr.s and attr.ib.

  • The newer attrs that only contains most modern APIs and relies on attrs.define and attrs.field to define your classes. Additionally it offers some attr APIs with nicer defaults (e.g. attrs.asdict).

The attrs namespace is built on top of attr – which will never go away – and is just as stable, since it doesn’t constitute a rewrite. To keep repetition low and this document at a reasonable size, the attr namespace is documented on a separate page, though.

Core#

attrs.NOTHING#

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

If extending attrs, you can use typing.Literal[NOTHING] to show that a value may be NOTHING.

Changed in version 21.1.0: bool(NOTHING) is now False.

Changed in version 22.2.0: NOTHING is now an enum.Enum variant.

attrs.define(maybe_cls=None, *, these=None, repr=None, unsafe_hash=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, field_transformer=None, match_args=True)#

Define an attrs class.

Differences to the classic attr.s that it uses underneath:

  • Automatically detect whether or not auto_attribs should be True (c.f. auto_attribs parameter).

  • Converters and validators run when attributes are set by default – if frozen is False.

  • slots=True

    Caution

    Usually this has only upsides and few visible effects in everyday programming. But it can lead to some surprising behaviors, so please make sure to read slotted classes.

  • auto_exc=True

  • auto_detect=True

  • order=False

  • Some options that were only relevant on Python 2 or were kept around for backwards-compatibility have been removed.

Please note that these are all defaults and you can change them as you wish.

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 any attributes are annotated and no unannotated attrs.fieldss are found, it assumes auto_attribs=True.

  2. Otherwise it assumes auto_attribs=False and tries to collect attrs.fieldss.

For now, please refer to attr.s for the rest of the parameters.

New in version 20.1.0.

Changed in version 21.3.0: Converters are also run on_setattr.

New in version 22.2.0: unsafe_hash as an alias for hash (for PEP 681 compliance).

attrs.mutable(same_as_define)#

Same as attrs.define.

New in version 20.1.0.

attrs.frozen(same_as_define)#

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

New in version 20.1.0.

attrs.field(*, default=_Nothing.NOTHING, validator=None, repr=True, hash=None, init=True, metadata=None, type=None, converter=None, factory=None, kw_only=False, eq=None, order=None, on_setattr=None, alias=None)#

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

New in version 23.1.0: The type parameter has been re-added; mostly for attrs.make_class. Please note that type checkers ignore this metadata.

New in version 20.1.0.

class attrs.Attribute(name, default, validator, repr, cmp, hash, init, inherited, metadata=None, type=None, converter=None, kw_only=False, eq=None, eq_key=None, order=None, order_key=None, on_setattr=None, alias=None)#

Read-only representation of an attribute.

Warning

You should never instantiate this class yourself.

The class has all arguments of attr.ib (except for factory which is only syntactic sugar for default=Factory(...) plus the following:

  • name (str): The name of the attribute.

  • alias (str): The __init__ parameter name of the attribute, after any explicit overrides and default private-attribute-name handling.

  • inherited (bool): Whether or not that attribute has been inherited from a base class.

  • eq_key and order_key (typing.Callable or None): The callables that are used for comparing and ordering objects by this attribute, respectively. These are set by passing a callable to attr.ib’s eq, order, or cmp arguments. See also comparison customization.

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.

  • The field transformer hook receives a list of them.

  • The alias property exposes the __init__ parameter name of the field, with any overrides and default private-attribute handling applied.

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.

New in version 21.1.0: eq_key and order_key

New in version 22.2.0: alias

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

For example:

>>> import attrs
>>> from attrs import define, field

>>> @define
... class C:
...     x = field()
>>> attrs.fields(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')
evolve(**changes)#

Copy self and apply changes.

This works similarly to attrs.evolve but that function does not work with Attribute.

It is mainly meant to be used for Automatic Field Transformation and Modification.

New in version 20.3.0.

attrs.make_class(name, attrs, bases=(<class 'object'>, ), class_body=None, **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 attr.ibs / attrs.fields.

    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.

  • class_body (dict) – An optional dictionary of class attributes for the new class.

  • 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.

Changed in version 23.2.0: class_body

This is handy if you want to programmatically create classes.

For example:

>>> 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=[])
class attrs.Factory(factory, takes_self=False)#

Stores a factory callable.

If passed as the default value to attrs.field, 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:

>>> @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})

Exceptions#

All exceptions are available from both attr.exceptions and attrs.exceptions and are the same thing. That means that it doesn’t matter from from which namespace they’ve been raised and/or caught:

>>> import attrs, attr
>>> try:
...     raise attrs.exceptions.FrozenError()
... except attr.exceptions.FrozenError:
...     print("this works!")
this works!
exception attrs.exceptions.PythonTooOldError#

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

New in version 18.2.0.

exception attrs.exceptions.FrozenError#

A frozen/immutable instance or attribute have 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 attrs.exceptions.FrozenInstanceError#

A frozen instance has been attempted to be modified.

New in version 16.1.0.

exception attrs.exceptions.FrozenAttributeError#

A frozen attribute has been attempted to be modified.

New in version 20.1.0.

exception attrs.exceptions.AttrsAttributeNotFoundError#

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

New in version 16.2.0.

exception attrs.exceptions.NotAnAttrsClassError#

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

New in version 16.2.0.

exception attrs.exceptions.DefaultAlreadySetError#

A default has been set when defining the field and is attempted to be reset using the decorator.

New in version 17.1.0.

exception attrs.exceptions.NotCallableError(msg, value)#

A field requiring a callable has been set with a value that is not callable.

New in version 19.2.0.

exception attrs.exceptions.UnannotatedAttributeError#

A class with auto_attribs=True has a field without a type annotation.

New in version 17.3.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:

attrs.cmp_using(eq=None, lt=None, le=None, gt=None, ge=None, require_same_type=True, class_name='Comparable')#

Create a class that can be passed into attrs.field’s eq, order, and cmp arguments to customize field comparison.

The resulting class will have a full set of ordering methods if at least one of {lt, le, gt, ge} and eq are provided.

Parameters:
  • eq (Optional[callable]) – callable used to evaluate equality of two objects.

  • lt (Optional[callable]) – callable used to evaluate whether one object is less than another object.

  • le (Optional[callable]) – callable used to evaluate whether one object is less than or equal to another object.

  • gt (Optional[callable]) – callable used to evaluate whether one object is greater than another object.

  • ge (Optional[callable]) – callable used to evaluate whether one object is greater than or equal to another object.

  • require_same_type (bool) – When True, equality and ordering methods will return NotImplemented if objects are not of the same type.

  • class_name (Optional[str]) – Name of class. Defaults to ‘Comparable’.

See Comparison for more details.

New in version 21.1.0.

attrs.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 attrs.Attribute

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

Changed in version 23.1.0: Add support for generic classes.

For example:

>>> @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
attrs.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:

dict

New in version 18.1.0.

For example:

>>> @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.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:
...     pass
>>> attr.has(C)
True
>>> attr.has(object)
False
attrs.resolve_types(cls, globalns=None, localns=None, attribs=None, include_extras=True)#

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.

  • attribs (Optional[list]) – List of attribs for the given class. This is necessary when calling from inside a field_transformer since cls is not an attrs class yet.

  • include_extras (bool) – Resolve more accurately, if possible. Pass include_extras to typing.get_hints, if supported by the typing module. On supported Python versions (3.9+), this resolves the types more accurately.

Raises:
Returns:

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

New in version 20.1.0.

New in version 21.1.0: attribs

New in version 23.1.0: include_extras

For example:

>>> import typing
>>> @define
... class A:
...     a: typing.List['A']
...     b: 'B'
...
>>> @define
... class B:
...     a: A
...
>>> attrs.fields(A).a.type
typing.List[ForwardRef('A')]
>>> attrs.fields(A).b.type
'B'
>>> attrs.resolve_types(A, globals(), locals())
<class 'A'>
>>> attrs.fields(A).a.type
typing.List[A]
>>> attrs.fields(A).b.type
<class 'B'>
attrs.asdict(inst, *, recurse=True, filter=None, value_serializer=None)#

Same as attr.asdict, except that collections types are always retained and dict is always used as dict_factory.

New in version 21.3.0.

For example:

>>> @define
... class C:
...     x: int
...     y: int
>>> attrs.asdict(C(1, C(2, 3)))
{'x': 1, 'y': {'x': 2, 'y': 3}}
attrs.astuple(inst, *, recurse=True, filter=None)#

Same as attr.astuple, except that collections types are always retained and tuple is always used as the tuple_factory.

New in version 21.3.0.

For example:

>>> @define
... class C:
...     x = field()
...     y = field()
>>> attrs.astuple(C(1,2))
(1, 2)

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

attrs.filters.include(*what)#

Include what.

Parameters:

what (list of classes type, field names str or attrs.Attributes) – What to include.

Return type:

callable

Changed in version 23.1.0: Accept strings with field names.

attrs.filters.exclude(*what)#

Exclude what.

Parameters:

what (list of classes type, field names str or attrs.Attributes.) – What to exclude.

Return type:

callable

Changed in version 23.3.0: Accept field name string as input argument

See attrs.asdict() for examples.

All objects from attrs.filters are also available from attr.filters (it’s the same module in a different namespace).


attrs.evolve(*args, **changes)#

Create a new instance, based on the first positional argument 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.

Deprecated since version 23.1.0: It is now deprecated to pass the instance using the keyword argument inst. It will raise a warning until at least April 2024, after which it will become an error. Always pass the instance as a positional argument.

For example:

>>> @define
... class C:
...     x: int
...     y: int
>>> i1 = C(1, 2)
>>> i1
C(x=1, y=2)
>>> i2 = attrs.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.

attrs.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:

>>> @define(on_setattr=attrs.setters.NO_OP)
... class C:
...     x = field(validator=attrs.validators.instance_of(int))
>>> i = C(1)
>>> i.x = "1"
>>> attrs.validate(i)
Traceback (most recent call last):
   ...
TypeError: ("'x' must be <class 'int'> (got '1' that is a <class 'str'>).", ...)

Validators#

attrs comes with some common validators in the attrs.validators module. All objects from attrs.validators are also available from attr.validators (it’s the same module in a different namespace).

attrs.validators.lt(val)#

A validator that raises ValueError if the initializer is called with a number larger or equal to val.

Parameters:

val – Exclusive upper bound for values

New in version 21.3.0.

For example:

>>> @define
... class C:
...     x = field(validator=attrs.validators.lt(42))
>>> C(41)
C(x=41)
>>> C(42)
Traceback (most recent call last):
   ...
ValueError: ("'x' must be < 42: 42")
attrs.validators.le(val)#

A validator that raises ValueError if the initializer is called with a number greater than val.

Parameters:

val – Inclusive upper bound for values

New in version 21.3.0.

For example:

>>> @define
... class C:
...     x = field(validator=attrs.validators.le(42))
>>> C(42)
C(x=42)
>>> C(43)
Traceback (most recent call last):
   ...
ValueError: ("'x' must be <= 42: 43")
attrs.validators.ge(val)#

A validator that raises ValueError if the initializer is called with a number smaller than val.

Parameters:

val – Inclusive lower bound for values

New in version 21.3.0.

For example:

>>> @define
... class C:
...     x = attrs.field(validator=attrs.validators.ge(42))
>>> C(42)
C(x=42)
>>> C(41)
Traceback (most recent call last):
   ...
ValueError: ("'x' must be => 42: 41")
attrs.validators.gt(val)#

A validator that raises ValueError if the initializer is called with a number smaller or equal to val.

Parameters:

val – Exclusive lower bound for values

New in version 21.3.0.

For example:

>>> @define
... class C:
...     x = field(validator=attrs.validators.gt(42))
>>> C(43)
C(x=43)
>>> C(42)
Traceback (most recent call last):
   ...
ValueError: ("'x' must be > 42: 42")
attrs.validators.max_len(length)#

A validator that raises ValueError if the initializer is called with a string or iterable that is longer than length.

Parameters:

length (int) – Maximum length of the string or iterable

New in version 21.3.0.

For example:

>>> @define
... class C:
...     x = field(validator=attrs.validators.max_len(4))
>>> C("spam")
C(x='spam')
>>> C("bacon")
Traceback (most recent call last):
   ...
ValueError: ("Length of 'x' must be <= 4: 5")
attrs.validators.min_len(length)#

A validator that raises ValueError if the initializer is called with a string or iterable that is shorter than length.

Parameters:

length (int) – Minimum length of the string or iterable

New in version 22.1.0.

For example:

>>> @define
... class C:
...     x = field(validator=attrs.validators.min_len(1))
>>> C("bacon")
C(x='bacon')
>>> C("")
Traceback (most recent call last):
   ...
ValueError: ("Length of 'x' must be => 1: 0")
attrs.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 type) – The type to check for.

Raises:

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

For example:

>>> @define
... class C:
...     x = field(validator=attrs.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)
attrs.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 attrs.Attribute), the expected options, and the value it got.

New in version 17.1.0.

Changed in version 22.1.0: The ValueError was incomplete until now and only contained the human readable error message. Now it contains all the information that has been promised since 17.1.0.

For example:

>>> import enum
>>> class State(enum.Enum):
...     ON = "on"
...     OFF = "off"
>>> @define
... class C:
...     state = field(validator=attrs.validators.in_(State))
...     val = field(validator=attrs.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'), Attribute(name='state', default=NOTHING, validator=<in_ validator with options <enum 'State'>>, 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), <enum 'State'>, 'on')
>>> C(State.ON, 4)
Traceback (most recent call last):
...
ValueError: 'val' must be in [1, 2, 3] (got 4), Attribute(name='val', default=NOTHING, validator=<in_ validator with options [1, 2, 3]>, 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), [1, 2, 3], 4)
attrs.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 attrs.Attribute), the expected interface, and the value it got.

Deprecated since version 23.1.0.

attrs.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 attrs.field’s validator argument.

Thus the following two statements are equivalent:

x = field(validator=attrs.validators.and_(v1, v2, v3))
x = field(validator=[v1, v2, v3])
attrs.validators.not_(validator, *, msg=None, exc_types=(<class 'ValueError'>, <class 'TypeError'>))#

A validator that wraps and logically ‘inverts’ the validator passed to it. It will raise a ValueError if the provided validator doesn’t raise a ValueError or TypeError (by default), and will suppress the exception if the provided validator does.

Intended to be used with existing validators to compose logic without needing to create inverted variants, for example, not_(in_(...)).

Parameters:
  • validator – A validator to be logically inverted.

  • msg (str) – Message to raise if validator fails. Formatted with keys exc_types and validator.

  • exc_types – Exception type(s) to capture. Other types raised by child validators will not be intercepted and pass through.

Raises:

ValueError – With a human readable error message, the attribute (of type attrs.Attribute), the validator that failed to raise an exception, the value it got, and the expected exception types.

New in version 22.2.0.

For example:

>>> reserved_names = {"id", "time", "source"}
>>> @define
... class Measurement:
...     tags = field(
...         validator=attrs.validators.deep_mapping(
...             key_validator=attrs.validators.not_(
...                 attrs.validators.in_(reserved_names),
...                 msg="reserved tag key",
...             ),
...             value_validator=attrs.validators.instance_of((str, int)),
...         )
...     )
>>> Measurement(tags={"source": "universe"})
Traceback (most recent call last):
   ...
ValueError: ("reserved tag key", Attribute(name='tags', default=NOTHING, validator=<not_ validator wrapping <in_ validator with options {'id', 'time', 'source'}>, capturing (<class 'ValueError'>, <class 'TypeError'>)>, type=None, kw_only=False), <in_ validator with options {'id', 'time', 'source'}>, {'source_': 'universe'}, (<class 'ValueError'>, <class 'TypeError'>))
>>> Measurement(tags={"source_": "universe"})
Measurement(tags={'source_': 'universe'})
attrs.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 | tuple[Callable] | list[Callable]) – A validator (or 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.

Changed in version 23.1.0: validator can also be a tuple of validators.

For example:

>>> @define
... class C:
...     x = field(
...         validator=attrs.validators.optional(
...             attrs.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)
attrs.validators.is_callable()#

A validator that raises a attrs.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:

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

For example:

>>> @define
... class C:
...     x = field(validator=attrs.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'>).
attrs.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 – a regex string or precompiled pattern 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. Valid options are re.fullmatch, re.search, and re.match; the default None means re.fullmatch. For performance reasons, the pattern is always precompiled using re.compile.

New in version 19.2.0.

Changed in version 21.3.0: regex can be a pre-compiled pattern.

For example:

>>> @define
... class User:
...     email = field(validator=attrs.validators.matches_re(
...         r"(^[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')
attrs.validators.deep_iterable(member_validator, iterable_validator=None)#

A validator that performs deep validation of an iterable.

Parameters:
  • member_validator – Validator(s) 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:

>>> @define
... class C:
...     x = field(validator=attrs.validators.deep_iterable(
...             member_validator=attrs.validators.instance_of(int),
...             iterable_validator=attrs.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')
attrs.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:

>>> @define
... class C:
...     x = field(validator=attrs.validators.deep_mapping(
...             key_validator=attrs.validators.instance_of(str),
...             value_validator=attrs.validators.instance_of(int),
...             mapping_validator=attrs.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)

Validators can be both globally and locally disabled:

attrs.validators.set_disabled(disabled)#

Globally disable or enable running validators.

By default, they are run.

Parameters:

disabled (bool) – If True, disable running all validators.

Warning

This function is not thread-safe!

New in version 21.3.0.

attrs.validators.get_disabled()#

Return a bool indicating whether validators are currently disabled or not.

Returns:

True if validators are currently disabled.

Return type:

bool

New in version 21.3.0.

attrs.validators.disabled()#

Context manager that disables running validators within its context.

Warning

This context manager is not thread-safe!

New in version 21.3.0.

Converters#

All objects from attrs.converters are also available from attr.converters (it’s the same module in a different namespace).

attrs.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.

Type annotations will be inferred from the wrapped converters’, if they have any.

Parameters:

converters (callables) – Arbitrary number of converters.

New in version 20.1.0.

For convenience, it’s also possible to pass a list to attrs.field / attr.ib’s converter arguments.

Thus the following two statements are equivalent:

x = attrs.field(converter=attrs.converter.pipe(c1, c2, c3))
x = attrs.field(converter=[c1, c2, c3])
attrs.converters.optional(converter)#

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

Type annotations will be inferred from the wrapped converter’s, if it has any.

Parameters:

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

New in version 17.1.0.

For example:

>>> @define
... class C:
...     x = field(converter=attrs.converters.optional(int))
>>> C(None)
C(x=None)
>>> C(42)
C(x=42)
attrs.converters.default_if_none(default=_Nothing.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 attrs.Factory is supported, however the takes_self option is not.

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

Raises:

New in version 18.2.0.

For example:

>>> @define
... class C:
...     x = field(
...         converter=attrs.converters.default_if_none("")
...     )
>>> C(None)
C(x='')
attrs.converters.to_bool(val)#

Convert “boolean” strings (e.g., from env. vars.) to real booleans.

Values mapping to True:

  • True

  • "true" / "t"

  • "yes" / "y"

  • "on"

  • "1"

  • 1

Values mapping to False:

  • False

  • "false" / "f"

  • "no" / "n"

  • "off"

  • "0"

  • 0

Raises:

ValueError – for any other value.

New in version 21.3.0.

For example:

>>> @define
... class C:
...     x = field(
...         converter=attrs.converters.to_bool
...     )
>>> C("yes")
C(x=True)
>>> C(0)
C(x=False)
>>> C("foo")
Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
ValueError: Cannot convert value to bool: foo

Setters#

These are helpers that you can use together with attrs.define’s and attrs.fields’s on_setattr arguments. All setters in attrs.setters are also available from attr.setters (it’s the same module in a different namespace).

attrs.setters.frozen(_, __, ___)#

Prevent an attribute to be modified.

New in version 20.1.0.

attrs.setters.validate(instance, attrib, new_value)#

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

New in version 20.1.0.

attrs.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.

attrs.setters.pipe(*setters)#

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

New in version 20.1.0.

attrs.setters.NO_OP#

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

Does not work in attrs.setters.pipe or within lists.

New in version 20.1.0.

For example, only x is frozen here:

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

N.B. Please use attrs.define’s frozen argument (or attrs.frozen) to freeze whole classes; it is more efficient.