1from __future__ import absolute_import, division, print_function
2
3import hashlib
4import linecache
5import sys
6import threading
7import warnings
8
9from operator import itemgetter
10
11from . import _config
12from ._compat import (
13    PY2, isclass, iteritems, metadata_proxy, ordered_dict, set_closure_cell
14)
15from .exceptions import (
16    DefaultAlreadySetError, FrozenInstanceError, NotAnAttrsClassError,
17    UnannotatedAttributeError
18)
19
20
21# This is used at least twice, so cache it here.
22_obj_setattr = object.__setattr__
23_init_converter_pat = "__attr_converter_{}"
24_init_factory_pat = "__attr_factory_{}"
25_tuple_property_pat = "    {attr_name} = property(itemgetter({index}))"
26_classvar_prefixes = ("typing.ClassVar", "t.ClassVar", "ClassVar")
27
28_empty_metadata_singleton = metadata_proxy({})
29
30
31class _Nothing(object):
32    """
33    Sentinel class to indicate the lack of a value when ``None`` is ambiguous.
34
35    All instances of `_Nothing` are equal.
36    """
37    def __copy__(self):
38        return self
39
40    def __deepcopy__(self, _):
41        return self
42
43    def __eq__(self, other):
44        return other.__class__ == _Nothing
45
46    def __ne__(self, other):
47        return not self == other
48
49    def __repr__(self):
50        return "NOTHING"
51
52    def __hash__(self):
53        return 0xc0ffee
54
55
56NOTHING = _Nothing()
57"""
58Sentinel to indicate the lack of a value when ``None`` is ambiguous.
59"""
60
61
62def attrib(default=NOTHING, validator=None,
63           repr=True, cmp=True, hash=None, init=True,
64           convert=None, metadata=None, type=None, converter=None,
65           factory=None):
66    """
67    Create a new attribute on a class.
68
69    ..  warning::
70
71        Does *not* do anything unless the class is also decorated with
72        :func:`attr.s`!
73
74    :param default: A value that is used if an ``attrs``-generated ``__init__``
75        is used and no value is passed while instantiating or the attribute is
76        excluded using ``init=False``.
77
78        If the value is an instance of :class:`Factory`, its callable will be
79        used to construct a new value (useful for mutable data types like lists
80        or dicts).
81
82        If a default is not set (or set manually to ``attr.NOTHING``), a value
83        *must* be supplied when instantiating; otherwise a :exc:`TypeError`
84        will be raised.
85
86        The default can also be set using decorator notation as shown below.
87
88    :type default: Any value.
89
90    :param callable factory: Syntactic sugar for
91        ``default=attr.Factory(callable)``.
92
93    :param validator: :func:`callable` that is called by ``attrs``-generated
94        ``__init__`` methods after the instance has been initialized.  They
95        receive the initialized instance, the :class:`Attribute`, and the
96        passed value.
97
98        The return value is *not* inspected so the validator has to throw an
99        exception itself.
100
101        If a ``list`` is passed, its items are treated as validators and must
102        all pass.
103
104        Validators can be globally disabled and re-enabled using
105        :func:`get_run_validators`.
106
107        The validator can also be set using decorator notation as shown below.
108
109    :type validator: ``callable`` or a ``list`` of ``callable``\\ s.
110
111    :param bool repr: Include this attribute in the generated ``__repr__``
112        method.
113    :param bool cmp: Include this attribute in the generated comparison methods
114        (``__eq__`` et al).
115    :param hash: Include this attribute in the generated ``__hash__``
116        method.  If ``None`` (default), mirror *cmp*'s value.  This is the
117        correct behavior according the Python spec.  Setting this value to
118        anything else than ``None`` is *discouraged*.
119    :type hash: ``bool`` or ``None``
120    :param bool init: Include this attribute in the generated ``__init__``
121        method.  It is possible to set this to ``False`` and set a default
122        value.  In that case this attributed is unconditionally initialized
123        with the specified default value or factory.
124    :param callable converter: :func:`callable` that is called by
125        ``attrs``-generated ``__init__`` methods to converter attribute's value
126        to the desired format.  It is given the passed-in value, and the
127        returned value will be used as the new value of the attribute.  The
128        value is converted before being passed to the validator, if any.
129    :param metadata: An arbitrary mapping, to be used by third-party
130        components.  See :ref:`extending_metadata`.
131    :param type: The type of the attribute.  In Python 3.6 or greater, the
132        preferred method to specify the type is using a variable annotation
133        (see `PEP 526 <https://www.python.org/dev/peps/pep-0526/>`_).
134        This argument is provided for backward compatibility.
135        Regardless of the approach used, the type will be stored on
136        ``Attribute.type``.
137
138    .. versionadded:: 15.2.0 *convert*
139    .. versionadded:: 16.3.0 *metadata*
140    .. versionchanged:: 17.1.0 *validator* can be a ``list`` now.
141    .. versionchanged:: 17.1.0
142       *hash* is ``None`` and therefore mirrors *cmp* by default.
143    .. versionadded:: 17.3.0 *type*
144    .. deprecated:: 17.4.0 *convert*
145    .. versionadded:: 17.4.0 *converter* as a replacement for the deprecated
146       *convert* to achieve consistency with other noun-based arguments.
147    .. versionadded:: 18.1.0
148       ``factory=f`` is syntactic sugar for ``default=attr.Factory(f)``.
149    """
150    if hash is not None and hash is not True and hash is not False:
151        raise TypeError(
152            "Invalid value for hash.  Must be True, False, or None."
153        )
154
155    if convert is not None:
156        if converter is not None:
157            raise RuntimeError(
158                "Can't pass both `convert` and `converter`.  "
159                "Please use `converter` only."
160            )
161        warnings.warn(
162            "The `convert` argument is deprecated in favor of `converter`.  "
163            "It will be removed after 2019/01.",
164            DeprecationWarning, stacklevel=2
165        )
166        converter = convert
167
168    if factory is not None:
169        if default is not NOTHING:
170            raise ValueError(
171                "The `default` and `factory` arguments are mutually "
172                "exclusive."
173            )
174        if not callable(factory):
175            raise ValueError(
176                "The `factory` argument must be a callable."
177            )
178        default = Factory(factory)
179
180    if metadata is None:
181        metadata = {}
182
183    return _CountingAttr(
184        default=default,
185        validator=validator,
186        repr=repr,
187        cmp=cmp,
188        hash=hash,
189        init=init,
190        converter=converter,
191        metadata=metadata,
192        type=type,
193    )
194
195
196def _make_attr_tuple_class(cls_name, attr_names):
197    """
198    Create a tuple subclass to hold `Attribute`s for an `attrs` class.
199
200    The subclass is a bare tuple with properties for names.
201
202    class MyClassAttributes(tuple):
203        __slots__ = ()
204        x = property(itemgetter(0))
205    """
206    attr_class_name = "{}Attributes".format(cls_name)
207    attr_class_template = [
208        "class {}(tuple):".format(attr_class_name),
209        "    __slots__ = ()",
210    ]
211    if attr_names:
212        for i, attr_name in enumerate(attr_names):
213            attr_class_template.append(_tuple_property_pat.format(
214                index=i,
215                attr_name=attr_name,
216            ))
217    else:
218        attr_class_template.append("    pass")
219    globs = {"itemgetter": itemgetter}
220    eval(compile("\n".join(attr_class_template), "", "exec"), globs)
221    return globs[attr_class_name]
222
223
224# Tuple class for extracted attributes from a class definition.
225# `super_attrs` is a subset of `attrs`.
226_Attributes = _make_attr_tuple_class("_Attributes", [
227    "attrs",            # all attributes to build dunder methods for
228    "super_attrs",      # attributes that have been inherited
229    "super_attrs_map",  # map inherited attributes to their originating classes
230])
231
232
233def _is_class_var(annot):
234    """
235    Check whether *annot* is a typing.ClassVar.
236
237    The string comparison hack is used to avoid evaluating all string
238    annotations which would put attrs-based classes at a performance
239    disadvantage compared to plain old classes.
240    """
241    return str(annot).startswith(_classvar_prefixes)
242
243
244def _get_annotations(cls):
245    """
246    Get annotations for *cls*.
247    """
248    anns = getattr(cls, "__annotations__", None)
249    if anns is None:
250        return {}
251
252    # Verify that the annotations aren't merely inherited.
253    for super_cls in cls.__mro__[1:]:
254        if anns is getattr(super_cls, "__annotations__", None):
255            return {}
256
257    return anns
258
259
260def _counter_getter(e):
261    """
262    Key function for sorting to avoid re-creating a lambda for every class.
263    """
264    return e[1].counter
265
266
267def _transform_attrs(cls, these, auto_attribs):
268    """
269    Transform all `_CountingAttr`s on a class into `Attribute`s.
270
271    If *these* is passed, use that and don't look for them on the class.
272
273    Return an `_Attributes`.
274    """
275    cd = cls.__dict__
276    anns = _get_annotations(cls)
277
278    if these is not None:
279        ca_list = [
280            (name, ca)
281            for name, ca
282            in iteritems(these)
283        ]
284
285        if not isinstance(these, ordered_dict):
286            ca_list.sort(key=_counter_getter)
287    elif auto_attribs is True:
288        ca_names = {
289            name
290            for name, attr
291            in cd.items()
292            if isinstance(attr, _CountingAttr)
293        }
294        ca_list = []
295        annot_names = set()
296        for attr_name, type in anns.items():
297            if _is_class_var(type):
298                continue
299            annot_names.add(attr_name)
300            a = cd.get(attr_name, NOTHING)
301            if not isinstance(a, _CountingAttr):
302                if a is NOTHING:
303                    a = attrib()
304                else:
305                    a = attrib(default=a)
306            ca_list.append((attr_name, a))
307
308        unannotated = ca_names - annot_names
309        if len(unannotated) > 0:
310            raise UnannotatedAttributeError(
311                "The following `attr.ib`s lack a type annotation: " +
312                ", ".join(sorted(
313                    unannotated,
314                    key=lambda n: cd.get(n).counter
315                )) + "."
316            )
317    else:
318        ca_list = sorted((
319            (name, attr)
320            for name, attr
321            in cd.items()
322            if isinstance(attr, _CountingAttr)
323        ), key=lambda e: e[1].counter)
324
325    own_attrs = [
326        Attribute.from_counting_attr(
327            name=attr_name,
328            ca=ca,
329            type=anns.get(attr_name),
330        )
331        for attr_name, ca
332        in ca_list
333    ]
334
335    super_attrs = []
336    super_attr_map = {}  # A dictionary of superattrs to their classes.
337    taken_attr_names = {a.name: a for a in own_attrs}
338
339    # Traverse the MRO and collect attributes.
340    for super_cls in cls.__mro__[1:-1]:
341        sub_attrs = getattr(super_cls, "__attrs_attrs__", None)
342        if sub_attrs is not None:
343            for a in sub_attrs:
344                prev_a = taken_attr_names.get(a.name)
345                # Only add an attribute if it hasn't been defined before.  This
346                # allows for overwriting attribute definitions by subclassing.
347                if prev_a is None:
348                    super_attrs.append(a)
349                    taken_attr_names[a.name] = a
350                    super_attr_map[a.name] = super_cls
351
352    attr_names = [a.name for a in super_attrs + own_attrs]
353
354    AttrsClass = _make_attr_tuple_class(cls.__name__, attr_names)
355
356    attrs = AttrsClass(
357        super_attrs + [
358            Attribute.from_counting_attr(
359                name=attr_name,
360                ca=ca,
361                type=anns.get(attr_name)
362            )
363            for attr_name, ca
364            in ca_list
365        ]
366    )
367
368    had_default = False
369    for a in attrs:
370        if had_default is True and a.default is NOTHING and a.init is True:
371            raise ValueError(
372                "No mandatory attributes allowed after an attribute with a "
373                "default value or factory.  Attribute in question: {a!r}"
374                .format(a=a)
375            )
376        elif had_default is False and \
377                a.default is not NOTHING and \
378                a.init is not False:
379            had_default = True
380
381    return _Attributes((attrs, super_attrs, super_attr_map))
382
383
384def _frozen_setattrs(self, name, value):
385    """
386    Attached to frozen classes as __setattr__.
387    """
388    raise FrozenInstanceError()
389
390
391def _frozen_delattrs(self, name):
392    """
393    Attached to frozen classes as __delattr__.
394    """
395    raise FrozenInstanceError()
396
397
398class _ClassBuilder(object):
399    """
400    Iteratively build *one* class.
401    """
402    __slots__ = (
403        "_cls", "_cls_dict", "_attrs", "_super_names", "_attr_names", "_slots",
404        "_frozen", "_has_post_init", "_delete_attribs", "_super_attr_map",
405    )
406
407    def __init__(self, cls, these, slots, frozen, auto_attribs):
408        attrs, super_attrs, super_map = _transform_attrs(
409            cls, these, auto_attribs
410        )
411
412        self._cls = cls
413        self._cls_dict = dict(cls.__dict__) if slots else {}
414        self._attrs = attrs
415        self._super_names = set(a.name for a in super_attrs)
416        self._super_attr_map = super_map
417        self._attr_names = tuple(a.name for a in attrs)
418        self._slots = slots
419        self._frozen = frozen or _has_frozen_superclass(cls)
420        self._has_post_init = bool(getattr(cls, "__attrs_post_init__", False))
421        self._delete_attribs = not bool(these)
422
423        self._cls_dict["__attrs_attrs__"] = self._attrs
424
425        if frozen:
426            self._cls_dict["__setattr__"] = _frozen_setattrs
427            self._cls_dict["__delattr__"] = _frozen_delattrs
428
429    def __repr__(self):
430        return "<_ClassBuilder(cls={cls})>".format(cls=self._cls.__name__)
431
432    def build_class(self):
433        """
434        Finalize class based on the accumulated configuration.
435
436        Builder cannot be used anymore after calling this method.
437        """
438        if self._slots is True:
439            return self._create_slots_class()
440        else:
441            return self._patch_original_class()
442
443    def _patch_original_class(self):
444        """
445        Apply accumulated methods and return the class.
446        """
447        cls = self._cls
448        super_names = self._super_names
449
450        # Clean class of attribute definitions (`attr.ib()`s).
451        if self._delete_attribs:
452            for name in self._attr_names:
453                if name not in super_names and \
454                        getattr(cls, name, None) is not None:
455                    delattr(cls, name)
456
457        # Attach our dunder methods.
458        for name, value in self._cls_dict.items():
459            setattr(cls, name, value)
460
461        return cls
462
463    def _create_slots_class(self):
464        """
465        Build and return a new class with a `__slots__` attribute.
466        """
467        super_names = self._super_names
468        cd = {
469            k: v
470            for k, v in iteritems(self._cls_dict)
471            if k not in tuple(self._attr_names) + ("__dict__",)
472        }
473
474        # We only add the names of attributes that aren't inherited.
475        # Settings __slots__ to inherited attributes wastes memory.
476        cd["__slots__"] = tuple(
477            name
478            for name in self._attr_names
479            if name not in super_names
480        )
481
482        qualname = getattr(self._cls, "__qualname__", None)
483        if qualname is not None:
484            cd["__qualname__"] = qualname
485
486        # __weakref__ is not writable.
487        state_attr_names = tuple(
488            an for an in self._attr_names if an != "__weakref__"
489        )
490
491        def slots_getstate(self):
492            """
493            Automatically created by attrs.
494            """
495            return tuple(
496                getattr(self, name)
497                for name in state_attr_names
498            )
499
500        def slots_setstate(self, state):
501            """
502            Automatically created by attrs.
503            """
504            __bound_setattr = _obj_setattr.__get__(self, Attribute)
505            for name, value in zip(state_attr_names, state):
506                __bound_setattr(name, value)
507
508        # slots and frozen require __getstate__/__setstate__ to work
509        cd["__getstate__"] = slots_getstate
510        cd["__setstate__"] = slots_setstate
511
512        # Create new class based on old class and our methods.
513        cls = type(self._cls)(
514            self._cls.__name__,
515            self._cls.__bases__,
516            cd,
517        )
518
519        # The following is a fix for
520        # https://github.com/python-attrs/attrs/issues/102.  On Python 3,
521        # if a method mentions `__class__` or uses the no-arg super(), the
522        # compiler will bake a reference to the class in the method itself
523        # as `method.__closure__`.  Since we replace the class with a
524        # clone, we rewrite these references so it keeps working.
525        for item in cls.__dict__.values():
526            if isinstance(item, (classmethod, staticmethod)):
527                # Class- and staticmethods hide their functions inside.
528                # These might need to be rewritten as well.
529                closure_cells = getattr(item.__func__, "__closure__", None)
530            else:
531                closure_cells = getattr(item, "__closure__", None)
532
533            if not closure_cells:  # Catch None or the empty list.
534                continue
535            for cell in closure_cells:
536                if cell.cell_contents is self._cls:
537                    set_closure_cell(cell, cls)
538
539        return cls
540
541    def add_repr(self, ns):
542        self._cls_dict["__repr__"] = self._add_method_dunders(
543            _make_repr(self._attrs, ns=ns)
544        )
545        return self
546
547    def add_str(self):
548        repr = self._cls_dict.get("__repr__")
549        if repr is None:
550            raise ValueError(
551                "__str__ can only be generated if a __repr__ exists."
552            )
553
554        def __str__(self):
555            return self.__repr__()
556
557        self._cls_dict["__str__"] = self._add_method_dunders(__str__)
558        return self
559
560    def make_unhashable(self):
561        self._cls_dict["__hash__"] = None
562        return self
563
564    def add_hash(self):
565        self._cls_dict["__hash__"] = self._add_method_dunders(
566            _make_hash(self._attrs)
567        )
568
569        return self
570
571    def add_init(self):
572        self._cls_dict["__init__"] = self._add_method_dunders(
573            _make_init(
574                self._attrs,
575                self._has_post_init,
576                self._frozen,
577                self._slots,
578                self._super_attr_map,
579            )
580        )
581
582        return self
583
584    def add_cmp(self):
585        cd = self._cls_dict
586
587        cd["__eq__"], cd["__ne__"], cd["__lt__"], cd["__le__"], cd["__gt__"], \
588            cd["__ge__"] = (
589                self._add_method_dunders(meth)
590                for meth in _make_cmp(self._attrs)
591            )
592
593        return self
594
595    def _add_method_dunders(self, method):
596        """
597        Add __module__ and __qualname__ to a *method* if possible.
598        """
599        try:
600            method.__module__ = self._cls.__module__
601        except AttributeError:
602            pass
603
604        try:
605            method.__qualname__ = ".".join(
606                (self._cls.__qualname__, method.__name__,)
607            )
608        except AttributeError:
609            pass
610
611        return method
612
613
614def attrs(maybe_cls=None, these=None, repr_ns=None,
615          repr=True, cmp=True, hash=None, init=True,
616          slots=False, frozen=False, str=False, auto_attribs=False):
617    r"""
618    A class decorator that adds `dunder
619    <https://wiki.python.org/moin/DunderAlias>`_\ -methods according to the
620    specified attributes using :func:`attr.ib` or the *these* argument.
621
622    :param these: A dictionary of name to :func:`attr.ib` mappings.  This is
623        useful to avoid the definition of your attributes within the class body
624        because you can't (e.g. if you want to add ``__repr__`` methods to
625        Django models) or don't want to.
626
627        If *these* is not ``None``, ``attrs`` will *not* search the class body
628        for attributes and will *not* remove any attributes from it.
629
630        If *these* is an ordered dict (:class:`dict` on Python 3.6+,
631        :class:`collections.OrderedDict` otherwise), the order is deduced from
632        the order of the attributes inside *these*.  Otherwise the order
633        of the definition of the attributes is used.
634
635    :type these: :class:`dict` of :class:`str` to :func:`attr.ib`
636
637    :param str repr_ns: When using nested classes, there's no way in Python 2
638        to automatically detect that.  Therefore it's possible to set the
639        namespace explicitly for a more meaningful ``repr`` output.
640    :param bool repr: Create a ``__repr__`` method with a human readable
641        representation of ``attrs`` attributes..
642    :param bool str: Create a ``__str__`` method that is identical to
643        ``__repr__``.  This is usually not necessary except for
644        :class:`Exception`\ s.
645    :param bool cmp: Create ``__eq__``, ``__ne__``, ``__lt__``, ``__le__``,
646        ``__gt__``, and ``__ge__`` methods that compare the class as if it were
647        a tuple of its ``attrs`` attributes.  But the attributes are *only*
648        compared, if the type of both classes is *identical*!
649    :param hash: If ``None`` (default), the ``__hash__`` method is generated
650        according how *cmp* and *frozen* are set.
651
652        1. If *both* are True, ``attrs`` will generate a ``__hash__`` for you.
653        2. If *cmp* is True and *frozen* is False, ``__hash__`` will be set to
654           None, marking it unhashable (which it is).
655        3. If *cmp* is False, ``__hash__`` will be left untouched meaning the
656           ``__hash__`` method of the superclass will be used (if superclass is
657           ``object``, this means it will fall back to id-based hashing.).
658
659        Although not recommended, you can decide for yourself and force
660        ``attrs`` to create one (e.g. if the class is immutable even though you
661        didn't freeze it programmatically) by passing ``True`` or not.  Both of
662        these cases are rather special and should be used carefully.
663
664        See the `Python documentation \
665        <https://docs.python.org/3/reference/datamodel.html#object.__hash__>`_
666        and the `GitHub issue that led to the default behavior \
667        <https://github.com/python-attrs/attrs/issues/136>`_ for more details.
668    :type hash: ``bool`` or ``None``
669    :param bool init: Create a ``__init__`` method that initializes the
670        ``attrs`` attributes.  Leading underscores are stripped for the
671        argument name.  If a ``__attrs_post_init__`` method exists on the
672        class, it will be called after the class is fully initialized.
673    :param bool slots: Create a slots_-style class that's more
674        memory-efficient.  See :ref:`slots` for further ramifications.
675    :param bool frozen: Make instances immutable after initialization.  If
676        someone attempts to modify a frozen instance,
677        :exc:`attr.exceptions.FrozenInstanceError` is raised.
678
679        Please note:
680
681            1. This is achieved by installing a custom ``__setattr__`` method
682               on your class so you can't implement an own one.
683
684            2. True immutability is impossible in Python.
685
686            3. This *does* have a minor a runtime performance :ref:`impact
687               <how-frozen>` when initializing new instances.  In other words:
688               ``__init__`` is slightly slower with ``frozen=True``.
689
690            4. If a class is frozen, you cannot modify ``self`` in
691               ``__attrs_post_init__`` or a self-written ``__init__``. You can
692               circumvent that limitation by using
693               ``object.__setattr__(self, "attribute_name", value)``.
694
695        ..  _slots: https://docs.python.org/3/reference/datamodel.html#slots
696    :param bool auto_attribs: If True, collect `PEP 526`_-annotated attributes
697        (Python 3.6 and later only) from the class body.
698
699        In this case, you **must** annotate every field.  If ``attrs``
700        encounters a field that is set to an :func:`attr.ib` but lacks a type
701        annotation, an :exc:`attr.exceptions.UnannotatedAttributeError` is
702        raised.  Use ``field_name: typing.Any = attr.ib(...)`` if you don't
703        want to set a type.
704
705        If you assign a value to those attributes (e.g. ``x: int = 42``), that
706        value becomes the default value like if it were passed using
707        ``attr.ib(default=42)``.  Passing an instance of :class:`Factory` also
708        works as expected.
709
710        Attributes annotated as :data:`typing.ClassVar` are **ignored**.
711
712        .. _`PEP 526`: https://www.python.org/dev/peps/pep-0526/
713
714    .. versionadded:: 16.0.0 *slots*
715    .. versionadded:: 16.1.0 *frozen*
716    .. versionadded:: 16.3.0 *str*
717    .. versionadded:: 16.3.0 Support for ``__attrs_post_init__``.
718    .. versionchanged:: 17.1.0
719       *hash* supports ``None`` as value which is also the default now.
720    .. versionadded:: 17.3.0 *auto_attribs*
721    .. versionchanged:: 18.1.0
722       If *these* is passed, no attributes are deleted from the class body.
723    .. versionchanged:: 18.1.0 If *these* is ordered, the order is retained.
724    """
725    def wrap(cls):
726        if getattr(cls, "__class__", None) is None:
727            raise TypeError("attrs only works with new-style classes.")
728
729        builder = _ClassBuilder(cls, these, slots, frozen, auto_attribs)
730
731        if repr is True:
732            builder.add_repr(repr_ns)
733        if str is True:
734            builder.add_str()
735        if cmp is True:
736            builder.add_cmp()
737
738        if hash is not True and hash is not False and hash is not None:
739            # Can't use `hash in` because 1 == True for example.
740            raise TypeError(
741                "Invalid value for hash.  Must be True, False, or None."
742            )
743        elif hash is False or (hash is None and cmp is False):
744            pass
745        elif hash is True or (hash is None and cmp is True and frozen is True):
746            builder.add_hash()
747        else:
748            builder.make_unhashable()
749
750        if init is True:
751            builder.add_init()
752
753        return builder.build_class()
754
755    # maybe_cls's type depends on the usage of the decorator.  It's a class
756    # if it's used as `@attrs` but ``None`` if used as `@attrs()`.
757    if maybe_cls is None:
758        return wrap
759    else:
760        return wrap(maybe_cls)
761
762
763_attrs = attrs
764"""
765Internal alias so we can use it in functions that take an argument called
766*attrs*.
767"""
768
769
770if PY2:
771    def _has_frozen_superclass(cls):
772        """
773        Check whether *cls* has a frozen ancestor by looking at its
774        __setattr__.
775        """
776        return (
777            getattr(
778                cls.__setattr__, "__module__", None
779            ) == _frozen_setattrs.__module__ and
780            cls.__setattr__.__name__ == _frozen_setattrs.__name__
781        )
782else:
783    def _has_frozen_superclass(cls):
784        """
785        Check whether *cls* has a frozen ancestor by looking at its
786        __setattr__.
787        """
788        return cls.__setattr__ == _frozen_setattrs
789
790
791def _attrs_to_tuple(obj, attrs):
792    """
793    Create a tuple of all values of *obj*'s *attrs*.
794    """
795    return tuple(getattr(obj, a.name) for a in attrs)
796
797
798def _make_hash(attrs):
799    attrs = tuple(
800        a
801        for a in attrs
802        if a.hash is True or (a.hash is None and a.cmp is True)
803    )
804
805    # We cache the generated hash methods for the same kinds of attributes.
806    sha1 = hashlib.sha1()
807    sha1.update(repr(attrs).encode("utf-8"))
808    unique_filename = "<attrs generated hash %s>" % (sha1.hexdigest(),)
809    type_hash = hash(unique_filename)
810    lines = [
811        "def __hash__(self):",
812        "    return hash((",
813        "        %d," % (type_hash,),
814    ]
815    for a in attrs:
816        lines.append("        self.%s," % (a.name))
817
818    lines.append("    ))")
819
820    script = "\n".join(lines)
821    globs = {}
822    locs = {}
823    bytecode = compile(script, unique_filename, "exec")
824    eval(bytecode, globs, locs)
825
826    # In order of debuggers like PDB being able to step through the code,
827    # we add a fake linecache entry.
828    linecache.cache[unique_filename] = (
829        len(script),
830        None,
831        script.splitlines(True),
832        unique_filename,
833    )
834
835    return locs["__hash__"]
836
837
838def _add_hash(cls, attrs):
839    """
840    Add a hash method to *cls*.
841    """
842    cls.__hash__ = _make_hash(attrs)
843    return cls
844
845
846def __ne__(self, other):
847    """
848    Check equality and either forward a NotImplemented or return the result
849    negated.
850    """
851    result = self.__eq__(other)
852    if result is NotImplemented:
853        return NotImplemented
854
855    return not result
856
857
858def _make_cmp(attrs):
859    attrs = [a for a in attrs if a.cmp]
860
861    # We cache the generated eq methods for the same kinds of attributes.
862    sha1 = hashlib.sha1()
863    sha1.update(repr(attrs).encode("utf-8"))
864    unique_filename = "<attrs generated eq %s>" % (sha1.hexdigest(),)
865    lines = [
866        "def __eq__(self, other):",
867        "    if other.__class__ is not self.__class__:",
868        "        return NotImplemented",
869    ]
870    # We can't just do a big self.x = other.x and... clause due to
871    # irregularities like nan == nan is false but (nan,) == (nan,) is true.
872    if attrs:
873        lines.append("    return  (")
874        others = [
875            "    ) == (",
876        ]
877        for a in attrs:
878            lines.append("        self.%s," % (a.name,))
879            others.append("        other.%s," % (a.name,))
880
881        lines += others + ["    )"]
882    else:
883        lines.append("    return True")
884
885    script = "\n".join(lines)
886    globs = {}
887    locs = {}
888    bytecode = compile(script, unique_filename, "exec")
889    eval(bytecode, globs, locs)
890
891    # In order of debuggers like PDB being able to step through the code,
892    # we add a fake linecache entry.
893    linecache.cache[unique_filename] = (
894        len(script),
895        None,
896        script.splitlines(True),
897        unique_filename,
898    )
899    eq = locs["__eq__"]
900    ne = __ne__
901
902    def attrs_to_tuple(obj):
903        """
904        Save us some typing.
905        """
906        return _attrs_to_tuple(obj, attrs)
907
908    def __lt__(self, other):
909        """
910        Automatically created by attrs.
911        """
912        if isinstance(other, self.__class__):
913            return attrs_to_tuple(self) < attrs_to_tuple(other)
914        else:
915            return NotImplemented
916
917    def __le__(self, other):
918        """
919        Automatically created by attrs.
920        """
921        if isinstance(other, self.__class__):
922            return attrs_to_tuple(self) <= attrs_to_tuple(other)
923        else:
924            return NotImplemented
925
926    def __gt__(self, other):
927        """
928        Automatically created by attrs.
929        """
930        if isinstance(other, self.__class__):
931            return attrs_to_tuple(self) > attrs_to_tuple(other)
932        else:
933            return NotImplemented
934
935    def __ge__(self, other):
936        """
937        Automatically created by attrs.
938        """
939        if isinstance(other, self.__class__):
940            return attrs_to_tuple(self) >= attrs_to_tuple(other)
941        else:
942            return NotImplemented
943
944    return eq, ne, __lt__, __le__, __gt__, __ge__
945
946
947def _add_cmp(cls, attrs=None):
948    """
949    Add comparison methods to *cls*.
950    """
951    if attrs is None:
952        attrs = cls.__attrs_attrs__
953
954    cls.__eq__, cls.__ne__, cls.__lt__, cls.__le__, cls.__gt__, cls.__ge__ = \
955        _make_cmp(attrs)
956
957    return cls
958
959
960_already_repring = threading.local()
961
962
963def _make_repr(attrs, ns):
964    """
965    Make a repr method for *attr_names* adding *ns* to the full name.
966    """
967    attr_names = tuple(
968        a.name
969        for a in attrs
970        if a.repr
971    )
972
973    def __repr__(self):
974        """
975        Automatically created by attrs.
976        """
977        try:
978            working_set = _already_repring.working_set
979        except AttributeError:
980            working_set = set()
981            _already_repring.working_set = working_set
982
983        if id(self) in working_set:
984            return "..."
985        real_cls = self.__class__
986        if ns is None:
987            qualname = getattr(real_cls, "__qualname__", None)
988            if qualname is not None:
989                class_name = qualname.rsplit(">.", 1)[-1]
990            else:
991                class_name = real_cls.__name__
992        else:
993            class_name = ns + "." + real_cls.__name__
994
995        # Since 'self' remains on the stack (i.e.: strongly referenced) for the
996        # duration of this call, it's safe to depend on id(...) stability, and
997        # not need to track the instance and therefore worry about properties
998        # like weakref- or hash-ability.
999        working_set.add(id(self))
1000        try:
1001            result = [class_name, "("]
1002            first = True
1003            for name in attr_names:
1004                if first:
1005                    first = False
1006                else:
1007                    result.append(", ")
1008                result.extend((name, "=", repr(getattr(self, name, NOTHING))))
1009            return "".join(result) + ")"
1010        finally:
1011            working_set.remove(id(self))
1012    return __repr__
1013
1014
1015def _add_repr(cls, ns=None, attrs=None):
1016    """
1017    Add a repr method to *cls*.
1018    """
1019    if attrs is None:
1020        attrs = cls.__attrs_attrs__
1021
1022    cls.__repr__ = _make_repr(attrs, ns)
1023    return cls
1024
1025
1026def _make_init(attrs, post_init, frozen, slots, super_attr_map):
1027    attrs = [
1028        a
1029        for a in attrs
1030        if a.init or a.default is not NOTHING
1031    ]
1032
1033    # We cache the generated init methods for the same kinds of attributes.
1034    sha1 = hashlib.sha1()
1035    sha1.update(repr(attrs).encode("utf-8"))
1036    unique_filename = "<attrs generated init {0}>".format(
1037        sha1.hexdigest()
1038    )
1039
1040    script, globs, annotations = _attrs_to_init_script(
1041        attrs,
1042        frozen,
1043        slots,
1044        post_init,
1045        super_attr_map,
1046    )
1047    locs = {}
1048    bytecode = compile(script, unique_filename, "exec")
1049    attr_dict = dict((a.name, a) for a in attrs)
1050    globs.update({
1051        "NOTHING": NOTHING,
1052        "attr_dict": attr_dict,
1053    })
1054    if frozen is True:
1055        # Save the lookup overhead in __init__ if we need to circumvent
1056        # immutability.
1057        globs["_cached_setattr"] = _obj_setattr
1058    eval(bytecode, globs, locs)
1059
1060    # In order of debuggers like PDB being able to step through the code,
1061    # we add a fake linecache entry.
1062    linecache.cache[unique_filename] = (
1063        len(script),
1064        None,
1065        script.splitlines(True),
1066        unique_filename,
1067    )
1068
1069    __init__ = locs["__init__"]
1070    __init__.__annotations__ = annotations
1071    return __init__
1072
1073
1074def _add_init(cls, frozen):
1075    """
1076    Add a __init__ method to *cls*.  If *frozen* is True, make it immutable.
1077    """
1078    cls.__init__ = _make_init(
1079        cls.__attrs_attrs__,
1080        getattr(cls, "__attrs_post_init__", False),
1081        frozen,
1082        _is_slot_cls(cls),
1083        {},
1084    )
1085    return cls
1086
1087
1088def fields(cls):
1089    """
1090    Return the tuple of ``attrs`` attributes for a class.
1091
1092    The tuple also allows accessing the fields by their names (see below for
1093    examples).
1094
1095    :param type cls: Class to introspect.
1096
1097    :raise TypeError: If *cls* is not a class.
1098    :raise attr.exceptions.NotAnAttrsClassError: If *cls* is not an ``attrs``
1099        class.
1100
1101    :rtype: tuple (with name accessors) of :class:`attr.Attribute`
1102
1103    ..  versionchanged:: 16.2.0 Returned tuple allows accessing the fields
1104        by name.
1105    """
1106    if not isclass(cls):
1107        raise TypeError("Passed object must be a class.")
1108    attrs = getattr(cls, "__attrs_attrs__", None)
1109    if attrs is None:
1110        raise NotAnAttrsClassError(
1111            "{cls!r} is not an attrs-decorated class.".format(cls=cls)
1112        )
1113    return attrs
1114
1115
1116def fields_dict(cls):
1117    """
1118    Return an ordered dictionary of ``attrs`` attributes for a class, whose
1119    keys are the attribute names.
1120
1121    :param type cls: Class to introspect.
1122
1123    :raise TypeError: If *cls* is not a class.
1124    :raise attr.exceptions.NotAnAttrsClassError: If *cls* is not an ``attrs``
1125        class.
1126
1127    :rtype: an ordered dict where keys are attribute names and values are
1128        :class:`attr.Attribute`\\ s. This will be a :class:`dict` if it's
1129        naturally ordered like on Python 3.6+ or an
1130        :class:`~collections.OrderedDict` otherwise.
1131
1132    .. versionadded:: 18.1.0
1133    """
1134    if not isclass(cls):
1135        raise TypeError("Passed object must be a class.")
1136    attrs = getattr(cls, "__attrs_attrs__", None)
1137    if attrs is None:
1138        raise NotAnAttrsClassError(
1139            "{cls!r} is not an attrs-decorated class.".format(cls=cls)
1140        )
1141    return ordered_dict(((a.name, a) for a in attrs))
1142
1143
1144def validate(inst):
1145    """
1146    Validate all attributes on *inst* that have a validator.
1147
1148    Leaves all exceptions through.
1149
1150    :param inst: Instance of a class with ``attrs`` attributes.
1151    """
1152    if _config._run_validators is False:
1153        return
1154
1155    for a in fields(inst.__class__):
1156        v = a.validator
1157        if v is not None:
1158            v(inst, a, getattr(inst, a.name))
1159
1160
1161def _is_slot_cls(cls):
1162    return "__slots__" in cls.__dict__
1163
1164
1165def _is_slot_attr(a_name, super_attr_map):
1166    """
1167    Check if the attribute name comes from a slot class.
1168    """
1169    return a_name in super_attr_map and _is_slot_cls(super_attr_map[a_name])
1170
1171
1172def _attrs_to_init_script(attrs, frozen, slots, post_init, super_attr_map):
1173    """
1174    Return a script of an initializer for *attrs* and a dict of globals.
1175
1176    The globals are expected by the generated script.
1177
1178    If *frozen* is True, we cannot set the attributes directly so we use
1179    a cached ``object.__setattr__``.
1180    """
1181    lines = []
1182    any_slot_ancestors = any(
1183        _is_slot_attr(a.name, super_attr_map)
1184        for a in attrs
1185    )
1186    if frozen is True:
1187        if slots is True:
1188            lines.append(
1189                # Circumvent the __setattr__ descriptor to save one lookup per
1190                # assignment.
1191                "_setattr = _cached_setattr.__get__(self, self.__class__)"
1192            )
1193
1194            def fmt_setter(attr_name, value_var):
1195                return "_setattr('%(attr_name)s', %(value_var)s)" % {
1196                    "attr_name": attr_name,
1197                    "value_var": value_var,
1198                }
1199
1200            def fmt_setter_with_converter(attr_name, value_var):
1201                conv_name = _init_converter_pat.format(attr_name)
1202                return "_setattr('%(attr_name)s', %(conv)s(%(value_var)s))" % {
1203                    "attr_name": attr_name,
1204                    "value_var": value_var,
1205                    "conv": conv_name,
1206                }
1207        else:
1208            # Dict frozen classes assign directly to __dict__.
1209            # But only if the attribute doesn't come from an ancestor slot
1210            # class.
1211            lines.append(
1212                "_inst_dict = self.__dict__"
1213            )
1214            if any_slot_ancestors:
1215                lines.append(
1216                    # Circumvent the __setattr__ descriptor to save one lookup
1217                    # per assignment.
1218                    "_setattr = _cached_setattr.__get__(self, self.__class__)"
1219                )
1220
1221            def fmt_setter(attr_name, value_var):
1222                if _is_slot_attr(attr_name, super_attr_map):
1223                    res = "_setattr('%(attr_name)s', %(value_var)s)" % {
1224                        "attr_name": attr_name,
1225                        "value_var": value_var,
1226                    }
1227                else:
1228                    res = "_inst_dict['%(attr_name)s'] = %(value_var)s" % {
1229                        "attr_name": attr_name,
1230                        "value_var": value_var,
1231                    }
1232                return res
1233
1234            def fmt_setter_with_converter(attr_name, value_var):
1235                conv_name = _init_converter_pat.format(attr_name)
1236                if _is_slot_attr(attr_name, super_attr_map):
1237                    tmpl = "_setattr('%(attr_name)s', %(c)s(%(value_var)s))"
1238                else:
1239                    tmpl = "_inst_dict['%(attr_name)s'] = %(c)s(%(value_var)s)"
1240                return tmpl % {
1241                    "attr_name": attr_name,
1242                    "value_var": value_var,
1243                    "c": conv_name,
1244                }
1245    else:
1246        # Not frozen.
1247        def fmt_setter(attr_name, value):
1248            return "self.%(attr_name)s = %(value)s" % {
1249                "attr_name": attr_name,
1250                "value": value,
1251            }
1252
1253        def fmt_setter_with_converter(attr_name, value_var):
1254            conv_name = _init_converter_pat.format(attr_name)
1255            return "self.%(attr_name)s = %(conv)s(%(value_var)s)" % {
1256                "attr_name": attr_name,
1257                "value_var": value_var,
1258                "conv": conv_name,
1259            }
1260
1261    args = []
1262    attrs_to_validate = []
1263
1264    # This is a dictionary of names to validator and converter callables.
1265    # Injecting this into __init__ globals lets us avoid lookups.
1266    names_for_globals = {}
1267    annotations = {'return': None}
1268
1269    for a in attrs:
1270        if a.validator:
1271            attrs_to_validate.append(a)
1272        attr_name = a.name
1273        arg_name = a.name.lstrip("_")
1274        has_factory = isinstance(a.default, Factory)
1275        if has_factory and a.default.takes_self:
1276            maybe_self = "self"
1277        else:
1278            maybe_self = ""
1279        if a.init is False:
1280            if has_factory:
1281                init_factory_name = _init_factory_pat.format(a.name)
1282                if a.converter is not None:
1283                    lines.append(fmt_setter_with_converter(
1284                        attr_name,
1285                        init_factory_name + "({0})".format(maybe_self)))
1286                    conv_name = _init_converter_pat.format(a.name)
1287                    names_for_globals[conv_name] = a.converter
1288                else:
1289                    lines.append(fmt_setter(
1290                        attr_name,
1291                        init_factory_name + "({0})".format(maybe_self)
1292                    ))
1293                names_for_globals[init_factory_name] = a.default.factory
1294            else:
1295                if a.converter is not None:
1296                    lines.append(fmt_setter_with_converter(
1297                        attr_name,
1298                        "attr_dict['{attr_name}'].default"
1299                        .format(attr_name=attr_name)
1300                    ))
1301                    conv_name = _init_converter_pat.format(a.name)
1302                    names_for_globals[conv_name] = a.converter
1303                else:
1304                    lines.append(fmt_setter(
1305                        attr_name,
1306                        "attr_dict['{attr_name}'].default"
1307                        .format(attr_name=attr_name)
1308                    ))
1309        elif a.default is not NOTHING and not has_factory:
1310            args.append(
1311                "{arg_name}=attr_dict['{attr_name}'].default".format(
1312                    arg_name=arg_name,
1313                    attr_name=attr_name,
1314                )
1315            )
1316            if a.converter is not None:
1317                lines.append(fmt_setter_with_converter(attr_name, arg_name))
1318                names_for_globals[_init_converter_pat.format(a.name)] = (
1319                    a.converter
1320                )
1321            else:
1322                lines.append(fmt_setter(attr_name, arg_name))
1323        elif has_factory:
1324            args.append("{arg_name}=NOTHING".format(arg_name=arg_name))
1325            lines.append("if {arg_name} is not NOTHING:"
1326                         .format(arg_name=arg_name))
1327            init_factory_name = _init_factory_pat.format(a.name)
1328            if a.converter is not None:
1329                lines.append("    " + fmt_setter_with_converter(
1330                    attr_name, arg_name
1331                ))
1332                lines.append("else:")
1333                lines.append("    " + fmt_setter_with_converter(
1334                    attr_name,
1335                    init_factory_name + "({0})".format(maybe_self)
1336                ))
1337                names_for_globals[_init_converter_pat.format(a.name)] = (
1338                    a.converter
1339                )
1340            else:
1341                lines.append("    " + fmt_setter(attr_name, arg_name))
1342                lines.append("else:")
1343                lines.append("    " + fmt_setter(
1344                    attr_name,
1345                    init_factory_name + "({0})".format(maybe_self)
1346                ))
1347            names_for_globals[init_factory_name] = a.default.factory
1348        else:
1349            args.append(arg_name)
1350            if a.converter is not None:
1351                lines.append(fmt_setter_with_converter(attr_name, arg_name))
1352                names_for_globals[_init_converter_pat.format(a.name)] = (
1353                    a.converter
1354                )
1355            else:
1356                lines.append(fmt_setter(attr_name, arg_name))
1357
1358        if a.init is True and a.converter is None and a.type is not None:
1359            annotations[arg_name] = a.type
1360
1361    if attrs_to_validate:  # we can skip this if there are no validators.
1362        names_for_globals["_config"] = _config
1363        lines.append("if _config._run_validators is True:")
1364        for a in attrs_to_validate:
1365            val_name = "__attr_validator_{}".format(a.name)
1366            attr_name = "__attr_{}".format(a.name)
1367            lines.append("    {}(self, {}, self.{})".format(
1368                val_name, attr_name, a.name))
1369            names_for_globals[val_name] = a.validator
1370            names_for_globals[attr_name] = a
1371    if post_init:
1372        lines.append("self.__attrs_post_init__()")
1373
1374    return """\
1375def __init__(self, {args}):
1376    {lines}
1377""".format(
1378        args=", ".join(args),
1379        lines="\n    ".join(lines) if lines else "pass",
1380    ), names_for_globals, annotations
1381
1382
1383class Attribute(object):
1384    """
1385    *Read-only* representation of an attribute.
1386
1387    :attribute name: The name of the attribute.
1388
1389    Plus *all* arguments of :func:`attr.ib`.
1390
1391    For the version history of the fields, see :func:`attr.ib`.
1392    """
1393    __slots__ = (
1394        "name", "default", "validator", "repr", "cmp", "hash", "init",
1395        "metadata", "type", "converter",
1396    )
1397
1398    def __init__(self, name, default, validator, repr, cmp, hash, init,
1399                 convert=None, metadata=None, type=None, converter=None):
1400        # Cache this descriptor here to speed things up later.
1401        bound_setattr = _obj_setattr.__get__(self, Attribute)
1402
1403        # Despite the big red warning, people *do* instantiate `Attribute`
1404        # themselves.
1405        if convert is not None:
1406            if converter is not None:
1407                raise RuntimeError(
1408                    "Can't pass both `convert` and `converter`.  "
1409                    "Please use `converter` only."
1410                )
1411            warnings.warn(
1412                "The `convert` argument is deprecated in favor of `converter`."
1413                "  It will be removed after 2019/01.",
1414                DeprecationWarning, stacklevel=2
1415            )
1416            converter = convert
1417
1418        bound_setattr("name", name)
1419        bound_setattr("default", default)
1420        bound_setattr("validator", validator)
1421        bound_setattr("repr", repr)
1422        bound_setattr("cmp", cmp)
1423        bound_setattr("hash", hash)
1424        bound_setattr("init", init)
1425        bound_setattr("converter", converter)
1426        bound_setattr("metadata", (
1427            metadata_proxy(metadata) if metadata
1428            else _empty_metadata_singleton
1429        ))
1430        bound_setattr("type", type)
1431
1432    def __setattr__(self, name, value):
1433        raise FrozenInstanceError()
1434
1435    @property
1436    def convert(self):
1437        warnings.warn(
1438            "The `convert` attribute is deprecated in favor of `converter`.  "
1439            "It will be removed after 2019/01.",
1440            DeprecationWarning, stacklevel=2,
1441        )
1442        return self.converter
1443
1444    @classmethod
1445    def from_counting_attr(cls, name, ca, type=None):
1446        # type holds the annotated value. deal with conflicts:
1447        if type is None:
1448            type = ca.type
1449        elif ca.type is not None:
1450            raise ValueError(
1451                "Type annotation and type argument cannot both be present"
1452            )
1453        inst_dict = {
1454            k: getattr(ca, k)
1455            for k
1456            in Attribute.__slots__
1457            if k not in (
1458                "name", "validator", "default", "type", "convert",
1459            )  # exclude methods and deprecated alias
1460        }
1461        return cls(
1462            name=name, validator=ca._validator, default=ca._default, type=type,
1463            **inst_dict
1464        )
1465
1466    # Don't use _add_pickle since fields(Attribute) doesn't work
1467    def __getstate__(self):
1468        """
1469        Play nice with pickle.
1470        """
1471        return tuple(getattr(self, name) if name != "metadata"
1472                     else dict(self.metadata)
1473                     for name in self.__slots__)
1474
1475    def __setstate__(self, state):
1476        """
1477        Play nice with pickle.
1478        """
1479        bound_setattr = _obj_setattr.__get__(self, Attribute)
1480        for name, value in zip(self.__slots__, state):
1481            if name != "metadata":
1482                bound_setattr(name, value)
1483            else:
1484                bound_setattr(name, metadata_proxy(value) if value else
1485                              _empty_metadata_singleton)
1486
1487
1488_a = [
1489    Attribute(name=name, default=NOTHING, validator=None,
1490              repr=True, cmp=True, hash=(name != "metadata"), init=True)
1491    for name in Attribute.__slots__
1492    if name != "convert"  # XXX: remove once `convert` is gone
1493]
1494
1495Attribute = _add_hash(
1496    _add_cmp(_add_repr(Attribute, attrs=_a), attrs=_a),
1497    attrs=[a for a in _a if a.hash]
1498)
1499
1500
1501class _CountingAttr(object):
1502    """
1503    Intermediate representation of attributes that uses a counter to preserve
1504    the order in which the attributes have been defined.
1505
1506    *Internal* data structure of the attrs library.  Running into is most
1507    likely the result of a bug like a forgotten `@attr.s` decorator.
1508    """
1509    __slots__ = ("counter", "_default", "repr", "cmp", "hash", "init",
1510                 "metadata", "_validator", "converter", "type")
1511    __attrs_attrs__ = tuple(
1512        Attribute(name=name, default=NOTHING, validator=None,
1513                  repr=True, cmp=True, hash=True, init=True)
1514        for name
1515        in ("counter", "_default", "repr", "cmp", "hash", "init",)
1516    ) + (
1517        Attribute(name="metadata", default=None, validator=None,
1518                  repr=True, cmp=True, hash=False, init=True),
1519    )
1520    cls_counter = 0
1521
1522    def __init__(self, default, validator, repr, cmp, hash, init, converter,
1523                 metadata, type):
1524        _CountingAttr.cls_counter += 1
1525        self.counter = _CountingAttr.cls_counter
1526        self._default = default
1527        # If validator is a list/tuple, wrap it using helper validator.
1528        if validator and isinstance(validator, (list, tuple)):
1529            self._validator = and_(*validator)
1530        else:
1531            self._validator = validator
1532        self.repr = repr
1533        self.cmp = cmp
1534        self.hash = hash
1535        self.init = init
1536        self.converter = converter
1537        self.metadata = metadata
1538        self.type = type
1539
1540    def validator(self, meth):
1541        """
1542        Decorator that adds *meth* to the list of validators.
1543
1544        Returns *meth* unchanged.
1545
1546        .. versionadded:: 17.1.0
1547        """
1548        if self._validator is None:
1549            self._validator = meth
1550        else:
1551            self._validator = and_(self._validator, meth)
1552        return meth
1553
1554    def default(self, meth):
1555        """
1556        Decorator that allows to set the default for an attribute.
1557
1558        Returns *meth* unchanged.
1559
1560        :raises DefaultAlreadySetError: If default has been set before.
1561
1562        .. versionadded:: 17.1.0
1563        """
1564        if self._default is not NOTHING:
1565            raise DefaultAlreadySetError()
1566
1567        self._default = Factory(meth, takes_self=True)
1568
1569        return meth
1570
1571
1572_CountingAttr = _add_cmp(_add_repr(_CountingAttr))
1573
1574
1575@attrs(slots=True, init=False, hash=True)
1576class Factory(object):
1577    """
1578    Stores a factory callable.
1579
1580    If passed as the default value to :func:`attr.ib`, the factory is used to
1581    generate a new value.
1582
1583    :param callable factory: A callable that takes either none or exactly one
1584        mandatory positional argument depending on *takes_self*.
1585    :param bool takes_self: Pass the partially initialized instance that is
1586        being initialized as a positional argument.
1587
1588    .. versionadded:: 17.1.0  *takes_self*
1589    """
1590    factory = attrib()
1591    takes_self = attrib()
1592
1593    def __init__(self, factory, takes_self=False):
1594        """
1595        `Factory` is part of the default machinery so if we want a default
1596        value here, we have to implement it ourselves.
1597        """
1598        self.factory = factory
1599        self.takes_self = takes_self
1600
1601
1602def make_class(name, attrs, bases=(object,), **attributes_arguments):
1603    """
1604    A quick way to create a new class called *name* with *attrs*.
1605
1606    :param name: The name for the new class.
1607    :type name: str
1608
1609    :param attrs: A list of names or a dictionary of mappings of names to
1610        attributes.
1611
1612        If *attrs* is a list or an ordered dict (:class:`dict` on Python 3.6+,
1613        :class:`collections.OrderedDict` otherwise), the order is deduced from
1614        the order of the names or attributes inside *attrs*.  Otherwise the
1615        order of the definition of the attributes is used.
1616    :type attrs: :class:`list` or :class:`dict`
1617
1618    :param tuple bases: Classes that the new class will subclass.
1619
1620    :param attributes_arguments: Passed unmodified to :func:`attr.s`.
1621
1622    :return: A new class with *attrs*.
1623    :rtype: type
1624
1625    .. versionadded:: 17.1.0 *bases*
1626    .. versionchanged:: 18.1.0 If *attrs* is ordered, the order is retained.
1627    """
1628    if isinstance(attrs, dict):
1629        cls_dict = attrs
1630    elif isinstance(attrs, (list, tuple)):
1631        cls_dict = dict((a, attrib()) for a in attrs)
1632    else:
1633        raise TypeError("attrs argument must be a dict or a list.")
1634
1635    post_init = cls_dict.pop("__attrs_post_init__", None)
1636    type_ = type(
1637        name,
1638        bases,
1639        {} if post_init is None else {"__attrs_post_init__": post_init}
1640    )
1641    # For pickling to work, the __module__ variable needs to be set to the
1642    # frame where the class is created.  Bypass this step in environments where
1643    # sys._getframe is not defined (Jython for example) or sys._getframe is not
1644    # defined for arguments greater than 0 (IronPython).
1645    try:
1646        type_.__module__ = sys._getframe(1).f_globals.get(
1647            "__name__", "__main__",
1648        )
1649    except (AttributeError, ValueError):
1650        pass
1651
1652    return _attrs(these=cls_dict, **attributes_arguments)(type_)
1653
1654
1655# These are required by within this module so we define them here and merely
1656# import into .validators.
1657
1658
1659@attrs(slots=True, hash=True)
1660class _AndValidator(object):
1661    """
1662    Compose many validators to a single one.
1663    """
1664    _validators = attrib()
1665
1666    def __call__(self, inst, attr, value):
1667        for v in self._validators:
1668            v(inst, attr, value)
1669
1670
1671def and_(*validators):
1672    """
1673    A validator that composes multiple validators into one.
1674
1675    When called on a value, it runs all wrapped validators.
1676
1677    :param validators: Arbitrary number of validators.
1678    :type validators: callables
1679
1680    .. versionadded:: 17.1.0
1681    """
1682    vals = []
1683    for validator in validators:
1684        vals.extend(
1685            validator._validators if isinstance(validator, _AndValidator)
1686            else [validator]
1687        )
1688
1689    return _AndValidator(tuple(vals))
1690