|
5 | 5 | import types
|
6 | 6 | from inspect import isclass
|
7 | 7 | from dataclasses import dataclass
|
8 |
| -from typing_extensions import TypedDict |
9 | 8 | from .parsers.json import JSONContent
|
10 |
| -from .converters import parse_basic, parse_type |
| 9 | +from .converters import encoders, parse_basic, parse_type |
11 | 10 | from .fields import Field
|
12 | 11 | from .functions import (
|
13 | 12 | is_dataclass,
|
@@ -79,11 +78,11 @@ def _dc_method_setattr_(
|
79 | 78 | if field_category == 'primitive':
|
80 | 79 | new_val = parse_basic(_type, value, _encoder)
|
81 | 80 | elif field_category == 'typing':
|
82 |
| - new_val = parse_type(_type, value, _encoder, field_category) |
| 81 | + new_val = parse_type(field_obj, _type, value, _encoder) |
83 | 82 | elif field_category in ('dataclass', 'class', ):
|
84 | 83 | new_val = value
|
85 | 84 | else:
|
86 |
| - new_val = parse_type(_type, value, _encoder, field_category) |
| 85 | + new_val = parse_type(field_obj, _type, value, _encoder) |
87 | 86 | # Assign the new value to the field
|
88 | 87 | value = new_val
|
89 | 88 | except Exception as e:
|
@@ -179,29 +178,54 @@ def _initialize_fields(attrs, annotations, strict):
|
179 | 178 | df = Field(required=False, type=_type, default=df)
|
180 | 179 | df.name = field
|
181 | 180 | df.type = _type
|
182 |
| - cols[field] = df |
| 181 | + df._encoder_fn = encoders.get(_type, None) |
| 182 | + |
| 183 | + # Cache reflection info so we DON’T need to call |
| 184 | + # get_origin/get_args repeatedly: |
| 185 | + origin = get_origin(_type) |
| 186 | + args = get_args(_type) |
| 187 | + _default = df.default |
| 188 | + _is_dc = is_dataclass(_type) |
| 189 | + _is_prim = is_primitive(_type) |
| 190 | + _is_typing = hasattr(_type, '__module__') and _type.__module__ == 'typing' |
| 191 | + |
| 192 | + # Store the type info in the field object: |
| 193 | + df.is_dc = _is_dc |
| 194 | + df.is_primitive = _is_prim |
| 195 | + df.is_typing = _is_typing |
| 196 | + df.origin = origin |
| 197 | + df.args = args |
| 198 | + df.type_args = getattr(_type, '__args__', None) |
| 199 | + |
| 200 | + df._typeinfo_ = { |
| 201 | + "default_callable": callable(_default) |
| 202 | + } |
| 203 | + |
183 | 204 | # check type of field:
|
184 |
| - if is_primitive(_type): |
185 |
| - _types_local[field] = 'primitive' |
186 |
| - elif is_dataclass(_type): |
187 |
| - _types_local[field] = 'dataclass' |
188 |
| - elif hasattr(_type, '__module__') and _type.__module__ == 'typing': # noqa |
189 |
| - _types_local[field] = 'typing' |
| 205 | + if _is_prim: |
| 206 | + _type_category = 'primitive' |
| 207 | + elif _is_dc: |
| 208 | + _type_category = 'dataclass' |
| 209 | + elif _is_typing: # noqa |
| 210 | + _type_category = 'typing' |
190 | 211 | elif isclass(_type):
|
191 |
| - _types_local[field] = 'class' |
| 212 | + _type_category = 'class' |
192 | 213 | else:
|
193 |
| - _types_local[field] = 'complex' |
| 214 | + _type_category = 'complex' |
| 215 | + _types_local[field] = _type_category |
| 216 | + df._type_category = _type_category |
194 | 217 |
|
195 | 218 | # Store them in a dict keyed by field name:
|
196 |
| - origin = get_origin(_type) |
197 |
| - args = get_args(_type) |
198 | 219 | _typing_args[field] = (origin, args)
|
199 | 220 | # Assign the field object to the attrs so dataclass can pick it up
|
200 | 221 | attrs[field] = df
|
| 222 | + cols[field] = df |
201 | 223 | return cols, _types_local, _typing_args, aliases
|
202 | 224 |
|
203 | 225 | # Initialize the fields
|
204 |
| - cols, _types, _typing_args, aliases = _initialize_fields(attrs, annotations, strict) |
| 226 | + cols, _types, _typing_args, aliases = _initialize_fields( |
| 227 | + attrs, annotations, strict |
| 228 | + ) |
205 | 229 | else:
|
206 | 230 | # if no __annotations__, cols is empty:
|
207 | 231 | cols = OrderedDict()
|
@@ -270,6 +294,7 @@ def _initialize_fields(attrs, annotations, strict):
|
270 | 294 | dc.__initialised__ = False
|
271 | 295 | dc.__field_types__ = _types
|
272 | 296 | dc.__aliases__ = aliases
|
| 297 | + dc.__typing_args__ = _typing_args |
273 | 298 | dc.modelName = dc.__name__
|
274 | 299 |
|
275 | 300 | # Override __setattr__ method
|
|
0 commit comments