File: test_exec_validation.py

package info (click to toggle)
python-datamodel-code-generator 0.55.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 15,792 kB
  • sloc: python: 44,931; makefile: 22
file content (152 lines) | stat: -rw-r--r-- 5,493 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
"""Tests that validate generated code execution on the current Python version.

These tests specifically target the current Python runtime to catch runtime errors
that may not be caught when --target-python-version differs from the test environment.

See: _should_skip_exec() in conftest.py for the skip logic that these tests bypass.
"""

from __future__ import annotations

import sys
from typing import TYPE_CHECKING

import pytest

from datamodel_code_generator.format import PythonVersion, is_supported_in_black

from .conftest import (
    CURRENT_PYTHON_VERSION,
    JSON_SCHEMA_DATA_PATH,
    OPEN_API_DATA_PATH,
    get_current_version_args,
    run_main_and_assert,
)

if TYPE_CHECKING:
    from pathlib import Path

_CURRENT_PY_VERSION = PythonVersion(CURRENT_PYTHON_VERSION)
_SKIP_BLACK = pytest.mark.skipif(
    not is_supported_in_black(_CURRENT_PY_VERSION),
    reason=f"Installed black doesn't support Python {CURRENT_PYTHON_VERSION}",
)


@_SKIP_BLACK
def test_openapi_api_exec_current_version(output_file: Path) -> None:
    """Test that api.yaml schema generates executable code on current Python."""
    run_main_and_assert(
        input_path=OPEN_API_DATA_PATH / "api.yaml",
        output_path=output_file,
        extra_args=get_current_version_args("--output-model-type", "pydantic_v2.BaseModel"),
        skip_code_validation=False,
        force_exec_validation=True,
    )


@_SKIP_BLACK
def test_openapi_with_refs_exec_current_version(output_file: Path) -> None:
    """Test that OpenAPI schema with $ref generates executable code."""
    run_main_and_assert(
        input_path=OPEN_API_DATA_PATH / "body_and_parameters.yaml",
        output_path=output_file,
        extra_args=get_current_version_args("--output-model-type", "pydantic_v2.BaseModel"),
        skip_code_validation=False,
        force_exec_validation=True,
    )


@_SKIP_BLACK
def test_openapi_allof_exec_current_version(output_file: Path) -> None:
    """Test that OpenAPI schema with allOf generates executable code."""
    run_main_and_assert(
        input_path=OPEN_API_DATA_PATH / "allof.yaml",
        output_path=output_file,
        extra_args=get_current_version_args("--output-model-type", "pydantic_v2.BaseModel"),
        skip_code_validation=False,
        force_exec_validation=True,
    )


@_SKIP_BLACK
def test_jsonschema_person_exec_current_version(output_file: Path) -> None:
    """Test that person.json schema generates executable code on current Python."""
    run_main_and_assert(
        input_path=JSON_SCHEMA_DATA_PATH / "person.json",
        output_path=output_file,
        extra_args=get_current_version_args("--output-model-type", "pydantic_v2.BaseModel"),
        skip_code_validation=False,
        force_exec_validation=True,
    )


@_SKIP_BLACK
def test_jsonschema_nested_array_exec_current_version(output_file: Path) -> None:
    """Test that nested array JSON Schema generates executable code."""
    run_main_and_assert(
        input_path=JSON_SCHEMA_DATA_PATH / "nested_array.json",
        output_path=output_file,
        extra_args=get_current_version_args("--output-model-type", "pydantic_v2.BaseModel"),
        skip_code_validation=False,
        force_exec_validation=True,
    )


@_SKIP_BLACK
def test_jsonschema_circular_reference_exec_current_version(output_file: Path) -> None:
    """Test that circular reference JSON Schema generates executable code."""
    run_main_and_assert(
        input_path=JSON_SCHEMA_DATA_PATH / "circular_reference.json",
        output_path=output_file,
        extra_args=get_current_version_args("--output-model-type", "pydantic_v2.BaseModel"),
        skip_code_validation=False,
        force_exec_validation=True,
    )


@_SKIP_BLACK
@pytest.mark.skipif(
    sys.version_info[:2] <= (3, 10),
    reason="Need runtime > target (3.10) to test force_exec_validation behavior",
)
def test_force_exec_with_different_target_version(output_file: Path) -> None:
    """Test that force_exec_validation runs exec even with different target version.

    This test uses --target-python-version 3.10 but force_exec_validation=True
    to verify that exec still runs on the current Python version.

    Requirements for this test to be meaningful:
    - Runtime must be > 3.10 (so target < runtime, allowing compile to proceed)
    - This ensures force_exec_validation can bypass the version mismatch skip
    """
    run_main_and_assert(
        input_path=JSON_SCHEMA_DATA_PATH / "person.json",
        output_path=output_file,
        extra_args=["--target-python-version", "3.10", "--output-model-type", "pydantic_v2.BaseModel"],
        skip_code_validation=False,
        force_exec_validation=True,
    )


def test_get_current_version_args_basic() -> None:
    """Test that get_current_version_args returns correct args."""
    args = get_current_version_args()
    assert args == ["--target-python-version", CURRENT_PYTHON_VERSION]


def test_get_current_version_args_with_extra() -> None:
    """Test that get_current_version_args includes extra args."""
    args = get_current_version_args("--use-field-description", "--strict")
    assert args == [
        "--target-python-version",
        CURRENT_PYTHON_VERSION,
        "--use-field-description",
        "--strict",
    ]


def test_current_python_version_format() -> None:
    """Test that CURRENT_PYTHON_VERSION matches expected format."""
    expected = f"{sys.version_info[0]}.{sys.version_info[1]}"
    assert expected == CURRENT_PYTHON_VERSION