Skip to content

Commit

Permalink
fix coverage
Browse files Browse the repository at this point in the history
  • Loading branch information
PrettyWood committed Mar 28, 2021
1 parent 7334e24 commit e1396e4
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 10 deletions.
4 changes: 2 additions & 2 deletions pydantic/dataclasses.py
Expand Up @@ -190,8 +190,8 @@ def new_post_init(
post_init(self, *args, **kwargs)
if __pydantic_run_validation__:
self.__pydantic_validate_values__()
if hasattr(self, '__post_init_post_parse__'):
self.__post_init_post_parse__(*args, **kwargs)
if hasattr(self, '__post_init_post_parse__'):
self.__post_init_post_parse__(*args, **kwargs)

setattr(dc_cls, '__init__', new_init)
setattr(dc_cls, '__post_init__', new_post_init)
Expand Down
5 changes: 3 additions & 2 deletions setup.cfg
Expand Up @@ -30,7 +30,8 @@ exclude_lines =
raise NotImplemented
if TYPE_CHECKING:
@overload
omit = wrapper.py
omit =
pydantic/wrapper.py

[coverage:paths]
source =
Expand Down Expand Up @@ -68,7 +69,7 @@ disallow_untyped_defs = True
;no_implicit_optional = True
;warn_return_any = True

exclude = wrapper.py
exclude = pydantic/wrapper.py

[mypy-email_validator]
ignore_missing_imports = true
Expand Down
2 changes: 1 addition & 1 deletion tests/mypy/outputs/plugin-fail-strict.txt
Expand Up @@ -34,6 +34,6 @@
189: error: Name 'Missing' is not defined [name-defined]
197: error: No overload variant of "dataclass" matches argument type "Dict[<nothing>, <nothing>]" [call-overload]
197: note: Possible overload variant:
197: note: def dataclass(*, init: bool = ..., repr: bool = ..., eq: bool = ..., order: bool = ..., unsafe_hash: bool = ..., frozen: bool = ..., config: Optional[Type[Any]] = ...) -> Callable[[Type[Any]], DataclassProxy]
197: note: def dataclass(*, init: bool = ..., repr: bool = ..., eq: bool = ..., order: bool = ..., unsafe_hash: bool = ..., frozen: bool = ..., config: Optional[Type[Any]] = ..., validate_on_init: Optional[bool] = ...) -> Callable[[Type[Any]], DataclassProxy]
197: note: <1 more non-matching overload not shown>
219: error: Property "y" defined in "FrozenModel" is read-only [misc]
2 changes: 1 addition & 1 deletion tests/mypy/outputs/plugin-fail.txt
Expand Up @@ -23,6 +23,6 @@
189: error: Name 'Missing' is not defined [name-defined]
197: error: No overload variant of "dataclass" matches argument type "Dict[<nothing>, <nothing>]" [call-overload]
197: note: Possible overload variant:
197: note: def dataclass(*, init: bool = ..., repr: bool = ..., eq: bool = ..., order: bool = ..., unsafe_hash: bool = ..., frozen: bool = ..., config: Optional[Type[Any]] = ...) -> Callable[[Type[Any]], DataclassProxy]
197: note: def dataclass(*, init: bool = ..., repr: bool = ..., eq: bool = ..., order: bool = ..., unsafe_hash: bool = ..., frozen: bool = ..., config: Optional[Type[Any]] = ..., validate_on_init: Optional[bool] = ...) -> Callable[[Type[Any]], DataclassProxy]
197: note: <1 more non-matching overload not shown>
219: error: Property "y" defined in "FrozenModel" is read-only [misc]
93 changes: 89 additions & 4 deletions tests/test_dataclasses.py
Expand Up @@ -11,6 +11,9 @@
import pydantic
from pydantic import BaseModel, ValidationError, validator

only_36 = pytest.mark.skipif(sys.version_info[:2] != (3, 6), reason='testing 3.6 behaviour only')
skip_pre_37 = pytest.mark.skipif(sys.version_info < (3, 7), reason='testing >= 3.7 behaviour only')


def test_simple():
@pydantic.dataclasses.dataclass
Expand Down Expand Up @@ -159,6 +162,23 @@ def __post_init__(self):
assert post_init_called


@skip_pre_37
def test_post_init_validation():
@dataclasses.dataclass
class DC:
a: int

def __post_init__(self):
self.a *= 2

def __post_init_post_parse__(self):
self.a += 1

PydanticDC = pydantic.dataclasses.dataclass(DC)
assert DC(a='2').a == '22'
assert PydanticDC(a='2').a == 23


def test_post_init_inheritance_chain():
parent_post_init_called = False
post_init_called = False
Expand Down Expand Up @@ -651,6 +671,7 @@ class MyDataclass:
MyDataclass(v=None)


@skip_pre_37
def test_override_builtin_dataclass():
@dataclasses.dataclass
class File:
Expand All @@ -660,26 +681,86 @@ class File:
content: Optional[bytes] = None

FileChecked = pydantic.dataclasses.dataclass(File)
f = FileChecked(hash='xxx', name=b'whatever.txt', size='456')
assert f.name == 'whatever.txt'
assert f.size == 456

f1 = File(hash='xxx', name=b'whatever.txt', size='456')
f2 = FileChecked(hash='xxx', name=b'whatever.txt', size='456')

assert f1.name == b'whatever.txt'
assert f1.size == '456'

assert f2.name == 'whatever.txt'
assert f2.size == 456

assert isinstance(f2, File)

with pytest.raises(ValidationError) as e:
FileChecked(hash=[1], name='name', size=3)
assert e.value.errors() == [{'loc': ('hash',), 'msg': 'str type expected', 'type': 'type_error.str'}]


@only_36
def test_override_builtin_dataclass__3_6():
@dataclasses.dataclass
class File:
hash: str
name: Optional[str]
size: int
content: Optional[bytes] = None

with pytest.warns(
UserWarning, match="Stdlib dataclass 'File' has been modified and validates everything by default"
):
FileChecked = pydantic.dataclasses.dataclass(File)

f1 = File(hash='xxx', name=b'whatever.txt', size='456')
f2 = FileChecked(hash='xxx', name=b'whatever.txt', size='456')

assert f1.name == f2.name == 'whatever.txt'
assert f1.size == f2.size == 456

with pytest.raises(ValidationError) as e:
FileChecked(hash=[1], name='name', size=3)
assert e.value.errors() == [{'loc': ('hash',), 'msg': 'str type expected', 'type': 'type_error.str'}]


@only_36
def test_override_builtin_dataclass__3_6_no_overwrite():
@dataclasses.dataclass
class File:
hash: str
name: Optional[str]
size: int
content: Optional[bytes] = None

FileChecked = pydantic.dataclasses.dataclass(File, validate_on_init=False)

f1 = File(hash='xxx', name=b'whatever.txt', size='456')
f2 = FileChecked(hash='xxx', name=b'whatever.txt', size='456')

assert f1.name == f2.name == b'whatever.txt'
assert f1.size == f2.size == '456'

with pytest.raises(ValidationError) as e:
FileChecked(hash=[1], name='name', size=3, __pydantic_run_validation__=True)
assert e.value.errors() == [{'loc': ('hash',), 'msg': 'str type expected', 'type': 'type_error.str'}]


@skip_pre_37
def test_override_builtin_dataclass_2():
@dataclasses.dataclass
class Meta:
modified_date: Optional[datetime]
seen_count: int

Meta(modified_date='not-validated', seen_count=0)

@pydantic.dataclasses.dataclass
@dataclasses.dataclass
class File(Meta):
filename: str

Meta(modified_date='still-not-validated', seen_count=0)

f = File(filename=b'thefilename', modified_date='2020-01-01T00:00', seen_count='7')
assert f.filename == 'thefilename'
assert f.modified_date == datetime(2020, 1, 1, 0, 0)
Expand Down Expand Up @@ -736,7 +817,10 @@ class File:
filename: str
meta: Meta

FileChecked = pydantic.dataclasses.dataclass(File)
if sys.version_info[:2] == (3, 6):
FileChecked = pydantic.dataclasses.dataclass(File, validate_on_init=False)
else:
FileChecked = pydantic.dataclasses.dataclass(File)
assert FileChecked.__pydantic_model__.schema() == {
'definitions': {
'Meta': {
Expand Down Expand Up @@ -1020,6 +1104,7 @@ class Thing(Base):
class ValidatedThing(Base):
y: str = dataclasses.field(default_factory=str)

assert Thing(x='hi').y == ''
assert ValidatedThing(x='hi').y == ''


Expand Down

0 comments on commit e1396e4

Please sign in to comment.