Skip to content

Commit c493ab6

Browse files
Merge pull request #227 from phenobarbital/changes_typing
Changes on typing
2 parents ea0d381 + 14977cd commit c493ab6

14 files changed

+866
-219
lines changed

datamodel/abstract.py

Lines changed: 41 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,8 @@
55
import types
66
from inspect import isclass
77
from dataclasses import dataclass
8-
from typing_extensions import TypedDict
98
from .parsers.json import JSONContent
10-
from .converters import parse_basic, parse_type
9+
from .converters import encoders, parse_basic, parse_type
1110
from .fields import Field
1211
from .functions import (
1312
is_dataclass,
@@ -79,11 +78,11 @@ def _dc_method_setattr_(
7978
if field_category == 'primitive':
8079
new_val = parse_basic(_type, value, _encoder)
8180
elif field_category == 'typing':
82-
new_val = parse_type(_type, value, _encoder, field_category)
81+
new_val = parse_type(field_obj, _type, value, _encoder)
8382
elif field_category in ('dataclass', 'class', ):
8483
new_val = value
8584
else:
86-
new_val = parse_type(_type, value, _encoder, field_category)
85+
new_val = parse_type(field_obj, _type, value, _encoder)
8786
# Assign the new value to the field
8887
value = new_val
8988
except Exception as e:
@@ -179,29 +178,54 @@ def _initialize_fields(attrs, annotations, strict):
179178
df = Field(required=False, type=_type, default=df)
180179
df.name = field
181180
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+
183204
# 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'
190211
elif isclass(_type):
191-
_types_local[field] = 'class'
212+
_type_category = 'class'
192213
else:
193-
_types_local[field] = 'complex'
214+
_type_category = 'complex'
215+
_types_local[field] = _type_category
216+
df._type_category = _type_category
194217

195218
# Store them in a dict keyed by field name:
196-
origin = get_origin(_type)
197-
args = get_args(_type)
198219
_typing_args[field] = (origin, args)
199220
# Assign the field object to the attrs so dataclass can pick it up
200221
attrs[field] = df
222+
cols[field] = df
201223
return cols, _types_local, _typing_args, aliases
202224

203225
# 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+
)
205229
else:
206230
# if no __annotations__, cols is empty:
207231
cols = OrderedDict()
@@ -270,6 +294,7 @@ def _initialize_fields(attrs, annotations, strict):
270294
dc.__initialised__ = False
271295
dc.__field_types__ = _types
272296
dc.__aliases__ = aliases
297+
dc.__typing_args__ = _typing_args
273298
dc.modelName = dc.__name__
274299

275300
# Override __setattr__ method

0 commit comments

Comments
 (0)