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
|