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

import pydantic objects from the _pydantic_compat module #17667

Merged
Merged
Show file tree
Hide file tree
Changes from 3 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
5 changes: 5 additions & 0 deletions changelog.d/17667.misc
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Import pydantic objects from the `_pydantic_compat` module.

This allows `check_pydantic_models.py` to mock those pydantic objects
only in the synapse module, and not interfere with pydantic objects in
external dependencies.
41 changes: 14 additions & 27 deletions scripts-dev/check_pydantic_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,25 +58,18 @@

from parameterized import parameterized

from synapse._pydantic_compat import HAS_PYDANTIC_V2
from synapse._pydantic_compat import (
HAS_PYDANTIC_V2,
BaseModel as PydanticBaseModel,
conbytes,
confloat,
conint,
constr,
)

if TYPE_CHECKING or HAS_PYDANTIC_V2:
from pydantic.v1 import (
BaseModel as PydanticBaseModel,
conbytes,
confloat,
conint,
constr,
)
from pydantic.v1.typing import get_args
else:
from pydantic import (
BaseModel as PydanticBaseModel,
conbytes,
confloat,
conint,
constr,
)
from pydantic.typing import get_args

from typing_extensions import ParamSpec
Expand Down Expand Up @@ -183,22 +176,16 @@ def monkeypatch_pydantic() -> Generator[None, None, None]:
# Most Synapse code ought to import the patched objects directly from
# `pydantic`. But we also patch their containing modules `pydantic.main` and
# `pydantic.types` for completeness.
patch_basemodel1 = unittest.mock.patch(
"pydantic.BaseModel", new=PatchedBaseModel
)
patch_basemodel2 = unittest.mock.patch(
"pydantic.main.BaseModel", new=PatchedBaseModel
patch_basemodel = unittest.mock.patch(
"synapse._pydantic_compat.BaseModel", new=PatchedBaseModel
)
patches.enter_context(patch_basemodel1)
patches.enter_context(patch_basemodel2)
patches.enter_context(patch_basemodel)
for factory in CONSTRAINED_TYPE_FACTORIES_WITH_STRICT_FLAG:
wrapper: Callable = make_wrapper(factory)
patch1 = unittest.mock.patch(f"pydantic.{factory.__name__}", new=wrapper)
patch2 = unittest.mock.patch(
f"pydantic.types.{factory.__name__}", new=wrapper
patch = unittest.mock.patch(
f"synapse._pydantic_compat.{factory.__name__}", new=wrapper
)
patches.enter_context(patch1)
patches.enter_context(patch2)
patches.enter_context(patch)
yield


Expand Down
9 changes: 8 additions & 1 deletion synapse/_pydantic_compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
#
#

from typing import TYPE_CHECKING

from packaging.version import Version

try:
Expand All @@ -30,4 +32,9 @@

HAS_PYDANTIC_V2: bool = Version(pydantic_version).major == 2

__all__ = ("HAS_PYDANTIC_V2",)
if TYPE_CHECKING or HAS_PYDANTIC_V2:
from pydantic.v1 import BaseModel, conbytes, confloat, conint, constr
else:
from pydantic import BaseModel, conbytes, confloat, conint, constr

__all__ = ("HAS_PYDANTIC_V2", "BaseModel", "constr", "conbytes", "conint", "confloat")
6 changes: 3 additions & 3 deletions synapse/config/_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,12 @@

import jsonschema

from synapse._pydantic_compat import HAS_PYDANTIC_V2
from synapse._pydantic_compat import HAS_PYDANTIC_V2, BaseModel

if TYPE_CHECKING or HAS_PYDANTIC_V2:
from pydantic.v1 import BaseModel, ValidationError, parse_obj_as
from pydantic.v1 import ValidationError, parse_obj_as
azmeuk marked this conversation as resolved.
Show resolved Hide resolved
else:
from pydantic import BaseModel, ValidationError, parse_obj_as
from pydantic import ValidationError, parse_obj_as

from synapse.config._base import ConfigError
from synapse.types import JsonDict, StrSequence
Expand Down
6 changes: 3 additions & 3 deletions synapse/config/workers.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,12 @@

import attr

from synapse._pydantic_compat import HAS_PYDANTIC_V2
from synapse._pydantic_compat import HAS_PYDANTIC_V2, BaseModel

if TYPE_CHECKING or HAS_PYDANTIC_V2:
from pydantic.v1 import BaseModel, Extra, StrictBool, StrictInt, StrictStr
from pydantic.v1 import Extra, StrictBool, StrictInt, StrictStr
else:
from pydantic import BaseModel, Extra, StrictBool, StrictInt, StrictStr
from pydantic import Extra, StrictBool, StrictInt, StrictStr

from synapse.config._base import (
Config,
Expand Down
6 changes: 3 additions & 3 deletions synapse/http/servlet.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,13 @@
overload,
)

from synapse._pydantic_compat import HAS_PYDANTIC_V2
from synapse._pydantic_compat import HAS_PYDANTIC_V2, BaseModel

if TYPE_CHECKING or HAS_PYDANTIC_V2:
from pydantic.v1 import BaseModel, MissingError, PydanticValueError, ValidationError
from pydantic.v1 import MissingError, PydanticValueError, ValidationError
from pydantic.v1.error_wrappers import ErrorWrapper
else:
from pydantic import BaseModel, MissingError, PydanticValueError, ValidationError
from pydantic import MissingError, PydanticValueError, ValidationError
from pydantic.error_wrappers import ErrorWrapper

from typing_extensions import Literal
Expand Down
6 changes: 3 additions & 3 deletions synapse/rest/client/account.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,12 @@
from typing import TYPE_CHECKING, List, Optional, Tuple
from urllib.parse import urlparse

from synapse._pydantic_compat import HAS_PYDANTIC_V2
from synapse._pydantic_compat import HAS_PYDANTIC_V2, constr

if TYPE_CHECKING or HAS_PYDANTIC_V2:
from pydantic.v1 import StrictBool, StrictStr, constr
from pydantic.v1 import StrictBool, StrictStr
else:
from pydantic import StrictBool, StrictStr, constr
from pydantic import StrictBool, StrictStr

import attr
from typing_extensions import Literal
Expand Down
7 changes: 1 addition & 6 deletions synapse/storage/background_updates.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@

import attr

from synapse._pydantic_compat import HAS_PYDANTIC_V2
from synapse._pydantic_compat import BaseModel
from synapse.metrics.background_process_metrics import run_as_background_process
from synapse.storage.engines import PostgresEngine
from synapse.storage.types import Connection, Cursor
Expand All @@ -49,11 +49,6 @@

from . import engines

if TYPE_CHECKING or HAS_PYDANTIC_V2:
from pydantic.v1 import BaseModel
else:
from pydantic import BaseModel

if TYPE_CHECKING:
from synapse.server import HomeServer
from synapse.storage.database import (
Expand Down
6 changes: 3 additions & 3 deletions synapse/types/rest/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,12 @@
#
from typing import TYPE_CHECKING

from synapse._pydantic_compat import HAS_PYDANTIC_V2
from synapse._pydantic_compat import HAS_PYDANTIC_V2, BaseModel

if TYPE_CHECKING or HAS_PYDANTIC_V2:
from pydantic.v1 import BaseModel, Extra
from pydantic.v1 import Extra
else:
from pydantic import BaseModel, Extra
from pydantic import Extra


class RequestBodyModel(BaseModel):
Expand Down
8 changes: 2 additions & 6 deletions synapse/types/rest/client/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,14 @@
#
from typing import TYPE_CHECKING, Dict, List, Optional, Tuple, Union

from synapse._pydantic_compat import HAS_PYDANTIC_V2
from synapse._pydantic_compat import HAS_PYDANTIC_V2, conint, constr

if TYPE_CHECKING or HAS_PYDANTIC_V2:
from pydantic.v1 import (
Extra,
StrictBool,
StrictInt,
StrictStr,
conint,
constr,
validator,
)
else:
Expand All @@ -38,8 +36,6 @@
StrictBool,
StrictInt,
StrictStr,
conint,
constr,
validator,
)

Expand Down Expand Up @@ -384,7 +380,7 @@ class TypingExtension(RequestBodyModel):
receipts: Optional[ReceiptsExtension] = None
typing: Optional[TypingExtension] = None

conn_id: Optional[str]
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My modifications revealed an issue with this str type that was rejected by check_pydantic_models. I am not sure if this was wanted though.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change seems fine to me. conn_id should be a string.

conn_id: Optional[StrictStr]

# mypy workaround via https://github.com/pydantic/pydantic/issues/156#issuecomment-1130883884
if TYPE_CHECKING:
Expand Down
6 changes: 3 additions & 3 deletions tests/rest/client/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,13 @@

from typing_extensions import Literal

from synapse._pydantic_compat import HAS_PYDANTIC_V2
from synapse._pydantic_compat import HAS_PYDANTIC_V2, BaseModel
from synapse.types.rest.client import EmailRequestTokenBody

if TYPE_CHECKING or HAS_PYDANTIC_V2:
from pydantic.v1 import BaseModel, ValidationError
from pydantic.v1 import ValidationError
else:
from pydantic import BaseModel, ValidationError
from pydantic import ValidationError


class ThreepidMediumEnumTestCase(stdlib_unittest.TestCase):
Expand Down