File: test_pydantic_v1_v2.py

package info (click to toggle)
python-polyfactory 3.1.0-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 2,132 kB
  • sloc: python: 11,414; makefile: 102; sh: 34
file content (125 lines) | stat: -rw-r--r-- 3,579 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
"""Tests to check that usage of pydantic v1 and v2 at the same time works."""

import sys
from typing import Annotated, Optional, Union

import pytest

import pydantic

from polyfactory.factories.pydantic_factory import ModelFactory

if pydantic.VERSION.startswith("1"):
    pytest.skip("only for pydantic v2", allow_module_level=True)

from pydantic import BaseModel as BaseModelV2

try:
    from pydantic.v1 import BaseModel as BaseModelV1
except ImportError:
    from pydantic import BaseModel as BaseModelV1  # type: ignore[assignment]

skip_pydantic_v1_on_py314 = pytest.mark.skipif(
    sys.version_info >= (3, 14),
    reason="pydantic v1 not supported on Python 3.14",
)


@pytest.mark.parametrize(
    "base_model",
    [
        pytest.param(BaseModelV1, marks=skip_pydantic_v1_on_py314),
        BaseModelV2,
    ],
)
def test_is_supported_type(base_model: type[Union[BaseModelV1, BaseModelV2]]) -> None:
    class Foo(base_model):  # type: ignore[valid-type, misc]
        ...

    assert ModelFactory.is_supported_type(Foo) is True


@pytest.mark.parametrize(
    "base_model",
    [
        pytest.param(BaseModelV1, marks=skip_pydantic_v1_on_py314),
        BaseModelV2,
    ],
)
def test_build(base_model: type[Union[BaseModelV1, BaseModelV2]]) -> None:
    class Foo(base_model):  # type: ignore[valid-type, misc]
        a: int
        b: str
        c: bool

    FooFactory = ModelFactory.create_factory(Foo)
    foo = FooFactory.build()

    assert isinstance(foo.a, int)
    assert isinstance(foo.b, str)
    assert isinstance(foo.c, bool)


@skip_pydantic_v1_on_py314
def test_build_v1_with_constrained_fields() -> None:
    from pydantic.v1.fields import Field

    ConstrainedInt = Annotated[int, Field(ge=100, le=200)]
    ConstrainedStr = Annotated[str, Field(min_length=1, max_length=3)]

    class Foo(BaseModelV1):
        a: ConstrainedInt
        b: ConstrainedStr
        c: Union[ConstrainedInt, ConstrainedStr]
        d: Optional[ConstrainedInt]
        e: Optional[Union[ConstrainedInt, ConstrainedStr]]
        f: list[ConstrainedInt]
        g: dict[ConstrainedInt, ConstrainedStr]

    ModelFactory.create_factory(Foo).build()


def test_build_v2_with_constrained_fields() -> None:
    from pydantic.fields import Field

    ConstrainedInt = Annotated[int, Field(ge=100, le=200)]
    ConstrainedStr = Annotated[str, Field(min_length=1, max_length=3)]

    class Foo(pydantic.BaseModel):  # pyright: ignore[reportGeneralTypeIssues]
        a: ConstrainedInt
        b: ConstrainedStr
        c: Union[ConstrainedInt, ConstrainedStr]
        d: Optional[ConstrainedInt]
        e: Optional[Union[ConstrainedInt, ConstrainedStr]]
        f: list[ConstrainedInt]
        g: dict[ConstrainedInt, ConstrainedStr]

    ModelFactory.create_factory(Foo).build()


def test_variadic_tuple_length() -> None:
    class Foo(pydantic.BaseModel):
        bar: tuple[int, ...]

    class Factory(ModelFactory[Foo]):
        __randomize_collection_length__ = True
        __min_collection_length__ = 7
        __max_collection_length__ = 8

    result = Factory.build()
    assert 7 <= len(result.bar) <= 8


@skip_pydantic_v1_on_py314
def test_build_v1_with_url_and_email_types() -> None:
    from pydantic.v1 import AnyHttpUrl, AnyUrl, EmailStr, HttpUrl, NameEmail

    class Foo(BaseModelV1):
        http_url: HttpUrl
        any_http_url: AnyHttpUrl
        any_url: AnyUrl
        email_str: EmailStr
        name_email: NameEmail
        composed: tuple[HttpUrl, AnyHttpUrl, AnyUrl, EmailStr, NameEmail]

    ModelFactory.create_factory(Foo).build()