File: test_literal.py

package info (click to toggle)
pydantic-core 2.41.4-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 3,828 kB
  • sloc: python: 35,564; javascript: 211; makefile: 128
file content (149 lines) | stat: -rw-r--r-- 5,633 bytes parent folder | download | duplicates (2)
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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
from dataclasses import dataclass
from enum import Enum
from typing import Literal, Union

import pytest

from pydantic_core import SchemaError, SchemaSerializer, core_schema

from ..conftest import plain_repr


def test_int_literal():
    s = SchemaSerializer(core_schema.literal_schema([1, 2, 3]))
    r = plain_repr(s)
    assert 'expected_int:{' in r
    assert 'expected_str:{}' in r
    assert 'expected_py:None' in r

    assert s.to_python(1) == 1
    assert s.to_python(1, mode='json') == 1
    assert s.to_python(44) == 44
    assert s.to_json(1) == b'1'

    # with pytest.warns(UserWarning, match='Expected `int` but got `str` - serialized value may not be as expected'):
    assert s.to_python('a', mode='json') == 'a'

    # with pytest.warns(UserWarning, match='Expected `int` but got `str` - serialized value may not be as expected'):
    assert s.to_json('a') == b'"a"'


def test_str_literal():
    s = SchemaSerializer(core_schema.literal_schema(['a', 'b', 'c']))
    r = plain_repr(s)
    assert 'expected_str:{' in r
    assert 'expected_int:{}' in r
    assert 'expected_py:None' in r

    assert s.to_python('a') == 'a'
    assert s.to_python('a', mode='json') == 'a'
    assert s.to_python('not in literal') == 'not in literal'
    assert s.to_json('a') == b'"a"'

    # with pytest.warns(UserWarning, match='Expected `str` but got `int` - serialized value may not be as expected'):
    assert s.to_python(1, mode='json') == 1

    # with pytest.warns(UserWarning, match='Expected `str` but got `int` - serialized value may not be as expected'):
    assert s.to_json(1) == b'1'


def test_other_literal():
    s = SchemaSerializer(core_schema.literal_schema(['a', 1]))
    assert 'expected_int:{1},expected_str:{"a"},expected_py:None' in plain_repr(s)

    assert s.to_python('a') == 'a'
    assert s.to_python('a', mode='json') == 'a'
    assert s.to_python('not in literal') == 'not in literal'
    assert s.to_json('a') == b'"a"'

    assert s.to_python(1) == 1
    assert s.to_python(1, mode='json') == 1
    assert s.to_python(44) == 44
    assert s.to_json(1) == b'1'


def test_empty_literal():
    with pytest.raises(SchemaError, match='`expected` should have length > 0'):
        SchemaSerializer(core_schema.literal_schema([]))


def test_bool_literal():
    s = SchemaSerializer(core_schema.literal_schema([False]))
    assert 'expected_int:{},expected_str:{},expected_py:Some(Py(' in plain_repr(s)

    assert s.to_python(False) is False
    assert s.to_python(False, mode='json') is False
    assert s.to_python(True) is True
    assert s.to_json(False) == b'false'


def test_literal_with_enum() -> None:
    class SomeEnum(str, Enum):
        CAT = 'cat'
        DOG = 'dog'

    @dataclass
    class Dog:
        name: str
        type: Literal[SomeEnum.DOG] = SomeEnum.DOG

    @dataclass
    class Cat:
        name: str
        type: Literal[SomeEnum.CAT] = SomeEnum.CAT

    @dataclass
    class Yard:
        pet: Union[Dog, Cat]

    serializer = SchemaSerializer(
        core_schema.model_schema(
            cls=Yard,
            schema=core_schema.model_fields_schema(
                fields={
                    'pet': core_schema.model_field(
                        schema=core_schema.tagged_union_schema(
                            choices={
                                SomeEnum.DOG: core_schema.model_schema(
                                    cls=Dog,
                                    schema=core_schema.model_fields_schema(
                                        fields={
                                            'type': core_schema.model_field(
                                                schema=core_schema.with_default_schema(
                                                    schema=core_schema.literal_schema([SomeEnum.DOG]),
                                                    default=SomeEnum.DOG,
                                                )
                                            ),
                                            'name': core_schema.model_field(schema=core_schema.str_schema()),
                                        },
                                        model_name='Dog',
                                    ),
                                ),
                                SomeEnum.CAT: core_schema.model_schema(
                                    cls=Cat,
                                    schema=core_schema.model_fields_schema(
                                        fields={
                                            'type': core_schema.model_field(
                                                schema=core_schema.with_default_schema(
                                                    schema=core_schema.literal_schema([SomeEnum.CAT]),
                                                    default=SomeEnum.CAT,
                                                )
                                            ),
                                            'name': core_schema.model_field(schema=core_schema.str_schema()),
                                        },
                                        model_name='Cat',
                                    ),
                                ),
                            },
                            discriminator='type',
                            strict=False,
                            from_attributes=True,
                        )
                    )
                }
            ),
        )
    )

    yard = Yard(pet=Dog(name='Rex'))
    assert serializer.to_python(yard, mode='json') == {'pet': {'type': 'dog', 'name': 'Rex'}}