mercurial/thirdparty/attr/_funcs.py
author Matt Harbison <matt_harbison@yahoo.com>
Mon, 21 Nov 2022 15:04:42 -0500
changeset 49643 e1c586b9a43c
parent 34397 765eb17a7eb8
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: 34397
diff changeset
     1
# SPDX-License-Identifier: MIT
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
     2
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
     3
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
     4
import copy
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
     5
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
     6
from ._make import NOTHING, _obj_setattr, fields
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
     7
from .exceptions import AttrsAttributeNotFoundError
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
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
    10
def asdict(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
    11
    inst,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
    12
    recurse=True,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
    13
    filter=None,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
    14
    dict_factory=dict,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
    15
    retain_collection_types=False,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
    16
    value_serializer=None,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
    17
):
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    18
    """
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    19
    Return the ``attrs`` attribute values of *inst* as a dict.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    20
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    21
    Optionally recurse into other ``attrs``-decorated classes.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    22
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    23
    :param inst: Instance of an ``attrs``-decorated class.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    24
    :param bool recurse: Recurse into classes that are also
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    25
        ``attrs``-decorated.
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
    26
    :param callable filter: A callable whose return code determines whether an
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    27
        attribute or element is included (``True``) or dropped (``False``).  Is
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
    28
        called with the `attrs.Attribute` as the first argument and the
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    29
        value as the second argument.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    30
    :param callable dict_factory: A callable to produce dictionaries from.  For
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    31
        example, to produce ordered dictionaries instead of normal Python
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    32
        dictionaries, pass in ``collections.OrderedDict``.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    33
    :param bool retain_collection_types: Do not convert to ``list`` when
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    34
        encountering an attribute whose type is ``tuple`` or ``set``.  Only
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    35
        meaningful if ``recurse`` is ``True``.
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
    36
    :param Optional[callable] value_serializer: A hook that is called for every
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
    37
        attribute or dict key/value.  It receives the current instance, field
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
    38
        and value and must return the (updated) value.  The hook is run *after*
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
    39
        the optional *filter* has been applied.
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    40
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    41
    :rtype: return type of *dict_factory*
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    42
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    43
    :raise attr.exceptions.NotAnAttrsClassError: If *cls* is not an ``attrs``
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    44
        class.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    45
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    46
    ..  versionadded:: 16.0.0 *dict_factory*
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    47
    ..  versionadded:: 16.1.0 *retain_collection_types*
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
    48
    ..  versionadded:: 20.3.0 *value_serializer*
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
    49
    ..  versionadded:: 21.3.0 If a dict has a collection for a key, it is
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
    50
        serialized as a tuple.
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    51
    """
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    52
    attrs = fields(inst.__class__)
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    53
    rv = dict_factory()
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    54
    for a in attrs:
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    55
        v = getattr(inst, a.name)
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    56
        if filter is not None and not filter(a, v):
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    57
            continue
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
    58
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
    59
        if value_serializer is not None:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
    60
            v = value_serializer(inst, a, v)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
    61
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    62
        if recurse is True:
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    63
            if has(v.__class__):
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
    64
                rv[a.name] = asdict(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
    65
                    v,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
    66
                    recurse=True,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
    67
                    filter=filter,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
    68
                    dict_factory=dict_factory,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
    69
                    retain_collection_types=retain_collection_types,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
    70
                    value_serializer=value_serializer,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
    71
                )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
    72
            elif isinstance(v, (tuple, list, set, frozenset)):
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    73
                cf = v.__class__ if retain_collection_types is True else list
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
    74
                rv[a.name] = cf(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
    75
                    [
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
    76
                        _asdict_anything(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
    77
                            i,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
    78
                            is_key=False,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
    79
                            filter=filter,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
    80
                            dict_factory=dict_factory,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
    81
                            retain_collection_types=retain_collection_types,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
    82
                            value_serializer=value_serializer,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
    83
                        )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
    84
                        for i in v
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
    85
                    ]
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
    86
                )
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    87
            elif isinstance(v, dict):
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    88
                df = dict_factory
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
    89
                rv[a.name] = df(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
    90
                    (
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
    91
                        _asdict_anything(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
    92
                            kk,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
    93
                            is_key=True,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
    94
                            filter=filter,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
    95
                            dict_factory=df,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
    96
                            retain_collection_types=retain_collection_types,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
    97
                            value_serializer=value_serializer,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
    98
                        ),
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
    99
                        _asdict_anything(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   100
                            vv,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   101
                            is_key=False,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   102
                            filter=filter,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   103
                            dict_factory=df,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   104
                            retain_collection_types=retain_collection_types,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   105
                            value_serializer=value_serializer,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   106
                        ),
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   107
                    )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   108
                    for kk, vv in v.items()
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   109
                )
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   110
            else:
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   111
                rv[a.name] = v
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   112
        else:
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   113
            rv[a.name] = v
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   114
    return rv
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   115
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   116
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   117
def _asdict_anything(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   118
    val,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   119
    is_key,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   120
    filter,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   121
    dict_factory,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   122
    retain_collection_types,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   123
    value_serializer,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   124
):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   125
    """
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   126
    ``asdict`` only works on attrs instances, this works on anything.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   127
    """
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   128
    if getattr(val.__class__, "__attrs_attrs__", None) is not None:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   129
        # Attrs class.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   130
        rv = asdict(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   131
            val,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   132
            recurse=True,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   133
            filter=filter,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   134
            dict_factory=dict_factory,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   135
            retain_collection_types=retain_collection_types,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   136
            value_serializer=value_serializer,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   137
        )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   138
    elif isinstance(val, (tuple, list, set, frozenset)):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   139
        if retain_collection_types is True:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   140
            cf = val.__class__
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   141
        elif is_key:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   142
            cf = tuple
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   143
        else:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   144
            cf = list
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   145
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   146
        rv = cf(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   147
            [
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   148
                _asdict_anything(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   149
                    i,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   150
                    is_key=False,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   151
                    filter=filter,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   152
                    dict_factory=dict_factory,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   153
                    retain_collection_types=retain_collection_types,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   154
                    value_serializer=value_serializer,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   155
                )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   156
                for i in val
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   157
            ]
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   158
        )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   159
    elif isinstance(val, dict):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   160
        df = dict_factory
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   161
        rv = df(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   162
            (
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   163
                _asdict_anything(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   164
                    kk,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   165
                    is_key=True,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   166
                    filter=filter,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   167
                    dict_factory=df,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   168
                    retain_collection_types=retain_collection_types,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   169
                    value_serializer=value_serializer,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   170
                ),
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   171
                _asdict_anything(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   172
                    vv,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   173
                    is_key=False,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   174
                    filter=filter,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   175
                    dict_factory=df,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   176
                    retain_collection_types=retain_collection_types,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   177
                    value_serializer=value_serializer,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   178
                ),
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   179
            )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   180
            for kk, vv in val.items()
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   181
        )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   182
    else:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   183
        rv = val
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   184
        if value_serializer is not None:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   185
            rv = value_serializer(None, None, rv)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   186
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   187
    return rv
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   188
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   189
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   190
def astuple(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   191
    inst,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   192
    recurse=True,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   193
    filter=None,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   194
    tuple_factory=tuple,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   195
    retain_collection_types=False,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   196
):
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   197
    """
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   198
    Return the ``attrs`` attribute values of *inst* as a tuple.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   199
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   200
    Optionally recurse into other ``attrs``-decorated classes.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   201
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   202
    :param inst: Instance of an ``attrs``-decorated class.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   203
    :param bool recurse: Recurse into classes that are also
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   204
        ``attrs``-decorated.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   205
    :param callable filter: A callable whose return code determines whether an
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   206
        attribute or element is included (``True``) or dropped (``False``).  Is
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   207
        called with the `attrs.Attribute` as the first argument and the
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   208
        value as the second argument.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   209
    :param callable tuple_factory: A callable to produce tuples from.  For
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   210
        example, to produce lists instead of tuples.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   211
    :param bool retain_collection_types: Do not convert to ``list``
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   212
        or ``dict`` when encountering an attribute which type is
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   213
        ``tuple``, ``dict`` or ``set``.  Only meaningful if ``recurse`` is
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   214
        ``True``.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   215
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   216
    :rtype: return type of *tuple_factory*
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   217
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   218
    :raise attr.exceptions.NotAnAttrsClassError: If *cls* is not an ``attrs``
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   219
        class.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   220
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   221
    ..  versionadded:: 16.2.0
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   222
    """
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   223
    attrs = fields(inst.__class__)
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   224
    rv = []
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   225
    retain = retain_collection_types  # Very long. :/
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   226
    for a in attrs:
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   227
        v = getattr(inst, a.name)
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   228
        if filter is not None and not filter(a, v):
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   229
            continue
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   230
        if recurse is True:
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   231
            if has(v.__class__):
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   232
                rv.append(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   233
                    astuple(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   234
                        v,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   235
                        recurse=True,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   236
                        filter=filter,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   237
                        tuple_factory=tuple_factory,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   238
                        retain_collection_types=retain,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   239
                    )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   240
                )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   241
            elif isinstance(v, (tuple, list, set, frozenset)):
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   242
                cf = v.__class__ if retain is True else list
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   243
                rv.append(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   244
                    cf(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   245
                        [
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   246
                            astuple(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   247
                                j,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   248
                                recurse=True,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   249
                                filter=filter,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   250
                                tuple_factory=tuple_factory,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   251
                                retain_collection_types=retain,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   252
                            )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   253
                            if has(j.__class__)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   254
                            else j
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   255
                            for j in v
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   256
                        ]
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   257
                    )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   258
                )
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   259
            elif isinstance(v, dict):
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   260
                df = v.__class__ if retain is True else dict
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   261
                rv.append(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   262
                    df(
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   263
                        (
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   264
                            astuple(
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   265
                                kk,
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   266
                                tuple_factory=tuple_factory,
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   267
                                retain_collection_types=retain,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   268
                            )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   269
                            if has(kk.__class__)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   270
                            else kk,
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   271
                            astuple(
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   272
                                vv,
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   273
                                tuple_factory=tuple_factory,
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   274
                                retain_collection_types=retain,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   275
                            )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   276
                            if has(vv.__class__)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   277
                            else vv,
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   278
                        )
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   279
                        for kk, vv in v.items()
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   280
                    )
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   281
                )
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   282
            else:
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   283
                rv.append(v)
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   284
        else:
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   285
            rv.append(v)
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   286
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   287
    return rv if tuple_factory is list else tuple_factory(rv)
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   288
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   289
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   290
def has(cls):
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   291
    """
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   292
    Check whether *cls* is a class with ``attrs`` attributes.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   293
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   294
    :param type cls: Class to introspect.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   295
    :raise TypeError: If *cls* is not a class.
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: 34397
diff changeset
   297
    :rtype: bool
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   298
    """
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   299
    return getattr(cls, "__attrs_attrs__", None) is not None
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   300
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   301
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   302
def assoc(inst, **changes):
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   303
    """
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   304
    Copy *inst* and apply *changes*.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   305
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   306
    :param inst: Instance of a class with ``attrs`` attributes.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   307
    :param changes: Keyword changes in the new copy.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   308
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   309
    :return: A copy of inst with *changes* incorporated.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   310
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   311
    :raise attr.exceptions.AttrsAttributeNotFoundError: If *attr_name* couldn't
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   312
        be found on *cls*.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   313
    :raise attr.exceptions.NotAnAttrsClassError: If *cls* is not an ``attrs``
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   314
        class.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   315
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   316
    ..  deprecated:: 17.1.0
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   317
        Use `attrs.evolve` instead if you can.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   318
        This function will not be removed du to the slightly different approach
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   319
        compared to `attrs.evolve`.
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   320
    """
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   321
    import warnings
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   322
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   323
    warnings.warn(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   324
        "assoc is deprecated and will be removed after 2018/01.",
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   325
        DeprecationWarning,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   326
        stacklevel=2,
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   327
    )
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   328
    new = copy.copy(inst)
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   329
    attrs = fields(inst.__class__)
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   330
    for k, v in changes.items():
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   331
        a = getattr(attrs, k, NOTHING)
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   332
        if a is NOTHING:
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   333
            raise AttrsAttributeNotFoundError(
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   334
                "{k} is not an attrs attribute on {cl}.".format(
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   335
                    k=k, cl=new.__class__
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   336
                )
34397
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
        _obj_setattr(new, k, v)
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   339
    return new
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   340
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   341
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   342
def evolve(inst, **changes):
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
    Create a new instance, based on *inst* with *changes* applied.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   345
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   346
    :param inst: Instance of a class with ``attrs`` attributes.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   347
    :param changes: Keyword changes in the new copy.
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
    :return: A copy of inst with *changes* incorporated.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   350
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   351
    :raise TypeError: If *attr_name* couldn't be found in the class
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   352
        ``__init__``.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   353
    :raise attr.exceptions.NotAnAttrsClassError: If *cls* is not an ``attrs``
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   354
        class.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   355
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   356
    ..  versionadded:: 17.1.0
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   357
    """
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   358
    cls = inst.__class__
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   359
    attrs = fields(cls)
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   360
    for a in attrs:
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   361
        if not a.init:
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   362
            continue
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   363
        attr_name = a.name  # To deal with private attributes.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   364
        init_name = attr_name if attr_name[0] != "_" else attr_name[1:]
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   365
        if init_name not in changes:
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   366
            changes[init_name] = getattr(inst, attr_name)
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   367
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   368
    return cls(**changes)
49643
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   369
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   370
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   371
def resolve_types(cls, globalns=None, localns=None, attribs=None):
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   372
    """
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   373
    Resolve any strings and forward annotations in type annotations.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   374
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   375
    This is only required if you need concrete types in `Attribute`'s *type*
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   376
    field. In other words, you don't need to resolve your types if you only
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   377
    use them for static type checking.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   378
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   379
    With no arguments, names will be looked up in the module in which the class
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   380
    was created. If this is not what you want, e.g. if the name only exists
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   381
    inside a method, you may pass *globalns* or *localns* to specify other
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   382
    dictionaries in which to look up these names. See the docs of
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   383
    `typing.get_type_hints` for more details.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   384
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   385
    :param type cls: Class to resolve.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   386
    :param Optional[dict] globalns: Dictionary containing global variables.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   387
    :param Optional[dict] localns: Dictionary containing local variables.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   388
    :param Optional[list] attribs: List of attribs for the given class.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   389
        This is necessary when calling from inside a ``field_transformer``
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   390
        since *cls* is not an ``attrs`` class yet.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   391
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   392
    :raise TypeError: If *cls* is not a class.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   393
    :raise attr.exceptions.NotAnAttrsClassError: If *cls* is not an ``attrs``
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   394
        class and you didn't pass any attribs.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   395
    :raise NameError: If types cannot be resolved because of missing variables.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   396
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   397
    :returns: *cls* so you can use this function also as a class decorator.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   398
        Please note that you have to apply it **after** `attrs.define`. That
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   399
        means the decorator has to come in the line **before** `attrs.define`.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   400
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   401
    ..  versionadded:: 20.1.0
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   402
    ..  versionadded:: 21.1.0 *attribs*
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   403
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   404
    """
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   405
    # Since calling get_type_hints is expensive we cache whether we've
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   406
    # done it already.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   407
    if getattr(cls, "__attrs_types_resolved__", None) != cls:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   408
        import typing
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   409
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   410
        hints = typing.get_type_hints(cls, globalns=globalns, localns=localns)
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   411
        for field in fields(cls) if attribs is None else attribs:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   412
            if field.name in hints:
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   413
                # Since fields have been frozen we must work around it.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   414
                _obj_setattr(field, "type", hints[field.name])
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   415
        # We store the class we resolved so that subclasses know they haven't
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   416
        # been resolved.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   417
        cls.__attrs_types_resolved__ = cls
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   418
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   419
    # Return the class so you can use it as a decorator too.
e1c586b9a43c attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents: 34397
diff changeset
   420
    return cls