Skip to content

Commit

Permalink
Fix compatibility with Python 3.9
Browse files Browse the repository at this point in the history
  • Loading branch information
shepilov-vladislav committed Jun 29, 2024
1 parent 520275d commit b4b4082
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 35 deletions.
8 changes: 5 additions & 3 deletions fastapi_filter/contrib/beanie/filter.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
from collections.abc import Callable, Mapping
from typing import Any
from typing import Any, Optional

from beanie.odm.interfaces.find import FindType
from beanie.odm.queries.find import FindMany
from pydantic import ValidationInfo, field_validator

from fastapi_filter.base.filter import BaseFilterModel

_odm_operator_transformer: dict[str, Callable[[str | None], dict[str, Any] | None]] = {
_odm_operator_transformer: dict[str, Callable[[Optional[str]], Optional[dict[str, Any]]]] = {
"neq": lambda value: {"$ne": value},
"gt": lambda value: {"$gt": value},
"gte": lambda value: {"$gte": value},
Expand Down Expand Up @@ -54,7 +54,9 @@ def sort(self, query: FindMany[FindType]) -> FindMany[FindType]:

@field_validator("*", mode="before")
@classmethod
def split_str(cls: type["BaseFilterModel"], value: str | None, field: ValidationInfo) -> list[str] | str | None:
def split_str(
cls: type["BaseFilterModel"], value: Optional[str], field: ValidationInfo
) -> Optional[list[str] | str]:
if (
field.field_name is not None
and (
Expand Down
65 changes: 33 additions & 32 deletions tests/test_beanie/conftest.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import asyncio
from collections.abc import AsyncGenerator, Generator
from datetime import datetime
from typing import Optional

import pytest
import pytest_asyncio
Expand All @@ -15,7 +16,7 @@


class Address(Document):
street: str | None = None
street: Optional[str] = None
city: str
country: str

Expand All @@ -27,11 +28,11 @@ class Sport(Document):

class User(Document):
created_at: datetime
name: str | None = None
email: EmailStr | None = None
name: Optional[str] = None
email: Optional[EmailStr] = None
age: int
address: Link[Address] | None = None
favorite_sports: list[Link[Sport]] | None = []
address: Optional[Link[Address]] = None
favorite_sports: Optional[list[Link[Sport]]] = []


@pytest.fixture(scope="session")
Expand Down Expand Up @@ -127,11 +128,11 @@ async def users(
@pytest.fixture(scope="package")
def AddressFilter(Address: Document, Filter: MongoFilter):
class AddressFilter(Filter): # type: ignore[misc, valid-type]
street__isnull: bool | None = None
country: str | None = None
city: str | None = None
city__in: list[str] | None = None
country__nin: list[str] | None = None
street__isnull: Optional[bool] = None
country: Optional[str] = None
city: Optional[str] = None
city__in: Optional[list[str]] = None
country__nin: Optional[list[str]] = None

class Constants(MongoFilter.Constants): # type: ignore[name-defined]
model = Address
Expand All @@ -142,21 +143,21 @@ class Constants(MongoFilter.Constants): # type: ignore[name-defined]
@pytest.fixture(scope="package")
def UserFilter(User, Filter, AddressFilter):
class UserFilter(Filter): # type: ignore[misc, valid-type]
name: str | None = None
name__in: list[str] | None = None
name__nin: list[str] | None = None
name__ne: str | None = None
name__isnull: bool | None = None
age: int | None = None
age__lt: int | None = None
age__lte: int | None = None
age__gt: int | None = None
age__gte: int | None = None
age__in: list[int] | None = None
address: AddressFilter | None = FilterDepends( # type: ignore[valid-type]
name: Optional[str] = None
name__in: Optional[list[str]] = None
name__nin: Optional[list[str]] = None
name__ne: Optional[str] = None
name__isnull: Optional[bool] = None
age: Optional[int] = None
age__lt: Optional[int] = None
age__lte: Optional[int] = None
age__gt: Optional[int] = None
age__gte: Optional[int] = None
age__in: Optional[list[int]] = None
address: Optional[AddressFilter] = FilterDepends( # type: ignore[valid-type]
with_prefix("address", AddressFilter),
)
search: str | None = None
search: Optional[str] = None

class Constants(MongoFilter.Constants): # type: ignore[name-defined]
model = User
Expand All @@ -170,7 +171,7 @@ class Constants(MongoFilter.Constants): # type: ignore[name-defined]
@pytest.fixture(scope="package")
def UserFilterByAlias(UserFilter, AddressFilter):
class UserFilterByAlias(UserFilter): # type: ignore[misc, valid-type]
address: AddressFilter | None = FilterDepends( # type: ignore[valid-type]
address: Optional[AddressFilter] = FilterDepends( # type: ignore[valid-type]
with_prefix("address", AddressFilter),
by_alias=True,
)
Expand All @@ -181,9 +182,9 @@ class UserFilterByAlias(UserFilter): # type: ignore[misc, valid-type]
@pytest.fixture(scope="package")
def SportFilter(Sport, Filter):
class SportFilter(MongoFilter): # type: ignore[misc, valid-type]
name: str | None = Field(Query(description="Name of the sport", default=None))
name: Optional[str] = Field(Query(description="Name of the sport", default=None))
is_individual: bool
bogus_filter: str | None = None
bogus_filter: Optional[str] = None

class Constants(MongoFilter.Constants): # type: ignore [name-defined]
model = Sport
Expand All @@ -201,8 +202,8 @@ def AddressOut():
class AddressOut(BaseModel):
model_config = ConfigDict(from_attributes=True)

id: PydanticObjectId | None = Field(default=None, description="MongoDB document ObjectID")
street: str | None = None
id: Optional[PydanticObjectId] = Field(default=None, description="MongoDB document ObjectID")
street: Optional[str] = None
city: str
country: str

Expand All @@ -214,11 +215,11 @@ def UserOut(AddressOut):
class UserOut(BaseModel):
model_config = ConfigDict(from_attributes=True)

id: PydanticObjectId | None = Field(default=None, description="MongoDB document ObjectID")
id: Optional[PydanticObjectId] = Field(default=None, description="MongoDB document ObjectID")
created_at: datetime
name: str | None = None
name: Optional[str] = None
age: int
address: AddressOut | None = None # type: ignore[valid-type]
address: Optional[AddressOut] = None # type: ignore[valid-type]

yield UserOut

Expand All @@ -228,7 +229,7 @@ def SportOut():
class SportOut(BaseModel):
model_config = ConfigDict(from_attributes=True)

id: PydanticObjectId | None = Field(default=None, description="MongoDB document ObjectID")
id: Optional[PydanticObjectId] = Field(default=None, description="MongoDB document ObjectID")
name: str
is_individual: bool

Expand Down

0 comments on commit b4b4082

Please sign in to comment.