Skip to content
Back to top

# 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 dry API explanation for people who understand how attrs works. If you’d like a 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, some of the APIs that also exist in `attr` have nicer defaults (for example, `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.

## Core

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, force_kw_only=False)

  A class decorator that adds dunder methods according to fields specified using type annotations, `field()` calls, or the these argument.

  Since attrs patches or replaces an existing class, you cannot use `object.__init_subclass__` with attrs classes, because it runs too early. As a replacement, you can define `__attrs_init_subclass__` on your class. It will be called by attrs classes that subclass it after they’re created. See also attrs and __init_subclass__.

  Parameters:

    - slots (bool) – Create a slotted class that’s more memory-efficient. Slotted classes are generally superior to the default dict classes, but have some gotchas you should know about, so we encourage you to read the glossary entry.

    - auto_detect (bool) –

      Instead of setting the init, repr, eq, 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 (meaning, it is not inherited from some base class).

      So, for example by implementing `__eq__` on a class yourself, attrs will deduce `eq=False` and will 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).

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

    - 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 exception class:

      - the values for eq, order, and hash are ignored and the instances compare and hash by the instance’s ids [1] ,

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

      [1]

      Note that attrs will not remove existing implementations of `__hash__` or the equality methods. It just won’t add own ones.

    - on_setattr (Callable | list[Callable] | None | Literal[attrs.setters.NO_OP]) –

      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 arguments 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 `attrs.setters.pipe`.

      If left None, the default behavior is to run converters and validators whenever an attribute is set.

    - init (bool) –

      Create a `__init__` method that initializes the attrs attributes. Leading underscores are stripped for the argument name, unless an alias is set on the attribute.

      See also

      Initialization shows advanced ways to customize the generated `__init__` method, including executing code before and after.

    - 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 `Exception`s.

    - eq (bool | None) –

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

      See also

      Comparison describes how to customize the comparison behavior going as far comparing NumPy arrays.

    - order (bool | None) –

      If True, add `__lt__`, `__le__`, `__gt__`, and `__ge__` methods that behave like eq above and allow instances to be ordered.

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

      If `None` mirror value of eq.

      See also

      Comparison

    - unsafe_hash (bool | None) –

      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 the 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 (for example, 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 also

      - Our documentation on Hashing,

      - Python’s documentation on `object.__hash__`,

      - and the GitHub issue that led to the default behavior for more details.

    - hash (bool | None) – Deprecated alias for unsafe_hash. unsafe_hash takes precedence.

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

    - frozen (bool) –

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

      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.

    - kw_only (bool) –

      Make attributes keyword-only in the generated `__init__` (if init is False, this parameter is ignored). Attributes that explicitly set `kw_only=False` are not affected; base class attributes are also not affected.

      Also see force_kw_only.

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

    - field_transformer (Callable | None) –

      A function that is called with the original class object and all fields right before attrs finalizes the class. You can use this, for example, to automatically add converters or validators to fields based on their types.

      See also

      Automatic Field Transformation and Modification

    - match_args (bool) – If True (default), set `__match_args__` on the class to support PEP 634 (Structural Pattern Matching). It is a tuple of all non-keyword-only `__init__` parameter names on Python 3.10 and later. Ignored on older Python versions.

    - collect_by_mro (bool) –

      If True, attrs collects attributes from base classes correctly according to the method resolution order. If False, attrs will mimic the (wrong) behavior of `dataclasses` and PEP 681.

      See also issue #428.

    - force_kw_only (bool) –

      A back-compat flag for restoring pre-25.4.0 behavior. If True and `kw_only=True`, all attributes are made keyword-only, including base class attributes, and those set to `kw_only=False` at the attribute level. Defaults to False.

      See also issue #980.

    - getstate_setstate (bool | None) –

      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 (meaning: not inherited), it is set to False (this is usually what you want).

    - auto_attribs (bool | None) –

      If True, look at type annotations to determine which attributes to use, like `dataclasses`. If False, it will only look for explicit `field()` class attributes, like classic attrs.

      If left None, it will guess:

      1. If any attributes are annotated and no unannotated `attrs.field`s are found, it assumes auto_attribs=True.

      2. Otherwise it assumes auto_attribs=False and tries to collect `attrs.field`s.

      If attrs decides to look at type annotations, all fields must be annotated. If attrs encounters a field that is set to a `field()` / `attr.ib` but lacks a type annotation, an `attrs.exceptions.UnannotatedAttributeError` is raised. Use `field_name: typing.Any = field(...)` if you don’t want to set a type.

      Warning

      For features that use the attribute name to create decorators (for example, validators), you still must assign `field()` / `attr.ib` to them. Otherwise Python will either not find the name or try to use the default value to call, for example, `validator` on it.

      Attributes annotated as `typing.ClassVar`, and attributes that are neither annotated nor set to an `field()` are ignored.

    - these (dict[str, object]) –

      A dictionary of name to the (private) return value of `field()` mappings. This is useful to avoid the definition of your attributes within the class body because you can’t (for example, 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.

      The order is deduced from the order of the attributes inside these.

      Arguably, this is a rather obscure feature.

  Added in version 20.1.0.

  Changed in version 21.3.0: Converters are also run `on_setattr`.

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

  Changed in version 24.1.0: Instances are not compared as tuples of attributes anymore, but using a big `and` condition. This is faster and has more correct behavior for uncomparable values like `math.nan`.

  Added in version 24.1.0: If a class has an inherited classmethod called `__attrs_init_subclass__`, it is executed after the class is created.

  Deprecated since version 24.1.0: hash is deprecated in favor of unsafe_hash.

  Added in version 24.3.0: Unless already present, a `__replace__` method is automatically created for `copy.replace` (Python 3.13+ only).

  Changed in version 25.4.0: kw_only now only applies to attributes defined in the current class, and respects attribute-level `kw_only=False` settings.

  Added in version 25.4.0: Added force_kw_only to go back to the previous kw_only behavior.

  Note

  The main differences to the classic `attr.s` are:

  - 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

    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

  - force_kw_only=False

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

attrs.mutable(same_as_define)

  Same as `attrs.define`.

  Added in version 20.1.0.

attrs.frozen(same_as_define)

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

  Added in version 20.1.0.

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

  Create a new field / attribute on a class.

  Warning

  Does nothing unless the class is also decorated with `attrs.define` (or similar)!

  Parameters:

    - default –

      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 `attrs.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 `attrs.NOTHING`), a value must be supplied when instantiating; otherwise a `TypeError` will be raised.

      See also

      Defaults

    - factory (Callable) – Syntactic sugar for `default=attr.Factory(factory)`.

    - validator (Callable | list[Callable]) –

      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 `attrs.validators.get_disabled` / `attrs.validators.set_disabled`.

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

      See also

      Validators

    - repr (bool | Callable) – 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, which means it will be used directly instead of calling `repr()` (the default).

    - eq (bool | Callable) –

      If True (default), include this attribute in the generated `__eq__` and `__ne__` methods that check two instances for equality. To override how the attribute value is compared, pass a callable that takes a single value and returns the value to be compared.

      See also

      Comparison

    - order (bool | Callable) –

      If True (default), include this attributes in the generated `__lt__`, `__le__`, `__gt__` and `__ge__` methods. To override how the attribute value is ordered, pass a callable that takes a single value and returns the value to be ordered.

      See also

      Comparison

    - hash (bool | None) –

      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.

      See also

      Hashing

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

      See also

      Initialization

    - converter (Callable | Converter) –

      A callable that is called by attrs-generated `__init__` methods to convert attribute’s value to the desired format.

      If a vanilla callable is passed, it is given the passed-in value as the only positional argument. It is possible to receive additional arguments by wrapping the callable in a `Converter`.

      Either way, 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.

      See also

      Converters

    - metadata (dict | None) –

      An arbitrary mapping, to be used by third-party code.

      See also

      Metadata.

    - type (type) –

      The type of the attribute. Nowadays, the preferred method to specify the type is using a variable annotation (see PEP 526). This argument is provided for backwards-compatibility and for usage with `make_class`. 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 (bool | None) – Make this attribute keyword-only in the generated `__init__` (if init is False, this parameter is ignored). If None (default), mirror the setting from `attrs.define`.

    - on_setattr (Callable | list[Callable] | None | Literal[attrs.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 `attrs.setters.NO_OP` to run no `setattr` hooks for this attribute – regardless of the setting in `define()`.

    - alias (str | None) – Override this attribute’s parameter name in the generated `__init__` method. If left None, default to `name` stripped of leading underscores. See Private Attributes and Aliases.

  Added in version 20.1.0.

  Changed in version 21.1.0: eq, order, and cmp also accept a custom callable

  Added in version 22.2.0: alias

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

  Changed in version 25.4.0: kw_only can now be None, and its default is also changed from False to None.

  See also

  `attr.ib`

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, alias_is_default=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.

  - `alias_is_default` (`bool`): Whether the `alias` was automatically generated (`True`) or explicitly provided by the user (`False`).

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

  Added in version 20.1.0: inherited

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

  Added in version 21.1.0: eq_key and order_key

  Added in version 22.2.0: alias

  Added in version 26.1.0: alias_is_default

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

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

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

  Note

  `make_class()` is a thin wrapper around `attr.s`, not `attrs.define` which means that it doesn’t come with some of the improved defaults.

  For example, if you want the same `on_setattr` behavior as in `attrs.define`, you have to pass the hooks yourself: `make_class(..., on_setattr=setters.pipe(setters.convert, setters.validate)`

  Warning

  It is your duty to ensure that the class name and the attribute names are valid identifiers. `make_class()` will not validate them for you.

  Parameters:

    - name (str) – The name for the new class.

    - attrs (list | dict) –

      A list of names or a dictionary of mappings of names to `attr.ib`s / `attrs.field`s.

      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[type, ...]) – 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

  Added 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

  Changed in version 25.2.0: Class names can now be unicode.

  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.

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

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.

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

  Added 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`.

  Added in version 20.1.0.

exception attrs.exceptions.FrozenInstanceError

  A frozen instance has been attempted to be modified.

  Added in version 16.1.0.

exception attrs.exceptions.FrozenAttributeError

  A frozen attribute has been attempted to be modified.

  Added in version 20.1.0.

exception attrs.exceptions.AttrsAttributeNotFoundError

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

  Added in version 16.2.0.

exception attrs.exceptions.NotAnAttrsClassError

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

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

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

  Added in version 19.2.0.

exception attrs.exceptions.UnannotatedAttributeError

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

  Added 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 (Callable | None) – Callable used to evaluate equality of two objects.

    - lt (Callable | None) – Callable used to evaluate whether one object is less than another object.

    - le (Callable | None) – Callable used to evaluate whether one object is less than or equal to another object.

    - gt (Callable | None) – Callable used to evaluate whether one object is greater than another object.

    - ge (Callable | None) – 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 (str | None) – Name of class. Defaults to “Comparable”.

  See Comparison for more details.

  Added in version 21.1.0.

attrs.fields(cls)

  Return the tuple of attrs attributes for a class or instance.

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

  Parameters:

    cls (type) – Class or instance to introspect.

  Raises:

    - TypeError – If cls is neither a class nor an attrs instance.

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

  Returns:

    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.

  Changed in version 26.1.0: Add support for instances.

  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, 2)) is attrs.fields(C)
      True
      >>> 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:

    - TypeError – If cls is not a class.

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

  Returns:

    Dict of attribute name to definition

  Return type:

    dict[str, attrs.Attribute]

  Added 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:

      >>> @define
      ... class C:
      ...     pass
      >>> attrs.has(C)
      True
      >>> attrs.has(object)
      False

attrs.inspect(cls)

  Inspect the class and return its effective build parameters.

  Warning

  This feature is currently experimental and is not covered by our strict backwards-compatibility guarantees.

  Parameters:

    cls – The attrs-decorated class to inspect.

  Returns:

    The effective build parameters of the class.

  Raises:

    NotAnAttrsClassError – If the class is not an attrs-decorated class.

  Added in version 25.4.0.

  For example:

      >>> @define
      ... class CInspect:
      ...     pass
      >>> attrs.inspect(CInspect)
      ClassProps(is_exception=False, is_slotted=True, has_weakref_slot=True, is_frozen=False, kw_only=<KeywordOnly.NO: 'no'>, collected_fields_by_mro=True, added_init=True, added_repr=True, added_eq=True, added_ordering=False, hashability=<Hashability.UNHASHABLE: 'unhashable'>, added_match_args=True, added_str=False, added_pickling=True, on_setattr_hook=<function pipe.<locals>.wrapped_pipe at ...>, field_transformer=None)

class attrs.ClassProps(is_exception, is_slotted, has_weakref_slot, is_frozen, kw_only, collected_fields_by_mro, added_init, added_repr, added_eq, added_ordering, hashability, added_match_args, added_str, added_pickling, on_setattr_hook, field_transformer)

  Effective class properties as derived from parameters to `attr.s()` or `define()` decorators.

  This is the same data structure that attrs uses internally to decide how to construct the final class.

  Warning

  This feature is currently experimental and is not covered by our strict backwards-compatibility guarantees.

  is_exception

    Whether the class is treated as an exception class.

    Type:

      bool

  is_slotted

    Whether the class is `slotted`.

    Type:

      bool

  has_weakref_slot

    Whether the class has a slot for weak references.

    Type:

      bool

  is_frozen

    Whether the class is frozen.

    Type:

      bool

  kw_only

    Whether / how the class enforces keyword-only arguments on the `__init__` method.

    Type:

      KeywordOnly

  collected_fields_by_mro

    Whether the class fields were collected by method resolution order. That is, correctly but unlike `dataclasses`.

    Type:

      bool

  added_init

    Whether the class has an attrs-generated `__init__` method.

    Type:

      bool

  added_repr

    Whether the class has an attrs-generated `__repr__` method.

    Type:

      bool

  added_eq

    Whether the class has attrs-generated equality methods.

    Type:

      bool

  added_ordering

    Whether the class has attrs-generated ordering methods.

    Type:

      bool

  hashability

    How hashable the class is.

    Type:

      Hashability

  added_match_args

    Whether the class supports positional `match` over its fields.

    Type:

      bool

  added_str

    Whether the class has an attrs-generated `__str__` method.

    Type:

      bool

  added_pickling

    Whether the class has attrs-generated `__getstate__` and `__setstate__` methods for `pickle`.

    Type:

      bool

  on_setattr_hook

    The class’s `__setattr__` hook.

    Type:

      Callable[[Any, Attribute[Any], Any], Any] | None

  field_transformer

    The class’s field transformers.

    Type:

      Callable[[Attribute[Any]], Attribute[Any]] | None

  Added in version 25.4.0.

class attrs.ClassProps.Hashability(*values)

  The hashability of a class.

  Added in version 25.4.0.

  HASHABLE = 'hashable'

    Write a `__hash__`.

  HASHABLE_CACHED = 'hashable_cache'

    Write a `__hash__` and cache the hash.

  LEAVE_ALONE = 'leave_alone'

    Don’t touch `__hash__`.

  UNHASHABLE = 'unhashable'

    Set `__hash__` to `None`.

class attrs.ClassProps.KeywordOnly(*values)

  How attributes should be treated regarding keyword-only parameters.

  Added in version 25.4.0.

  FORCE = 'force'

    All attributes are keyword-only.

  NO = 'no'

    Attributes are not keyword-only.

  YES = 'yes'

    Attributes in current class without kw_only=False are keyword-only.

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, for example, 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 (dict | None) – Dictionary containing global variables.

    - localns (dict | None) – Dictionary containing local variables.

    - attribs (list | None) – 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:

    - TypeError – If cls is not a class.

    - attrs.exceptions.NotAnAttrsClassError – If cls is not an attrs class and you didn’t pass any attribs.

    - NameError – If types cannot be resolved because of missing variables.

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

  Added in version 20.1.0.

  Added in version 21.1.0: attribs

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

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

  Added 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)

  Create a filter that only allows what.

  Parameters:

    what (list[type, str, attrs.Attribute]) – What to include. Can be a type, a name, or an attribute.

  Returns:

    A callable that can be passed to `attrs.asdict`’s and `attrs.astuple`’s filter argument.

  Return type:

    Callable

  Changed in version 23.1.0: Accept strings with field names.

attrs.filters.exclude(*what)

  Create a filter that does not allow what.

  Parameters:

    what (list[type, str, attrs.Attribute]) – What to exclude. Can be a type, a name, or an attribute.

  Returns:

    A callable that can be passed to `attrs.asdict`’s and `attrs.astuple`’s filter argument.

  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)

  Method generated by attrs for class VersionInfo.

  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.

  The validator uses `operator.lt` to compare the values.

  Parameters:

    val – Exclusive upper bound for values.

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

  The validator uses `operator.le` to compare the values.

  Parameters:

    val – Inclusive upper bound for values.

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

  The validator uses `operator.ge` to compare the values.

  Parameters:

    val – Inclusive lower bound for values

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

  The validator uses `operator.gt` to compare the values.

  Parameters:

    val – Exclusive lower bound for values

  Added 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

  Added 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

  Added 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 | tuple[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`, so options has to support that operation.

  To keep the validator hashable, dicts, lists, and sets are transparently transformed into a `tuple`.

  Parameters:

    options – Allowed options.

  Raises:

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

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

  Changed in version 24.1.0: options that are a list, dict, or a set are now transformed into a tuple to keep the validator hashable.

  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.and_(*validators)

  A validator that composes multiple validators into one.

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

  Parameters:

    validators (Iterable[Callable]) – Arbitrary number of validators.

  Added 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.or_(*validators)

  A validator that composes multiple validators into one.

  When called on a value, it runs all wrapped validators until one of them is satisfied.

  Parameters:

    validators (Iterable[Callable]) – Arbitrary number of validators.

  Raises:

    ValueError – If no validator is satisfied. Raised with a human-readable error message listing all the wrapped validators and the value that failed all of them.

  Added in version 24.1.0.

  For example:

      >>> @define
      ... class C:
      ...     val: int | list[int] = field(
      ...         validator=attrs.validators.or_(
      ...             attrs.validators.instance_of(int),
      ...             attrs.validators.deep_iterable(attrs.validators.instance_of(int)),
      ...         )
      ...     )
      >>> C(42)
      C(val=42)
      >>> C([1, 2, 3])
      C(val=[1, 2, 3])
      >>> C(val='42')
      Traceback (most recent call last):
         ...
      ValueError: None of (<instance_of validator for type <class 'int'>>, <deep_iterable validator for iterables of <instance_of validator for type <class 'int'>>>) satisfied for value '42'

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 (tuple[type, ...]) – 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.

  Added 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 – (typing.Callable | tuple[typing.Callable] | list[typing.Callable]): A validator (or validators) that is used for non-`None` values.

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

  Added 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 (str, re.Pattern) – 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`.

  Added 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(s) to apply to iterable itself (optional).

  Raises

    TypeError: if any sub-validators fail

  Added in version 19.1.0.

  Changed in version 25.4.0: member_validator and iterable_validator can now be a list or tuple of validators.

  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=None, value_validator=None, mapping_validator=None)

  A validator that performs deep validation of a dictionary.

  All validators are optional, but at least one of key_validator or value_validator must be provided.

  Parameters:

    - key_validator – Validator(s) to apply to dictionary keys.

    - value_validator – Validator(s) to apply to dictionary values.

    - mapping_validator – Validator(s) to apply to top-level mapping attribute.

  Added in version 19.1.0.

  Changed in version 25.4.0: key_validator and value_validator are now optional, but at least one of them must be provided.

  Changed in version 25.4.0: key_validator, value_validator, and mapping_validator can now be a list or tuple of validators.

  Raises:

    - TypeError – If any sub-validator fails on validation.

    - ValueError – If neither key_validator nor value_validator is provided on instantiation.

  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!

  Added 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

  Added 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!

  Added in version 21.3.0.

  Changed in version 26.1.0: The contextmanager is nestable.

## Converters

class attrs.Converter(converter, *, takes_self=False, takes_field=False)

  Stores a converter callable.

  Allows for the wrapped converter to take additional arguments. The arguments are passed in the order they are documented.

  Parameters:

    - converter (Callable) – A callable that converts the passed value.

    - takes_self (bool) – Pass the partially initialized instance that is being initialized as a positional argument. (default: `False`)

    - takes_field (bool) – Pass the field definition (an `Attribute`) into the converter as a positional argument. (default: `False`)

  Added in version 24.1.0.

  For example:

      >>> def complicated(value, self_, field):
      ...     return int(value) * self_.factor + field.metadata["offset"]
      >>> @define
      ... class C:
      ...     factor = 5  # not an *attrs* field
      ...     x = field(
      ...         metadata={"offset": 200},
      ...         converter=attrs.Converter(
      ...             complicated,
      ...             takes_self=True, takes_field=True
      ...     ))
      >>> C("42")
      C(x=410)

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.

  > converters (~collections.abc.Iterable[typing.Callable]):

  >   Arbitrary number of converters.

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

  Added 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, 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:

    - TypeError – If neither default or factory is passed.

    - TypeError – If both default and factory are passed.

    - ValueError – If an instance of `attrs.Factory` is passed with `takes_self=True`.

  Added 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 (for example, from environment variables) 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.

  Added 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("norway")
      Traceback (most recent call last):
         File "<stdin>", line 1, in <module>
      ValueError: Cannot convert value to bool: norway

## Setters

These are helpers that you can use together with `attrs.define`’s and `attrs.field`’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.

  Added in version 20.1.0.

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

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

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

  Added in version 20.1.0.

attrs.setters.pipe(*setters)

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

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

  Added 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: ()

  Tip

  Use `attrs.define`’s frozen argument (or `attrs.frozen`) to freeze whole classes; it is more efficient.