File: test_uuid.py

package info (click to toggle)
pydantic-core 2.37.2-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 3,784 kB
  • sloc: python: 34,800; javascript: 211; makefile: 126
file content (236 lines) | stat: -rw-r--r-- 12,789 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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
import copy
import re
from uuid import UUID

import pytest

from pydantic_core import SchemaValidator, ValidationError, core_schema

from ..conftest import Err, PyAndJson


class MyStr(str): ...


@pytest.mark.parametrize(
    'input_value,expected',
    [
        # Valid UUIDs
        ('12345678-1234-1234-1234-567812345678', UUID('12345678-1234-1234-1234-567812345678')),
        ('550e8400-e29b-41d4-a716-446655440000', UUID('550e8400-e29b-41d4-a716-446655440000')),
        ('f47ac10b-58cc-4372-a567-0e02b2c3d479', UUID('f47ac10b-58cc-4372-a567-0e02b2c3d479')),
        ('123e4567-e89b-12d3-a456-426655440000', UUID('123e4567-e89b-12d3-a456-426655440000')),
        ('de305d54-75b4-431b-adb2-eb6b9e546014', UUID('de305d54-75b4-431b-adb2-eb6b9e546014')),
        ('00000000-0000-0000-0000-000000000000', UUID('00000000-0000-0000-0000-000000000000')),
        ('1b4e28ba-2fa1-11d2-883f-0016d3cca427', UUID('1b4e28ba-2fa1-11d2-883f-0016d3cca427')),
        ('6ba7b810-9dad-11d1-80b4-00c04fd430c8', UUID('6ba7b810-9dad-11d1-80b4-00c04fd430c8')),
        ('886313e1-3b8a-5372-9b90-0c9aee199e5d', UUID('886313e1-3b8a-5372-9b90-0c9aee199e5d')),
        ('c0a8f9a8-aa5e-482b-a067-9cb3a51f5c11', UUID('c0a8f9a8-aa5e-482b-a067-9cb3a51f5c11')),
        ('1efea93d-7bb8-6ea0-afdc-e76cbc0c8e05', UUID('1efea93d-7bb8-6ea0-afdc-e76cbc0c8e05')),
        ('0194fdc2-5d6a-733c-97f9-2feeb9d2a609', UUID('0194fdc2-5d6a-733c-97f9-2feeb9d2a609')),
        ('c0a8f9a8-aa5e-882b-a067-9cb3a51f5c11', UUID('c0a8f9a8-aa5e-882b-a067-9cb3a51f5c11')),
        ('00000000-8000-4000-8000-000000000000', UUID('00000000-8000-4000-8000-000000000000')),
        ('00000000-0000-4000-0000-000000000000', UUID('00000000-0000-4000-0000-000000000000')),
        (MyStr('00000000-0000-4000-0000-000000000000'), UUID('00000000-0000-4000-0000-000000000000')),
        (b'\x12\x34\x56\x78' * 4, UUID('12345678-1234-5678-1234-567812345678')),
        (b'\x00\x00\x00\x00' * 4, UUID('00000000-0000-0000-0000-000000000000')),
        (b'ebcdab58-6eb8-46fb-a190-d07a33e9eac8', UUID('ebcdab58-6eb8-46fb-a190-d07a33e9eac8')),
        (UUID('12345678-1234-5678-1234-567812345678'), UUID('12345678-1234-5678-1234-567812345678')),
        (UUID('550e8400-e29b-41d4-a716-446655440000'), UUID('550e8400-e29b-41d4-a716-446655440000')),
        # Invalid UUIDs
        (
            'not-a-valid-uuid',
            Err(
                'Input should be a valid UUID, invalid character: expected an optional prefix of'
                + ' `urn:uuid:` followed by [0-9a-fA-F-], found `n` at 1'
            ),
        ),
        (
            '12345678-1234-5678-1234-5678123456789',
            Err('Input should be a valid UUID, invalid group length in group 4: expected 12, found 13'),
        ),
        (
            '12345678-1234-1234-1234-1234567890123',
            Err('Input should be a valid UUID, invalid group length in group 4: expected 12, found 13'),
        ),
        (b'\x00\x00\x00\x000' * 4, Err('Input should be a valid UUID, invalid length: expected 16 bytes, found 20')),
        ('550e8400-e29b-41d4-a716', Err('Input should be a valid UUID, invalid group count: expected 5, found 4')),
        (
            'f47ac10b-58cc-4372-a567-0e02b2c3d47',
            Err('Input should be a valid UUID, invalid group length in group 4: expected 12, found 11'),
        ),
        (
            'de305d54-75b4-431b-adb2-eb6b9e54601',
            Err('Input should be a valid UUID, invalid group length in group 4: expected 12, found 11'),
        ),
        (
            '1b4e28ba-2fa1-11d2-883f-0016d3cca42',
            Err('Input should be a valid UUID, invalid group length in group 4: expected 12, found 11'),
        ),
        (
            '6ba7b810-9dad-11d1-80b4-00c04fd430c',
            Err('Input should be a valid UUID, invalid group length in group 4: expected 12, found 11'),
        ),
        (
            '886313e1-3b8a-5372-9b90-0c9aee199e5',
            Err('Input should be a valid UUID, invalid group length in group 4: expected 12, found 11'),
        ),
        (
            'c0a8f9a8-aa5e-482b-a067-9cb3a51f5c1',
            Err('Input should be a valid UUID, invalid group length in group 4: expected 12, found 11'),
        ),
        (0xA1A2A3A4B1B2C1C2D1D2D3D4D5D6D7D8, Err('UUID input should be a string, bytes or UUID object')),
        (00000000000000000000000000, Err('UUID input should be a string, bytes or UUID object')),
    ],
)
def test_uuid(input_value, expected):
    v = SchemaValidator(core_schema.uuid_schema())
    if isinstance(expected, Err):
        with pytest.raises(ValidationError, match=re.escape(expected.message)):
            result = v.validate_python(input_value)
            print(f'input_value={input_value} result={result}')
    else:
        output = v.validate_python(input_value)
        assert output == expected
        assert isinstance(output, UUID)


@pytest.mark.parametrize(
    'input_value,expected',
    [
        (UUID('12345678-1234-5678-1234-567812345678'), UUID('12345678-1234-5678-1234-567812345678')),
        ('12345678-1234-5678-1234-567812345678', Err('Input should be an instance of UUID [type=is_instance_of,')),
        (b'12345678-1234-5678-1234-567812345678', Err('Input should be an instance of UUID [type=is_instance_of,')),
        (1654646400, Err('Input should be an instance of UUID [type=is_instance_of')),
    ],
)
def test_uuid_strict(input_value, expected):
    v = SchemaValidator(core_schema.uuid_schema(strict=True))
    if isinstance(expected, Err):
        with pytest.raises(ValidationError, match=re.escape(expected.message)):
            v.validate_python(input_value)
    else:
        output = v.validate_python(input_value)
        assert output == expected
        assert isinstance(output, UUID)


@pytest.mark.parametrize(
    'input_value, version, expected',
    [
        # Valid UUIDs
        ('a6cc5730-2261-11ee-9c43-2eb5a363657c', 1, UUID('a6cc5730-2261-11ee-9c43-2eb5a363657c')),
        (UUID('a6cc5730-2261-11ee-9c43-2eb5a363657c'), 1, UUID('a6cc5730-2261-11ee-9c43-2eb5a363657c')),
        ('04e4aeb3-8f20-30d0-8852-d295e1265eed', 3, UUID('04e4aeb3-8f20-30d0-8852-d295e1265eed')),
        (UUID('04e4aeb3-8f20-30d0-8852-d295e1265eed'), 3, UUID('04e4aeb3-8f20-30d0-8852-d295e1265eed')),
        ('0e7ac198-9acd-4c0c-b4b4-761974bf71d7', 4, UUID('0e7ac198-9acd-4c0c-b4b4-761974bf71d7')),
        (UUID('0e7ac198-9acd-4c0c-b4b4-761974bf71d7'), 4, UUID('0e7ac198-9acd-4c0c-b4b4-761974bf71d7')),
        ('0e7ac198-9acd-4c0c-b4b4-761974bf71d7', 4, UUID('0e7ac198-9acd-4c0c-b4b4-761974bf71d7')),
        (UUID('0e7ac198-9acd-4c0c-b4b4-761974bf71d7'), 4, UUID('0e7ac198-9acd-4c0c-b4b4-761974bf71d7')),
        ('0194fdc2-5d6a-733c-97f9-2feeb9d2a609', 7, UUID('0194fdc2-5d6a-733c-97f9-2feeb9d2a609')),
        (UUID('0194fdc2-5d6a-733c-97f9-2feeb9d2a609'), 7, UUID('0194fdc2-5d6a-733c-97f9-2feeb9d2a609')),
        ('1efea93d-7bb8-6ea0-afdc-e76cbc0c8e05', 6, UUID('1efea93d-7bb8-6ea0-afdc-e76cbc0c8e05')),
        (UUID('1efea93d-7bb8-6ea0-afdc-e76cbc0c8e05'), 6, UUID('1efea93d-7bb8-6ea0-afdc-e76cbc0c8e05')),
        ('c0a8f9a8-aa5e-882b-a067-9cb3a51f5c11', 8, UUID('c0a8f9a8-aa5e-882b-a067-9cb3a51f5c11')),
        (UUID('c0a8f9a8-aa5e-882b-a067-9cb3a51f5c11'), 8, UUID('c0a8f9a8-aa5e-882b-a067-9cb3a51f5c11')),
        # Cases from pydantic#7355 and pydantic#7537
        # `UUID.version` makes sense for RFC 4122 UUIDs only. For non RFC 4122 UUIDs Python uses `UUID.version=None`
        ('00000000-8000-4000-8000-000000000000', 4, UUID('00000000-8000-4000-8000-000000000000')),
        (UUID('00000000-8000-4000-8000-000000000000'), 4, UUID('00000000-8000-4000-8000-000000000000')),
        ('00000000-0000-4000-0000-000000000000', None, UUID('00000000-0000-4000-0000-000000000000')),
        (UUID('00000000-0000-4000-0000-000000000000'), None, UUID('00000000-0000-4000-0000-000000000000')),
        ('00000000-7fff-4000-7fff-000000000000', None, UUID('00000000-7fff-4000-7fff-000000000000')),
        (UUID('00000000-7fff-4000-7fff-000000000000'), None, UUID('00000000-7fff-4000-7fff-000000000000')),
        (UUID('00000000-7fff-4000-7fff-000000000000'), 4, Err('UUID version 4 expected')),
        ('b34b6755-f49c-3bd2-6f06-131a708c2bf3', None, UUID('b34b6755-f49c-3bd2-6f06-131a708c2bf3')),
        (UUID('b34b6755-f49c-3bd2-6f06-131a708c2bf3'), None, UUID('b34b6755-f49c-3bd2-6f06-131a708c2bf3')),
        (UUID('b34b6755-f49c-3bd2-6f06-131a708c2bf3'), 4, Err('UUID version 4 expected')),
        # Invalid UUIDs
        ('1efea93d-7bb8-6ea0-afdc-e76cbc0c8e05', 8, Err('UUID version 8 expected')),
        (UUID('1efea93d-7bb8-6ea0-afdc-e76cbc0c8e05'), 8, Err('UUID version 8 expected')),
        ('c0a8f9a8-aa5e-882b-a067-9cb3a51f5c11', 6, Err('UUID version 6 expected')),
        (UUID('c0a8f9a8-aa5e-882b-a067-9cb3a51f5c11'), 6, Err('UUID version 6 expected')),
        ('a6cc5730-2261-11ee-9c43-2eb5a363657c', 7, Err('UUID version 7 expected')),
        (UUID('a6cc5730-2261-11ee-9c43-2eb5a363657c'), 7, Err('UUID version 7 expected')),
        ('a6cc5730-2261-11ee-9c43-2eb5a363657c', 5, Err('UUID version 5 expected')),
        (UUID('a6cc5730-2261-11ee-9c43-2eb5a363657c'), 5, Err('UUID version 5 expected')),
        ('04e4aeb3-8f20-30d0-8852-d295e1265eed', 4, Err('UUID version 4 expected')),
        (UUID('04e4aeb3-8f20-30d0-8852-d295e1265eed'), 4, Err('UUID version 4 expected')),
        ('0e7ac198-9acd-4c0c-b4b4-761974bf71d7', 3, Err('UUID version 3 expected')),
        (UUID('0e7ac198-9acd-4c0c-b4b4-761974bf71d7'), 3, Err('UUID version 3 expected')),
        ('08ed0736-fb95-5cc5-85ed-37e4f3df9b29', 1, Err('UUID version 1 expected')),
        (UUID('08ed0736-fb95-5cc5-85ed-37e4f3df9b29'), 1, Err('UUID version 1 expected')),
        ('00000000-0000-4000-0000-000000000000', 4, Err('UUID version 4 expected')),
        (UUID('00000000-0000-4000-0000-000000000000'), 4, Err('UUID version 4 expected')),
    ],
)
def test_uuid_version(input_value, version, expected):
    schema = core_schema.uuid_schema()
    if version is not None:
        schema = core_schema.uuid_schema(version=version)

    v = SchemaValidator(schema)

    if isinstance(expected, Err):
        with pytest.raises(ValidationError, match=re.escape(expected.message)):
            v.validate_python(input_value)
    else:
        output = v.validate_python(input_value)
        assert output == expected
        assert isinstance(output, UUID)


@pytest.mark.parametrize(
    'input_value,expected',
    [
        ('a6cc5730-2261-11ee-9c43-2eb5a363657c', UUID('a6cc5730-2261-11ee-9c43-2eb5a363657c')),
        ('12345678123456781234567812345678', UUID('12345678-1234-5678-1234-567812345678')),
        (
            'c0a8f9a8-aa5e-482b-a067-9cb3a51f5c1',
            Err('Input should be a valid UUID, invalid group length in group 4: expected 12, found 11'),
        ),
        (1e1, Err('input should be a string, bytes or UUID object')),
        (None, Err('input should be a string, bytes or UUID object')),
        (True, Err('input should be a string, bytes or UUID object')),
        (0xA1A2A3A4B1B2C1C2D1D2D3D4D5D6D7D8, Err('input should be a string, bytes or UUID object')),
        (0x12345678123456781234567812345678, Err('input should be a string, bytes or UUID object')),
    ],
)
def test_uuid_json(py_and_json: PyAndJson, input_value, expected):
    v = py_and_json({'type': 'uuid'})
    if isinstance(expected, Err):
        with pytest.raises(ValidationError, match=re.escape(expected.message)):
            v.validate_test(input_value)
    else:
        output = v.validate_test(input_value)
        assert output == expected
        assert isinstance(output, UUID)


def test_uuid_deepcopy():
    output = SchemaValidator(core_schema.uuid_schema()).validate_python('a6cc5730-2261-11ee-9c43-2eb5a363657c')
    c = copy.deepcopy(output)
    assert repr(output) == "UUID('a6cc5730-2261-11ee-9c43-2eb5a363657c')"
    assert c == output
    assert isinstance(output, UUID)


def test_uuid_copy():
    output = SchemaValidator(core_schema.uuid_schema()).validate_python('a6cc5730-2261-11ee-9c43-2eb5a363657c')
    c = copy.copy(output)
    assert repr(output) == "UUID('a6cc5730-2261-11ee-9c43-2eb5a363657c')"
    assert c == output
    assert isinstance(output, UUID)


def test_uuid_wrap_json():
    # https://github.com/pydantic/pydantic/issues/8147
    schema = core_schema.no_info_wrap_validator_function(lambda v, handler: handler(v), core_schema.uuid_schema())
    v = SchemaValidator(schema)

    assert v.validate_python(UUID('a6cc5730-2261-11ee-9c43-2eb5a363657c'), strict=True) == UUID(
        'a6cc5730-2261-11ee-9c43-2eb5a363657c'
    )
    assert v.validate_json('"a6cc5730-2261-11ee-9c43-2eb5a363657c"', strict=True) == UUID(
        'a6cc5730-2261-11ee-9c43-2eb5a363657c'
    )