omlish 0.0.0.dev284__py3-none-any.whl → 0.0.0.dev286__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (107) hide show
  1. omlish/__about__.py +6 -2
  2. omlish/dataclasses/__init__.py +58 -60
  3. omlish/dataclasses/api/__init__.py +25 -0
  4. omlish/dataclasses/api/classes/__init__.py +0 -0
  5. omlish/dataclasses/api/classes/conversion.py +30 -0
  6. omlish/dataclasses/api/classes/decorator.py +145 -0
  7. omlish/dataclasses/api/classes/make.py +109 -0
  8. omlish/dataclasses/api/classes/metadata.py +133 -0
  9. omlish/dataclasses/api/classes/params.py +78 -0
  10. omlish/dataclasses/api/fields/__init__.py +0 -0
  11. omlish/dataclasses/api/fields/building.py +120 -0
  12. omlish/dataclasses/api/fields/constructor.py +56 -0
  13. omlish/dataclasses/api/fields/conversion.py +191 -0
  14. omlish/dataclasses/api/fields/metadata.py +94 -0
  15. omlish/dataclasses/concerns/__init__.py +17 -0
  16. omlish/dataclasses/concerns/abc.py +15 -0
  17. omlish/dataclasses/concerns/copy.py +63 -0
  18. omlish/dataclasses/concerns/doc.py +53 -0
  19. omlish/dataclasses/concerns/eq.py +60 -0
  20. omlish/dataclasses/concerns/fields.py +119 -0
  21. omlish/dataclasses/concerns/frozen.py +133 -0
  22. omlish/dataclasses/concerns/hash.py +165 -0
  23. omlish/dataclasses/concerns/init.py +453 -0
  24. omlish/dataclasses/concerns/matchargs.py +27 -0
  25. omlish/dataclasses/concerns/mro.py +16 -0
  26. omlish/dataclasses/concerns/order.py +87 -0
  27. omlish/dataclasses/concerns/override.py +98 -0
  28. omlish/dataclasses/concerns/params.py +14 -0
  29. omlish/dataclasses/concerns/replace.py +48 -0
  30. omlish/dataclasses/concerns/repr.py +95 -0
  31. omlish/dataclasses/{impl → concerns}/slots.py +25 -1
  32. omlish/dataclasses/debug.py +2 -0
  33. omlish/dataclasses/errors.py +115 -0
  34. omlish/dataclasses/generation/__init__.py +0 -0
  35. omlish/dataclasses/generation/base.py +38 -0
  36. omlish/dataclasses/generation/compilation.py +258 -0
  37. omlish/dataclasses/generation/execution.py +195 -0
  38. omlish/dataclasses/generation/globals.py +83 -0
  39. omlish/dataclasses/generation/idents.py +6 -0
  40. omlish/dataclasses/generation/mangling.py +18 -0
  41. omlish/dataclasses/generation/manifests.py +20 -0
  42. omlish/dataclasses/generation/ops.py +97 -0
  43. omlish/dataclasses/generation/plans.py +35 -0
  44. omlish/dataclasses/generation/processor.py +179 -0
  45. omlish/dataclasses/generation/registry.py +42 -0
  46. omlish/dataclasses/generation/utils.py +83 -0
  47. omlish/dataclasses/{impl/reflect.py → inspect.py} +53 -90
  48. omlish/dataclasses/{impl/internals.py → internals.py} +26 -32
  49. omlish/dataclasses/metaclass/__init__.py +0 -0
  50. omlish/dataclasses/metaclass/bases.py +69 -0
  51. omlish/dataclasses/metaclass/confer.py +65 -0
  52. omlish/dataclasses/metaclass/meta.py +115 -0
  53. omlish/dataclasses/metaclass/specs.py +38 -0
  54. omlish/dataclasses/processing/__init__.py +0 -0
  55. omlish/dataclasses/processing/base.py +83 -0
  56. omlish/dataclasses/processing/driving.py +49 -0
  57. omlish/dataclasses/processing/priority.py +13 -0
  58. omlish/dataclasses/processing/registry.py +81 -0
  59. omlish/dataclasses/reflection.py +81 -0
  60. omlish/dataclasses/specs.py +224 -0
  61. omlish/dataclasses/tools/__init__.py +0 -0
  62. omlish/dataclasses/{impl → tools}/as_.py +23 -8
  63. omlish/dataclasses/tools/iter.py +27 -0
  64. omlish/dataclasses/tools/modifiers.py +52 -0
  65. omlish/dataclasses/tools/replace.py +17 -0
  66. omlish/dataclasses/tools/repr.py +12 -0
  67. omlish/dataclasses/{static.py → tools/static.py} +25 -4
  68. omlish/dataclasses/utils.py +54 -109
  69. omlish/diag/__init__.py +4 -4
  70. omlish/inject/impl/origins.py +1 -1
  71. omlish/lang/cached/function.py +4 -2
  72. omlish/lang/maybes.py +17 -0
  73. omlish/lite/maybes.py +17 -0
  74. omlish/marshal/objects/dataclasses.py +3 -7
  75. omlish/marshal/objects/helpers.py +3 -3
  76. omlish/secrets/marshal.py +1 -1
  77. omlish/secrets/secrets.py +1 -1
  78. omlish/sql/queries/base.py +1 -1
  79. omlish/text/minja.py +81 -25
  80. omlish/text/templating.py +116 -0
  81. omlish/typedvalues/marshal.py +2 -2
  82. {omlish-0.0.0.dev284.dist-info → omlish-0.0.0.dev286.dist-info}/METADATA +4 -1
  83. {omlish-0.0.0.dev284.dist-info → omlish-0.0.0.dev286.dist-info}/RECORD +87 -46
  84. omlish/dataclasses/impl/LICENSE +0 -279
  85. omlish/dataclasses/impl/__init__.py +0 -33
  86. omlish/dataclasses/impl/api.py +0 -278
  87. omlish/dataclasses/impl/copy.py +0 -30
  88. omlish/dataclasses/impl/errors.py +0 -53
  89. omlish/dataclasses/impl/fields.py +0 -245
  90. omlish/dataclasses/impl/frozen.py +0 -93
  91. omlish/dataclasses/impl/hashing.py +0 -86
  92. omlish/dataclasses/impl/init.py +0 -199
  93. omlish/dataclasses/impl/main.py +0 -93
  94. omlish/dataclasses/impl/metaclass.py +0 -235
  95. omlish/dataclasses/impl/metadata.py +0 -75
  96. omlish/dataclasses/impl/order.py +0 -57
  97. omlish/dataclasses/impl/overrides.py +0 -53
  98. omlish/dataclasses/impl/params.py +0 -128
  99. omlish/dataclasses/impl/processing.py +0 -24
  100. omlish/dataclasses/impl/replace.py +0 -40
  101. omlish/dataclasses/impl/repr.py +0 -66
  102. omlish/dataclasses/impl/simple.py +0 -50
  103. omlish/dataclasses/impl/utils.py +0 -167
  104. {omlish-0.0.0.dev284.dist-info → omlish-0.0.0.dev286.dist-info}/WHEEL +0 -0
  105. {omlish-0.0.0.dev284.dist-info → omlish-0.0.0.dev286.dist-info}/entry_points.txt +0 -0
  106. {omlish-0.0.0.dev284.dist-info → omlish-0.0.0.dev286.dist-info}/licenses/LICENSE +0 -0
  107. {omlish-0.0.0.dev284.dist-info → omlish-0.0.0.dev286.dist-info}/top_level.txt +0 -0
@@ -1,33 +0,0 @@
1
- """
2
- TODO:
3
- - metaclass:
4
- - cleanup confer
5
- - descriptors - check_type/validators don't handle setters lol
6
- - deep_frozen?
7
- - field:
8
- - frozen
9
- - pickle/transient
10
- - mangled
11
- - doc
12
- - derive
13
- - check_type
14
- - class
15
- - strict_eq
16
- - allow_setattr
17
- - mangler
18
- - observable
19
- - c/py gen
20
- - iterable
21
- - proto/jsonschema gen
22
- - enums
23
- - nodal
24
- - embedding? forward kwargs in general? or only for replace?
25
-
26
- TODO refs:
27
- - batch up exec calls
28
- - https://github.com/python/cpython/commit/8945b7ff55b87d11c747af2dad0e3e4d631e62d6
29
- - add doc parameter to dataclasses.field
30
- - https://github.com/python/cpython/commit/9c7657f09914254724683d91177aed7947637be5
31
- - add decorator argument to make_dataclass
32
- - https://github.com/python/cpython/commit/3e3a4d231518f91ff2f3c5a085b3849e32f1d548
33
- """
@@ -1,278 +0,0 @@
1
- """
2
- TODO:
3
- - fix code redundancy
4
- """
5
- import collections.abc
6
- import contextlib
7
- import dataclasses as dc
8
- import keyword
9
- import sys
10
- import types
11
- import typing as ta
12
-
13
- from ... import check as check_
14
- from ... import lang
15
- from .internals import PARAMS_ATTR
16
- from .internals import Params
17
- from .main import process_class
18
- from .metadata import METADATA_ATTR
19
- from .metadata import Metadata
20
- from .params import FieldExtras
21
- from .params import ParamsExtras
22
-
23
-
24
- MISSING = dc.MISSING
25
-
26
-
27
- def field( # noqa
28
- default=MISSING,
29
- *,
30
- default_factory=MISSING,
31
- init=True,
32
- repr=True, # noqa
33
- hash=None, # noqa
34
- compare=True,
35
- metadata=None,
36
- kw_only=MISSING,
37
-
38
- derive: ta.Callable[..., ta.Any] | None = None,
39
- coerce: bool | ta.Callable[[ta.Any], ta.Any] | None = None,
40
- validate: ta.Callable[[ta.Any], bool] | None = None,
41
- check_type: bool | type | tuple[type | None, ...] | None = None,
42
- override: bool = False,
43
- repr_fn: ta.Callable[[ta.Any], str | None] | None = None,
44
- repr_priority: int | None = None,
45
- frozen: bool | None = None,
46
- ): # -> dc.Field
47
- if default is not MISSING and default_factory is not MISSING:
48
- raise ValueError('cannot specify both default and default_factory')
49
-
50
- fx = FieldExtras()
51
- if metadata is not None:
52
- fx = metadata.get(FieldExtras, fx)
53
-
54
- fx = dc.replace(fx, **lang.opt_kw(
55
- derive=derive,
56
- coerce=coerce,
57
- validate=validate,
58
- check_type=check_type,
59
- override=override,
60
- repr_fn=repr_fn,
61
- repr_priority=repr_priority,
62
- frozen=frozen,
63
- ))
64
-
65
- md: ta.Mapping = {FieldExtras: fx}
66
- if metadata is not None:
67
- md = collections.ChainMap(md, check_.isinstance(metadata, collections.abc.Mapping)) # type: ignore
68
-
69
- return dc.Field(
70
- default,
71
- default_factory, # noqa
72
- init,
73
- repr,
74
- hash,
75
- compare,
76
- types.MappingProxyType(md),
77
- kw_only, # noqa
78
- )
79
-
80
-
81
- def _strip_missing_values(d):
82
- return {k: v for k, v in d.items() if v is not MISSING}
83
-
84
-
85
- def dataclass( # noqa
86
- cls=None,
87
- /,
88
- *,
89
- init=True,
90
- repr=True, # noqa
91
- eq=True,
92
- order=False,
93
- unsafe_hash=False,
94
- frozen=False,
95
- match_args=True,
96
- kw_only=False,
97
- slots=False,
98
- weakref_slot=False,
99
-
100
- metadata=None,
101
-
102
- reorder=MISSING,
103
- cache_hash=MISSING,
104
- generic_init=MISSING,
105
- override=MISSING,
106
- repr_id=MISSING,
107
- ):
108
- def wrap(cls):
109
- pkw = dict(
110
- init=init,
111
- repr=repr,
112
- eq=eq,
113
- order=order,
114
- unsafe_hash=unsafe_hash,
115
- frozen=frozen,
116
- match_args=match_args,
117
- kw_only=kw_only,
118
- slots=slots,
119
- weakref_slot=weakref_slot,
120
- )
121
-
122
- dmd = cls.__dict__.get(METADATA_ATTR)
123
-
124
- epk = dict(dmd.get(_ExtraParamsKwargs, ()) if dmd is not None else ())
125
- epk.update(_strip_missing_values(dict(
126
- reorder=reorder,
127
- cache_hash=cache_hash,
128
- generic_init=generic_init,
129
- override=override,
130
- repr_id=repr_id,
131
- )))
132
- pex = ParamsExtras(**epk)
133
-
134
- mmd: dict = {
135
- ParamsExtras: pex,
136
- }
137
-
138
- md: Metadata = mmd
139
- cmds = []
140
- if metadata is not None:
141
- cmds.append(check_.isinstance(metadata, collections.abc.Mapping))
142
- if dmd is not None:
143
- cmds.append(dmd)
144
- if cmds:
145
- md = collections.ChainMap(md, *cmds) # type: ignore
146
-
147
- setattr(cls, PARAMS_ATTR, Params(**pkw))
148
- setattr(cls, METADATA_ATTR, types.MappingProxyType(md))
149
-
150
- return process_class(cls)
151
-
152
- if cls is None:
153
- return wrap
154
-
155
- return wrap(cls)
156
-
157
-
158
- def make_dataclass( # noqa
159
- cls_name,
160
- fields,
161
- *,
162
- bases=(),
163
- namespace=None,
164
- init=True,
165
- repr=True, # noqa
166
- eq=True,
167
- order=False,
168
- unsafe_hash=False,
169
- frozen=False,
170
- match_args=True,
171
- kw_only=False,
172
- slots=False,
173
- weakref_slot=False,
174
- module=None,
175
-
176
- reorder=MISSING,
177
- cache_hash=MISSING,
178
- generic_init=MISSING,
179
- override=MISSING,
180
- repr_id=MISSING,
181
- ):
182
- if namespace is None:
183
- namespace = {}
184
-
185
- seen = set()
186
- annotations = {}
187
- defaults = {}
188
- for item in fields:
189
- if isinstance(item, str):
190
- name = item
191
- tp = 'typing.Any'
192
- elif len(item) == 2:
193
- name, tp, = item
194
- elif len(item) == 3:
195
- name, tp, spec = item
196
- defaults[name] = spec
197
- else:
198
- raise TypeError(f'Invalid field: {item!r}')
199
- if not isinstance(name, str) or not name.isidentifier():
200
- raise TypeError(f'Field names must be valid identifiers: {name!r}')
201
- if keyword.iskeyword(name):
202
- raise TypeError(f'Field names must not be keywords: {name!r}')
203
- if name in seen:
204
- raise TypeError(f'Field name duplicated: {name!r}')
205
-
206
- seen.add(name)
207
- annotations[name] = tp
208
-
209
- def exec_body_callback(ns):
210
- ns.update(namespace)
211
- ns.update(defaults)
212
- ns['__annotations__'] = annotations
213
-
214
- cls = types.new_class(cls_name, bases, {}, exec_body_callback)
215
-
216
- if module is None:
217
- try:
218
- module = sys._getframemodulename(1) or '__main__' # type: ignore # noqa
219
- except AttributeError:
220
- with contextlib.suppress(AttributeError, ValueError):
221
- module = sys._getframe(1).f_globals.get('__name__', '__main__') # noqa
222
- if module is not None:
223
- cls.__module__ = module
224
-
225
- return dataclass(
226
- cls,
227
- init=init,
228
- repr=repr,
229
- eq=eq,
230
- order=order,
231
- unsafe_hash=unsafe_hash,
232
- frozen=frozen,
233
- match_args=match_args,
234
- kw_only=kw_only,
235
- slots=slots,
236
- weakref_slot=weakref_slot,
237
-
238
- reorder=reorder,
239
- cache_hash=cache_hash,
240
- generic_init=generic_init,
241
- override=override,
242
- repr_id=repr_id,
243
- )
244
-
245
-
246
- class _ExtraParamsKwargs:
247
- pass
248
-
249
-
250
- def extra_class_params( # noqa
251
- *,
252
- reorder=MISSING,
253
- cache_hash=MISSING,
254
- generic_init=MISSING,
255
- override=MISSING,
256
- repr_id=MISSING,
257
- ):
258
- def inner(cls):
259
- if PARAMS_ATTR in cls.__dict__:
260
- raise TypeError(cls)
261
- try:
262
- md = cls.__dict__[METADATA_ATTR]
263
- except KeyError:
264
- md = {}
265
- setattr(cls, METADATA_ATTR, md)
266
- if _ExtraParamsKwargs in md:
267
- raise TypeError(cls)
268
-
269
- md[_ExtraParamsKwargs] = _strip_missing_values(dict(
270
- reorder=reorder,
271
- cache_hash=cache_hash,
272
- generic_init=generic_init,
273
- override=override,
274
- repr_id=repr_id,
275
- ))
276
-
277
- return cls
278
- return inner
@@ -1,30 +0,0 @@
1
- """
2
- TODO:
3
- - __deepcopy__
4
- """
5
- import dataclasses as dc
6
-
7
- from .fields import field_type
8
- from .internals import FIELDS_ATTR
9
- from .internals import FieldType
10
- from .processing import Processor
11
- from .utils import set_new_attribute
12
-
13
-
14
- MISSING = dc.MISSING
15
-
16
-
17
- def _copy(obj):
18
- kw = {}
19
-
20
- for f in getattr(obj, FIELDS_ATTR).values():
21
- if field_type(f) is FieldType.CLASS:
22
- continue
23
- kw[f.name] = getattr(obj, f.name)
24
-
25
- return obj.__class__(**kw)
26
-
27
-
28
- class CopyProcessor(Processor):
29
- def _process(self) -> None:
30
- set_new_attribute(self._cls, '__copy__', _copy)
@@ -1,53 +0,0 @@
1
- import types
2
- import typing as ta
3
-
4
-
5
- ##
6
-
7
-
8
- class ValidationError(Exception):
9
- pass
10
-
11
-
12
- def _hands_off_repr(obj: ta.Any) -> str:
13
- return f'{obj.__class__.__qualname__}@{hex(id(obj))[2:]}'
14
-
15
-
16
- def _fn_repr(fn: ta.Callable) -> str:
17
- if (co := getattr(fn, '__code__', None)) is None or not isinstance(co, types.CodeType):
18
- return repr(fn)
19
-
20
- if not (co_filename := co.co_filename):
21
- return repr(fn)
22
-
23
- return f'{fn!r} ({co_filename}:{co.co_firstlineno})'
24
-
25
-
26
- class FieldValidationError(ValidationError):
27
- def __init__(
28
- self,
29
- obj: ta.Any,
30
- field: str,
31
- fn: ta.Callable,
32
- value: ta.Any,
33
- ) -> None:
34
- super().__init__(
35
- f'{self.__class__.__name__} '
36
- f'for field {field!r} '
37
- f'on object {_hands_off_repr(obj)} '
38
- f'in validator {_fn_repr(fn)} '
39
- f'with value {value!r}',
40
- )
41
-
42
- self.obj = obj
43
- self.field = field
44
- self.fn = fn
45
- self.value = value
46
-
47
- def __repr__(self) -> str:
48
- return f'{self.__class__.__name__}({", ".join([
49
- f"obj={_hands_off_repr(self.obj)}",
50
- f"field={self.field!r}",
51
- f"fn={_fn_repr(self.fn)}",
52
- f"value={self.value!r}",
53
- ])})'
@@ -1,245 +0,0 @@
1
- """
2
- TODO:
3
- - point validate / check exceptions to lambdas
4
- """
5
- import dataclasses as dc
6
- import types
7
- import typing as ta
8
-
9
- from ... import check as check_
10
- from ... import lang
11
- from .errors import FieldValidationError
12
- from .internals import FIELDS_ATTR
13
- from .internals import FieldType
14
- from .internals import is_classvar
15
- from .internals import is_initvar
16
- from .internals import is_kw_only
17
- from .params import get_field_extras
18
- from .processing import Processor
19
-
20
-
21
- if ta.TYPE_CHECKING:
22
- from . import api
23
- else:
24
- api = lang.proxy_import('.api', __package__)
25
-
26
-
27
- MISSING = dc.MISSING
28
-
29
-
30
- ##
31
-
32
-
33
- def raise_field_validation_error(
34
- obj: ta.Any,
35
- field: str,
36
- fn: ta.Callable,
37
- value: ta.Any,
38
- ) -> ta.NoReturn:
39
- raise FieldValidationError(
40
- obj,
41
- field,
42
- fn,
43
- value,
44
- )
45
-
46
-
47
- ##
48
-
49
-
50
- def field_type(f: dc.Field) -> FieldType:
51
- if (ft := getattr(f, '_field_type')) is not None:
52
- return FieldType(ft)
53
- else:
54
- return FieldType.INSTANCE
55
-
56
-
57
- def has_default(f: dc.Field) -> bool:
58
- return not (f.default is MISSING and f.default_factory is MISSING)
59
-
60
-
61
- ##
62
-
63
-
64
- class FieldsProcessor(Processor):
65
- def _process(self) -> None:
66
- cls = self._info.cls
67
- fields: dict[str, dc.Field] = {}
68
-
69
- for b in cls.__mro__[-1:0:-1]:
70
- base_fields = getattr(b, FIELDS_ATTR, None)
71
- if base_fields is not None:
72
- for f in base_fields.values():
73
- fields[f.name] = f
74
-
75
- cls_fields: list[dc.Field] = []
76
-
77
- kw_only = self._info.params.kw_only
78
- kw_only_seen = False
79
- for name, ann in self._info.cls_annotations.items():
80
- if is_kw_only(cls, ann):
81
- if kw_only_seen:
82
- raise TypeError(f'{name!r} is KW_ONLY, but KW_ONLY has already been specified')
83
- kw_only_seen = True
84
- kw_only = True
85
- else:
86
- cls_fields.append(preprocess_field(cls, name, ann, kw_only))
87
-
88
- for f in cls_fields:
89
- fields[f.name] = f
90
- if isinstance(getattr(cls, f.name, None), dc.Field):
91
- if f.default is MISSING:
92
- delattr(cls, f.name)
93
- else:
94
- setattr(cls, f.name, f.default)
95
-
96
- for name, value in cls.__dict__.items():
97
- if isinstance(value, dc.Field) and name not in self._info.cls_annotations:
98
- raise TypeError(f'{name!r} is a field but has no type annotation')
99
-
100
- setattr(cls, FIELDS_ATTR, fields)
101
-
102
-
103
- ##
104
-
105
-
106
- def preprocess_field(
107
- cls: type,
108
- a_name: str,
109
- a_type: ta.Any,
110
- default_kw_only: bool,
111
- ) -> dc.Field:
112
- default = getattr(cls, a_name, MISSING)
113
- if isinstance(default, dc.Field):
114
- f = default
115
- else:
116
- if isinstance(default, types.MemberDescriptorType):
117
- # This is a field in __slots__, so it has no default value.
118
- default = MISSING
119
- f = api.field(default=default)
120
-
121
- f.name = a_name
122
- f.type = a_type
123
-
124
- ft = FieldType.INSTANCE
125
- if is_classvar(cls, f.type):
126
- ft = FieldType.CLASS
127
- if is_initvar(cls, f.type):
128
- ft = FieldType.INIT
129
- if ft in (FieldType.CLASS, FieldType.INIT):
130
- if f.default_factory is not MISSING:
131
- raise TypeError(f'field {f.name} cannot have a default factory')
132
- f._field_type = ft.value # type: ignore # noqa
133
-
134
- if ft in (FieldType.INSTANCE, FieldType.INIT):
135
- if f.kw_only is MISSING:
136
- f.kw_only = default_kw_only
137
- else:
138
- check_.arg(ft is FieldType.CLASS)
139
- if f.kw_only is not MISSING:
140
- raise TypeError(f'field {f.name} is a ClassVar but specifies kw_only')
141
-
142
- if ft is FieldType.INSTANCE and f.default is not MISSING and f.default.__class__.__hash__ is None:
143
- raise ValueError(f'mutable default {type(f.default)} for field {f.name} is not allowed: use default_factory')
144
-
145
- return f
146
-
147
-
148
- def field_assign(
149
- frozen: bool,
150
- name: str,
151
- value: ta.Any,
152
- self_name: str,
153
- override: bool,
154
- ) -> str:
155
- if override:
156
- return f'{self_name}.__dict__[{name!r}] = {value}'
157
- if frozen:
158
- return f'__dataclass_builtins_object__.__setattr__({self_name}, {name!r}, {value})'
159
- return f'{self_name}.{name} = {value}'
160
-
161
-
162
- def field_init(
163
- f: dc.Field,
164
- frozen: bool,
165
- locals: dict[str, ta.Any], # noqa
166
- self_name: str,
167
- slots: bool,
168
- cls_override: bool,
169
- ) -> ta.Sequence[str]:
170
- default_name = f'__dataclass_dflt_{f.name}__'
171
- fx = get_field_extras(f)
172
-
173
- lines = []
174
-
175
- value: str | None = None
176
- if f.default_factory is not MISSING:
177
- locals[default_name] = f.default_factory
178
- if f.init:
179
- lines.append(f'if {f.name} is __dataclass_HAS_DEFAULT_FACTORY__: {f.name} = {default_name}()')
180
- else:
181
- lines.append(f'{f.name} = {default_name}()')
182
- value = f.name
183
-
184
- elif f.init:
185
- if f.default is MISSING:
186
- value = f.name
187
- elif f.default is not MISSING:
188
- locals[default_name] = f.default # Not referenced her, just useful / consistent to have in function scope
189
- value = f.name
190
-
191
- elif slots and f.default is not MISSING:
192
- locals[default_name] = f.default
193
- lines.append(f'{f.name} = {default_name}')
194
- value = default_name
195
-
196
- else:
197
- pass
198
-
199
- if fx.derive is not None:
200
- raise NotImplementedError
201
-
202
- if fx.frozen:
203
- raise NotImplementedError
204
-
205
- if fx.coerce is not None:
206
- cn = f'__dataclass_coerce__{f.name}__'
207
- locals[cn] = fx.coerce
208
- lines.append(f'{value} = {cn}({value})')
209
-
210
- if fx.validate is not None:
211
- cn = f'__dataclass_validate__{f.name}__'
212
- locals[cn] = fx.validate
213
- lines.append(
214
- f'if not {cn}({value}): '
215
- f'__dataclass_raise_field_validation_error__({self_name}, {f.name!r}, {cn}, {value})',
216
- )
217
-
218
- if fx.check_type:
219
- cn = f'__dataclass_check_type__{f.name}__'
220
- ct: ta.Any
221
- if isinstance(fx.check_type, tuple):
222
- ct = tuple(type(None) if e is None else check_.isinstance(e, type) for e in fx.check_type)
223
- elif isinstance(fx.check_type, (type, tuple)):
224
- ct = fx.check_type
225
- # FIXME:
226
- # elif info.params_extras.generic_init:
227
- # ct = info.generic_replaced_field_annotations[f.name]
228
- else:
229
- ct = f.type
230
- locals[cn] = ct
231
- lines.append(
232
- f'if not __dataclass_builtins_isinstance__({value}, {cn}): '
233
- f'raise __dataclass_builtins_TypeError__({value}, {cn})',
234
- )
235
-
236
- if value is not None and field_type(f) is not FieldType.INIT:
237
- lines.append(field_assign(
238
- frozen,
239
- f.name,
240
- value,
241
- self_name,
242
- fx.override or cls_override,
243
- ))
244
-
245
- return lines