Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/attr/_next_gen.py: 87%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

38 statements  

1# SPDX-License-Identifier: MIT 

2 

3""" 

4These are keyword-only APIs that call `attr.s` and `attr.ib` with different 

5default values. 

6""" 

7 

8 

9from functools import partial 

10 

11from . import setters 

12from ._funcs import asdict as _asdict 

13from ._funcs import astuple as _astuple 

14from ._make import ( 

15 NOTHING, 

16 _frozen_setattrs, 

17 _ng_default_on_setattr, 

18 attrib, 

19 attrs, 

20) 

21from .exceptions import UnannotatedAttributeError 

22 

23 

24def define( 

25 maybe_cls=None, 

26 *, 

27 these=None, 

28 repr=None, 

29 unsafe_hash=None, 

30 hash=None, 

31 init=None, 

32 slots=True, 

33 frozen=False, 

34 weakref_slot=True, 

35 str=False, 

36 auto_attribs=None, 

37 kw_only=False, 

38 cache_hash=False, 

39 auto_exc=True, 

40 eq=None, 

41 order=False, 

42 auto_detect=True, 

43 getstate_setstate=None, 

44 on_setattr=None, 

45 field_transformer=None, 

46 match_args=True, 

47): 

48 r""" 

49 Define an *attrs* class. 

50 

51 Differences to the classic `attr.s` that it uses underneath: 

52 

53 - Automatically detect whether or not *auto_attribs* should be `True` (c.f. 

54 *auto_attribs* parameter). 

55 - Converters and validators run when attributes are set by default -- if 

56 *frozen* is `False`. 

57 - *slots=True* 

58 

59 .. caution:: 

60 

61 Usually this has only upsides and few visible effects in everyday 

62 programming. But it *can* lead to some surprising behaviors, so please 

63 make sure to read :term:`slotted classes`. 

64 - *auto_exc=True* 

65 - *auto_detect=True* 

66 - *order=False* 

67 - Some options that were only relevant on Python 2 or were kept around for 

68 backwards-compatibility have been removed. 

69 

70 Please note that these are all defaults and you can change them as you 

71 wish. 

72 

73 :param Optional[bool] auto_attribs: If set to `True` or `False`, it behaves 

74 exactly like `attr.s`. If left `None`, `attr.s` will try to guess: 

75 

76 1. If any attributes are annotated and no unannotated `attrs.fields`\ s 

77 are found, it assumes *auto_attribs=True*. 

78 2. Otherwise it assumes *auto_attribs=False* and tries to collect 

79 `attrs.fields`\ s. 

80 

81 For now, please refer to `attr.s` for the rest of the parameters. 

82 

83 .. versionadded:: 20.1.0 

84 .. versionchanged:: 21.3.0 Converters are also run ``on_setattr``. 

85 .. versionadded:: 22.2.0 

86 *unsafe_hash* as an alias for *hash* (for :pep:`681` compliance). 

87 """ 

88 

89 def do_it(cls, auto_attribs): 

90 return attrs( 

91 maybe_cls=cls, 

92 these=these, 

93 repr=repr, 

94 hash=hash, 

95 unsafe_hash=unsafe_hash, 

96 init=init, 

97 slots=slots, 

98 frozen=frozen, 

99 weakref_slot=weakref_slot, 

100 str=str, 

101 auto_attribs=auto_attribs, 

102 kw_only=kw_only, 

103 cache_hash=cache_hash, 

104 auto_exc=auto_exc, 

105 eq=eq, 

106 order=order, 

107 auto_detect=auto_detect, 

108 collect_by_mro=True, 

109 getstate_setstate=getstate_setstate, 

110 on_setattr=on_setattr, 

111 field_transformer=field_transformer, 

112 match_args=match_args, 

113 ) 

114 

115 def wrap(cls): 

116 """ 

117 Making this a wrapper ensures this code runs during class creation. 

118 

119 We also ensure that frozen-ness of classes is inherited. 

120 """ 

121 nonlocal frozen, on_setattr 

122 

123 had_on_setattr = on_setattr not in (None, setters.NO_OP) 

124 

125 # By default, mutable classes convert & validate on setattr. 

126 if frozen is False and on_setattr is None: 

127 on_setattr = _ng_default_on_setattr 

128 

129 # However, if we subclass a frozen class, we inherit the immutability 

130 # and disable on_setattr. 

131 for base_cls in cls.__bases__: 

132 if base_cls.__setattr__ is _frozen_setattrs: 

133 if had_on_setattr: 

134 msg = "Frozen classes can't use on_setattr (frozen-ness was inherited)." 

135 raise ValueError(msg) 

136 

137 on_setattr = setters.NO_OP 

138 break 

139 

140 if auto_attribs is not None: 

141 return do_it(cls, auto_attribs) 

142 

143 try: 

144 return do_it(cls, True) 

145 except UnannotatedAttributeError: 

146 return do_it(cls, False) 

147 

148 # maybe_cls's type depends on the usage of the decorator. It's a class 

149 # if it's used as `@attrs` but ``None`` if used as `@attrs()`. 

150 if maybe_cls is None: 

151 return wrap 

152 

153 return wrap(maybe_cls) 

154 

155 

156mutable = define 

157frozen = partial(define, frozen=True, on_setattr=None) 

158 

159 

160def field( 

161 *, 

162 default=NOTHING, 

163 validator=None, 

164 repr=True, 

165 hash=None, 

166 init=True, 

167 metadata=None, 

168 type=None, 

169 converter=None, 

170 factory=None, 

171 kw_only=False, 

172 eq=None, 

173 order=None, 

174 on_setattr=None, 

175 alias=None, 

176): 

177 """ 

178 Identical to `attr.ib`, except keyword-only and with some arguments 

179 removed. 

180 

181 .. versionadded:: 23.1.0 

182 The *type* parameter has been re-added; mostly for `attrs.make_class`. 

183 Please note that type checkers ignore this metadata. 

184 .. versionadded:: 20.1.0 

185 """ 

186 return attrib( 

187 default=default, 

188 validator=validator, 

189 repr=repr, 

190 hash=hash, 

191 init=init, 

192 metadata=metadata, 

193 type=type, 

194 converter=converter, 

195 factory=factory, 

196 kw_only=kw_only, 

197 eq=eq, 

198 order=order, 

199 on_setattr=on_setattr, 

200 alias=alias, 

201 ) 

202 

203 

204def asdict(inst, *, recurse=True, filter=None, value_serializer=None): 

205 """ 

206 Same as `attr.asdict`, except that collections types are always retained 

207 and dict is always used as *dict_factory*. 

208 

209 .. versionadded:: 21.3.0 

210 """ 

211 return _asdict( 

212 inst=inst, 

213 recurse=recurse, 

214 filter=filter, 

215 value_serializer=value_serializer, 

216 retain_collection_types=True, 

217 ) 

218 

219 

220def astuple(inst, *, recurse=True, filter=None): 

221 """ 

222 Same as `attr.astuple`, except that collections types are always retained 

223 and `tuple` is always used as the *tuple_factory*. 

224 

225 .. versionadded:: 21.3.0 

226 """ 

227 return _astuple( 

228 inst=inst, recurse=recurse, filter=filter, retain_collection_types=True 

229 )