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¶
-
attr.
s
(these=None, repr_ns=None, repr=True, cmp=True, hash=None, init=True, slots=False, frozen=False, str=False)¶ A class decorator that adds dunder-methods according to the specified attributes using
attr.ib()
or the these argument.Parameters: - these (
dict
ofstr
toattr.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. - 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. - repr (bool) – Create a
__repr__
method with a human readable representation ofattrs
attributes.. - str (bool) – Create a
__str__
method that is identical to__repr__
. This is usually not necessary except forException
s. - cmp (bool) – Create
__eq__
,__ne__
,__lt__
,__le__
,__gt__
, and__ge__
methods that compare the class as if it were a tuple of itsattrs
attributes. But the attributes are only compared, if the type of both classes is identical! - hash (
bool
orNone
) –If
None
(default), the__hash__
method is generated according how cmp and frozen are set.- If both are True,
attrs
will generate a__hash__
for you. - If cmp is True and frozen is False,
__hash__
will be set to None, marking it unhashable (which it is). - If cmp is False,
__hash__
will be left untouched meaning the__hash__
method of the superclass will be used (if superclass isobject
, 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 passingTrue
or not. Both of these cases are rather special and should be used carefully.See the Python documentation and the GitHub issue that led to the default behavior for more details.
- If both are True,
- init (bool) – Create a
__init__
method that initializes theattrs
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 slots-style class that’s more memory-efficient. See Slots for further ramifications.
- frozen (bool) –
Make instances immutable after initialization. If someone attempts to modify a frozen instance,
attr.exceptions.FrozenInstanceError
is raised.Please note:
- This is achieved by installing a custom
__setattr__
method on your class so you can’t implement an own one. - True immutability is impossible in Python.
- This does have a minor a runtime performance impact when initializing new instances. In other words:
__init__
is slightly slower withfrozen=True
. - If a class is frozen, you cannot modify
self
in__attrs_post_init__
or a self-written__init__
. You can circumvent that limitation by usingobject.__setattr__(self, "attribute_name", value)
.
- This is achieved by installing a custom
- 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 anattr.ib()
but lacks a type annotation, anattr.exceptions.UnannotatedAttributeError
is raised. Usefield_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 usingattr.ib(default=42)
. Passing an instance ofFactory
also works as expected.Attributes annotated as
typing.ClassVar
are ignored.
New in version 16.0.0: slots
New in version 16.1.0: frozen
New in version 16.3.0: str, and 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
Note
attrs
also comes with a serious business aliasattr.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)
- these (
-
attr.
ib
(default=NOTHING, validator=None, repr=True, cmp=True, hash=None, init=True, convert=None, metadata={}, type=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 usinginit=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 aTypeError
will be raised.The default can also be set using decorator notation as shown below.
- validator (
callable
or alist
ofcallable
s.) –callable()
that is called byattrs
-generated__init__
methods after the instance has been initialized. They receive the initialized instance, theAttribute
, 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 (bool) – Include this attribute in the generated
__repr__
method. - cmp (bool) – Include this attribute in the generated comparison methods
(
__eq__
et al). - hash (
bool
orNone
) – Include this attribute in the generated__hash__
method. IfNone
(default), mirror cmp’s value. This is the correct behavior according the Python spec. Setting this value to anything else thanNone
is discouraged. - init (bool) – Include this attribute in the generated
__init__
method. It is possible to set this toFalse
and set a default value. In that case this attributed is unconditionally initialized with the specified default value or factory. - convert (callable) –
callable()
that is called byattrs
-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
.
Changed in version 17.1.0: validator can be a
list
now.Changed in version 17.1.0: hash is
None
and therefore mirrors cmp by default.New in version 17.3.0: type
Note
attrs
also comes with a serious business aliasattr.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 name_can_be_anything(self, attribute, value): ... if value < 0: ... raise ValueError("x must be positive") ... @y.default ... def name_does_not_matter(self): ... return self.x + 1 >>> C(1) C(x=1, y=2) >>> C(-1) Traceback (most recent call last): ... ValueError: x must be positive
- default (Any value.) –
-
class
attr.
Attribute
(name, default, validator, repr, cmp, hash, init, convert=None, metadata=None, type=None)¶ Read-only representation of an attribute.
Attribute name: The name of the attribute. Plus all arguments of
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, cmp=True, hash=None, init=True, convert=None, metadata=mappingproxy({}), type=None)
-
attr.
make_class
(name, attrs, bases=(<class ‘object’>, ), **attributes_arguments)¶ A quick way to create a new class called name with attrs.
Parameters: Returns: A new class with attrs.
Return type: New in version 17.1.0: bases
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: 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})
-
exception
attr.exceptions.
FrozenInstanceError
¶ A frozen/immutable instance has been attempted to be modified.
It mirrors the behavior of
namedtuples
by using the same error message and subclassingAttributeError
.New in version 16.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 anattrs
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 anattr.ib()
without a type annotation.New in version 17.3.0.
For example:
@attr.s(auto_attribs=True) class C: x: int y = attr.ib()
Influencing Initialization¶
Generally speaking, it’s best to keep logic out of your __init__
.
The moment you need a finer control over how your class is instantiated, it’s usually best to use a classmethod factory or to apply the builder pattern.
However, sometimes you need to do that one quick thing after your class is initialized.
And for that attrs
offers the __attrs_post_init__
hook that is automatically detected and run after attrs
is done initializing your instance:
>>> @attr.s
... class C(object):
... x = attr.ib()
... y = attr.ib(init=False)
... def __attrs_post_init__(self):
... self.y = self.x + 1
>>> C(1)
C(x=1, y=2)
Please note that you can’t directly set attributes on frozen classes:
>>> @attr.s(frozen=True)
... class FrozenBroken(object):
... x = attr.ib()
... y = attr.ib(init=False)
... def __attrs_post_init__(self):
... self.y = self.x + 1
>>> FrozenBroken(1)
Traceback (most recent call last):
...
attr.exceptions.FrozenInstanceError: can't set attribute
If you need to set attributes on a frozen class, you’ll have to resort to the same trick as attrs
and use object.__setattr__()
:
>>> @attr.s(frozen=True)
... class Frozen(object):
... x = attr.ib()
... y = attr.ib(init=False)
... def __attrs_post_init__(self):
... object.__setattr__(self, "y", self.x + 1)
>>> Frozen(1)
Frozen(x=1, y=2)
Helpers¶
attrs
comes with a bunch of helper methods that make working with it easier:
-
attr.
fields
(cls)¶ Returns 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: - TypeError – If cls is not a class.
- attr.exceptions.NotAnAttrsClassError – If cls is not an
attrs
class.
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, cmp=True, hash=None, init=True, convert=None, metadata=mappingproxy({}), type=None), Attribute(name='y', default=NOTHING, validator=None, repr=True, cmp=True, hash=None, init=True, convert=None, metadata=mappingproxy({}), type=None)) >>> attr.fields(C)[1] Attribute(name='y', default=NOTHING, validator=None, repr=True, cmp=True, hash=None, init=True, convert=None, metadata=mappingproxy({}), type=None) >>> attr.fields(C).y is attr.fields(C)[1] 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.
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 theattr.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 istuple
orset
. Only meaningful ifrecurse
isTrue
.
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}}
- inst – Instance of an
-
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 theattr.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
ordict
when encountering an attribute which type istuple
,dict
orset
. Only meaningful ifrecurse
isTrue
.
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)
- inst – Instance of an
attrs
includes some handy helpers for filtering:
-
attr.filters.
include
(*what)¶ Whitelist what.
Parameters: what ( list
oftype
orattr.Attribute
s) – What to whitelist.Return type: callable
-
attr.filters.
exclude
(*what)¶ Blacklist what.
Parameters: what ( list
of classes orattr.Attribute
s.) – What to blacklist.Return type: callable
See Converting to Collections Types 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: - TypeError – If attr_name couldn’t be found in the class
__init__
. - attr.exceptions.NotAnAttrsClassError – If cls is not an
attrs
class.
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 withevolve
. - the usual
__init__
validators will validate the new values.
- inst – Instance of a class with
-
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 <type 'int'> (got '1' that is a <type 'str'>).", Attribute(name='x', default=NOTHING, validator=<instance_of validator for type <type 'int'>>, repr=True, cmp=True, hash=None, init=True, type=None), <type 'int'>, '1')
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 usingisinstance()
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), <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), <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 usingvalue 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 usinginterface.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), <type 'int'>, '42') >>> C(None) C(x=None)
Converters¶
-
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(convert=attr.converters.optional(int)) >>> C(None) C(x=None) >>> C(42) C(x=42)
Deprecated APIs¶
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.
-
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: - attr.exceptions.AttrsAttributeNotFoundError – If attr_name couldn’t be found on cls.
- attr.exceptions.NotAnAttrsClassError – If cls is not an
attrs
class.
Deprecated since version 17.1.0: Use
evolve()
instead.- inst – Instance of a class with