Skip to content

Commit

Permalink
Merge pull request #51 from phenobarbital/new-version
Browse files Browse the repository at this point in the history
fix error on validation with required and nullable fields
  • Loading branch information
phenobarbital authored Oct 25, 2022
2 parents 761dd55 + 70095e8 commit 7e2a388
Show file tree
Hide file tree
Showing 5 changed files with 25 additions and 24 deletions.
21 changes: 11 additions & 10 deletions datamodel/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ def _dc_method_setattr(
"This DataClass is frozen (read-only class)"
)
else:
value = None if callable(value) else value
object.__setattr__(self, name, value)
if name not in self.__fields__:
if self.Meta.strict is True:
Expand Down Expand Up @@ -111,7 +112,6 @@ def __new__(cls, name, bases, attrs, **kwargs):
if "__annotations__" in attrs:
annotations = attrs["__annotations__"]
for field, _type in annotations.items():
# print(f"Field: {field}, Type: {_type}")
if field in attrs:
df = attrs[field]
if isinstance(df, Field):
Expand All @@ -122,8 +122,9 @@ def __new__(cls, name, bases, attrs, **kwargs):
df.type = _type
setattr(cls, field, df)
else:
# print(f"HERE Field: {field}, Type: {_type}")
# add a new field, based on type
df = Field(factory=_type, required=False)
df = Field(factory=_type, required=False, default=None)
df.name = field
df.type = _type
setattr(cls, field, df)
Expand Down Expand Up @@ -267,8 +268,6 @@ def __post_init__(self) -> None:
else:
encoder = None
if hasattr(f, 'default') and self.is_callable(value):
print('CHECK ::: ', f, ':: VALUE ::', value, 'DEF::: ', f.default)
print('TYPE ', type(value))
continue
### Factory Value:
elif isinstance(f.type, types.MethodType):
Expand All @@ -292,11 +291,11 @@ def __post_init__(self) -> None:
new_val = parse_type(f.type, value, encoder)
setattr(self, key, new_val)
continue
except AttributeError as e:
except (ValueError, AttributeError, TypeError) as e:
raise TypeError(
f"DataModel: Wrong type for {key}: {f.type}, error: {e}"
f"DataModel: Wrong Type for {key}: {f.type}, error: {e}"
) from e
print(f'FIELD {key} = {value}', 'TYPE : ', f.type, type(f.type))
# print(f'FIELD {key} = {value}', 'TYPE : ', f.type, type(f.type), ' VALUE: ', value)
if isinstance(value, list):
try:
sub_type = f.type.__args__[0]
Expand All @@ -320,10 +319,12 @@ def __post_init__(self) -> None:
else:
try:
# be processed by _parse_type
new_val= parse_type(f.type, value, encoder)
new_val = parse_type(f.type, value, encoder)
setattr(self, key, new_val)
except (TypeError, ValueError):
pass
except (TypeError, ValueError) as ex:
raise ValueError(
f"Wrong Type for {key}: {f.type}, error: {ex}"
) from ex
continue
try:
self._validation()
Expand Down
14 changes: 7 additions & 7 deletions datamodel/converters.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,9 @@ cpdef object to_integer(object obj):
try:
return int(obj)
except (TypeError, ValueError) as e:
return ValueError(
f"Invalid conversion to Integer of {obj}: {e}"
)
raise ValueError(
f"Invalid conversion to Integer of literal {obj}"
) from e

cpdef object to_float(object obj):
"""to_float.
Expand Down Expand Up @@ -161,7 +161,7 @@ cpdef datetime.timedelta to_timedelta(object obj):
)
return tdelta
except ValueError:
return ValueError(
raise ValueError(
f"Invalid timedelta Object: {obj}"
)

Expand Down Expand Up @@ -355,10 +355,10 @@ def parse_type(object T, object data, object encoder = None):
return conv(data)
except KeyError:
pass
except ValueError as e:
except (TypeError, ValueError) as e:
raise ValueError(
f"DataModel: Error parsing type {T}, {e}"
)
f"Error type {T}: {e}"
) from e
# making last conversion:
if inspect.isclass(T):
try:
Expand Down
10 changes: 5 additions & 5 deletions datamodel/validation.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from libcpp cimport bool
from dataclasses import _MISSING_TYPE
from functools import partial

import types

cpdef bool is_callable(object value):
if value is None:
Expand Down Expand Up @@ -58,13 +58,13 @@ def validator(object F, str name, object value, object annotated_type):
})
# check: data type hint
try:
print('VALIDATION ', val_type, annotated_type)
if annotated_type.__module__ == 'typing':
# TODO: validation of annotated types
pass
elif F.metadata['required'] is False or F.metadata['nullable'] is True:
if value is None:
pass
elif hasattr(F, 'required'):
if F.required() is False or F.nullable() is True:
if value is None:
pass
elif is_function(val_type):
pass # value will be calculated.
elif val_type <> annotated_type:
Expand Down
2 changes: 1 addition & 1 deletion datamodel/version.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
__title__ = 'python-datamodel'
__description__ = ('simple library based on python +3.8 to use Dataclass-syntax'
'for interacting with Data')
__version__ = '0.1.2'
__version__ = '0.1.3'
__author__ = 'Jesus Lara'
__author_email__ = '[email protected]'
__license__ = 'BSD'
2 changes: 1 addition & 1 deletion examples/test_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class WidgetTemplate(BaseModel):
widget_name: str = Column(required=False)
title: str
description: str
url: str = Column(required=False)
url: str = Column(required=False, default='http://example.com')
active: bool = Column(required=True, default=True)
params: Optional[dict] = Column(required=False, db_type="jsonb")
embed: str = Column(required=False)
Expand Down

0 comments on commit 7e2a388

Please sign in to comment.