Funktionierender Prototyp des Serious Games zur Vermittlung von Wissen zu Software-Engineering-Arbeitsmodellen.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

_next_gen.py 6.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. # SPDX-License-Identifier: MIT
  2. """
  3. These are keyword-only APIs that call `attr.s` and `attr.ib` with different
  4. default values.
  5. """
  6. from functools import partial
  7. from . import setters
  8. from ._funcs import asdict as _asdict
  9. from ._funcs import astuple as _astuple
  10. from ._make import (
  11. NOTHING,
  12. _frozen_setattrs,
  13. _ng_default_on_setattr,
  14. attrib,
  15. attrs,
  16. )
  17. from .exceptions import UnannotatedAttributeError
  18. def define(
  19. maybe_cls=None,
  20. *,
  21. these=None,
  22. repr=None,
  23. unsafe_hash=None,
  24. hash=None,
  25. init=None,
  26. slots=True,
  27. frozen=False,
  28. weakref_slot=True,
  29. str=False,
  30. auto_attribs=None,
  31. kw_only=False,
  32. cache_hash=False,
  33. auto_exc=True,
  34. eq=None,
  35. order=False,
  36. auto_detect=True,
  37. getstate_setstate=None,
  38. on_setattr=None,
  39. field_transformer=None,
  40. match_args=True,
  41. ):
  42. r"""
  43. Define an *attrs* class.
  44. Differences to the classic `attr.s` that it uses underneath:
  45. - Automatically detect whether or not *auto_attribs* should be `True` (c.f.
  46. *auto_attribs* parameter).
  47. - If *frozen* is `False`, run converters and validators when setting an
  48. attribute by default.
  49. - *slots=True*
  50. .. caution::
  51. Usually this has only upsides and few visible effects in everyday
  52. programming. But it *can* lead to some suprising behaviors, so please
  53. make sure to read :term:`slotted classes`.
  54. - *auto_exc=True*
  55. - *auto_detect=True*
  56. - *order=False*
  57. - Some options that were only relevant on Python 2 or were kept around for
  58. backwards-compatibility have been removed.
  59. Please note that these are all defaults and you can change them as you
  60. wish.
  61. :param Optional[bool] auto_attribs: If set to `True` or `False`, it behaves
  62. exactly like `attr.s`. If left `None`, `attr.s` will try to guess:
  63. 1. If any attributes are annotated and no unannotated `attrs.fields`\ s
  64. are found, it assumes *auto_attribs=True*.
  65. 2. Otherwise it assumes *auto_attribs=False* and tries to collect
  66. `attrs.fields`\ s.
  67. For now, please refer to `attr.s` for the rest of the parameters.
  68. .. versionadded:: 20.1.0
  69. .. versionchanged:: 21.3.0 Converters are also run ``on_setattr``.
  70. .. versionadded:: 22.2.0
  71. *unsafe_hash* as an alias for *hash* (for :pep:`681` compliance).
  72. """
  73. def do_it(cls, auto_attribs):
  74. return attrs(
  75. maybe_cls=cls,
  76. these=these,
  77. repr=repr,
  78. hash=hash,
  79. unsafe_hash=unsafe_hash,
  80. init=init,
  81. slots=slots,
  82. frozen=frozen,
  83. weakref_slot=weakref_slot,
  84. str=str,
  85. auto_attribs=auto_attribs,
  86. kw_only=kw_only,
  87. cache_hash=cache_hash,
  88. auto_exc=auto_exc,
  89. eq=eq,
  90. order=order,
  91. auto_detect=auto_detect,
  92. collect_by_mro=True,
  93. getstate_setstate=getstate_setstate,
  94. on_setattr=on_setattr,
  95. field_transformer=field_transformer,
  96. match_args=match_args,
  97. )
  98. def wrap(cls):
  99. """
  100. Making this a wrapper ensures this code runs during class creation.
  101. We also ensure that frozen-ness of classes is inherited.
  102. """
  103. nonlocal frozen, on_setattr
  104. had_on_setattr = on_setattr not in (None, setters.NO_OP)
  105. # By default, mutable classes convert & validate on setattr.
  106. if frozen is False and on_setattr is None:
  107. on_setattr = _ng_default_on_setattr
  108. # However, if we subclass a frozen class, we inherit the immutability
  109. # and disable on_setattr.
  110. for base_cls in cls.__bases__:
  111. if base_cls.__setattr__ is _frozen_setattrs:
  112. if had_on_setattr:
  113. raise ValueError(
  114. "Frozen classes can't use on_setattr "
  115. "(frozen-ness was inherited)."
  116. )
  117. on_setattr = setters.NO_OP
  118. break
  119. if auto_attribs is not None:
  120. return do_it(cls, auto_attribs)
  121. try:
  122. return do_it(cls, True)
  123. except UnannotatedAttributeError:
  124. return do_it(cls, False)
  125. # maybe_cls's type depends on the usage of the decorator. It's a class
  126. # if it's used as `@attrs` but ``None`` if used as `@attrs()`.
  127. if maybe_cls is None:
  128. return wrap
  129. else:
  130. return wrap(maybe_cls)
  131. mutable = define
  132. frozen = partial(define, frozen=True, on_setattr=None)
  133. def field(
  134. *,
  135. default=NOTHING,
  136. validator=None,
  137. repr=True,
  138. hash=None,
  139. init=True,
  140. metadata=None,
  141. type=None,
  142. converter=None,
  143. factory=None,
  144. kw_only=False,
  145. eq=None,
  146. order=None,
  147. on_setattr=None,
  148. alias=None,
  149. ):
  150. """
  151. Identical to `attr.ib`, except keyword-only and with some arguments
  152. removed.
  153. .. versionadded:: 23.1.0
  154. The *type* parameter has been re-added; mostly for
  155. {func}`attrs.make_class`. Please note that type checkers ignore this
  156. metadata.
  157. .. versionadded:: 20.1.0
  158. """
  159. return attrib(
  160. default=default,
  161. validator=validator,
  162. repr=repr,
  163. hash=hash,
  164. init=init,
  165. metadata=metadata,
  166. type=type,
  167. converter=converter,
  168. factory=factory,
  169. kw_only=kw_only,
  170. eq=eq,
  171. order=order,
  172. on_setattr=on_setattr,
  173. alias=alias,
  174. )
  175. def asdict(inst, *, recurse=True, filter=None, value_serializer=None):
  176. """
  177. Same as `attr.asdict`, except that collections types are always retained
  178. and dict is always used as *dict_factory*.
  179. .. versionadded:: 21.3.0
  180. """
  181. return _asdict(
  182. inst=inst,
  183. recurse=recurse,
  184. filter=filter,
  185. value_serializer=value_serializer,
  186. retain_collection_types=True,
  187. )
  188. def astuple(inst, *, recurse=True, filter=None):
  189. """
  190. Same as `attr.astuple`, except that collections types are always retained
  191. and `tuple` is always used as the *tuple_factory*.
  192. .. versionadded:: 21.3.0
  193. """
  194. return _astuple(
  195. inst=inst, recurse=recurse, filter=filter, retain_collection_types=True
  196. )