| .. _api: |
| |
| API Reference |
| ============= |
| |
| .. currentmodule:: attr |
| |
| ``attrs`` works by decorating a class using :func:`attr.s` and then optionally defining attributes on the class using :func:`attr.ib`. |
| |
| .. note:: |
| |
| When this documentation speaks about "``attrs`` attributes" it means those attributes that are defined using :func:`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 :doc:`examples`. |
| |
| |
| |
| Core |
| ---- |
| |
| .. autofunction:: attr.s(these=None, repr_ns=None, repr=True, cmp=True, hash=None, init=True, slots=False, frozen=False, weakref_slot=True, str=False, auto_attribs=False, kw_only=False, cache_hash=False, auto_exc=False) |
| |
| .. note:: |
| |
| ``attrs`` also comes with a serious business alias ``attr.attrs``. |
| |
| For example: |
| |
| .. doctest:: |
| |
| >>> 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) |
| |
| |
| .. autofunction:: attr.ib |
| |
| .. note:: |
| |
| ``attrs`` also comes with a serious business alias ``attr.attrib``. |
| |
| The object returned by :func:`attr.ib` also allows for setting the default and the validator using decorators: |
| |
| .. doctest:: |
| |
| >>> @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 |
| |
| .. autoclass:: attr.Attribute |
| |
| Instances of this class are frequently used for introspection purposes like: |
| |
| - :func:`fields` returns a tuple of them. |
| - Validators get them passed as the first argument. |
| |
| .. warning:: |
| |
| You should never instantiate this class yourself! |
| |
| .. doctest:: |
| |
| >>> 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, metadata=mappingproxy({}), type=None, converter=None, kw_only=False) |
| |
| |
| .. autofunction:: attr.make_class |
| |
| This is handy if you want to programmatically create classes. |
| |
| For example: |
| |
| .. doctest:: |
| |
| >>> 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=[]) |
| |
| |
| .. autoclass:: attr.Factory |
| |
| For example: |
| |
| .. doctest:: |
| |
| >>> @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}) |
| |
| |
| .. autoexception:: attr.exceptions.FrozenInstanceError |
| .. autoexception:: attr.exceptions.AttrsAttributeNotFoundError |
| .. autoexception:: attr.exceptions.NotAnAttrsClassError |
| .. autoexception:: attr.exceptions.DefaultAlreadySetError |
| .. autoexception:: attr.exceptions.UnannotatedAttributeError |
| |
| For example:: |
| |
| @attr.s(auto_attribs=True) |
| class C: |
| x: int |
| y = attr.ib() # <- ERROR! |
| |
| |
| .. _helpers: |
| |
| Helpers |
| ------- |
| |
| ``attrs`` comes with a bunch of helper methods that make working with it easier: |
| |
| .. autofunction:: attr.fields |
| |
| For example: |
| |
| .. doctest:: |
| |
| >>> @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, metadata=mappingproxy({}), type=None, converter=None, kw_only=False), Attribute(name='y', default=NOTHING, validator=None, repr=True, cmp=True, hash=None, init=True, metadata=mappingproxy({}), type=None, converter=None, kw_only=False)) |
| >>> attr.fields(C)[1] |
| Attribute(name='y', default=NOTHING, validator=None, repr=True, cmp=True, hash=None, init=True, metadata=mappingproxy({}), type=None, converter=None, kw_only=False) |
| >>> attr.fields(C).y is attr.fields(C)[1] |
| True |
| |
| .. autofunction:: attr.fields_dict |
| |
| For example: |
| |
| .. doctest:: |
| |
| >>> @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, cmp=True, hash=None, init=True, metadata=mappingproxy({}), type=None, converter=None, kw_only=False), 'y': Attribute(name='y', default=NOTHING, validator=None, repr=True, cmp=True, hash=None, init=True, metadata=mappingproxy({}), type=None, converter=None, kw_only=False)} |
| >>> attr.fields_dict(C)['y'] |
| Attribute(name='y', default=NOTHING, validator=None, repr=True, cmp=True, hash=None, init=True, metadata=mappingproxy({}), type=None, converter=None, kw_only=False) |
| >>> attr.fields_dict(C)['y'] is attr.fields(C).y |
| True |
| |
| |
| .. autofunction:: attr.has |
| |
| For example: |
| |
| .. doctest:: |
| |
| >>> @attr.s |
| ... class C(object): |
| ... pass |
| >>> attr.has(C) |
| True |
| >>> attr.has(object) |
| False |
| |
| |
| .. autofunction:: attr.asdict |
| |
| For example: |
| |
| .. doctest:: |
| |
| >>> @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}} |
| |
| |
| .. autofunction:: attr.astuple |
| |
| For example: |
| |
| .. doctest:: |
| |
| >>> @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: |
| |
| .. autofunction:: attr.filters.include |
| |
| .. autofunction:: attr.filters.exclude |
| |
| See :ref:`asdict` for examples. |
| |
| .. autofunction:: attr.evolve |
| |
| For example: |
| |
| .. doctest:: |
| |
| >>> @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. |
| |
| .. autofunction:: validate |
| |
| For example: |
| |
| .. doctest:: |
| |
| >>> @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, kw_only=False), <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: |
| |
| .. autofunction:: set_run_validators |
| |
| .. autofunction:: get_run_validators |
| |
| |
| .. _api_validators: |
| |
| Validators |
| ---------- |
| |
| ``attrs`` comes with some common validators in the ``attrs.validators`` module: |
| |
| |
| .. autofunction:: attr.validators.instance_of |
| |
| |
| For example: |
| |
| .. doctest:: |
| |
| >>> @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) |
| |
| .. autofunction:: attr.validators.in_ |
| |
| For example: |
| |
| .. doctest:: |
| |
| >>> 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) |
| |
| .. autofunction:: attr.validators.provides |
| |
| .. autofunction:: attr.validators.and_ |
| |
| For convenience, it's also possible to pass a list to :func:`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]) |
| |
| .. autofunction:: attr.validators.optional |
| |
| For example: |
| |
| .. doctest:: |
| |
| >>> @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) |
| |
| |
| .. autofunction:: attr.validators.is_callable |
| |
| For example: |
| |
| .. doctest:: |
| |
| >>> @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): |
| ... |
| TypeError: 'x' must be callable |
| |
| |
| .. autofunction:: attr.validators.deep_iterable |
| |
| For example: |
| |
| .. doctest:: |
| |
| >>> @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') |
| |
| |
| .. autofunction:: attr.validators.deep_mapping |
| |
| For example: |
| |
| .. doctest:: |
| |
| >>> @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 |
| ---------- |
| |
| .. autofunction:: attr.converters.optional |
| |
| For example: |
| |
| .. doctest:: |
| |
| >>> @attr.s |
| ... class C(object): |
| ... x = attr.ib(converter=attr.converters.optional(int)) |
| >>> C(None) |
| C(x=None) |
| >>> C(42) |
| C(x=42) |
| |
| |
| .. autofunction:: attr.converters.default_if_none |
| |
| For example: |
| |
| .. doctest:: |
| |
| >>> @attr.s |
| ... class C(object): |
| ... x = attr.ib( |
| ... converter=attr.converters.default_if_none("") |
| ... ) |
| >>> C(None) |
| C(x='') |
| |
| |
| 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. |
| |
| .. autofunction:: assoc |