Dataclass schema attr (#438)

fix #408

* Fix default field value compatibility for dataclass-based models

* Add unittests for dataclass schema bugfix

* Update HISTORY
This commit is contained in:
Vitaly R. Samigullin
2019-03-28 15:56:58 +03:00
committed by Samuel Colvin
parent 8e0bfa37ce
commit caaa16ee71
3 changed files with 47 additions and 1 deletions
+1
View File
@@ -7,6 +7,7 @@ v0.21.1 (unreleased)
....................
* add ``IPv{4,6,Any}Network`` and ``IPv{4,6,Any}Interface`` types from ``ipaddress`` stdlib, #333 by @pilosus
* add docs for ``datetime`` types, #386 by @pilosus
* fix to schema generation in dataclass-based models, #408 by @pilosus
v0.21.0 (2019-03-15)
+5 -1
View File
@@ -3,6 +3,7 @@ from typing import TYPE_CHECKING, Any, Callable, Dict, Generator, Optional, Type
from .error_wrappers import ValidationError
from .errors import DataclassTypeError
from .fields import Required
from .main import create_model, validate_model
from .utils import AnyType
@@ -72,7 +73,10 @@ def _process_class(
_cls.__post_init__ = _pydantic_post_init
cls = dataclasses._process_class(_cls, init, repr, eq, order, unsafe_hash, frozen) # type: ignore
fields: Dict[str, Any] = {name: (field.type, field.default) for name, field in cls.__dataclass_fields__.items()}
fields: Dict[str, Any] = {
name: (field.type, field.default if field.default != dataclasses.MISSING else Required)
for name, field in cls.__dataclass_fields__.items()
}
cls.__post_init_original__ = post_init_original
cls.__pydantic_model__ = create_model(cls.__name__, __config__=config, __module__=_cls.__module__, **fields)
+41
View File
@@ -1,4 +1,5 @@
import dataclasses
from datetime import datetime
import pytest
@@ -260,3 +261,43 @@ def test_nested_dataclass_model():
navbar = Outer(n=Nested(number='1'))
assert navbar.n.number == 1
def test_fields():
@pydantic.dataclasses.dataclass
class User:
id: int
name: str = 'John Doe'
signup_ts: datetime = None
user = User(id=123)
fields = user.__pydantic_model__.__fields__
assert fields['id'].required is True
assert fields['id'].default is None
assert fields['name'].required is False
assert fields['name'].default == 'John Doe'
assert fields['signup_ts'].required is False
assert fields['signup_ts'].default is None
def test_schema():
@pydantic.dataclasses.dataclass
class User:
id: int
name: str = 'John Doe'
signup_ts: datetime = None
user = User(id=123)
assert user.__pydantic_model__.schema() == {
'title': 'User',
'type': 'object',
'properties': {
'id': {'title': 'Id', 'type': 'integer'},
'name': {'title': 'Name', 'default': 'John Doe', 'type': 'string'},
'signup_ts': {'title': 'Signup_Ts', 'type': 'string', 'format': 'date-time'},
},
'required': ['id'],
}