mercurial/thirdparty/attr/_funcs.py
author Manuel Jacob <me@manueljacob.de>
Thu, 15 Sep 2022 01:48:38 +0200
changeset 49494 c96ed4029fda
parent 34397 765eb17a7eb8
child 49643 e1c586b9a43c
permissions -rw-r--r--
templates: add filter to reverse list The filter supports only lists because for lists, it’s straightforward to implement. Reversing text doesn’t seem very useful and is hard to implement. Reversing the bytes would break multi-bytes encodings. Reversing the code points would break characters consisting of multiple code points. Reversing graphemes is non-trivial without using a library not included in the standard library.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
34397
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
     1
from __future__ import absolute_import, division, print_function
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
     2
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
     3
import copy
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
     4
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
     5
from ._compat import iteritems
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
     6
from ._make import NOTHING, fields, _obj_setattr
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
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    10
def asdict(inst, recurse=True, filter=None, dict_factory=dict,
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    11
           retain_collection_types=False):
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    12
    """
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    13
    Return the ``attrs`` attribute values of *inst* as a dict.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    14
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    15
    Optionally recurse into other ``attrs``-decorated classes.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    16
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    17
    :param inst: Instance of an ``attrs``-decorated class.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    18
    :param bool recurse: Recurse into classes that are also
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    19
        ``attrs``-decorated.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    20
    :param callable filter: A callable whose return code deteremines whether an
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    21
        attribute or element is included (``True``) or dropped (``False``).  Is
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    22
        called with the :class:`attr.Attribute` as the first argument and the
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    23
        value as the second argument.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    24
    :param callable dict_factory: A callable to produce dictionaries from.  For
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    25
        example, to produce ordered dictionaries instead of normal Python
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    26
        dictionaries, pass in ``collections.OrderedDict``.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    27
    :param bool retain_collection_types: Do not convert to ``list`` when
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    28
        encountering an attribute whose type is ``tuple`` or ``set``.  Only
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    29
        meaningful if ``recurse`` is ``True``.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    30
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    31
    :rtype: return type of *dict_factory*
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    32
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    33
    :raise attr.exceptions.NotAnAttrsClassError: If *cls* is not an ``attrs``
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    34
        class.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    35
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    36
    ..  versionadded:: 16.0.0 *dict_factory*
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    37
    ..  versionadded:: 16.1.0 *retain_collection_types*
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    38
    """
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    39
    attrs = fields(inst.__class__)
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    40
    rv = dict_factory()
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    41
    for a in attrs:
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    42
        v = getattr(inst, a.name)
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    43
        if filter is not None and not filter(a, v):
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    44
            continue
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    45
        if recurse is True:
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    46
            if has(v.__class__):
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    47
                rv[a.name] = asdict(v, recurse=True, filter=filter,
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    48
                                    dict_factory=dict_factory)
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    49
            elif isinstance(v, (tuple, list, set)):
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    50
                cf = v.__class__ if retain_collection_types is True else list
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    51
                rv[a.name] = cf([
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    52
                    asdict(i, recurse=True, filter=filter,
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    53
                           dict_factory=dict_factory)
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    54
                    if has(i.__class__) else i
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    55
                    for i in v
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    56
                ])
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    57
            elif isinstance(v, dict):
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    58
                df = dict_factory
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    59
                rv[a.name] = df((
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    60
                    asdict(kk, dict_factory=df) if has(kk.__class__) else kk,
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    61
                    asdict(vv, dict_factory=df) if has(vv.__class__) else vv)
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    62
                    for kk, vv in iteritems(v))
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    63
            else:
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    64
                rv[a.name] = v
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    65
        else:
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    66
            rv[a.name] = v
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    67
    return rv
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    68
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    69
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    70
def astuple(inst, recurse=True, filter=None, tuple_factory=tuple,
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    71
            retain_collection_types=False):
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    72
    """
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    73
    Return the ``attrs`` attribute values of *inst* as a tuple.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    74
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    75
    Optionally recurse into other ``attrs``-decorated classes.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    76
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    77
    :param inst: Instance of an ``attrs``-decorated class.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    78
    :param bool recurse: Recurse into classes that are also
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    79
        ``attrs``-decorated.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    80
    :param callable filter: A callable whose return code determines whether an
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    81
        attribute or element is included (``True``) or dropped (``False``).  Is
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    82
        called with the :class:`attr.Attribute` as the first argument and the
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    83
        value as the second argument.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    84
    :param callable tuple_factory: A callable to produce tuples from.  For
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    85
        example, to produce lists instead of tuples.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    86
    :param bool retain_collection_types: Do not convert to ``list``
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    87
        or ``dict`` when encountering an attribute which type is
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    88
        ``tuple``, ``dict`` or ``set``.  Only meaningful if ``recurse`` is
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    89
        ``True``.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    90
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    91
    :rtype: return type of *tuple_factory*
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    92
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    93
    :raise attr.exceptions.NotAnAttrsClassError: If *cls* is not an ``attrs``
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    94
        class.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    95
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    96
    ..  versionadded:: 16.2.0
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    97
    """
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    98
    attrs = fields(inst.__class__)
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    99
    rv = []
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   100
    retain = retain_collection_types  # Very long. :/
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   101
    for a in attrs:
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   102
        v = getattr(inst, a.name)
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   103
        if filter is not None and not filter(a, v):
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   104
            continue
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   105
        if recurse is True:
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   106
            if has(v.__class__):
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   107
                rv.append(astuple(v, recurse=True, filter=filter,
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   108
                                  tuple_factory=tuple_factory,
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   109
                                  retain_collection_types=retain))
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   110
            elif isinstance(v, (tuple, list, set)):
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   111
                cf = v.__class__ if retain is True else list
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   112
                rv.append(cf([
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   113
                    astuple(j, recurse=True, filter=filter,
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   114
                            tuple_factory=tuple_factory,
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   115
                            retain_collection_types=retain)
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   116
                    if has(j.__class__) else j
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   117
                    for j in v
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   118
                ]))
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   119
            elif isinstance(v, dict):
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   120
                df = v.__class__ if retain is True else dict
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   121
                rv.append(df(
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   122
                        (
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   123
                            astuple(
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   124
                                kk,
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   125
                                tuple_factory=tuple_factory,
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   126
                                retain_collection_types=retain
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   127
                            ) if has(kk.__class__) else kk,
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   128
                            astuple(
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   129
                                vv,
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   130
                                tuple_factory=tuple_factory,
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   131
                                retain_collection_types=retain
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   132
                            ) if has(vv.__class__) else vv
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   133
                        )
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   134
                        for kk, vv in iteritems(v)))
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   135
            else:
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   136
                rv.append(v)
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   137
        else:
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   138
            rv.append(v)
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   139
    return rv if tuple_factory is list else tuple_factory(rv)
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   140
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   141
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   142
def has(cls):
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   143
    """
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   144
    Check whether *cls* is a class with ``attrs`` attributes.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   145
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   146
    :param type cls: Class to introspect.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   147
    :raise TypeError: If *cls* is not a class.
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
    :rtype: :class:`bool`
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   150
    """
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   151
    return getattr(cls, "__attrs_attrs__", None) is not None
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   152
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   153
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   154
def assoc(inst, **changes):
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   155
    """
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   156
    Copy *inst* and apply *changes*.
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
    :param inst: Instance of a class with ``attrs`` attributes.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   159
    :param changes: Keyword changes in the new copy.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   160
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   161
    :return: A copy of inst with *changes* incorporated.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   162
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   163
    :raise attr.exceptions.AttrsAttributeNotFoundError: If *attr_name* couldn't
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   164
        be found on *cls*.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   165
    :raise attr.exceptions.NotAnAttrsClassError: If *cls* is not an ``attrs``
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   166
        class.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   167
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   168
    ..  deprecated:: 17.1.0
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   169
        Use :func:`evolve` instead.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   170
    """
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   171
    import warnings
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   172
    warnings.warn("assoc is deprecated and will be removed after 2018/01.",
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   173
                  DeprecationWarning)
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   174
    new = copy.copy(inst)
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   175
    attrs = fields(inst.__class__)
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   176
    for k, v in iteritems(changes):
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   177
        a = getattr(attrs, k, NOTHING)
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   178
        if a is NOTHING:
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   179
            raise AttrsAttributeNotFoundError(
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   180
                "{k} is not an attrs attribute on {cl}."
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   181
                .format(k=k, cl=new.__class__)
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   182
            )
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   183
        _obj_setattr(new, k, v)
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   184
    return new
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   185
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   186
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   187
def evolve(inst, **changes):
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   188
    """
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   189
    Create a new instance, based on *inst* with *changes* applied.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   190
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   191
    :param inst: Instance of a class with ``attrs`` attributes.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   192
    :param changes: Keyword changes in the new copy.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   193
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   194
    :return: A copy of inst with *changes* incorporated.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   195
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   196
    :raise TypeError: If *attr_name* couldn't be found in the class
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   197
        ``__init__``.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   198
    :raise attr.exceptions.NotAnAttrsClassError: If *cls* is not an ``attrs``
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   199
        class.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   200
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   201
    ..  versionadded:: 17.1.0
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   202
    """
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   203
    cls = inst.__class__
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   204
    attrs = fields(cls)
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   205
    for a in attrs:
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   206
        if not a.init:
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   207
            continue
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   208
        attr_name = a.name  # To deal with private attributes.
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   209
        init_name = attr_name if attr_name[0] != "_" else attr_name[1:]
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   210
        if init_name not in changes:
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   211
            changes[init_name] = getattr(inst, attr_name)
765eb17a7eb8 thirdparty: vendor attrs
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   212
    return cls(**changes)