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

37 statements  

« prev     ^ index     » next       coverage.py v7.3.2, created at 2023-12-08 06:51 +0000

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 - If *frozen* is `False`, run converters and validators when setting an 

56 attribute by default. 

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 suprising 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 raise ValueError( 

135 "Frozen classes can't use on_setattr " 

136 "(frozen-ness was inherited)." 

137 ) 

138 

139 on_setattr = setters.NO_OP 

140 break 

141 

142 if auto_attribs is not None: 

143 return do_it(cls, auto_attribs) 

144 

145 try: 

146 return do_it(cls, True) 

147 except UnannotatedAttributeError: 

148 return do_it(cls, False) 

149 

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

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

152 if maybe_cls is None: 

153 return wrap 

154 else: 

155 return wrap(maybe_cls) 

156 

157 

158mutable = define 

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

160 

161 

162def field( 

163 *, 

164 default=NOTHING, 

165 validator=None, 

166 repr=True, 

167 hash=None, 

168 init=True, 

169 metadata=None, 

170 type=None, 

171 converter=None, 

172 factory=None, 

173 kw_only=False, 

174 eq=None, 

175 order=None, 

176 on_setattr=None, 

177 alias=None, 

178): 

179 """ 

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

181 removed. 

182 

183 .. versionadded:: 23.1.0 

184 The *type* parameter has been re-added; mostly for 

185 {func}`attrs.make_class`. Please note that type checkers ignore this 

186 metadata. 

187 .. versionadded:: 20.1.0 

188 """ 

189 return attrib( 

190 default=default, 

191 validator=validator, 

192 repr=repr, 

193 hash=hash, 

194 init=init, 

195 metadata=metadata, 

196 type=type, 

197 converter=converter, 

198 factory=factory, 

199 kw_only=kw_only, 

200 eq=eq, 

201 order=order, 

202 on_setattr=on_setattr, 

203 alias=alias, 

204 ) 

205 

206 

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

208 """ 

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

210 and dict is always used as *dict_factory*. 

211 

212 .. versionadded:: 21.3.0 

213 """ 

214 return _asdict( 

215 inst=inst, 

216 recurse=recurse, 

217 filter=filter, 

218 value_serializer=value_serializer, 

219 retain_collection_types=True, 

220 ) 

221 

222 

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

224 """ 

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

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

227 

228 .. versionadded:: 21.3.0 

229 """ 

230 return _astuple( 

231 inst=inst, recurse=recurse, filter=filter, retain_collection_types=True 

232 )