File: nested_schema.py

package info (click to toggle)
pydantic-core 2.27.2-3
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 3,428 kB
  • sloc: python: 32,538; javascript: 210; makefile: 149
file content (93 lines) | stat: -rw-r--r-- 2,799 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
from __future__ import annotations

from typing import TYPE_CHECKING, Any

if TYPE_CHECKING:
    from pydantic_core import core_schema as cs

N = 5  # arbitrary number that takes ~0.05s per run


class MyModel:
    # __slots__ is not required, but it avoids __pydantic_fields_set__ falling into __dict__
    __slots__ = '__dict__', '__pydantic_fields_set__', '__pydantic_extra__', '__pydantic_private__'


def schema_using_defs() -> cs.CoreSchema:
    definitions: list[cs.CoreSchema] = [
        {'type': 'int', 'ref': 'int'},
        {
            'type': 'model',
            'cls': MyModel,
            'schema': {
                'type': 'model-fields',
                'fields': {
                    str(c): {'type': 'model-field', 'schema': {'type': 'definition-ref', 'schema_ref': 'int'}}
                    for c in range(N)
                },
            },
            'ref': f'model_{N}',
        },
    ]
    level = N
    for level in reversed(range(N)):
        definitions.append(
            {
                'type': 'model',
                'cls': MyModel,
                'schema': {
                    'type': 'model-fields',
                    'fields': {
                        str(c): {
                            'type': 'model-field',
                            'schema': {'type': 'definition-ref', 'schema_ref': f'model_{level+1}'},
                        }
                        for c in range(N)
                    },
                },
                'ref': f'model_{level}',
            }
        )
    return {
        'type': 'definitions',
        'definitions': definitions,
        'schema': {'type': 'definition-ref', 'schema_ref': 'model_0'},
    }


def inlined_schema() -> cs.CoreSchema:
    level = N
    schema: cs.CoreSchema = {
        'type': 'model',
        'cls': MyModel,
        'schema': {
            'type': 'model-fields',
            'fields': {str(c): {'type': 'model-field', 'schema': {'type': 'int'}} for c in range(N)},
        },
        'ref': f'model_{N}',
    }
    for level in reversed(range(N)):
        schema = {
            'type': 'model',
            'cls': MyModel,
            'schema': {
                'type': 'model-fields',
                'fields': {str(c): {'type': 'model-field', 'schema': schema} for c in range(N)},
            },
            'ref': f'model_{level}',
        }
    return schema


def input_data_valid(levels: int = N) -> Any:
    data = {str(c): 1 for c in range(N)}
    for _ in range(levels):
        data = {str(c): data for c in range(N)}
    return data


if __name__ == '__main__':
    from pydantic_core import SchemaValidator

    SchemaValidator(schema_using_defs()).validate_python(input_data_valid())
    SchemaValidator(inlined_schema()).validate_python(input_data_valid())