Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions src/azure_functions_validation/decorator.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@

from collections.abc import Callable, Mapping
import inspect
import sys
import types
from typing import Any, get_type_hints
import warnings

from pydantic import TypeAdapter
from pydantic.v1 import BaseModel as BaseModelV1

from ._endpoint import build_endpoint_metadata, set_endpoint_metadata
from ._metadata import METADATA_ATTR, ValidationMetadata, set_validation_metadata
Expand Down Expand Up @@ -146,7 +146,13 @@ def decorator(func: Callable[..., Any]) -> Callable[..., Any]:
("request_model", request_model),
("response_model", response_model),
):
if isinstance(model, type(BaseModelV1)) and issubclass(model, BaseModelV1):
legacy_module = sys.modules.get("pydantic.v1")
legacy_base = getattr(legacy_module, "BaseModel", None)
if (
legacy_base is not None
and isinstance(model, type)
and issubclass(model, legacy_base)
):
raise TypeError(
f"{option_name} uses a Pydantic v1 model; Pydantic v2 models are required"
)
Expand Down
20 changes: 20 additions & 0 deletions tests/test_lazy_legacy_import.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import subprocess
import sys


def test_v2_decoration_does_not_import_legacy_pydantic() -> None:
result = subprocess.run(
[
sys.executable,
"-c",
"import sys; from pydantic import BaseModel; "
"from azure_functions_validation import validate_http; "
"Model = type('Model', (BaseModel,), {'__annotations__': {'name': str}}); "
"validate_http(body=Model)(lambda req, body: body); "
"assert 'pydantic.v1' not in sys.modules",
],
capture_output=True,
text=True,
timeout=30,
)
assert result.returncode == 0, result.stderr
Loading