Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support Pydantic v2 with v1 backport #326

Merged
merged 2 commits into from
Jul 18, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
3 changes: 2 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
.DEFAULT_GOAL:=install

SOURCE_FILES=spectree tests examples
MYPY_SOURCE_FILES=spectree tests # temporary
jaykv marked this conversation as resolved.
Show resolved Hide resolved

install:
pip install -U -e .[email,quart,flask,falcon,starlette,dev]
Expand Down Expand Up @@ -43,6 +44,6 @@ lint:
isort --check --diff --project=spectree ${SOURCE_FILES}
black --check --diff ${SOURCE_FILES}
flake8 ${SOURCE_FILES} --count --show-source --statistics --ignore=D203,E203,W503 --max-line-length=88 --max-complexity=15
mypy --install-types --non-interactive ${SOURCE_FILES}
mypy --install-types --non-interactive ${MYPY_SOURCE_FILES}

.PHONY: test doc
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ classifiers = [
"Topic :: Software Development :: Libraries :: Python Modules",
]
dependencies = [
"pydantic>=1.2,<2",
"pydantic>=1.2,<3",
]

[project.optional-dependencies]
Expand All @@ -37,7 +37,7 @@ dev = [
"syrupy>=4.0",
]
email = [
"pydantic[email]>=1.2,<2",
"pydantic[email]>=1.2,<3",
]
falcon = [
"falcon>=3.0.0",
Expand Down
4 changes: 2 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@
setup(
name="spectree",
install_requires=[
"pydantic>=1.2,<2",
"pydantic>=1.2,<3",
],
extras_require={
"email": ["pydantic[email]>=1.2,<2"],
"email": ["pydantic[email]>=1.2,<3"],
"flask": ["flask"],
"quart": ["quart"],
"falcon": ["falcon>=3.0.0"],
Expand Down
37 changes: 37 additions & 0 deletions spectree/_pydantic.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
from pydantic.version import VERSION as PYDANTIC_VERSION

PYDANTIC2 = PYDANTIC_VERSION.startswith("2")

__all__ = [
"BaseModel",
"ValidationError",
"Field",
"root_validator",
"AnyUrl",
"BaseSettings",
"EmailStr",
"validator",
]

if PYDANTIC2:
from pydantic.v1 import (
AnyUrl,
BaseModel,
BaseSettings,
EmailStr,
Field,
ValidationError,
root_validator,
validator,
)
else:
from pydantic import ( # type: ignore[no-redef,assignment]
AnyUrl,
BaseModel,
BaseSettings,
EmailStr,
Field,
ValidationError,
root_validator,
validator,
)
3 changes: 2 additions & 1 deletion spectree/_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@
Union,
)

from pydantic import BaseModel
from typing_extensions import Protocol

from ._pydantic import BaseModel

ModelType = Type[BaseModel]
OptionalModelType = Optional[ModelType]
NamingStrategy = Callable[[ModelType], str]
Expand Down
3 changes: 1 addition & 2 deletions spectree/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@
from enum import Enum
from typing import TYPE_CHECKING, Any, Dict, List, Mapping, Optional, Union

from pydantic import AnyUrl, BaseModel, BaseSettings, EmailStr, root_validator

from ._pydantic import AnyUrl, BaseModel, BaseSettings, EmailStr, root_validator
from .models import SecurityScheme, Server
from .page import DEFAULT_PAGE_TEMPLATES

Expand Down
2 changes: 1 addition & 1 deletion spectree/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from enum import Enum
from typing import Any, Dict, Optional, Sequence

from pydantic import BaseModel, Field, root_validator, validator
from ._pydantic import BaseModel, Field, root_validator, validator

# OpenAPI names validation regexp
OpenAPI_NAME_RE = re.compile(r"^[A-Za-z0-9-._]+")
Expand Down
2 changes: 1 addition & 1 deletion spectree/plugins/falcon_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@

from falcon import HTTP_400, HTTP_415, HTTPError
from falcon.routing.compiled import _FIELD_PATTERN as FALCON_FIELD_PATTERN
from pydantic import ValidationError

from .._pydantic import ValidationError
from .._types import ModelType
from ..response import Response
from .base import BasePlugin
Expand Down
2 changes: 1 addition & 1 deletion spectree/plugins/flask_plugin.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
from typing import Any, Callable, Mapping, Optional, Tuple, get_type_hints

from flask import Blueprint, abort, current_app, jsonify, make_response, request
from pydantic import BaseModel, ValidationError
from werkzeug.routing import parse_converter_args

from .._pydantic import BaseModel, ValidationError
from .._types import ModelType
from ..response import Response
from ..utils import get_multidict_items, werkzeug_parse_rule
Expand Down
2 changes: 1 addition & 1 deletion spectree/plugins/quart_plugin.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import inspect
from typing import Any, Callable, Mapping, Optional, Tuple, get_type_hints

from pydantic import BaseModel, ValidationError
from quart import Blueprint, abort, current_app, jsonify, make_response, request
from werkzeug.routing import parse_converter_args

from .._pydantic import BaseModel, ValidationError
from .._types import ModelType
from ..response import Response
from ..utils import get_multidict_items, werkzeug_parse_rule
Expand Down
2 changes: 1 addition & 1 deletion spectree/plugins/starlette_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@
from json import JSONDecodeError
from typing import Any, Callable, Optional, get_type_hints

from pydantic import ValidationError
from starlette.convertors import CONVERTOR_TYPES
from starlette.requests import Request
from starlette.responses import HTMLResponse, JSONResponse
from starlette.routing import compile_path

from .._pydantic import ValidationError
from .._types import ModelType
from ..response import Response
from .base import BasePlugin, Context
Expand Down
3 changes: 1 addition & 2 deletions spectree/response.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
from http import HTTPStatus
from typing import Any, Dict, Iterable, List, Optional, Tuple, Union

from pydantic import BaseModel

from ._pydantic import BaseModel
from ._types import ModelType, NamingStrategy, OptionalModelType
from .utils import gen_list_model, get_model_key, parse_code

Expand Down
3 changes: 1 addition & 2 deletions spectree/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@
Union,
)

from pydantic import BaseModel, ValidationError

from ._pydantic import BaseModel, ValidationError
from ._types import ModelType, MultiDict, NamingStrategy, NestedNamingStrategy

# parse HTTP status code to get the code
Expand Down
3 changes: 1 addition & 2 deletions tests/common.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
from enum import Enum, IntEnum
from typing import Dict, List

from pydantic import BaseModel, Field, root_validator

from spectree import BaseFile, ExternalDocs, SecurityScheme, SecuritySchemeData, Tag
from spectree._pydantic import BaseModel, Field, root_validator
from spectree.utils import hash_module_path

api_tag = Tag(
Expand Down
2 changes: 1 addition & 1 deletion tests/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
from typing import Type

import pytest
from pydantic import ValidationError

from spectree import SecurityScheme
from spectree._pydantic import ValidationError
from spectree.config import Configuration, EmailFieldType

from .common import SECURITY_SCHEMAS, WRONG_SECURITY_SCHEMAS_DATA
Expand Down
2 changes: 1 addition & 1 deletion tests/test_response.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
from typing import List, get_type_hints

import pytest
from pydantic import BaseModel

from spectree._pydantic import BaseModel
from spectree.models import ValidationError
from spectree.response import DEFAULT_CODE_DESC, Response
from spectree.utils import gen_list_model
Expand Down
2 changes: 1 addition & 1 deletion tests/test_spec.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import pytest
from falcon import App as FalconApp
from flask import Flask
from pydantic import BaseModel
from starlette.applications import Starlette

from spectree import Response
from spectree._pydantic import BaseModel
from spectree.config import Configuration
from spectree.models import Server, ValidationError
from spectree.plugins.flask_plugin import FlaskPlugin
Expand Down