File: test_format.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 (125 lines) | stat: -rw-r--r-- 4,659 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
import json
import re
from datetime import date
from uuid import UUID

import pytest

from pydantic_core import PydanticSerializationError, SchemaSerializer, core_schema


@pytest.mark.parametrize(
    'value,formatting_string,expected_python,expected_json',
    [
        (42.12345, '0.4f', 42.12345, b'"42.1234"'),
        (42.12, '0.4f', 42.12, b'"42.1200"'),
        (42.12, '', 42.12, b'"42.12"'),
        (42.1234567, '', 42.1234567, b'"42.1234567"'),
        (date(2022, 11, 20), '%Y-%m-%d', date(2022, 11, 20), b'"2022-11-20"'),
        ('foo', '^5s', 'foo', b'" foo "'),
        (
            UUID('ebcdab58-6eb8-46fb-a190-d07a33e9eac8'),
            '',
            UUID('ebcdab58-6eb8-46fb-a190-d07a33e9eac8'),
            b'"ebcdab58-6eb8-46fb-a190-d07a33e9eac8"',
        ),
    ],
)
def test_format(value, formatting_string, expected_python, expected_json):
    s = SchemaSerializer(core_schema.any_schema(serialization=core_schema.format_ser_schema(formatting_string)))
    assert s.to_python(value) == expected_python
    assert s.to_json(value) == expected_json
    assert s.to_python(value, mode='json') == json.loads(expected_json)


def test_format_when_used_unless_none():
    s = SchemaSerializer(
        core_schema.any_schema(serialization=core_schema.format_ser_schema('0.1f', when_used='unless-none'))
    )
    assert 'FormatSerializer' in repr(s)
    assert 'ToStringSerializer' not in repr(s)
    assert s.to_python(42.12345) == '42.1'
    assert s.to_python(42.12345, mode='json') == '42.1'
    assert s.to_json(42.12345) == b'"42.1"'


def test_format_when_used_json():
    s = SchemaSerializer(core_schema.any_schema(serialization=core_schema.format_ser_schema('0.1f', when_used='json')))
    assert s.to_python(42.12345) == 42.12345
    assert s.to_python(None) is None
    assert s.to_python(42.12345, mode='json') == '42.1'
    assert s.to_json(42.12345) == b'"42.1"'
    # fails because you can't format `None`
    with pytest.raises(PydanticSerializationError, match=r'Error calling `format\(value, \'0.1f\'\)`: TypeError:'):
        s.to_json(None)


def test_to_string_when_used_always():
    s = SchemaSerializer(core_schema.any_schema(serialization=core_schema.format_ser_schema('', when_used='always')))
    assert s.to_python(123) == '123'
    assert s.to_python(None) == 'None'
    assert s.to_python(123, mode='json') == '123'
    assert s.to_python(None, mode='json') == 'None'
    assert s.to_json(None) == b'"None"'
    assert s.to_json(123) == b'"123"'


def test_to_string_when_used_unless_none():
    s = SchemaSerializer(
        core_schema.any_schema(serialization=core_schema.format_ser_schema('', when_used='unless-none'))
    )
    assert 'ToStringSerializer' in repr(s)
    assert 'FormatSerializer' not in repr(s)
    assert s.to_python(42) == '42'
    assert s.to_python(42, mode='json') == '42'
    assert s.to_json(42) == b'"42"'


def test_format_error():
    s = SchemaSerializer(core_schema.any_schema(serialization=core_schema.format_ser_schema('^5d')))
    assert s.to_python(123) == 123

    # the actual error message differs slightly between cpython and pypy
    msg = "Error calling `format(value, '^5d')`: ValueError:"
    with pytest.raises(PydanticSerializationError, match=re.escape(msg)):
        s.to_python('x', mode='json')

    with pytest.raises(PydanticSerializationError, match=re.escape(msg)):
        s.to_json('x')


def test_dict_keys():
    s = SchemaSerializer(
        core_schema.dict_schema(core_schema.float_schema(serialization=core_schema.format_ser_schema('0.4f')))
    )
    assert s.to_python({1: True}, mode='json') == {'1.0000': True}


def test_format_fallback():
    s = SchemaSerializer(core_schema.any_schema(serialization=core_schema.format_ser_schema('^5s')))
    assert s.to_python('abc') == 'abc'
    assert s.to_python('abc', mode='json') == ' abc '
    assert s.to_json('abc') == b'" abc "'

    assert s.to_python(None) is None
    assert s.to_python(None, mode='json') is None
    assert s.to_json(None) == b'null'


class BrokenToString:
    def __str__(self):
        raise ValueError('broken')

    def __repr__(self):
        return 'BrokenToString()'


def test_to_string():
    s = SchemaSerializer(core_schema.any_schema(serialization={'type': 'to-string'}))
    assert s.to_python(123, mode='json') == '123'
    assert s.to_python(None, mode='json') is None
    uuid = UUID('ebcdab58-6eb8-46fb-a190-d07a33e9eac8')
    assert s.to_python(uuid, mode='json') == str(uuid)
    assert s.to_json(uuid) == b'"%s"' % str(uuid).encode('utf-8')
    with pytest.raises(ValueError, match='broken'):
        s.to_python(BrokenToString(), mode='json')