Skip to content

Commit

Permalink
chore(infra): fix ci issues
Browse files Browse the repository at this point in the history
  • Loading branch information
Goldziher committed Jul 15, 2023
1 parent 5a38660 commit 7354ab7
Show file tree
Hide file tree
Showing 11 changed files with 53 additions and 86 deletions.
5 changes: 4 additions & 1 deletion .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,10 @@ jobs:
run: poetry install --no-interaction
- if: ${{ inputs.pydantic-version == '1' }}
name: Install pydantic v1
run: source .venv/bin/activate && pip install "pydantic>=1.10.10"
run: poetry add "pydantic>=1.10.10,<2" && poetry remove pydantic-extra-types
- if: ${{ inputs.pydantic-version == '2' }}
name: Install pydantic v2
run: poetry add "pydantic>=2" && poetry add pydantic-extra-types
- name: Set pythonpath
run: echo "PYTHONPATH=$PWD" >> $GITHUB_ENV
- name: Test
Expand Down
2 changes: 1 addition & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,6 @@
(PY_METH, "_types.TypeDecorator.process_bind_param"),
(PY_METH, "_types.TypeDecorator.process_result_value"),
(PY_METH, "type_engine"),
(PY_METH, "litestar.typing.ParsedType.is_subclass_of"),
# type vars and aliases / intentionally undocumented
(PY_CLASS, "RouteHandlerType"),
(PY_OBJ, "litestar.security.base.AuthType"),
Expand All @@ -114,6 +113,7 @@
(PY_CLASS, "litestar.response.RedirectResponse"),
(PY_CLASS, "anyio.abc.BlockingPortal"),
(PY_CLASS, "litestar.typing.ParsedType"),
(PY_CLASS, "pydantic.BaseModel"),
]

nitpick_ignore_regex = [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@
class BaseModel(_BaseModel):
"""Extend Pydantic's BaseModel to enable ORM mode"""

class Config:
orm_mode = True
model_config = {"from_attributes": True}


# the SQLAlchemy base includes a declarative model for you to use in your models.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@
class BaseModel(_BaseModel):
"""Extend Pydantic's BaseModel to enable ORM mode"""

class Config:
orm_mode = True
model_config = {"from_attributes": True}


# we are going to add a simple "slug" to our model that is a URL safe surrogate key to
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@
class BaseModel(_BaseModel):
"""Extend Pydantic's BaseModel to enable ORM mode"""

class Config:
orm_mode = True
model_config = {"from_attributes": True}


# the SQLAlchemy base includes a declarative model for you to use in your models.
Expand Down
13 changes: 9 additions & 4 deletions litestar/dto/factory/_backends/pydantic/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from typing import TYPE_CHECKING, TypeVar, Union

from msgspec import UNSET, UnsetType
from pydantic import BaseModel, create_model
from pydantic import VERSION, BaseModel, create_model
from pydantic.fields import FieldInfo

from litestar.dto.factory._backends.utils import create_transfer_model_type_annotation
Expand All @@ -21,9 +21,14 @@


class _OrmModeBase(BaseModel):
class Config:
arbitrary_types_allowed = True
orm_mode = True
if VERSION.startswith("1"):

class Config:
arbitrary_types_allowed = True
orm_mode = True

else:
model_config = {"arbitrary_types_allowed": True, "from_attributes": True}


def _create_field_info(field_definition: TransferDTOFieldDefinition) -> FieldInfo:
Expand Down
4 changes: 3 additions & 1 deletion litestar/serialization/_pydantic_serialization.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,9 @@ def create_pydantic_encoders() -> dict[Any, Callable[[Any], Any]]:
if pydantic.VERSION.startswith("1"): # pragma: no cover
encoders.update(
{
pydantic.BaseModel: lambda model: model.dict(),
pydantic.BaseModel: lambda model: {
k: v if not isinstance(v, bytes) else v.decode() for k, v in model.dict().items()
},
pydantic.SecretField: str,
pydantic.StrictBool: int,
pydantic.color.Color: str, # pyright: ignore
Expand Down
50 changes: 5 additions & 45 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ picologging = "*"
pre-commit = "*"
prometheus-client = "*"
psycopg = "*"
pydantic = ">=2"
pydantic = "*"
pydantic-extra-types = "*"
pytest = "*"
pytest-asyncio = "*"
Expand Down Expand Up @@ -259,6 +259,7 @@ exclude_lines = [
'except ImportError:',
'\.\.\.',
'raise NotImplementedError',
'if VERSION.startswith("1"):',
]

[tool.pytest.ini_options]
Expand Down
12 changes: 11 additions & 1 deletion tests/unit/test_serialization.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,17 @@ def test_serialization_of_model_instance(model: BaseModel) -> None:
def test_pydantic_json_compatibility(model: BaseModel) -> None:
raw = model.model_dump_json() if hasattr(model, "model_dump_json") else model.json()
encoded_json = encode_json(model)
assert json.loads(raw) == json.loads(encoded_json)

raw_result = json.loads(raw)
encoded_result = json.loads(encoded_json)

if VERSION.startswith("1"):
# pydantic v1 dumps decimals into floats as json, we therefore regard this as an error
assert raw_result.get("condecimal") == float(encoded_result.get("condecimal"))
del raw_result["condecimal"]
del encoded_result["condecimal"]

assert raw_result == encoded_result


@pytest.mark.parametrize("encoder", [encode_json, encode_msgpack])
Expand Down
41 changes: 15 additions & 26 deletions tests/unit/test_signature/test_validation.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

import pytest
from attr import define
from pydantic import VERSION, BaseModel
from pydantic import BaseModel
from typing_extensions import TypedDict

from litestar import get, post
Expand Down Expand Up @@ -163,31 +163,20 @@ def test(
data = response.json()

assert data
if VERSION.startswith("1"):
assert data["extra"] == [
{"key": "child.val", "message": "value is not a valid integer", "source": "body"},
{"key": "child.other_val", "message": "value is not a valid integer", "source": "body"},
{"key": "other_child.val.1", "message": "value is not a valid integer", "source": "body"},
{"key": "int_param", "message": "value is not a valid integer", "source": "query"},
{"key": "length_param", "message": "ensure this value has at least 2 characters", "source": "query"},
{"key": "int_header", "message": "value is not a valid integer", "source": "header"},
{"key": "int_cookie", "message": "value is not a valid integer", "source": "cookie"},
]
else:
assert data["extra"] == [
{
"message": "Input should be a valid integer, unable to parse string as an integer",
"key": "child.val",
},
{
"message": "Input should be a valid integer, unable to parse string as an integer",
"key": "child.other_val",
},
{
"message": "Input should be a valid integer, unable to parse string as an integer",
"key": "other_child.val.1",
},
]
assert data["extra"] == [
{
"message": "Input should be a valid integer, unable to parse string as an integer",
"key": "child.val",
},
{
"message": "Input should be a valid integer, unable to parse string as an integer",
"key": "child.other_val",
},
{
"message": "Input should be a valid integer, unable to parse string as an integer",
"key": "other_child.val.1",
},
]


def test_invalid_input_attrs() -> None:
Expand Down

0 comments on commit 7354ab7

Please sign in to comment.