mercurial/thirdparty/attr/_make.py
author Matt Harbison <matt_harbison@yahoo.com>
Mon, 21 Nov 2022 15:04:42 -0500
changeset 49643 e1c586b9a43c
parent 41833 89f01ea906ae
permissions -rw-r--r--
attr: vendor 22.1.0 The previous version was 5 years old, and pytype 2022.06.30 started complaining about various uses (e.g. seeing `mercurial.thirdparty.attr._make._CountingAttr` instead of `bytearray`). Hopefully this helps. Additionally, this has official python 3.11 support. The `attrs` package is left out, because it is simply a bunch of *.pyi stubs and `from attr.X import *`, and that's not how they've been used up to this point. We'd probably need to customize those anyway to `from mercurial.thirdparty.attr import *`.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
     1
# SPDX-License-Identifier: MIT
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
     2
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
     3
import copy
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
     4
import linecache
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
     5
import sys
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
     6
import types
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
     7
import typing
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
     8
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
     9
from operator import itemgetter
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    10
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
    11
# We need to import _compat itself in addition to the _compat members to avoid
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
    12
# having the thread-local in the globals here.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
    13
from . import _compat, _config, setters
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
    14
from ._compat import (
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
    15
    HAS_F_STRINGS,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
    16
    PY310,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
    17
    PYPY,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
    18
    _AnnotationExtractor,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
    19
    ordered_dict,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
    20
    set_closure_cell,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
    21
)
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    22
from .exceptions import (
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    23
    DefaultAlreadySetError,
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    24
    FrozenInstanceError,
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    25
    NotAnAttrsClassError,
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
    26
    UnannotatedAttributeError,
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    27
)
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    28
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    29
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    30
# This is used at least twice, so cache it here.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    31
_obj_setattr = object.__setattr__
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
    32
_init_converter_pat = "__attr_converter_%s"
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    33
_init_factory_pat = "__attr_factory_{}"
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
    34
_tuple_property_pat = (
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
    35
    "    {attr_name} = _attrs_property(_attrs_itemgetter({index}))"
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
    36
)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
    37
_classvar_prefixes = (
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
    38
    "typing.ClassVar",
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
    39
    "t.ClassVar",
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
    40
    "ClassVar",
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
    41
    "typing_extensions.ClassVar",
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
    42
)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
    43
# we don't use a double-underscore prefix because that triggers
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
    44
# name mangling when trying to create a slot for the field
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
    45
# (when slots=True)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
    46
_hash_cache_field = "_attrs_cached_hash"
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
    47
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
    48
_empty_metadata_singleton = types.MappingProxyType({})
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
    49
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
    50
# Unique object for unequivocal getattr() defaults.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
    51
_sentinel = object()
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
    52
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
    53
_ng_default_on_setattr = setters.pipe(setters.convert, setters.validate)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
    54
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
    55
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
    56
class _Nothing:
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    57
    """
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    58
    Sentinel class to indicate the lack of a value when ``None`` is ambiguous.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    59
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
    60
    ``_Nothing`` is a singleton. There is only ever one of it.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
    61
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
    62
    .. versionchanged:: 21.1.0 ``bool(NOTHING)`` is now False.
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    63
    """
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
    64
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
    65
    _singleton = None
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
    66
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
    67
    def __new__(cls):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
    68
        if _Nothing._singleton is None:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
    69
            _Nothing._singleton = super().__new__(cls)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
    70
        return _Nothing._singleton
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    71
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    72
    def __repr__(self):
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    73
        return "NOTHING"
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    74
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
    75
    def __bool__(self):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
    76
        return False
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    77
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    78
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    79
NOTHING = _Nothing()
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    80
"""
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    81
Sentinel to indicate the lack of a value when ``None`` is ambiguous.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    82
"""
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    83
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    84
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
    85
class _CacheHashWrapper(int):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
    86
    """
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
    87
    An integer subclass that pickles / copies as None
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
    88
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
    89
    This is used for non-slots classes with ``cache_hash=True``, to avoid
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
    90
    serializing a potentially (even likely) invalid hash value. Since ``None``
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
    91
    is the default value for uncalculated hashes, whenever this is copied,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
    92
    the copy's value for the hash should automatically reset.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
    93
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
    94
    See GH #613 for more details.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
    95
    """
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
    96
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
    97
    def __reduce__(self, _none_constructor=type(None), _args=()):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
    98
        return _none_constructor, _args
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
    99
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   100
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   101
def attrib(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   102
    default=NOTHING,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   103
    validator=None,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   104
    repr=True,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   105
    cmp=None,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   106
    hash=None,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   107
    init=True,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   108
    metadata=None,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   109
    type=None,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   110
    converter=None,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   111
    factory=None,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   112
    kw_only=False,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   113
    eq=None,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   114
    order=None,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   115
    on_setattr=None,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   116
):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   117
    """
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   118
    Create a new attribute on a class.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   119
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   120
    ..  warning::
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   121
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   122
        Does *not* do anything unless the class is also decorated with
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   123
        `attr.s`!
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   124
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   125
    :param default: A value that is used if an ``attrs``-generated ``__init__``
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   126
        is used and no value is passed while instantiating or the attribute is
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   127
        excluded using ``init=False``.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   128
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   129
        If the value is an instance of `attrs.Factory`, its callable will be
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   130
        used to construct a new value (useful for mutable data types like lists
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   131
        or dicts).
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   132
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   133
        If a default is not set (or set manually to `attrs.NOTHING`), a value
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   134
        *must* be supplied when instantiating; otherwise a `TypeError`
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   135
        will be raised.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   136
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   137
        The default can also be set using decorator notation as shown below.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   138
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   139
    :type default: Any value
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   140
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   141
    :param callable factory: Syntactic sugar for
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   142
        ``default=attr.Factory(factory)``.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   143
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   144
    :param validator: `callable` that is called by ``attrs``-generated
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   145
        ``__init__`` methods after the instance has been initialized.  They
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   146
        receive the initialized instance, the :func:`~attrs.Attribute`, and the
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   147
        passed value.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   148
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   149
        The return value is *not* inspected so the validator has to throw an
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   150
        exception itself.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   151
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   152
        If a `list` is passed, its items are treated as validators and must
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   153
        all pass.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   154
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   155
        Validators can be globally disabled and re-enabled using
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   156
        `get_run_validators`.
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   157
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   158
        The validator can also be set using decorator notation as shown below.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   159
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   160
    :type validator: `callable` or a `list` of `callable`\\ s.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   161
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   162
    :param repr: Include this attribute in the generated ``__repr__``
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   163
        method. If ``True``, include the attribute; if ``False``, omit it. By
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   164
        default, the built-in ``repr()`` function is used. To override how the
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   165
        attribute value is formatted, pass a ``callable`` that takes a single
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   166
        value and returns a string. Note that the resulting string is used
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   167
        as-is, i.e. it will be used directly *instead* of calling ``repr()``
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   168
        (the default).
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   169
    :type repr: a `bool` or a `callable` to use a custom function.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   170
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   171
    :param eq: If ``True`` (default), include this attribute in the
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   172
        generated ``__eq__`` and ``__ne__`` methods that check two instances
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   173
        for equality. To override how the attribute value is compared,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   174
        pass a ``callable`` that takes a single value and returns the value
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   175
        to be compared.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   176
    :type eq: a `bool` or a `callable`.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   177
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   178
    :param order: If ``True`` (default), include this attributes in the
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   179
        generated ``__lt__``, ``__le__``, ``__gt__`` and ``__ge__`` methods.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   180
        To override how the attribute value is ordered,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   181
        pass a ``callable`` that takes a single value and returns the value
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   182
        to be ordered.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   183
    :type order: a `bool` or a `callable`.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   184
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   185
    :param cmp: Setting *cmp* is equivalent to setting *eq* and *order* to the
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   186
        same value. Must not be mixed with *eq* or *order*.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   187
    :type cmp: a `bool` or a `callable`.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   188
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   189
    :param Optional[bool] hash: Include this attribute in the generated
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   190
        ``__hash__`` method.  If ``None`` (default), mirror *eq*'s value.  This
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   191
        is the correct behavior according the Python spec.  Setting this value
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   192
        to anything else than ``None`` is *discouraged*.
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   193
    :param bool init: Include this attribute in the generated ``__init__``
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   194
        method.  It is possible to set this to ``False`` and set a default
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   195
        value.  In that case this attributed is unconditionally initialized
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   196
        with the specified default value or factory.
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   197
    :param callable converter: `callable` that is called by
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   198
        ``attrs``-generated ``__init__`` methods to convert attribute's value
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   199
        to the desired format.  It is given the passed-in value, and the
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   200
        returned value will be used as the new value of the attribute.  The
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   201
        value is converted before being passed to the validator, if any.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   202
    :param metadata: An arbitrary mapping, to be used by third-party
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   203
        components.  See `extending_metadata`.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   204
    :param type: The type of the attribute.  In Python 3.6 or greater, the
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   205
        preferred method to specify the type is using a variable annotation
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   206
        (see :pep:`526`).
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   207
        This argument is provided for backward compatibility.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   208
        Regardless of the approach used, the type will be stored on
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   209
        ``Attribute.type``.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   210
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   211
        Please note that ``attrs`` doesn't do anything with this metadata by
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   212
        itself. You can use it as part of your own code or for
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   213
        `static type checking <types>`.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   214
    :param kw_only: Make this attribute keyword-only (Python 3+)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   215
        in the generated ``__init__`` (if ``init`` is ``False``, this
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   216
        parameter is ignored).
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   217
    :param on_setattr: Allows to overwrite the *on_setattr* setting from
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   218
        `attr.s`. If left `None`, the *on_setattr* value from `attr.s` is used.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   219
        Set to `attrs.setters.NO_OP` to run **no** `setattr` hooks for this
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   220
        attribute -- regardless of the setting in `attr.s`.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   221
    :type on_setattr: `callable`, or a list of callables, or `None`, or
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   222
        `attrs.setters.NO_OP`
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   223
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   224
    .. versionadded:: 15.2.0 *convert*
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   225
    .. versionadded:: 16.3.0 *metadata*
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   226
    .. versionchanged:: 17.1.0 *validator* can be a ``list`` now.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   227
    .. versionchanged:: 17.1.0
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   228
       *hash* is ``None`` and therefore mirrors *eq* by default.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   229
    .. versionadded:: 17.3.0 *type*
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   230
    .. deprecated:: 17.4.0 *convert*
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   231
    .. versionadded:: 17.4.0 *converter* as a replacement for the deprecated
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   232
       *convert* to achieve consistency with other noun-based arguments.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   233
    .. versionadded:: 18.1.0
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   234
       ``factory=f`` is syntactic sugar for ``default=attr.Factory(f)``.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   235
    .. versionadded:: 18.2.0 *kw_only*
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   236
    .. versionchanged:: 19.2.0 *convert* keyword argument removed.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   237
    .. versionchanged:: 19.2.0 *repr* also accepts a custom callable.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   238
    .. deprecated:: 19.2.0 *cmp* Removal on or after 2021-06-01.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   239
    .. versionadded:: 19.2.0 *eq* and *order*
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   240
    .. versionadded:: 20.1.0 *on_setattr*
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   241
    .. versionchanged:: 20.3.0 *kw_only* backported to Python 2
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   242
    .. versionchanged:: 21.1.0
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   243
       *eq*, *order*, and *cmp* also accept a custom callable
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   244
    .. versionchanged:: 21.1.0 *cmp* undeprecated
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   245
    """
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   246
    eq, eq_key, order, order_key = _determine_attrib_eq_order(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   247
        cmp, eq, order, True
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   248
    )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   249
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   250
    if hash is not None and hash is not True and hash is not False:
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   251
        raise TypeError(
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   252
            "Invalid value for hash.  Must be True, False, or None."
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   253
        )
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   254
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   255
    if factory is not None:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   256
        if default is not NOTHING:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   257
            raise ValueError(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   258
                "The `default` and `factory` arguments are mutually "
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   259
                "exclusive."
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   260
            )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   261
        if not callable(factory):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   262
            raise ValueError("The `factory` argument must be a callable.")
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   263
        default = Factory(factory)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   264
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   265
    if metadata is None:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   266
        metadata = {}
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   267
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   268
    # Apply syntactic sugar by auto-wrapping.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   269
    if isinstance(on_setattr, (list, tuple)):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   270
        on_setattr = setters.pipe(*on_setattr)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   271
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   272
    if validator and isinstance(validator, (list, tuple)):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   273
        validator = and_(*validator)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   274
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   275
    if converter and isinstance(converter, (list, tuple)):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   276
        converter = pipe(*converter)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   277
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   278
    return _CountingAttr(
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   279
        default=default,
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   280
        validator=validator,
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   281
        repr=repr,
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   282
        cmp=None,
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   283
        hash=hash,
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   284
        init=init,
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   285
        converter=converter,
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   286
        metadata=metadata,
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   287
        type=type,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   288
        kw_only=kw_only,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   289
        eq=eq,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   290
        eq_key=eq_key,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   291
        order=order,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   292
        order_key=order_key,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   293
        on_setattr=on_setattr,
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   294
    )
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   295
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   296
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   297
def _compile_and_eval(script, globs, locs=None, filename=""):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   298
    """
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   299
    "Exec" the script with the given global (globs) and local (locs) variables.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   300
    """
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   301
    bytecode = compile(script, filename, "exec")
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   302
    eval(bytecode, globs, locs)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   303
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   304
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   305
def _make_method(name, script, filename, globs):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   306
    """
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   307
    Create the method with the script given and return the method object.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   308
    """
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   309
    locs = {}
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   310
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   311
    # In order of debuggers like PDB being able to step through the code,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   312
    # we add a fake linecache entry.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   313
    count = 1
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   314
    base_filename = filename
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   315
    while True:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   316
        linecache_tuple = (
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   317
            len(script),
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   318
            None,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   319
            script.splitlines(True),
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   320
            filename,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   321
        )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   322
        old_val = linecache.cache.setdefault(filename, linecache_tuple)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   323
        if old_val == linecache_tuple:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   324
            break
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   325
        else:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   326
            filename = "{}-{}>".format(base_filename[:-1], count)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   327
            count += 1
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   328
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   329
    _compile_and_eval(script, globs, locs, filename)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   330
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   331
    return locs[name]
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   332
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   333
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   334
def _make_attr_tuple_class(cls_name, attr_names):
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   335
    """
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   336
    Create a tuple subclass to hold `Attribute`s for an `attrs` class.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   337
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   338
    The subclass is a bare tuple with properties for names.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   339
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   340
    class MyClassAttributes(tuple):
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   341
        __slots__ = ()
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   342
        x = property(itemgetter(0))
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   343
    """
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   344
    attr_class_name = "{}Attributes".format(cls_name)
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   345
    attr_class_template = [
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   346
        "class {}(tuple):".format(attr_class_name),
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   347
        "    __slots__ = ()",
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   348
    ]
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   349
    if attr_names:
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   350
        for i, attr_name in enumerate(attr_names):
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   351
            attr_class_template.append(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   352
                _tuple_property_pat.format(index=i, attr_name=attr_name)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   353
            )
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   354
    else:
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   355
        attr_class_template.append("    pass")
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   356
    globs = {"_attrs_itemgetter": itemgetter, "_attrs_property": property}
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   357
    _compile_and_eval("\n".join(attr_class_template), globs)
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   358
    return globs[attr_class_name]
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   359
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   360
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   361
# Tuple class for extracted attributes from a class definition.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   362
# `base_attrs` is a subset of `attrs`.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   363
_Attributes = _make_attr_tuple_class(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   364
    "_Attributes",
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   365
    [
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   366
        # all attributes to build dunder methods for
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   367
        "attrs",
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   368
        # attributes that have been inherited
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   369
        "base_attrs",
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   370
        # map inherited attributes to their originating classes
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   371
        "base_attrs_map",
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   372
    ],
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   373
)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   374
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   375
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   376
def _is_class_var(annot):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   377
    """
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   378
    Check whether *annot* is a typing.ClassVar.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   379
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   380
    The string comparison hack is used to avoid evaluating all string
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   381
    annotations which would put attrs-based classes at a performance
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   382
    disadvantage compared to plain old classes.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   383
    """
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   384
    annot = str(annot)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   385
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   386
    # Annotation can be quoted.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   387
    if annot.startswith(("'", '"')) and annot.endswith(("'", '"')):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   388
        annot = annot[1:-1]
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   389
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   390
    return annot.startswith(_classvar_prefixes)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   391
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   392
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   393
def _has_own_attribute(cls, attrib_name):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   394
    """
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   395
    Check whether *cls* defines *attrib_name* (and doesn't just inherit it).
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   396
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   397
    Requires Python 3.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   398
    """
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   399
    attr = getattr(cls, attrib_name, _sentinel)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   400
    if attr is _sentinel:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   401
        return False
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   402
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   403
    for base_cls in cls.__mro__[1:]:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   404
        a = getattr(base_cls, attrib_name, None)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   405
        if attr is a:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   406
            return False
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   407
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   408
    return True
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   409
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   410
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   411
def _get_annotations(cls):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   412
    """
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   413
    Get annotations for *cls*.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   414
    """
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   415
    if _has_own_attribute(cls, "__annotations__"):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   416
        return cls.__annotations__
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   417
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   418
    return {}
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   419
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   420
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   421
def _counter_getter(e):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   422
    """
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   423
    Key function for sorting to avoid re-creating a lambda for every class.
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   424
    """
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   425
    return e[1].counter
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   426
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   427
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   428
def _collect_base_attrs(cls, taken_attr_names):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   429
    """
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   430
    Collect attr.ibs from base classes of *cls*, except *taken_attr_names*.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   431
    """
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   432
    base_attrs = []
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   433
    base_attr_map = {}  # A dictionary of base attrs to their classes.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   434
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   435
    # Traverse the MRO and collect attributes.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   436
    for base_cls in reversed(cls.__mro__[1:-1]):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   437
        for a in getattr(base_cls, "__attrs_attrs__", []):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   438
            if a.inherited or a.name in taken_attr_names:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   439
                continue
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   440
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   441
            a = a.evolve(inherited=True)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   442
            base_attrs.append(a)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   443
            base_attr_map[a.name] = base_cls
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   444
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   445
    # For each name, only keep the freshest definition i.e. the furthest at the
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   446
    # back.  base_attr_map is fine because it gets overwritten with every new
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   447
    # instance.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   448
    filtered = []
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   449
    seen = set()
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   450
    for a in reversed(base_attrs):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   451
        if a.name in seen:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   452
            continue
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   453
        filtered.insert(0, a)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   454
        seen.add(a.name)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   455
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   456
    return filtered, base_attr_map
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   457
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   458
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   459
def _collect_base_attrs_broken(cls, taken_attr_names):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   460
    """
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   461
    Collect attr.ibs from base classes of *cls*, except *taken_attr_names*.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   462
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   463
    N.B. *taken_attr_names* will be mutated.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   464
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   465
    Adhere to the old incorrect behavior.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   466
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   467
    Notably it collects from the front and considers inherited attributes which
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   468
    leads to the buggy behavior reported in #428.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   469
    """
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   470
    base_attrs = []
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   471
    base_attr_map = {}  # A dictionary of base attrs to their classes.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   472
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   473
    # Traverse the MRO and collect attributes.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   474
    for base_cls in cls.__mro__[1:-1]:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   475
        for a in getattr(base_cls, "__attrs_attrs__", []):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   476
            if a.name in taken_attr_names:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   477
                continue
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   478
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   479
            a = a.evolve(inherited=True)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   480
            taken_attr_names.add(a.name)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   481
            base_attrs.append(a)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   482
            base_attr_map[a.name] = base_cls
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   483
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   484
    return base_attrs, base_attr_map
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   485
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   486
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   487
def _transform_attrs(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   488
    cls, these, auto_attribs, kw_only, collect_by_mro, field_transformer
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   489
):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   490
    """
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   491
    Transform all `_CountingAttr`s on a class into `Attribute`s.
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   492
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   493
    If *these* is passed, use that and don't look for them on the class.
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   494
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   495
    *collect_by_mro* is True, collect them in the correct MRO order, otherwise
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   496
    use the old -- incorrect -- order.  See #428.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   497
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   498
    Return an `_Attributes`.
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   499
    """
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   500
    cd = cls.__dict__
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   501
    anns = _get_annotations(cls)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   502
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   503
    if these is not None:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   504
        ca_list = [(name, ca) for name, ca in these.items()]
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   505
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   506
        if not isinstance(these, ordered_dict):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   507
            ca_list.sort(key=_counter_getter)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   508
    elif auto_attribs is True:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   509
        ca_names = {
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   510
            name
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   511
            for name, attr in cd.items()
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   512
            if isinstance(attr, _CountingAttr)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   513
        }
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   514
        ca_list = []
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   515
        annot_names = set()
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   516
        for attr_name, type in anns.items():
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   517
            if _is_class_var(type):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   518
                continue
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   519
            annot_names.add(attr_name)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   520
            a = cd.get(attr_name, NOTHING)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   521
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   522
            if not isinstance(a, _CountingAttr):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   523
                if a is NOTHING:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   524
                    a = attrib()
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   525
                else:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   526
                    a = attrib(default=a)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   527
            ca_list.append((attr_name, a))
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   528
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   529
        unannotated = ca_names - annot_names
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   530
        if len(unannotated) > 0:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   531
            raise UnannotatedAttributeError(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   532
                "The following `attr.ib`s lack a type annotation: "
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   533
                + ", ".join(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   534
                    sorted(unannotated, key=lambda n: cd.get(n).counter)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   535
                )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   536
                + "."
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   537
            )
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   538
    else:
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   539
        ca_list = sorted(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   540
            (
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   541
                (name, attr)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   542
                for name, attr in cd.items()
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   543
                if isinstance(attr, _CountingAttr)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   544
            ),
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   545
            key=lambda e: e[1].counter,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   546
        )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   547
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   548
    own_attrs = [
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   549
        Attribute.from_counting_attr(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   550
            name=attr_name, ca=ca, type=anns.get(attr_name)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   551
        )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   552
        for attr_name, ca in ca_list
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   553
    ]
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   554
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   555
    if collect_by_mro:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   556
        base_attrs, base_attr_map = _collect_base_attrs(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   557
            cls, {a.name for a in own_attrs}
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   558
        )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   559
    else:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   560
        base_attrs, base_attr_map = _collect_base_attrs_broken(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   561
            cls, {a.name for a in own_attrs}
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   562
        )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   563
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   564
    if kw_only:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   565
        own_attrs = [a.evolve(kw_only=True) for a in own_attrs]
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   566
        base_attrs = [a.evolve(kw_only=True) for a in base_attrs]
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   567
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   568
    attrs = base_attrs + own_attrs
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   569
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   570
    # Mandatory vs non-mandatory attr order only matters when they are part of
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   571
    # the __init__ signature and when they aren't kw_only (which are moved to
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   572
    # the end and can be mandatory or non-mandatory in any order, as they will
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   573
    # be specified as keyword args anyway). Check the order of those attrs:
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   574
    had_default = False
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   575
    for a in (a for a in attrs if a.init is not False and a.kw_only is False):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   576
        if had_default is True and a.default is NOTHING:
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   577
            raise ValueError(
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   578
                "No mandatory attributes allowed after an attribute with a "
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   579
                "default value or factory.  Attribute in question: %r" % (a,)
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   580
            )
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   581
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   582
        if had_default is False and a.default is not NOTHING:
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   583
            had_default = True
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   584
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   585
    if field_transformer is not None:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   586
        attrs = field_transformer(cls, attrs)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   587
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   588
    # Create AttrsClass *after* applying the field_transformer since it may
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   589
    # add or remove attributes!
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   590
    attr_names = [a.name for a in attrs]
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   591
    AttrsClass = _make_attr_tuple_class(cls.__name__, attr_names)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   592
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   593
    return _Attributes((AttrsClass(attrs), base_attrs, base_attr_map))
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   594
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   595
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   596
if PYPY:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   597
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   598
    def _frozen_setattrs(self, name, value):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   599
        """
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   600
        Attached to frozen classes as __setattr__.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   601
        """
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   602
        if isinstance(self, BaseException) and name in (
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   603
            "__cause__",
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   604
            "__context__",
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   605
        ):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   606
            BaseException.__setattr__(self, name, value)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   607
            return
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   608
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   609
        raise FrozenInstanceError()
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   610
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   611
else:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   612
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   613
    def _frozen_setattrs(self, name, value):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   614
        """
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   615
        Attached to frozen classes as __setattr__.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   616
        """
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   617
        raise FrozenInstanceError()
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   618
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   619
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   620
def _frozen_delattrs(self, name):
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   621
    """
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   622
    Attached to frozen classes as __delattr__.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   623
    """
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   624
    raise FrozenInstanceError()
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   625
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   626
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   627
class _ClassBuilder:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   628
    """
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   629
    Iteratively build *one* class.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   630
    """
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   631
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   632
    __slots__ = (
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   633
        "_attr_names",
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   634
        "_attrs",
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   635
        "_base_attr_map",
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   636
        "_base_names",
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   637
        "_cache_hash",
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   638
        "_cls",
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   639
        "_cls_dict",
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   640
        "_delete_attribs",
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   641
        "_frozen",
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   642
        "_has_pre_init",
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   643
        "_has_post_init",
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   644
        "_is_exc",
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   645
        "_on_setattr",
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   646
        "_slots",
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   647
        "_weakref_slot",
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   648
        "_wrote_own_setattr",
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   649
        "_has_custom_setattr",
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   650
    )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   651
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   652
    def __init__(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   653
        self,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   654
        cls,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   655
        these,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   656
        slots,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   657
        frozen,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   658
        weakref_slot,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   659
        getstate_setstate,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   660
        auto_attribs,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   661
        kw_only,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   662
        cache_hash,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   663
        is_exc,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   664
        collect_by_mro,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   665
        on_setattr,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   666
        has_custom_setattr,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   667
        field_transformer,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   668
    ):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   669
        attrs, base_attrs, base_map = _transform_attrs(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   670
            cls,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   671
            these,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   672
            auto_attribs,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   673
            kw_only,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   674
            collect_by_mro,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   675
            field_transformer,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   676
        )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   677
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   678
        self._cls = cls
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   679
        self._cls_dict = dict(cls.__dict__) if slots else {}
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   680
        self._attrs = attrs
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   681
        self._base_names = {a.name for a in base_attrs}
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   682
        self._base_attr_map = base_map
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   683
        self._attr_names = tuple(a.name for a in attrs)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   684
        self._slots = slots
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   685
        self._frozen = frozen
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   686
        self._weakref_slot = weakref_slot
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   687
        self._cache_hash = cache_hash
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   688
        self._has_pre_init = bool(getattr(cls, "__attrs_pre_init__", False))
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   689
        self._has_post_init = bool(getattr(cls, "__attrs_post_init__", False))
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   690
        self._delete_attribs = not bool(these)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   691
        self._is_exc = is_exc
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   692
        self._on_setattr = on_setattr
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   693
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   694
        self._has_custom_setattr = has_custom_setattr
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   695
        self._wrote_own_setattr = False
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   696
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   697
        self._cls_dict["__attrs_attrs__"] = self._attrs
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   698
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   699
        if frozen:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   700
            self._cls_dict["__setattr__"] = _frozen_setattrs
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   701
            self._cls_dict["__delattr__"] = _frozen_delattrs
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   702
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   703
            self._wrote_own_setattr = True
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   704
        elif on_setattr in (
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   705
            _ng_default_on_setattr,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   706
            setters.validate,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   707
            setters.convert,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   708
        ):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   709
            has_validator = has_converter = False
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   710
            for a in attrs:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   711
                if a.validator is not None:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   712
                    has_validator = True
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   713
                if a.converter is not None:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   714
                    has_converter = True
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   715
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   716
                if has_validator and has_converter:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   717
                    break
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   718
            if (
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   719
                (
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   720
                    on_setattr == _ng_default_on_setattr
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   721
                    and not (has_validator or has_converter)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   722
                )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   723
                or (on_setattr == setters.validate and not has_validator)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   724
                or (on_setattr == setters.convert and not has_converter)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   725
            ):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   726
                # If class-level on_setattr is set to convert + validate, but
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   727
                # there's no field to convert or validate, pretend like there's
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   728
                # no on_setattr.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   729
                self._on_setattr = None
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   730
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   731
        if getstate_setstate:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   732
            (
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   733
                self._cls_dict["__getstate__"],
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   734
                self._cls_dict["__setstate__"],
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   735
            ) = self._make_getstate_setstate()
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   736
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   737
    def __repr__(self):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   738
        return "<_ClassBuilder(cls={cls})>".format(cls=self._cls.__name__)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   739
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   740
    def build_class(self):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   741
        """
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   742
        Finalize class based on the accumulated configuration.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   743
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   744
        Builder cannot be used after calling this method.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   745
        """
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   746
        if self._slots is True:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   747
            return self._create_slots_class()
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   748
        else:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   749
            return self._patch_original_class()
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   750
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   751
    def _patch_original_class(self):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   752
        """
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   753
        Apply accumulated methods and return the class.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   754
        """
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   755
        cls = self._cls
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   756
        base_names = self._base_names
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   757
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   758
        # Clean class of attribute definitions (`attr.ib()`s).
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   759
        if self._delete_attribs:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   760
            for name in self._attr_names:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   761
                if (
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   762
                    name not in base_names
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   763
                    and getattr(cls, name, _sentinel) is not _sentinel
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   764
                ):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   765
                    try:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   766
                        delattr(cls, name)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   767
                    except AttributeError:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   768
                        # This can happen if a base class defines a class
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   769
                        # variable and we want to set an attribute with the
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   770
                        # same name by using only a type annotation.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   771
                        pass
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   772
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   773
        # Attach our dunder methods.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   774
        for name, value in self._cls_dict.items():
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   775
            setattr(cls, name, value)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   776
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   777
        # If we've inherited an attrs __setattr__ and don't write our own,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   778
        # reset it to object's.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   779
        if not self._wrote_own_setattr and getattr(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   780
            cls, "__attrs_own_setattr__", False
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   781
        ):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   782
            cls.__attrs_own_setattr__ = False
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   783
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   784
            if not self._has_custom_setattr:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   785
                cls.__setattr__ = _obj_setattr
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   786
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   787
        return cls
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   788
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   789
    def _create_slots_class(self):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   790
        """
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   791
        Build and return a new class with a `__slots__` attribute.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   792
        """
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   793
        cd = {
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   794
            k: v
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   795
            for k, v in self._cls_dict.items()
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   796
            if k not in tuple(self._attr_names) + ("__dict__", "__weakref__")
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   797
        }
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   798
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   799
        # If our class doesn't have its own implementation of __setattr__
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   800
        # (either from the user or by us), check the bases, if one of them has
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   801
        # an attrs-made __setattr__, that needs to be reset. We don't walk the
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   802
        # MRO because we only care about our immediate base classes.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   803
        # XXX: This can be confused by subclassing a slotted attrs class with
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   804
        # XXX: a non-attrs class and subclass the resulting class with an attrs
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   805
        # XXX: class.  See `test_slotted_confused` for details.  For now that's
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   806
        # XXX: OK with us.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   807
        if not self._wrote_own_setattr:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   808
            cd["__attrs_own_setattr__"] = False
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   809
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   810
            if not self._has_custom_setattr:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   811
                for base_cls in self._cls.__bases__:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   812
                    if base_cls.__dict__.get("__attrs_own_setattr__", False):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   813
                        cd["__setattr__"] = _obj_setattr
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   814
                        break
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   815
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   816
        # Traverse the MRO to collect existing slots
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   817
        # and check for an existing __weakref__.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   818
        existing_slots = dict()
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   819
        weakref_inherited = False
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   820
        for base_cls in self._cls.__mro__[1:-1]:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   821
            if base_cls.__dict__.get("__weakref__", None) is not None:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   822
                weakref_inherited = True
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   823
            existing_slots.update(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   824
                {
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   825
                    name: getattr(base_cls, name)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   826
                    for name in getattr(base_cls, "__slots__", [])
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   827
                }
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   828
            )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   829
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   830
        base_names = set(self._base_names)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   831
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   832
        names = self._attr_names
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   833
        if (
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   834
            self._weakref_slot
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   835
            and "__weakref__" not in getattr(self._cls, "__slots__", ())
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   836
            and "__weakref__" not in names
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   837
            and not weakref_inherited
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   838
        ):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   839
            names += ("__weakref__",)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   840
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   841
        # We only add the names of attributes that aren't inherited.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   842
        # Setting __slots__ to inherited attributes wastes memory.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   843
        slot_names = [name for name in names if name not in base_names]
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   844
        # There are slots for attributes from current class
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   845
        # that are defined in parent classes.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   846
        # As their descriptors may be overridden by a child class,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   847
        # we collect them here and update the class dict
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   848
        reused_slots = {
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   849
            slot: slot_descriptor
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   850
            for slot, slot_descriptor in existing_slots.items()
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   851
            if slot in slot_names
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   852
        }
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   853
        slot_names = [name for name in slot_names if name not in reused_slots]
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   854
        cd.update(reused_slots)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   855
        if self._cache_hash:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   856
            slot_names.append(_hash_cache_field)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   857
        cd["__slots__"] = tuple(slot_names)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   858
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   859
        cd["__qualname__"] = self._cls.__qualname__
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   860
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   861
        # Create new class based on old class and our methods.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   862
        cls = type(self._cls)(self._cls.__name__, self._cls.__bases__, cd)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   863
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   864
        # The following is a fix for
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   865
        # <https://github.com/python-attrs/attrs/issues/102>.  On Python 3,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   866
        # if a method mentions `__class__` or uses the no-arg super(), the
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   867
        # compiler will bake a reference to the class in the method itself
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   868
        # as `method.__closure__`.  Since we replace the class with a
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   869
        # clone, we rewrite these references so it keeps working.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   870
        for item in cls.__dict__.values():
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   871
            if isinstance(item, (classmethod, staticmethod)):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   872
                # Class- and staticmethods hide their functions inside.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   873
                # These might need to be rewritten as well.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   874
                closure_cells = getattr(item.__func__, "__closure__", None)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   875
            elif isinstance(item, property):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   876
                # Workaround for property `super()` shortcut (PY3-only).
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   877
                # There is no universal way for other descriptors.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   878
                closure_cells = getattr(item.fget, "__closure__", None)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   879
            else:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   880
                closure_cells = getattr(item, "__closure__", None)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   881
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   882
            if not closure_cells:  # Catch None or the empty list.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   883
                continue
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   884
            for cell in closure_cells:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   885
                try:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   886
                    match = cell.cell_contents is self._cls
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   887
                except ValueError:  # ValueError: Cell is empty
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   888
                    pass
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   889
                else:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   890
                    if match:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   891
                        set_closure_cell(cell, cls)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   892
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   893
        return cls
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   894
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   895
    def add_repr(self, ns):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   896
        self._cls_dict["__repr__"] = self._add_method_dunders(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   897
            _make_repr(self._attrs, ns, self._cls)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   898
        )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   899
        return self
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   900
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   901
    def add_str(self):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   902
        repr = self._cls_dict.get("__repr__")
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   903
        if repr is None:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   904
            raise ValueError(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   905
                "__str__ can only be generated if a __repr__ exists."
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   906
            )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   907
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   908
        def __str__(self):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   909
            return self.__repr__()
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   910
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   911
        self._cls_dict["__str__"] = self._add_method_dunders(__str__)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   912
        return self
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   913
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   914
    def _make_getstate_setstate(self):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   915
        """
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   916
        Create custom __setstate__ and __getstate__ methods.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   917
        """
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   918
        # __weakref__ is not writable.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   919
        state_attr_names = tuple(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   920
            an for an in self._attr_names if an != "__weakref__"
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   921
        )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   922
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   923
        def slots_getstate(self):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   924
            """
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   925
            Automatically created by attrs.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   926
            """
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   927
            return tuple(getattr(self, name) for name in state_attr_names)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   928
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   929
        hash_caching_enabled = self._cache_hash
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   930
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   931
        def slots_setstate(self, state):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   932
            """
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   933
            Automatically created by attrs.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   934
            """
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   935
            __bound_setattr = _obj_setattr.__get__(self, Attribute)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   936
            for name, value in zip(state_attr_names, state):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   937
                __bound_setattr(name, value)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   938
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   939
            # The hash code cache is not included when the object is
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   940
            # serialized, but it still needs to be initialized to None to
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   941
            # indicate that the first call to __hash__ should be a cache
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   942
            # miss.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   943
            if hash_caching_enabled:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   944
                __bound_setattr(_hash_cache_field, None)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   945
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   946
        return slots_getstate, slots_setstate
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   947
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   948
    def make_unhashable(self):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   949
        self._cls_dict["__hash__"] = None
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   950
        return self
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   951
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   952
    def add_hash(self):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   953
        self._cls_dict["__hash__"] = self._add_method_dunders(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   954
            _make_hash(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   955
                self._cls,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   956
                self._attrs,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   957
                frozen=self._frozen,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   958
                cache_hash=self._cache_hash,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   959
            )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   960
        )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   961
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   962
        return self
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   963
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   964
    def add_init(self):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   965
        self._cls_dict["__init__"] = self._add_method_dunders(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   966
            _make_init(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   967
                self._cls,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   968
                self._attrs,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   969
                self._has_pre_init,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   970
                self._has_post_init,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   971
                self._frozen,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   972
                self._slots,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   973
                self._cache_hash,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   974
                self._base_attr_map,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   975
                self._is_exc,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   976
                self._on_setattr,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   977
                attrs_init=False,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   978
            )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   979
        )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   980
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   981
        return self
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   982
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   983
    def add_match_args(self):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   984
        self._cls_dict["__match_args__"] = tuple(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   985
            field.name
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   986
            for field in self._attrs
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   987
            if field.init and not field.kw_only
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   988
        )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   989
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   990
    def add_attrs_init(self):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   991
        self._cls_dict["__attrs_init__"] = self._add_method_dunders(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   992
            _make_init(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   993
                self._cls,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   994
                self._attrs,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   995
                self._has_pre_init,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   996
                self._has_post_init,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   997
                self._frozen,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   998
                self._slots,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
   999
                self._cache_hash,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1000
                self._base_attr_map,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1001
                self._is_exc,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1002
                self._on_setattr,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1003
                attrs_init=True,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1004
            )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1005
        )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1006
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1007
        return self
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1008
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1009
    def add_eq(self):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1010
        cd = self._cls_dict
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1011
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1012
        cd["__eq__"] = self._add_method_dunders(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1013
            _make_eq(self._cls, self._attrs)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1014
        )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1015
        cd["__ne__"] = self._add_method_dunders(_make_ne())
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1016
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1017
        return self
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1018
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1019
    def add_order(self):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1020
        cd = self._cls_dict
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1021
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1022
        cd["__lt__"], cd["__le__"], cd["__gt__"], cd["__ge__"] = (
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1023
            self._add_method_dunders(meth)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1024
            for meth in _make_order(self._cls, self._attrs)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1025
        )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1026
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1027
        return self
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1028
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1029
    def add_setattr(self):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1030
        if self._frozen:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1031
            return self
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1032
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1033
        sa_attrs = {}
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1034
        for a in self._attrs:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1035
            on_setattr = a.on_setattr or self._on_setattr
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1036
            if on_setattr and on_setattr is not setters.NO_OP:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1037
                sa_attrs[a.name] = a, on_setattr
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1038
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1039
        if not sa_attrs:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1040
            return self
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1041
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1042
        if self._has_custom_setattr:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1043
            # We need to write a __setattr__ but there already is one!
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1044
            raise ValueError(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1045
                "Can't combine custom __setattr__ with on_setattr hooks."
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1046
            )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1047
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1048
        # docstring comes from _add_method_dunders
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1049
        def __setattr__(self, name, val):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1050
            try:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1051
                a, hook = sa_attrs[name]
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1052
            except KeyError:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1053
                nval = val
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1054
            else:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1055
                nval = hook(self, a, val)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1056
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1057
            _obj_setattr(self, name, nval)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1058
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1059
        self._cls_dict["__attrs_own_setattr__"] = True
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1060
        self._cls_dict["__setattr__"] = self._add_method_dunders(__setattr__)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1061
        self._wrote_own_setattr = True
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1062
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1063
        return self
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1064
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1065
    def _add_method_dunders(self, method):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1066
        """
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1067
        Add __module__ and __qualname__ to a *method* if possible.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1068
        """
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1069
        try:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1070
            method.__module__ = self._cls.__module__
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1071
        except AttributeError:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1072
            pass
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1073
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1074
        try:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1075
            method.__qualname__ = ".".join(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1076
                (self._cls.__qualname__, method.__name__)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1077
            )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1078
        except AttributeError:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1079
            pass
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1080
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1081
        try:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1082
            method.__doc__ = "Method generated by attrs for class %s." % (
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1083
                self._cls.__qualname__,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1084
            )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1085
        except AttributeError:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1086
            pass
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1087
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1088
        return method
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1089
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1090
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1091
def _determine_attrs_eq_order(cmp, eq, order, default_eq):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1092
    """
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1093
    Validate the combination of *cmp*, *eq*, and *order*. Derive the effective
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1094
    values of eq and order.  If *eq* is None, set it to *default_eq*.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1095
    """
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1096
    if cmp is not None and any((eq is not None, order is not None)):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1097
        raise ValueError("Don't mix `cmp` with `eq' and `order`.")
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1098
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1099
    # cmp takes precedence due to bw-compatibility.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1100
    if cmp is not None:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1101
        return cmp, cmp
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1102
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1103
    # If left None, equality is set to the specified default and ordering
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1104
    # mirrors equality.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1105
    if eq is None:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1106
        eq = default_eq
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1107
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1108
    if order is None:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1109
        order = eq
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1110
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1111
    if eq is False and order is True:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1112
        raise ValueError("`order` can only be True if `eq` is True too.")
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1113
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1114
    return eq, order
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1115
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1116
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1117
def _determine_attrib_eq_order(cmp, eq, order, default_eq):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1118
    """
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1119
    Validate the combination of *cmp*, *eq*, and *order*. Derive the effective
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1120
    values of eq and order.  If *eq* is None, set it to *default_eq*.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1121
    """
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1122
    if cmp is not None and any((eq is not None, order is not None)):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1123
        raise ValueError("Don't mix `cmp` with `eq' and `order`.")
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1124
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1125
    def decide_callable_or_boolean(value):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1126
        """
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1127
        Decide whether a key function is used.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1128
        """
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1129
        if callable(value):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1130
            value, key = True, value
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1131
        else:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1132
            key = None
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1133
        return value, key
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1134
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1135
    # cmp takes precedence due to bw-compatibility.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1136
    if cmp is not None:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1137
        cmp, cmp_key = decide_callable_or_boolean(cmp)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1138
        return cmp, cmp_key, cmp, cmp_key
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1139
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1140
    # If left None, equality is set to the specified default and ordering
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1141
    # mirrors equality.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1142
    if eq is None:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1143
        eq, eq_key = default_eq, None
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1144
    else:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1145
        eq, eq_key = decide_callable_or_boolean(eq)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1146
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1147
    if order is None:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1148
        order, order_key = eq, eq_key
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1149
    else:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1150
        order, order_key = decide_callable_or_boolean(order)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1151
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1152
    if eq is False and order is True:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1153
        raise ValueError("`order` can only be True if `eq` is True too.")
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1154
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1155
    return eq, eq_key, order, order_key
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1156
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1157
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1158
def _determine_whether_to_implement(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1159
    cls, flag, auto_detect, dunders, default=True
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1160
):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1161
    """
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1162
    Check whether we should implement a set of methods for *cls*.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1163
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1164
    *flag* is the argument passed into @attr.s like 'init', *auto_detect* the
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1165
    same as passed into @attr.s and *dunders* is a tuple of attribute names
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1166
    whose presence signal that the user has implemented it themselves.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1167
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1168
    Return *default* if no reason for either for or against is found.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1169
    """
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1170
    if flag is True or flag is False:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1171
        return flag
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1172
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1173
    if flag is None and auto_detect is False:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1174
        return default
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1175
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1176
    # Logically, flag is None and auto_detect is True here.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1177
    for dunder in dunders:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1178
        if _has_own_attribute(cls, dunder):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1179
            return False
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1180
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1181
    return default
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1182
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1183
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1184
def attrs(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1185
    maybe_cls=None,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1186
    these=None,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1187
    repr_ns=None,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1188
    repr=None,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1189
    cmp=None,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1190
    hash=None,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1191
    init=None,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1192
    slots=False,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1193
    frozen=False,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1194
    weakref_slot=True,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1195
    str=False,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1196
    auto_attribs=False,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1197
    kw_only=False,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1198
    cache_hash=False,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1199
    auto_exc=False,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1200
    eq=None,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1201
    order=None,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1202
    auto_detect=False,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1203
    collect_by_mro=False,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1204
    getstate_setstate=None,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1205
    on_setattr=None,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1206
    field_transformer=None,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1207
    match_args=True,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1208
):
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1209
    r"""
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1210
    A class decorator that adds `dunder
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1211
    <https://wiki.python.org/moin/DunderAlias>`_\ -methods according to the
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1212
    specified attributes using `attr.ib` or the *these* argument.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1213
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1214
    :param these: A dictionary of name to `attr.ib` mappings.  This is
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1215
        useful to avoid the definition of your attributes within the class body
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1216
        because you can't (e.g. if you want to add ``__repr__`` methods to
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1217
        Django models) or don't want to.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1218
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1219
        If *these* is not ``None``, ``attrs`` will *not* search the class body
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1220
        for attributes and will *not* remove any attributes from it.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1221
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1222
        If *these* is an ordered dict (`dict` on Python 3.6+,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1223
        `collections.OrderedDict` otherwise), the order is deduced from
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1224
        the order of the attributes inside *these*.  Otherwise the order
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1225
        of the definition of the attributes is used.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1226
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1227
    :type these: `dict` of `str` to `attr.ib`
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1228
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1229
    :param str repr_ns: When using nested classes, there's no way in Python 2
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1230
        to automatically detect that.  Therefore it's possible to set the
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1231
        namespace explicitly for a more meaningful ``repr`` output.
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1232
    :param bool auto_detect: Instead of setting the *init*, *repr*, *eq*,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1233
        *order*, and *hash* arguments explicitly, assume they are set to
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1234
        ``True`` **unless any** of the involved methods for one of the
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1235
        arguments is implemented in the *current* class (i.e. it is *not*
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1236
        inherited from some base class).
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1237
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1238
        So for example by implementing ``__eq__`` on a class yourself,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1239
        ``attrs`` will deduce ``eq=False`` and will create *neither*
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1240
        ``__eq__`` *nor* ``__ne__`` (but Python classes come with a sensible
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1241
        ``__ne__`` by default, so it *should* be enough to only implement
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1242
        ``__eq__`` in most cases).
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1243
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1244
        .. warning::
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1245
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1246
           If you prevent ``attrs`` from creating the ordering methods for you
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1247
           (``order=False``, e.g. by implementing ``__le__``), it becomes
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1248
           *your* responsibility to make sure its ordering is sound. The best
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1249
           way is to use the `functools.total_ordering` decorator.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1250
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1251
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1252
        Passing ``True`` or ``False`` to *init*, *repr*, *eq*, *order*,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1253
        *cmp*, or *hash* overrides whatever *auto_detect* would determine.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1254
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1255
        *auto_detect* requires Python 3. Setting it ``True`` on Python 2 raises
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1256
        an `attrs.exceptions.PythonTooOldError`.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1257
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1258
    :param bool repr: Create a ``__repr__`` method with a human readable
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1259
        representation of ``attrs`` attributes..
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1260
    :param bool str: Create a ``__str__`` method that is identical to
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1261
        ``__repr__``.  This is usually not necessary except for
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1262
        `Exception`\ s.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1263
    :param Optional[bool] eq: If ``True`` or ``None`` (default), add ``__eq__``
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1264
        and ``__ne__`` methods that check two instances for equality.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1265
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1266
        They compare the instances as if they were tuples of their ``attrs``
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1267
        attributes if and only if the types of both classes are *identical*!
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1268
    :param Optional[bool] order: If ``True``, add ``__lt__``, ``__le__``,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1269
        ``__gt__``, and ``__ge__`` methods that behave like *eq* above and
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1270
        allow instances to be ordered. If ``None`` (default) mirror value of
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1271
        *eq*.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1272
    :param Optional[bool] cmp: Setting *cmp* is equivalent to setting *eq*
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1273
        and *order* to the same value. Must not be mixed with *eq* or *order*.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1274
    :param Optional[bool] hash: If ``None`` (default), the ``__hash__`` method
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1275
        is generated according how *eq* and *frozen* are set.
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1276
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1277
        1. If *both* are True, ``attrs`` will generate a ``__hash__`` for you.
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1278
        2. If *eq* is True and *frozen* is False, ``__hash__`` will be set to
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1279
           None, marking it unhashable (which it is).
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1280
        3. If *eq* is False, ``__hash__`` will be left untouched meaning the
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1281
           ``__hash__`` method of the base class will be used (if base class is
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1282
           ``object``, this means it will fall back to id-based hashing.).
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1283
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1284
        Although not recommended, you can decide for yourself and force
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1285
        ``attrs`` to create one (e.g. if the class is immutable even though you
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1286
        didn't freeze it programmatically) by passing ``True`` or not.  Both of
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1287
        these cases are rather special and should be used carefully.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1288
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1289
        See our documentation on `hashing`, Python's documentation on
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1290
        `object.__hash__`, and the `GitHub issue that led to the default \
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1291
        behavior <https://github.com/python-attrs/attrs/issues/136>`_ for more
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1292
        details.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1293
    :param bool init: Create a ``__init__`` method that initializes the
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1294
        ``attrs`` attributes. Leading underscores are stripped for the argument
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1295
        name. If a ``__attrs_pre_init__`` method exists on the class, it will
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1296
        be called before the class is initialized. If a ``__attrs_post_init__``
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1297
        method exists on the class, it will be called after the class is fully
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1298
        initialized.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1299
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1300
        If ``init`` is ``False``, an ``__attrs_init__`` method will be
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1301
        injected instead. This allows you to define a custom ``__init__``
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1302
        method that can do pre-init work such as ``super().__init__()``,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1303
        and then call ``__attrs_init__()`` and ``__attrs_post_init__()``.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1304
    :param bool slots: Create a `slotted class <slotted classes>` that's more
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1305
        memory-efficient. Slotted classes are generally superior to the default
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1306
        dict classes, but have some gotchas you should know about, so we
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1307
        encourage you to read the `glossary entry <slotted classes>`.
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1308
    :param bool frozen: Make instances immutable after initialization.  If
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1309
        someone attempts to modify a frozen instance,
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1310
        `attr.exceptions.FrozenInstanceError` is raised.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1311
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1312
        .. note::
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1313
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1314
            1. This is achieved by installing a custom ``__setattr__`` method
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1315
               on your class, so you can't implement your own.
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1316
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1317
            2. True immutability is impossible in Python.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1318
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1319
            3. This *does* have a minor a runtime performance `impact
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1320
               <how-frozen>` when initializing new instances.  In other words:
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1321
               ``__init__`` is slightly slower with ``frozen=True``.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1322
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1323
            4. If a class is frozen, you cannot modify ``self`` in
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1324
               ``__attrs_post_init__`` or a self-written ``__init__``. You can
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1325
               circumvent that limitation by using
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1326
               ``object.__setattr__(self, "attribute_name", value)``.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1327
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1328
            5. Subclasses of a frozen class are frozen too.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1329
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1330
    :param bool weakref_slot: Make instances weak-referenceable.  This has no
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1331
        effect unless ``slots`` is also enabled.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1332
    :param bool auto_attribs: If ``True``, collect :pep:`526`-annotated
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1333
        attributes (Python 3.6 and later only) from the class body.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1334
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1335
        In this case, you **must** annotate every field.  If ``attrs``
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1336
        encounters a field that is set to an `attr.ib` but lacks a type
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1337
        annotation, an `attr.exceptions.UnannotatedAttributeError` is
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1338
        raised.  Use ``field_name: typing.Any = attr.ib(...)`` if you don't
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1339
        want to set a type.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1340
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1341
        If you assign a value to those attributes (e.g. ``x: int = 42``), that
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1342
        value becomes the default value like if it were passed using
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1343
        ``attr.ib(default=42)``.  Passing an instance of `attrs.Factory` also
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1344
        works as expected in most cases (see warning below).
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1345
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1346
        Attributes annotated as `typing.ClassVar`, and attributes that are
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1347
        neither annotated nor set to an `attr.ib` are **ignored**.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1348
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1349
        .. warning::
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1350
           For features that use the attribute name to create decorators (e.g.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1351
           `validators <validators>`), you still *must* assign `attr.ib` to
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1352
           them. Otherwise Python will either not find the name or try to use
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1353
           the default value to call e.g. ``validator`` on it.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1354
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1355
           These errors can be quite confusing and probably the most common bug
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1356
           report on our bug tracker.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1357
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1358
    :param bool kw_only: Make all attributes keyword-only (Python 3+)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1359
        in the generated ``__init__`` (if ``init`` is ``False``, this
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1360
        parameter is ignored).
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1361
    :param bool cache_hash: Ensure that the object's hash code is computed
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1362
        only once and stored on the object.  If this is set to ``True``,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1363
        hashing must be either explicitly or implicitly enabled for this
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1364
        class.  If the hash code is cached, avoid any reassignments of
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1365
        fields involved in hash code computation or mutations of the objects
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1366
        those fields point to after object creation.  If such changes occur,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1367
        the behavior of the object's hash code is undefined.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1368
    :param bool auto_exc: If the class subclasses `BaseException`
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1369
        (which implicitly includes any subclass of any exception), the
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1370
        following happens to behave like a well-behaved Python exceptions
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1371
        class:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1372
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1373
        - the values for *eq*, *order*, and *hash* are ignored and the
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1374
          instances compare and hash by the instance's ids (N.B. ``attrs`` will
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1375
          *not* remove existing implementations of ``__hash__`` or the equality
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1376
          methods. It just won't add own ones.),
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1377
        - all attributes that are either passed into ``__init__`` or have a
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1378
          default value are additionally available as a tuple in the ``args``
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1379
          attribute,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1380
        - the value of *str* is ignored leaving ``__str__`` to base classes.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1381
    :param bool collect_by_mro: Setting this to `True` fixes the way ``attrs``
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1382
       collects attributes from base classes.  The default behavior is
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1383
       incorrect in certain cases of multiple inheritance.  It should be on by
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1384
       default but is kept off for backward-compatibility.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1385
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1386
       See issue `#428 <https://github.com/python-attrs/attrs/issues/428>`_ for
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1387
       more details.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1388
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1389
    :param Optional[bool] getstate_setstate:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1390
       .. note::
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1391
          This is usually only interesting for slotted classes and you should
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1392
          probably just set *auto_detect* to `True`.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1393
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1394
       If `True`, ``__getstate__`` and
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1395
       ``__setstate__`` are generated and attached to the class. This is
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1396
       necessary for slotted classes to be pickleable. If left `None`, it's
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1397
       `True` by default for slotted classes and ``False`` for dict classes.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1398
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1399
       If *auto_detect* is `True`, and *getstate_setstate* is left `None`,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1400
       and **either** ``__getstate__`` or ``__setstate__`` is detected directly
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1401
       on the class (i.e. not inherited), it is set to `False` (this is usually
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1402
       what you want).
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1403
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1404
    :param on_setattr: A callable that is run whenever the user attempts to set
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1405
        an attribute (either by assignment like ``i.x = 42`` or by using
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1406
        `setattr` like ``setattr(i, "x", 42)``). It receives the same arguments
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1407
        as validators: the instance, the attribute that is being modified, and
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1408
        the new value.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1409
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1410
        If no exception is raised, the attribute is set to the return value of
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1411
        the callable.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1412
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1413
        If a list of callables is passed, they're automatically wrapped in an
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1414
        `attrs.setters.pipe`.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1415
    :type on_setattr: `callable`, or a list of callables, or `None`, or
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1416
        `attrs.setters.NO_OP`
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1417
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1418
    :param Optional[callable] field_transformer:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1419
        A function that is called with the original class object and all
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1420
        fields right before ``attrs`` finalizes the class.  You can use
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1421
        this, e.g., to automatically add converters or validators to
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1422
        fields based on their types.  See `transform-fields` for more details.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1423
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1424
    :param bool match_args:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1425
        If `True` (default), set ``__match_args__`` on the class to support
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1426
        :pep:`634` (Structural Pattern Matching). It is a tuple of all
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1427
        non-keyword-only ``__init__`` parameter names on Python 3.10 and later.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1428
        Ignored on older Python versions.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1429
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1430
    .. versionadded:: 16.0.0 *slots*
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1431
    .. versionadded:: 16.1.0 *frozen*
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1432
    .. versionadded:: 16.3.0 *str*
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1433
    .. versionadded:: 16.3.0 Support for ``__attrs_post_init__``.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1434
    .. versionchanged:: 17.1.0
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1435
       *hash* supports ``None`` as value which is also the default now.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1436
    .. versionadded:: 17.3.0 *auto_attribs*
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1437
    .. versionchanged:: 18.1.0
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1438
       If *these* is passed, no attributes are deleted from the class body.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1439
    .. versionchanged:: 18.1.0 If *these* is ordered, the order is retained.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1440
    .. versionadded:: 18.2.0 *weakref_slot*
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1441
    .. deprecated:: 18.2.0
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1442
       ``__lt__``, ``__le__``, ``__gt__``, and ``__ge__`` now raise a
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1443
       `DeprecationWarning` if the classes compared are subclasses of
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1444
       each other. ``__eq`` and ``__ne__`` never tried to compared subclasses
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1445
       to each other.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1446
    .. versionchanged:: 19.2.0
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1447
       ``__lt__``, ``__le__``, ``__gt__``, and ``__ge__`` now do not consider
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1448
       subclasses comparable anymore.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1449
    .. versionadded:: 18.2.0 *kw_only*
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1450
    .. versionadded:: 18.2.0 *cache_hash*
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1451
    .. versionadded:: 19.1.0 *auto_exc*
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1452
    .. deprecated:: 19.2.0 *cmp* Removal on or after 2021-06-01.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1453
    .. versionadded:: 19.2.0 *eq* and *order*
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1454
    .. versionadded:: 20.1.0 *auto_detect*
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1455
    .. versionadded:: 20.1.0 *collect_by_mro*
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1456
    .. versionadded:: 20.1.0 *getstate_setstate*
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1457
    .. versionadded:: 20.1.0 *on_setattr*
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1458
    .. versionadded:: 20.3.0 *field_transformer*
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1459
    .. versionchanged:: 21.1.0
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1460
       ``init=False`` injects ``__attrs_init__``
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1461
    .. versionchanged:: 21.1.0 Support for ``__attrs_pre_init__``
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1462
    .. versionchanged:: 21.1.0 *cmp* undeprecated
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1463
    .. versionadded:: 21.3.0 *match_args*
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1464
    """
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1465
    eq_, order_ = _determine_attrs_eq_order(cmp, eq, order, None)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1466
    hash_ = hash  # work around the lack of nonlocal
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1467
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1468
    if isinstance(on_setattr, (list, tuple)):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1469
        on_setattr = setters.pipe(*on_setattr)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1470
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1471
    def wrap(cls):
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1472
        is_frozen = frozen or _has_frozen_base_class(cls)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1473
        is_exc = auto_exc is True and issubclass(cls, BaseException)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1474
        has_own_setattr = auto_detect and _has_own_attribute(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1475
            cls, "__setattr__"
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1476
        )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1477
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1478
        if has_own_setattr and is_frozen:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1479
            raise ValueError("Can't freeze a class with a custom __setattr__.")
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1480
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1481
        builder = _ClassBuilder(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1482
            cls,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1483
            these,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1484
            slots,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1485
            is_frozen,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1486
            weakref_slot,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1487
            _determine_whether_to_implement(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1488
                cls,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1489
                getstate_setstate,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1490
                auto_detect,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1491
                ("__getstate__", "__setstate__"),
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1492
                default=slots,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1493
            ),
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1494
            auto_attribs,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1495
            kw_only,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1496
            cache_hash,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1497
            is_exc,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1498
            collect_by_mro,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1499
            on_setattr,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1500
            has_own_setattr,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1501
            field_transformer,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1502
        )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1503
        if _determine_whether_to_implement(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1504
            cls, repr, auto_detect, ("__repr__",)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1505
        ):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1506
            builder.add_repr(repr_ns)
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1507
        if str is True:
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1508
            builder.add_str()
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1509
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1510
        eq = _determine_whether_to_implement(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1511
            cls, eq_, auto_detect, ("__eq__", "__ne__")
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1512
        )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1513
        if not is_exc and eq is True:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1514
            builder.add_eq()
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1515
        if not is_exc and _determine_whether_to_implement(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1516
            cls, order_, auto_detect, ("__lt__", "__le__", "__gt__", "__ge__")
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1517
        ):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1518
            builder.add_order()
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1519
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1520
        builder.add_setattr()
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1521
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1522
        if (
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1523
            hash_ is None
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1524
            and auto_detect is True
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1525
            and _has_own_attribute(cls, "__hash__")
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1526
        ):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1527
            hash = False
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1528
        else:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1529
            hash = hash_
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1530
        if hash is not True and hash is not False and hash is not None:
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1531
            # Can't use `hash in` because 1 == True for example.
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1532
            raise TypeError(
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1533
                "Invalid value for hash.  Must be True, False, or None."
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1534
            )
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1535
        elif hash is False or (hash is None and eq is False) or is_exc:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1536
            # Don't do anything. Should fall back to __object__'s __hash__
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1537
            # which is by id.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1538
            if cache_hash:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1539
                raise TypeError(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1540
                    "Invalid value for cache_hash.  To use hash caching,"
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1541
                    " hashing must be either explicitly or implicitly "
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1542
                    "enabled."
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1543
                )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1544
        elif hash is True or (
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1545
            hash is None and eq is True and is_frozen is True
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1546
        ):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1547
            # Build a __hash__ if told so, or if it's safe.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1548
            builder.add_hash()
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1549
        else:
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1550
            # Raise TypeError on attempts to hash.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1551
            if cache_hash:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1552
                raise TypeError(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1553
                    "Invalid value for cache_hash.  To use hash caching,"
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1554
                    " hashing must be either explicitly or implicitly "
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1555
                    "enabled."
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1556
                )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1557
            builder.make_unhashable()
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1558
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1559
        if _determine_whether_to_implement(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1560
            cls, init, auto_detect, ("__init__",)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1561
        ):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1562
            builder.add_init()
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1563
        else:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1564
            builder.add_attrs_init()
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1565
            if cache_hash:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1566
                raise TypeError(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1567
                    "Invalid value for cache_hash.  To use hash caching,"
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1568
                    " init must be True."
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1569
                )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1570
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1571
        if (
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1572
            PY310
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1573
            and match_args
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1574
            and not _has_own_attribute(cls, "__match_args__")
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1575
        ):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1576
            builder.add_match_args()
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1577
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1578
        return builder.build_class()
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1579
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1580
    # maybe_cls's type depends on the usage of the decorator.  It's a class
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1581
    # if it's used as `@attrs` but ``None`` if used as `@attrs()`.
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1582
    if maybe_cls is None:
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1583
        return wrap
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1584
    else:
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1585
        return wrap(maybe_cls)
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1586
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1587
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1588
_attrs = attrs
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1589
"""
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1590
Internal alias so we can use it in functions that take an argument called
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1591
*attrs*.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1592
"""
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1593
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1594
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1595
def _has_frozen_base_class(cls):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1596
    """
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1597
    Check whether *cls* has a frozen ancestor by looking at its
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1598
    __setattr__.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1599
    """
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1600
    return cls.__setattr__ is _frozen_setattrs
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1601
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1602
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1603
def _generate_unique_filename(cls, func_name):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1604
    """
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1605
    Create a "filename" suitable for a function being generated.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1606
    """
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1607
    unique_filename = "<attrs generated {} {}.{}>".format(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1608
        func_name,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1609
        cls.__module__,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1610
        getattr(cls, "__qualname__", cls.__name__),
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1611
    )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1612
    return unique_filename
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1613
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1614
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1615
def _make_hash(cls, attrs, frozen, cache_hash):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1616
    attrs = tuple(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1617
        a for a in attrs if a.hash is True or (a.hash is None and a.eq is True)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1618
    )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1619
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1620
    tab = "        "
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1621
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1622
    unique_filename = _generate_unique_filename(cls, "hash")
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1623
    type_hash = hash(unique_filename)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1624
    # If eq is custom generated, we need to include the functions in globs
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1625
    globs = {}
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1626
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1627
    hash_def = "def __hash__(self"
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1628
    hash_func = "hash(("
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1629
    closing_braces = "))"
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1630
    if not cache_hash:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1631
        hash_def += "):"
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1632
    else:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1633
        hash_def += ", *"
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1634
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1635
        hash_def += (
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1636
            ", _cache_wrapper="
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1637
            + "__import__('attr._make')._make._CacheHashWrapper):"
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1638
        )
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1639
        hash_func = "_cache_wrapper(" + hash_func
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1640
        closing_braces += ")"
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1641
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1642
    method_lines = [hash_def]
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1644
    def append_hash_computation_lines(prefix, indent):
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1645
        """
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1646
        Generate the code for actually computing the hash code.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1647
        Below this will either be returned directly or used to compute
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1648
        a value which is then cached, depending on the value of cache_hash
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1649
        """
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1650
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1651
        method_lines.extend(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1652
            [
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1653
                indent + prefix + hash_func,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1654
                indent + "        %d," % (type_hash,),
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1655
            ]
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1656
        )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1657
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1658
        for a in attrs:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1659
            if a.eq_key:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1660
                cmp_name = "_%s_key" % (a.name,)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1661
                globs[cmp_name] = a.eq_key
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1662
                method_lines.append(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1663
                    indent + "        %s(self.%s)," % (cmp_name, a.name)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1664
                )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1665
            else:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1666
                method_lines.append(indent + "        self.%s," % a.name)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1667
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1668
        method_lines.append(indent + "    " + closing_braces)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1669
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1670
    if cache_hash:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1671
        method_lines.append(tab + "if self.%s is None:" % _hash_cache_field)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1672
        if frozen:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1673
            append_hash_computation_lines(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1674
                "object.__setattr__(self, '%s', " % _hash_cache_field, tab * 2
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1675
            )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1676
            method_lines.append(tab * 2 + ")")  # close __setattr__
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1677
        else:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1678
            append_hash_computation_lines(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1679
                "self.%s = " % _hash_cache_field, tab * 2
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1680
            )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1681
        method_lines.append(tab + "return self.%s" % _hash_cache_field)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1682
    else:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1683
        append_hash_computation_lines("return ", tab)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1684
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1685
    script = "\n".join(method_lines)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1686
    return _make_method("__hash__", script, unique_filename, globs)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1687
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1688
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1689
def _add_hash(cls, attrs):
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1690
    """
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1691
    Add a hash method to *cls*.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1692
    """
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1693
    cls.__hash__ = _make_hash(cls, attrs, frozen=False, cache_hash=False)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1694
    return cls
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1695
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1696
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1697
def _make_ne():
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1698
    """
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1699
    Create __ne__ method.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1700
    """
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1701
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1702
    def __ne__(self, other):
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1703
        """
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1704
        Check equality and either forward a NotImplemented or
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1705
        return the result negated.
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1706
        """
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1707
        result = self.__eq__(other)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1708
        if result is NotImplemented:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1709
            return NotImplemented
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1710
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1711
        return not result
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1712
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1713
    return __ne__
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1714
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1715
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1716
def _make_eq(cls, attrs):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1717
    """
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1718
    Create __eq__ method for *cls* with *attrs*.
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1719
    """
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1720
    attrs = [a for a in attrs if a.eq]
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1721
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1722
    unique_filename = _generate_unique_filename(cls, "eq")
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1723
    lines = [
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1724
        "def __eq__(self, other):",
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1725
        "    if other.__class__ is not self.__class__:",
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1726
        "        return NotImplemented",
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1727
    ]
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1728
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1729
    # We can't just do a big self.x = other.x and... clause due to
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1730
    # irregularities like nan == nan is false but (nan,) == (nan,) is true.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1731
    globs = {}
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1732
    if attrs:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1733
        lines.append("    return  (")
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1734
        others = ["    ) == ("]
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1735
        for a in attrs:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1736
            if a.eq_key:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1737
                cmp_name = "_%s_key" % (a.name,)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1738
                # Add the key function to the global namespace
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1739
                # of the evaluated function.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1740
                globs[cmp_name] = a.eq_key
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1741
                lines.append(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1742
                    "        %s(self.%s),"
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1743
                    % (
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1744
                        cmp_name,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1745
                        a.name,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1746
                    )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1747
                )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1748
                others.append(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1749
                    "        %s(other.%s),"
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1750
                    % (
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1751
                        cmp_name,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1752
                        a.name,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1753
                    )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1754
                )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1755
            else:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1756
                lines.append("        self.%s," % (a.name,))
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1757
                others.append("        other.%s," % (a.name,))
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1758
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1759
        lines += others + ["    )"]
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1760
    else:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1761
        lines.append("    return True")
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1762
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1763
    script = "\n".join(lines)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1764
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1765
    return _make_method("__eq__", script, unique_filename, globs)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1766
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1767
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1768
def _make_order(cls, attrs):
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1769
    """
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1770
    Create ordering methods for *cls* with *attrs*.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1771
    """
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1772
    attrs = [a for a in attrs if a.order]
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1773
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1774
    def attrs_to_tuple(obj):
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1775
        """
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1776
        Save us some typing.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1777
        """
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1778
        return tuple(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1779
            key(value) if key else value
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1780
            for value, key in (
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1781
                (getattr(obj, a.name), a.order_key) for a in attrs
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1782
            )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1783
        )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1784
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1785
    def __lt__(self, other):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1786
        """
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1787
        Automatically created by attrs.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1788
        """
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1789
        if other.__class__ is self.__class__:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1790
            return attrs_to_tuple(self) < attrs_to_tuple(other)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1791
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1792
        return NotImplemented
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1793
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1794
    def __le__(self, other):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1795
        """
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1796
        Automatically created by attrs.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1797
        """
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1798
        if other.__class__ is self.__class__:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1799
            return attrs_to_tuple(self) <= attrs_to_tuple(other)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1800
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1801
        return NotImplemented
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1802
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1803
    def __gt__(self, other):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1804
        """
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1805
        Automatically created by attrs.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1806
        """
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1807
        if other.__class__ is self.__class__:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1808
            return attrs_to_tuple(self) > attrs_to_tuple(other)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1809
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1810
        return NotImplemented
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1811
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1812
    def __ge__(self, other):
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1813
        """
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1814
        Automatically created by attrs.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1815
        """
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1816
        if other.__class__ is self.__class__:
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1817
            return attrs_to_tuple(self) >= attrs_to_tuple(other)
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1818
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1819
        return NotImplemented
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1820
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1821
    return __lt__, __le__, __gt__, __ge__
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1822
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1823
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1824
def _add_eq(cls, attrs=None):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1825
    """
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1826
    Add equality methods to *cls* with *attrs*.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1827
    """
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1828
    if attrs is None:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1829
        attrs = cls.__attrs_attrs__
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1830
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1831
    cls.__eq__ = _make_eq(cls, attrs)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1832
    cls.__ne__ = _make_ne()
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1833
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1834
    return cls
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1835
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1836
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1837
if HAS_F_STRINGS:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1838
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1839
    def _make_repr(attrs, ns, cls):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1840
        unique_filename = _generate_unique_filename(cls, "repr")
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1841
        # Figure out which attributes to include, and which function to use to
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1842
        # format them. The a.repr value can be either bool or a custom
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1843
        # callable.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1844
        attr_names_with_reprs = tuple(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1845
            (a.name, (repr if a.repr is True else a.repr), a.init)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1846
            for a in attrs
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1847
            if a.repr is not False
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1848
        )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1849
        globs = {
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1850
            name + "_repr": r
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1851
            for name, r, _ in attr_names_with_reprs
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1852
            if r != repr
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1853
        }
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1854
        globs["_compat"] = _compat
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1855
        globs["AttributeError"] = AttributeError
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1856
        globs["NOTHING"] = NOTHING
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1857
        attribute_fragments = []
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1858
        for name, r, i in attr_names_with_reprs:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1859
            accessor = (
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1860
                "self." + name
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1861
                if i
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1862
                else 'getattr(self, "' + name + '", NOTHING)'
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1863
            )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1864
            fragment = (
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1865
                "%s={%s!r}" % (name, accessor)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1866
                if r == repr
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1867
                else "%s={%s_repr(%s)}" % (name, name, accessor)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1868
            )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1869
            attribute_fragments.append(fragment)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1870
        repr_fragment = ", ".join(attribute_fragments)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1871
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1872
        if ns is None:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1873
            cls_name_fragment = (
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1874
                '{self.__class__.__qualname__.rsplit(">.", 1)[-1]}'
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1875
            )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1876
        else:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1877
            cls_name_fragment = ns + ".{self.__class__.__name__}"
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1878
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1879
        lines = [
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1880
            "def __repr__(self):",
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1881
            "  try:",
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1882
            "    already_repring = _compat.repr_context.already_repring",
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1883
            "  except AttributeError:",
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1884
            "    already_repring = {id(self),}",
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1885
            "    _compat.repr_context.already_repring = already_repring",
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1886
            "  else:",
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1887
            "    if id(self) in already_repring:",
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1888
            "      return '...'",
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1889
            "    else:",
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1890
            "      already_repring.add(id(self))",
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1891
            "  try:",
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1892
            "    return f'%s(%s)'" % (cls_name_fragment, repr_fragment),
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1893
            "  finally:",
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1894
            "    already_repring.remove(id(self))",
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1895
        ]
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1896
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1897
        return _make_method(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1898
            "__repr__", "\n".join(lines), unique_filename, globs=globs
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1899
        )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1900
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1901
else:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1902
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1903
    def _make_repr(attrs, ns, _):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1904
        """
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1905
        Make a repr method that includes relevant *attrs*, adding *ns* to the
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1906
        full name.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1907
        """
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1908
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1909
        # Figure out which attributes to include, and which function to use to
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1910
        # format them. The a.repr value can be either bool or a custom
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1911
        # callable.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1912
        attr_names_with_reprs = tuple(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1913
            (a.name, repr if a.repr is True else a.repr)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1914
            for a in attrs
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1915
            if a.repr is not False
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1916
        )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1917
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1918
        def __repr__(self):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1919
            """
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1920
            Automatically created by attrs.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1921
            """
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1922
            try:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1923
                already_repring = _compat.repr_context.already_repring
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1924
            except AttributeError:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1925
                already_repring = set()
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1926
                _compat.repr_context.already_repring = already_repring
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1927
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1928
            if id(self) in already_repring:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1929
                return "..."
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1930
            real_cls = self.__class__
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1931
            if ns is None:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1932
                class_name = real_cls.__qualname__.rsplit(">.", 1)[-1]
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1933
            else:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1934
                class_name = ns + "." + real_cls.__name__
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1935
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1936
            # Since 'self' remains on the stack (i.e.: strongly referenced)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1937
            # for the duration of this call, it's safe to depend on id(...)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1938
            # stability, and not need to track the instance and therefore
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1939
            # worry about properties like weakref- or hash-ability.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1940
            already_repring.add(id(self))
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1941
            try:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1942
                result = [class_name, "("]
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1943
                first = True
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1944
                for name, attr_repr in attr_names_with_reprs:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1945
                    if first:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1946
                        first = False
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1947
                    else:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1948
                        result.append(", ")
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1949
                    result.extend(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1950
                        (name, "=", attr_repr(getattr(self, name, NOTHING)))
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1951
                    )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1952
                return "".join(result) + ")"
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1953
            finally:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1954
                already_repring.remove(id(self))
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1955
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1956
        return __repr__
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1957
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1958
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1959
def _add_repr(cls, ns=None, attrs=None):
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1960
    """
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1961
    Add a repr method to *cls*.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1962
    """
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1963
    if attrs is None:
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1964
        attrs = cls.__attrs_attrs__
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1965
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1966
    cls.__repr__ = _make_repr(attrs, ns, cls)
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1967
    return cls
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1968
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1969
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1970
def fields(cls):
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1971
    """
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1972
    Return the tuple of ``attrs`` attributes for a class.
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1973
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1974
    The tuple also allows accessing the fields by their names (see below for
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1975
    examples).
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1976
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1977
    :param type cls: Class to introspect.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1978
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1979
    :raise TypeError: If *cls* is not a class.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1980
    :raise attr.exceptions.NotAnAttrsClassError: If *cls* is not an ``attrs``
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1981
        class.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1982
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1983
    :rtype: tuple (with name accessors) of `attrs.Attribute`
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1984
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1985
    ..  versionchanged:: 16.2.0 Returned tuple allows accessing the fields
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1986
        by name.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1987
    """
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1988
    if not isinstance(cls, type):
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1989
        raise TypeError("Passed object must be a class.")
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1990
    attrs = getattr(cls, "__attrs_attrs__", None)
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1991
    if attrs is None:
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1992
        raise NotAnAttrsClassError(
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1993
            "{cls!r} is not an attrs-decorated class.".format(cls=cls)
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1994
        )
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1995
    return attrs
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1996
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  1997
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1998
def fields_dict(cls):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  1999
    """
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2000
    Return an ordered dictionary of ``attrs`` attributes for a class, whose
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2001
    keys are the attribute names.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2002
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2003
    :param type cls: Class to introspect.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2004
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2005
    :raise TypeError: If *cls* is not a class.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2006
    :raise attr.exceptions.NotAnAttrsClassError: If *cls* is not an ``attrs``
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2007
        class.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2008
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2009
    :rtype: an ordered dict where keys are attribute names and values are
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2010
        `attrs.Attribute`\\ s. This will be a `dict` if it's
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2011
        naturally ordered like on Python 3.6+ or an
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2012
        :class:`~collections.OrderedDict` otherwise.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2013
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2014
    .. versionadded:: 18.1.0
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2015
    """
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2016
    if not isinstance(cls, type):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2017
        raise TypeError("Passed object must be a class.")
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2018
    attrs = getattr(cls, "__attrs_attrs__", None)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2019
    if attrs is None:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2020
        raise NotAnAttrsClassError(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2021
            "{cls!r} is not an attrs-decorated class.".format(cls=cls)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2022
        )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2023
    return ordered_dict((a.name, a) for a in attrs)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2024
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2025
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2026
def validate(inst):
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2027
    """
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2028
    Validate all attributes on *inst* that have a validator.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2029
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2030
    Leaves all exceptions through.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2031
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2032
    :param inst: Instance of a class with ``attrs`` attributes.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2033
    """
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2034
    if _config._run_validators is False:
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2035
        return
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2036
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2037
    for a in fields(inst.__class__):
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2038
        v = a.validator
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2039
        if v is not None:
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2040
            v(inst, a, getattr(inst, a.name))
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2041
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2042
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2043
def _is_slot_cls(cls):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2044
    return "__slots__" in cls.__dict__
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2045
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2046
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2047
def _is_slot_attr(a_name, base_attr_map):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2048
    """
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2049
    Check if the attribute name comes from a slot class.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2050
    """
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2051
    return a_name in base_attr_map and _is_slot_cls(base_attr_map[a_name])
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2052
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2053
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2054
def _make_init(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2055
    cls,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2056
    attrs,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2057
    pre_init,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2058
    post_init,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2059
    frozen,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2060
    slots,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2061
    cache_hash,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2062
    base_attr_map,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2063
    is_exc,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2064
    cls_on_setattr,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2065
    attrs_init,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2066
):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2067
    has_cls_on_setattr = (
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2068
        cls_on_setattr is not None and cls_on_setattr is not setters.NO_OP
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2069
    )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2070
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2071
    if frozen and has_cls_on_setattr:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2072
        raise ValueError("Frozen classes can't use on_setattr.")
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2073
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2074
    needs_cached_setattr = cache_hash or frozen
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2075
    filtered_attrs = []
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2076
    attr_dict = {}
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2077
    for a in attrs:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2078
        if not a.init and a.default is NOTHING:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2079
            continue
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2080
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2081
        filtered_attrs.append(a)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2082
        attr_dict[a.name] = a
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2083
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2084
        if a.on_setattr is not None:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2085
            if frozen is True:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2086
                raise ValueError("Frozen classes can't use on_setattr.")
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2087
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2088
            needs_cached_setattr = True
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2089
        elif has_cls_on_setattr and a.on_setattr is not setters.NO_OP:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2090
            needs_cached_setattr = True
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2091
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2092
    unique_filename = _generate_unique_filename(cls, "init")
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2093
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2094
    script, globs, annotations = _attrs_to_init_script(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2095
        filtered_attrs,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2096
        frozen,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2097
        slots,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2098
        pre_init,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2099
        post_init,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2100
        cache_hash,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2101
        base_attr_map,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2102
        is_exc,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2103
        has_cls_on_setattr,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2104
        attrs_init,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2105
    )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2106
    if cls.__module__ in sys.modules:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2107
        # This makes typing.get_type_hints(CLS.__init__) resolve string types.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2108
        globs.update(sys.modules[cls.__module__].__dict__)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2109
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2110
    globs.update({"NOTHING": NOTHING, "attr_dict": attr_dict})
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2111
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2112
    if needs_cached_setattr:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2113
        # Save the lookup overhead in __init__ if we need to circumvent
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2114
        # setattr hooks.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2115
        globs["_setattr"] = _obj_setattr
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2116
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2117
    init = _make_method(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2118
        "__attrs_init__" if attrs_init else "__init__",
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2119
        script,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2120
        unique_filename,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2121
        globs,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2122
    )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2123
    init.__annotations__ = annotations
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2124
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2125
    return init
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2126
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2127
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2128
def _setattr(attr_name, value_var, has_on_setattr):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2129
    """
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2130
    Use the cached object.setattr to set *attr_name* to *value_var*.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2131
    """
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2132
    return "_setattr(self, '%s', %s)" % (attr_name, value_var)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2133
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2134
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2135
def _setattr_with_converter(attr_name, value_var, has_on_setattr):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2136
    """
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2137
    Use the cached object.setattr to set *attr_name* to *value_var*, but run
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2138
    its converter first.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2139
    """
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2140
    return "_setattr(self, '%s', %s(%s))" % (
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2141
        attr_name,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2142
        _init_converter_pat % (attr_name,),
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2143
        value_var,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2144
    )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2145
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2146
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2147
def _assign(attr_name, value, has_on_setattr):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2148
    """
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2149
    Unless *attr_name* has an on_setattr hook, use normal assignment. Otherwise
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2150
    relegate to _setattr.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2151
    """
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2152
    if has_on_setattr:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2153
        return _setattr(attr_name, value, True)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2154
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2155
    return "self.%s = %s" % (attr_name, value)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2156
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2157
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2158
def _assign_with_converter(attr_name, value_var, has_on_setattr):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2159
    """
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2160
    Unless *attr_name* has an on_setattr hook, use normal assignment after
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2161
    conversion. Otherwise relegate to _setattr_with_converter.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2162
    """
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2163
    if has_on_setattr:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2164
        return _setattr_with_converter(attr_name, value_var, True)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2165
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2166
    return "self.%s = %s(%s)" % (
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2167
        attr_name,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2168
        _init_converter_pat % (attr_name,),
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2169
        value_var,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2170
    )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2171
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2172
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2173
def _attrs_to_init_script(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2174
    attrs,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2175
    frozen,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2176
    slots,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2177
    pre_init,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2178
    post_init,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2179
    cache_hash,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2180
    base_attr_map,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2181
    is_exc,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2182
    has_cls_on_setattr,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2183
    attrs_init,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2184
):
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2185
    """
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2186
    Return a script of an initializer for *attrs* and a dict of globals.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2187
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2188
    The globals are expected by the generated script.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2189
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2190
    If *frozen* is True, we cannot set the attributes directly so we use
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2191
    a cached ``object.__setattr__``.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2192
    """
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2193
    lines = []
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2194
    if pre_init:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2195
        lines.append("self.__attrs_pre_init__()")
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2196
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2197
    if frozen is True:
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2198
        if slots is True:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2199
            fmt_setter = _setattr
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2200
            fmt_setter_with_converter = _setattr_with_converter
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2201
        else:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2202
            # Dict frozen classes assign directly to __dict__.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2203
            # But only if the attribute doesn't come from an ancestor slot
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2204
            # class.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2205
            # Note _inst_dict will be used again below if cache_hash is True
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2206
            lines.append("_inst_dict = self.__dict__")
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2207
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2208
            def fmt_setter(attr_name, value_var, has_on_setattr):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2209
                if _is_slot_attr(attr_name, base_attr_map):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2210
                    return _setattr(attr_name, value_var, has_on_setattr)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2211
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2212
                return "_inst_dict['%s'] = %s" % (attr_name, value_var)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2213
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2214
            def fmt_setter_with_converter(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2215
                attr_name, value_var, has_on_setattr
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2216
            ):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2217
                if has_on_setattr or _is_slot_attr(attr_name, base_attr_map):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2218
                    return _setattr_with_converter(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2219
                        attr_name, value_var, has_on_setattr
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2220
                    )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2221
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2222
                return "_inst_dict['%s'] = %s(%s)" % (
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2223
                    attr_name,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2224
                    _init_converter_pat % (attr_name,),
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2225
                    value_var,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2226
                )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2227
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2228
    else:
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2229
        # Not frozen.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2230
        fmt_setter = _assign
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2231
        fmt_setter_with_converter = _assign_with_converter
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2232
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2233
    args = []
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2234
    kw_only_args = []
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2235
    attrs_to_validate = []
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2236
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2237
    # This is a dictionary of names to validator and converter callables.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2238
    # Injecting this into __init__ globals lets us avoid lookups.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2239
    names_for_globals = {}
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2240
    annotations = {"return": None}
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2241
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2242
    for a in attrs:
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2243
        if a.validator:
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2244
            attrs_to_validate.append(a)
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2245
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2246
        attr_name = a.name
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2247
        has_on_setattr = a.on_setattr is not None or (
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2248
            a.on_setattr is not setters.NO_OP and has_cls_on_setattr
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2249
        )
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2250
        arg_name = a.name.lstrip("_")
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2251
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2252
        has_factory = isinstance(a.default, Factory)
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2253
        if has_factory and a.default.takes_self:
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2254
            maybe_self = "self"
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2255
        else:
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2256
            maybe_self = ""
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2257
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2258
        if a.init is False:
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2259
            if has_factory:
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2260
                init_factory_name = _init_factory_pat.format(a.name)
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2261
                if a.converter is not None:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2262
                    lines.append(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2263
                        fmt_setter_with_converter(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2264
                            attr_name,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2265
                            init_factory_name + "(%s)" % (maybe_self,),
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2266
                            has_on_setattr,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2267
                        )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2268
                    )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2269
                    conv_name = _init_converter_pat % (a.name,)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2270
                    names_for_globals[conv_name] = a.converter
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2271
                else:
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2272
                    lines.append(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2273
                        fmt_setter(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2274
                            attr_name,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2275
                            init_factory_name + "(%s)" % (maybe_self,),
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2276
                            has_on_setattr,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2277
                        )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2278
                    )
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2279
                names_for_globals[init_factory_name] = a.default.factory
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2280
            else:
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2281
                if a.converter is not None:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2282
                    lines.append(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2283
                        fmt_setter_with_converter(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2284
                            attr_name,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2285
                            "attr_dict['%s'].default" % (attr_name,),
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2286
                            has_on_setattr,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2287
                        )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2288
                    )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2289
                    conv_name = _init_converter_pat % (a.name,)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2290
                    names_for_globals[conv_name] = a.converter
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2291
                else:
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2292
                    lines.append(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2293
                        fmt_setter(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2294
                            attr_name,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2295
                            "attr_dict['%s'].default" % (attr_name,),
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2296
                            has_on_setattr,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2297
                        )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2298
                    )
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2299
        elif a.default is not NOTHING and not has_factory:
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2300
            arg = "%s=attr_dict['%s'].default" % (arg_name, attr_name)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2301
            if a.kw_only:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2302
                kw_only_args.append(arg)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2303
            else:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2304
                args.append(arg)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2305
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2306
            if a.converter is not None:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2307
                lines.append(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2308
                    fmt_setter_with_converter(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2309
                        attr_name, arg_name, has_on_setattr
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2310
                    )
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2311
                )
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2312
                names_for_globals[
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2313
                    _init_converter_pat % (a.name,)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2314
                ] = a.converter
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2315
            else:
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2316
                lines.append(fmt_setter(attr_name, arg_name, has_on_setattr))
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2317
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2318
        elif has_factory:
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2319
            arg = "%s=NOTHING" % (arg_name,)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2320
            if a.kw_only:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2321
                kw_only_args.append(arg)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2322
            else:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2323
                args.append(arg)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2324
            lines.append("if %s is not NOTHING:" % (arg_name,))
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2325
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2326
            init_factory_name = _init_factory_pat.format(a.name)
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2327
            if a.converter is not None:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2328
                lines.append(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2329
                    "    "
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2330
                    + fmt_setter_with_converter(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2331
                        attr_name, arg_name, has_on_setattr
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2332
                    )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2333
                )
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2334
                lines.append("else:")
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2335
                lines.append(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2336
                    "    "
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2337
                    + fmt_setter_with_converter(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2338
                        attr_name,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2339
                        init_factory_name + "(" + maybe_self + ")",
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2340
                        has_on_setattr,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2341
                    )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2342
                )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2343
                names_for_globals[
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2344
                    _init_converter_pat % (a.name,)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2345
                ] = a.converter
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2346
            else:
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2347
                lines.append(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2348
                    "    " + fmt_setter(attr_name, arg_name, has_on_setattr)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2349
                )
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2350
                lines.append("else:")
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2351
                lines.append(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2352
                    "    "
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2353
                    + fmt_setter(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2354
                        attr_name,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2355
                        init_factory_name + "(" + maybe_self + ")",
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2356
                        has_on_setattr,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2357
                    )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2358
                )
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2359
            names_for_globals[init_factory_name] = a.default.factory
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2360
        else:
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2361
            if a.kw_only:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2362
                kw_only_args.append(arg_name)
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2363
            else:
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2364
                args.append(arg_name)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2365
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2366
            if a.converter is not None:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2367
                lines.append(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2368
                    fmt_setter_with_converter(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2369
                        attr_name, arg_name, has_on_setattr
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2370
                    )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2371
                )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2372
                names_for_globals[
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2373
                    _init_converter_pat % (a.name,)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2374
                ] = a.converter
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2375
            else:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2376
                lines.append(fmt_setter(attr_name, arg_name, has_on_setattr))
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2377
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2378
        if a.init is True:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2379
            if a.type is not None and a.converter is None:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2380
                annotations[arg_name] = a.type
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2381
            elif a.converter is not None:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2382
                # Try to get the type from the converter.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2383
                t = _AnnotationExtractor(a.converter).get_first_param_type()
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2384
                if t:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2385
                    annotations[arg_name] = t
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2386
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2387
    if attrs_to_validate:  # we can skip this if there are no validators.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2388
        names_for_globals["_config"] = _config
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2389
        lines.append("if _config._run_validators is True:")
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2390
        for a in attrs_to_validate:
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2391
            val_name = "__attr_validator_" + a.name
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2392
            attr_name = "__attr_" + a.name
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2393
            lines.append(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2394
                "    %s(self, %s, self.%s)" % (val_name, attr_name, a.name)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2395
            )
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2396
            names_for_globals[val_name] = a.validator
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2397
            names_for_globals[attr_name] = a
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2398
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2399
    if post_init:
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2400
        lines.append("self.__attrs_post_init__()")
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2401
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2402
    # because this is set only after __attrs_post_init__ is called, a crash
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2403
    # will result if post-init tries to access the hash code.  This seemed
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2404
    # preferable to setting this beforehand, in which case alteration to
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2405
    # field values during post-init combined with post-init accessing the
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2406
    # hash code would result in silent bugs.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2407
    if cache_hash:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2408
        if frozen:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2409
            if slots:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2410
                # if frozen and slots, then _setattr defined above
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2411
                init_hash_cache = "_setattr(self, '%s', %s)"
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2412
            else:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2413
                # if frozen and not slots, then _inst_dict defined above
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2414
                init_hash_cache = "_inst_dict['%s'] = %s"
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2415
        else:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2416
            init_hash_cache = "self.%s = %s"
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2417
        lines.append(init_hash_cache % (_hash_cache_field, "None"))
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2418
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2419
    # For exceptions we rely on BaseException.__init__ for proper
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2420
    # initialization.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2421
    if is_exc:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2422
        vals = ",".join("self." + a.name for a in attrs if a.init)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2423
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2424
        lines.append("BaseException.__init__(self, %s)" % (vals,))
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2425
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2426
    args = ", ".join(args)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2427
    if kw_only_args:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2428
        args += "%s*, %s" % (
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2429
            ", " if args else "",  # leading comma
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2430
            ", ".join(kw_only_args),  # kw_only args
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2431
        )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2432
    return (
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2433
        """\
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2434
def {init_name}(self, {args}):
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2435
    {lines}
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2436
""".format(
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2437
            init_name=("__attrs_init__" if attrs_init else "__init__"),
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2438
            args=args,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2439
            lines="\n    ".join(lines) if lines else "pass",
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2440
        ),
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2441
        names_for_globals,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2442
        annotations,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2443
    )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2444
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2445
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2446
class Attribute:
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2447
    """
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2448
    *Read-only* representation of an attribute.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2449
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2450
    The class has *all* arguments of `attr.ib` (except for ``factory``
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2451
    which is only syntactic sugar for ``default=Factory(...)`` plus the
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2452
    following:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2453
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2454
    - ``name`` (`str`): The name of the attribute.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2455
    - ``inherited`` (`bool`): Whether or not that attribute has been inherited
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2456
      from a base class.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2457
    - ``eq_key`` and ``order_key`` (`typing.Callable` or `None`): The callables
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2458
      that are used for comparing and ordering objects by this attribute,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2459
      respectively. These are set by passing a callable to `attr.ib`'s ``eq``,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2460
      ``order``, or ``cmp`` arguments. See also :ref:`comparison customization
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2461
      <custom-comparison>`.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2462
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2463
    Instances of this class are frequently used for introspection purposes
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2464
    like:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2465
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2466
    - `fields` returns a tuple of them.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2467
    - Validators get them passed as the first argument.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2468
    - The :ref:`field transformer <transform-fields>` hook receives a list of
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2469
      them.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2470
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2471
    .. versionadded:: 20.1.0 *inherited*
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2472
    .. versionadded:: 20.1.0 *on_setattr*
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2473
    .. versionchanged:: 20.2.0 *inherited* is not taken into account for
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2474
        equality checks and hashing anymore.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2475
    .. versionadded:: 21.1.0 *eq_key* and *order_key*
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2476
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2477
    For the full version history of the fields, see `attr.ib`.
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2478
    """
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2479
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2480
    __slots__ = (
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2481
        "name",
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2482
        "default",
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2483
        "validator",
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2484
        "repr",
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2485
        "eq",
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2486
        "eq_key",
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2487
        "order",
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2488
        "order_key",
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2489
        "hash",
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2490
        "init",
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2491
        "metadata",
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2492
        "type",
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2493
        "converter",
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2494
        "kw_only",
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2495
        "inherited",
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2496
        "on_setattr",
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2497
    )
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2498
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2499
    def __init__(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2500
        self,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2501
        name,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2502
        default,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2503
        validator,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2504
        repr,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2505
        cmp,  # XXX: unused, remove along with other cmp code.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2506
        hash,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2507
        init,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2508
        inherited,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2509
        metadata=None,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2510
        type=None,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2511
        converter=None,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2512
        kw_only=False,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2513
        eq=None,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2514
        eq_key=None,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2515
        order=None,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2516
        order_key=None,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2517
        on_setattr=None,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2518
    ):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2519
        eq, eq_key, order, order_key = _determine_attrib_eq_order(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2520
            cmp, eq_key or eq, order_key or order, True
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2521
        )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2522
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2523
        # Cache this descriptor here to speed things up later.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2524
        bound_setattr = _obj_setattr.__get__(self, Attribute)
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2525
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2526
        # Despite the big red warning, people *do* instantiate `Attribute`
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2527
        # themselves.
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2528
        bound_setattr("name", name)
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2529
        bound_setattr("default", default)
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2530
        bound_setattr("validator", validator)
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2531
        bound_setattr("repr", repr)
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2532
        bound_setattr("eq", eq)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2533
        bound_setattr("eq_key", eq_key)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2534
        bound_setattr("order", order)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2535
        bound_setattr("order_key", order_key)
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2536
        bound_setattr("hash", hash)
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2537
        bound_setattr("init", init)
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2538
        bound_setattr("converter", converter)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2539
        bound_setattr(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2540
            "metadata",
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2541
            (
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2542
                types.MappingProxyType(dict(metadata))  # Shallow copy
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2543
                if metadata
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2544
                else _empty_metadata_singleton
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2545
            ),
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2546
        )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2547
        bound_setattr("type", type)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2548
        bound_setattr("kw_only", kw_only)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2549
        bound_setattr("inherited", inherited)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2550
        bound_setattr("on_setattr", on_setattr)
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2551
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2552
    def __setattr__(self, name, value):
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2553
        raise FrozenInstanceError()
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2554
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2555
    @classmethod
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2556
    def from_counting_attr(cls, name, ca, type=None):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2557
        # type holds the annotated value. deal with conflicts:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2558
        if type is None:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2559
            type = ca.type
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2560
        elif ca.type is not None:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2561
            raise ValueError(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2562
                "Type annotation and type argument cannot both be present"
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2563
            )
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2564
        inst_dict = {
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2565
            k: getattr(ca, k)
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2566
            for k in Attribute.__slots__
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2567
            if k
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2568
            not in (
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2569
                "name",
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2570
                "validator",
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2571
                "default",
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2572
                "type",
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2573
                "inherited",
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2574
            )  # exclude methods and deprecated alias
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2575
        }
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2576
        return cls(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2577
            name=name,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2578
            validator=ca._validator,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2579
            default=ca._default,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2580
            type=type,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2581
            cmp=None,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2582
            inherited=False,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2583
            **inst_dict
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2584
        )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2585
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2586
    # Don't use attr.evolve since fields(Attribute) doesn't work
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2587
    def evolve(self, **changes):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2588
        """
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2589
        Copy *self* and apply *changes*.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2590
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2591
        This works similarly to `attr.evolve` but that function does not work
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2592
        with ``Attribute``.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2593
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2594
        It is mainly meant to be used for `transform-fields`.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2595
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2596
        .. versionadded:: 20.3.0
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2597
        """
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2598
        new = copy.copy(self)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2599
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2600
        new._setattrs(changes.items())
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2601
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2602
        return new
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2603
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2604
    # Don't use _add_pickle since fields(Attribute) doesn't work
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2605
    def __getstate__(self):
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2606
        """
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2607
        Play nice with pickle.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2608
        """
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2609
        return tuple(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2610
            getattr(self, name) if name != "metadata" else dict(self.metadata)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2611
            for name in self.__slots__
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2612
        )
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2613
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2614
    def __setstate__(self, state):
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2615
        """
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2616
        Play nice with pickle.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2617
        """
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2618
        self._setattrs(zip(self.__slots__, state))
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2619
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2620
    def _setattrs(self, name_values_pairs):
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2621
        bound_setattr = _obj_setattr.__get__(self, Attribute)
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2622
        for name, value in name_values_pairs:
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2623
            if name != "metadata":
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2624
                bound_setattr(name, value)
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2625
            else:
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2626
                bound_setattr(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2627
                    name,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2628
                    types.MappingProxyType(dict(value))
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2629
                    if value
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2630
                    else _empty_metadata_singleton,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2631
                )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2632
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2633
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2634
_a = [
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2635
    Attribute(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2636
        name=name,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2637
        default=NOTHING,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2638
        validator=None,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2639
        repr=True,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2640
        cmp=None,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2641
        eq=True,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2642
        order=False,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2643
        hash=(name != "metadata"),
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2644
        init=True,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2645
        inherited=False,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2646
    )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2647
    for name in Attribute.__slots__
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2648
]
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2649
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2650
Attribute = _add_hash(
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2651
    _add_eq(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2652
        _add_repr(Attribute, attrs=_a),
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2653
        attrs=[a for a in _a if a.name != "inherited"],
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2654
    ),
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2655
    attrs=[a for a in _a if a.hash and a.name != "inherited"],
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2656
)
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2657
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2658
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2659
class _CountingAttr:
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2660
    """
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2661
    Intermediate representation of attributes that uses a counter to preserve
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2662
    the order in which the attributes have been defined.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2663
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2664
    *Internal* data structure of the attrs library.  Running into is most
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2665
    likely the result of a bug like a forgotten `@attr.s` decorator.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2666
    """
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2667
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2668
    __slots__ = (
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2669
        "counter",
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2670
        "_default",
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2671
        "repr",
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2672
        "eq",
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2673
        "eq_key",
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2674
        "order",
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2675
        "order_key",
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2676
        "hash",
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2677
        "init",
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2678
        "metadata",
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2679
        "_validator",
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2680
        "converter",
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2681
        "type",
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2682
        "kw_only",
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2683
        "on_setattr",
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2684
    )
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2685
    __attrs_attrs__ = tuple(
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2686
        Attribute(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2687
            name=name,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2688
            default=NOTHING,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2689
            validator=None,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2690
            repr=True,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2691
            cmp=None,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2692
            hash=True,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2693
            init=True,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2694
            kw_only=False,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2695
            eq=True,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2696
            eq_key=None,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2697
            order=False,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2698
            order_key=None,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2699
            inherited=False,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2700
            on_setattr=None,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2701
        )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2702
        for name in (
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2703
            "counter",
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2704
            "_default",
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2705
            "repr",
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2706
            "eq",
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2707
            "order",
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2708
            "hash",
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2709
            "init",
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2710
            "on_setattr",
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2711
        )
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2712
    ) + (
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2713
        Attribute(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2714
            name="metadata",
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2715
            default=None,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2716
            validator=None,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2717
            repr=True,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2718
            cmp=None,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2719
            hash=False,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2720
            init=True,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2721
            kw_only=False,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2722
            eq=True,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2723
            eq_key=None,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2724
            order=False,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2725
            order_key=None,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2726
            inherited=False,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2727
            on_setattr=None,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2728
        ),
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2729
    )
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2730
    cls_counter = 0
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2731
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2732
    def __init__(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2733
        self,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2734
        default,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2735
        validator,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2736
        repr,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2737
        cmp,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2738
        hash,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2739
        init,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2740
        converter,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2741
        metadata,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2742
        type,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2743
        kw_only,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2744
        eq,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2745
        eq_key,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2746
        order,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2747
        order_key,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2748
        on_setattr,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2749
    ):
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2750
        _CountingAttr.cls_counter += 1
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2751
        self.counter = _CountingAttr.cls_counter
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2752
        self._default = default
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2753
        self._validator = validator
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2754
        self.converter = converter
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2755
        self.repr = repr
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2756
        self.eq = eq
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2757
        self.eq_key = eq_key
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2758
        self.order = order
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2759
        self.order_key = order_key
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2760
        self.hash = hash
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2761
        self.init = init
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2762
        self.metadata = metadata
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2763
        self.type = type
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2764
        self.kw_only = kw_only
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2765
        self.on_setattr = on_setattr
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2766
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2767
    def validator(self, meth):
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2768
        """
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2769
        Decorator that adds *meth* to the list of validators.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2770
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2771
        Returns *meth* unchanged.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2772
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2773
        .. versionadded:: 17.1.0
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2774
        """
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2775
        if self._validator is None:
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2776
            self._validator = meth
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2777
        else:
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2778
            self._validator = and_(self._validator, meth)
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2779
        return meth
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2780
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2781
    def default(self, meth):
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2782
        """
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2783
        Decorator that allows to set the default for an attribute.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2784
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2785
        Returns *meth* unchanged.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2786
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2787
        :raises DefaultAlreadySetError: If default has been set before.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2788
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2789
        .. versionadded:: 17.1.0
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2790
        """
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2791
        if self._default is not NOTHING:
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2792
            raise DefaultAlreadySetError()
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2793
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2794
        self._default = Factory(meth, takes_self=True)
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2795
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2796
        return meth
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2797
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2798
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2799
_CountingAttr = _add_eq(_add_repr(_CountingAttr))
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2800
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2801
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2802
class Factory:
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2803
    """
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2804
    Stores a factory callable.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2805
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2806
    If passed as the default value to `attrs.field`, the factory is used to
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2807
    generate a new value.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2808
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2809
    :param callable factory: A callable that takes either none or exactly one
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2810
        mandatory positional argument depending on *takes_self*.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2811
    :param bool takes_self: Pass the partially initialized instance that is
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2812
        being initialized as a positional argument.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2813
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2814
    .. versionadded:: 17.1.0  *takes_self*
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2815
    """
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2816
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2817
    __slots__ = ("factory", "takes_self")
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2818
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2819
    def __init__(self, factory, takes_self=False):
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2820
        """
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2821
        `Factory` is part of the default machinery so if we want a default
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2822
        value here, we have to implement it ourselves.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2823
        """
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2824
        self.factory = factory
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2825
        self.takes_self = takes_self
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2826
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2827
    def __getstate__(self):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2828
        """
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2829
        Play nice with pickle.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2830
        """
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2831
        return tuple(getattr(self, name) for name in self.__slots__)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2832
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2833
    def __setstate__(self, state):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2834
        """
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2835
        Play nice with pickle.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2836
        """
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2837
        for name, value in zip(self.__slots__, state):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2838
            setattr(self, name, value)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2839
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2840
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2841
_f = [
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2842
    Attribute(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2843
        name=name,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2844
        default=NOTHING,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2845
        validator=None,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2846
        repr=True,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2847
        cmp=None,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2848
        eq=True,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2849
        order=False,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2850
        hash=True,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2851
        init=True,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2852
        inherited=False,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2853
    )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2854
    for name in Factory.__slots__
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2855
]
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2856
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2857
Factory = _add_hash(_add_eq(_add_repr(Factory, attrs=_f), attrs=_f), attrs=_f)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2858
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2859
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2860
def make_class(name, attrs, bases=(object,), **attributes_arguments):
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2861
    """
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2862
    A quick way to create a new class called *name* with *attrs*.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2863
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2864
    :param str name: The name for the new class.
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2865
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2866
    :param attrs: A list of names or a dictionary of mappings of names to
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2867
        attributes.
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2868
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2869
        If *attrs* is a list or an ordered dict (`dict` on Python 3.6+,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2870
        `collections.OrderedDict` otherwise), the order is deduced from
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2871
        the order of the names or attributes inside *attrs*.  Otherwise the
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2872
        order of the definition of the attributes is used.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2873
    :type attrs: `list` or `dict`
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2874
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2875
    :param tuple bases: Classes that the new class will subclass.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2876
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2877
    :param attributes_arguments: Passed unmodified to `attr.s`.
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2878
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2879
    :return: A new class with *attrs*.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2880
    :rtype: type
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2881
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2882
    .. versionadded:: 17.1.0 *bases*
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2883
    .. versionchanged:: 18.1.0 If *attrs* is ordered, the order is retained.
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2884
    """
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2885
    if isinstance(attrs, dict):
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2886
        cls_dict = attrs
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2887
    elif isinstance(attrs, (list, tuple)):
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2888
        cls_dict = {a: attrib() for a in attrs}
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2889
    else:
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2890
        raise TypeError("attrs argument must be a dict or a list.")
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2891
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2892
    pre_init = cls_dict.pop("__attrs_pre_init__", None)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2893
    post_init = cls_dict.pop("__attrs_post_init__", None)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2894
    user_init = cls_dict.pop("__init__", None)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2895
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2896
    body = {}
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2897
    if pre_init is not None:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2898
        body["__attrs_pre_init__"] = pre_init
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2899
    if post_init is not None:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2900
        body["__attrs_post_init__"] = post_init
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2901
    if user_init is not None:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2902
        body["__init__"] = user_init
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2903
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2904
    type_ = types.new_class(name, bases, {}, lambda ns: ns.update(body))
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2905
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2906
    # For pickling to work, the __module__ variable needs to be set to the
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2907
    # frame where the class is created.  Bypass this step in environments where
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2908
    # sys._getframe is not defined (Jython for example) or sys._getframe is not
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2909
    # defined for arguments greater than 0 (IronPython).
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2910
    try:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2911
        type_.__module__ = sys._getframe(1).f_globals.get(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2912
            "__name__", "__main__"
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2913
        )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2914
    except (AttributeError, ValueError):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2915
        pass
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2916
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2917
    # We do it here for proper warnings with meaningful stacklevel.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2918
    cmp = attributes_arguments.pop("cmp", None)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2919
    (
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2920
        attributes_arguments["eq"],
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2921
        attributes_arguments["order"],
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2922
    ) = _determine_attrs_eq_order(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2923
        cmp,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2924
        attributes_arguments.get("eq"),
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2925
        attributes_arguments.get("order"),
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2926
        True,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2927
    )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2928
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2929
    return _attrs(these=cls_dict, **attributes_arguments)(type_)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2930
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2931
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2932
# These are required by within this module so we define them here and merely
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2933
# import into .validators / .converters.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2934
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2935
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2936
@attrs(slots=True, hash=True)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2937
class _AndValidator:
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2938
    """
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2939
    Compose many validators to a single one.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2940
    """
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2941
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2942
    _validators = attrib()
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2943
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2944
    def __call__(self, inst, attr, value):
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2945
        for v in self._validators:
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2946
            v(inst, attr, value)
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2947
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2948
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2949
def and_(*validators):
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2950
    """
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2951
    A validator that composes multiple validators into one.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2952
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2953
    When called on a value, it runs all wrapped validators.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2954
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2955
    :param callables validators: Arbitrary number of validators.
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2956
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2957
    .. versionadded:: 17.1.0
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2958
    """
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2959
    vals = []
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2960
    for validator in validators:
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2961
        vals.extend(
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2962
            validator._validators
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2963
            if isinstance(validator, _AndValidator)
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2964
            else [validator]
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2965
        )
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2966
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
  2967
    return _AndValidator(tuple(vals))
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2968
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2969
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2970
def pipe(*converters):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2971
    """
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2972
    A converter that composes multiple converters into one.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2973
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2974
    When called on a value, it runs all wrapped converters, returning the
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2975
    *last* value.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2976
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2977
    Type annotations will be inferred from the wrapped converters', if
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2978
    they have any.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2979
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2980
    :param callables converters: Arbitrary number of converters.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2981
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2982
    .. versionadded:: 20.1.0
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2983
    """
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2984
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2985
    def pipe_converter(val):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2986
        for converter in converters:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2987
            val = converter(val)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2988
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2989
        return val
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2990
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2991
    if not converters:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2992
        # If the converter list is empty, pipe_converter is the identity.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2993
        A = typing.TypeVar("A")
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2994
        pipe_converter.__annotations__ = {"val": A, "return": A}
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2995
    else:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2996
        # Get parameter type from first converter.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2997
        t = _AnnotationExtractor(converters[0]).get_first_param_type()
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2998
        if t:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  2999
            pipe_converter.__annotations__["val"] = t
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  3000
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  3001
        # Get return type from last converter.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  3002
        rt = _AnnotationExtractor(converters[-1]).get_return_type()
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  3003
        if rt:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  3004
            pipe_converter.__annotations__["return"] = rt
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  3005
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 41833
diff changeset
  3006
    return pipe_converter