_make.py 55 KB

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