Skip to content

Commit

Permalink
Bump dependencies versions (#1385)
Browse files Browse the repository at this point in the history
  • Loading branch information
uriyyo authored Dec 9, 2024
1 parent 3a21f63 commit cab00f7
Show file tree
Hide file tree
Showing 33 changed files with 1,013 additions and 772 deletions.
47 changes: 11 additions & 36 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,13 @@ on:
jobs:
test:
runs-on: ubuntu-latest
name: "py${{ matrix.python-version }}; pydantic-${{ matrix.pydantic_v2 == 'true' && 'v2' || 'v1' }}; fastapi${{ matrix.fastapi_pre_0_112_4 == 'true' && '<0.12.4' || '>=0.12.4' }}"
strategy:
fail-fast: false
matrix:
python-version: [ "3.8", "3.9", "3.10", "3.11" ] # , "3.12" ]
python-version: [ "3.8", "3.9", "3.10", "3.11", "3.12", "3.13" ]
pydantic_v2: [ "true", "false" ]
fastapi_version: [ "<0.112.4", ">=0.112.4" ]
fastapi_pre_0_112_4: [ "true", "false" ]

steps:
- uses: actions/checkout@v4
Expand Down Expand Up @@ -58,41 +59,15 @@ jobs:
~/.cache/pypoetry/virtualenvs
key: ${{ runner.os }}-py${{ matrix.python-version }}-poetry-${{ hashFiles('poetry.lock') }}-v1

- name: Install dependencies
- name: Run tests
shell: bash
env:
CQL_TEST_HOST: ${{ env.CQL_TEST_HOST }}
PY_VERSION: ${{ matrix.python-version }}
PYDANTIC_V2: ${{ matrix.pydantic_v2 }}
FASTAPI_PRE_0_112_4: ${{ matrix.fastapi_pre_0_112_4 }}
run: |
poetry install -E all --sync
- name: Install pydantic v2
if: ${{ matrix.pydantic_v2 == 'true' }}
run: |
poetry run pip install -U --pre fastapi pydantic
- name: Install FastAPI
run : |
poetry run pip install -U "fastapi${{ matrix.fastapi_version }}"
- name: Unit tests pydantic v2
if: ${{ matrix.pydantic_v2 == 'true' }}
run: |
poetry run pytest tests --ignore=tests/ext --cov-report=xml --cassandra-dsn=${CQL_TEST_HOST}
- name: Unit tests
if: ${{ matrix.pydantic_v2 == 'false' }}
run: |
poetry run pytest tests -m "not gino" --cov-report=xml --cassandra-dsn=${CQL_TEST_HOST}
- name: Unit tests SQLAlchemy 2.0
if: ${{ matrix.pydantic_v2 == 'false' }}
run: |
poetry run pip install -U "sqlalchemy>2.0.0"
poetry run pytest tests -m "sqlalchemy20" --cov-append --cov-report=xml --cassandra-dsn=${CQL_TEST_HOST}
# TODO: remove it when ormar will support pydantic v2
- name: Unit tests Odmantic
if: ${{ matrix.pydantic_v2 == 'true' }}
run: |
poetry run pip install -U odmantic "pydantic<2.7"
poetry run pytest tests -m "odmantic" --cov-append --cov-report=xml --cassandra-dsn=${CQL_TEST_HOST}
bash scripts/ci-test.sh
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v5
Expand Down
4 changes: 2 additions & 2 deletions fastapi_pagination/bases.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,11 @@
if IS_PYDANTIC_V2:
from pydantic import BaseModel as GenericModel
else:
from pydantic.generics import GenericModel
from pydantic.generics import GenericModel # type: ignore[no-redef]


try:
from pydantic import PydanticUndefinedAnnotation # type: ignore[attr-defined]
from pydantic import PydanticUndefinedAnnotation
except ImportError:

class PydanticUndefinedAnnotation(Exception): # type: ignore[no-redef]
Expand Down
8 changes: 4 additions & 4 deletions fastapi_pagination/customization.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,9 +189,9 @@ def customize_page_ns(self, page_cls: PageCls, ns: ClsNamespace) -> None:

def _get_model_fields(cls: Type[BaseModel]) -> ClsNamespace:
if IS_PYDANTIC_V2:
return cls.model_fields # type: ignore
return {**cls.model_fields}

return cls.__fields__
return {**cls.__fields__} # type: ignore[dict-item]


if IS_PYDANTIC_V2:
Expand All @@ -210,7 +210,7 @@ def _make_field_optional(field: Any) -> Any:
return field

else:
from pydantic.fields import ModelField as _PydanticField # type: ignore[assignment]
from pydantic.fields import ModelField as _PydanticField # type: ignore

def _make_field_optional(field: Any) -> Any:
assert isinstance(field, _PydanticField)
Expand Down Expand Up @@ -321,7 +321,7 @@ def customize_page_ns(self, page_cls: PageCls, ns: ClsNamespace) -> None:
fields_config = _pydantic_v1_get_inited_fields(ns["Config"], *self.aliases)

for name, alias in self.aliases.items():
assert name in page_cls.__fields__, f"Unknown field {name!r}"
assert name in page_cls.__fields__, f"Unknown field {name!r}" # type: ignore[operator]
fields_config[name]["alias"] = alias


Expand Down
4 changes: 2 additions & 2 deletions fastapi_pagination/ext/async_sqlalchemy.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

__all__ = ["paginate"]

from typing import Any, Optional, Union
from typing import Any, Optional, Tuple, Union

from sqlalchemy.ext.asyncio import AsyncConnection, AsyncSession
from sqlalchemy.sql import Select
Expand All @@ -20,7 +20,7 @@
)
async def paginate(
conn: Union[AsyncSession, AsyncConnection],
query: Select,
query: Select[Tuple[Any, ...]],
params: Optional[AbstractParams] = None,
*,
transformer: Optional[AsyncItemsTransformer] = None,
Expand Down
7 changes: 6 additions & 1 deletion fastapi_pagination/ext/beanie.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

__all__ = ["paginate"]

from copy import copy
from typing import TYPE_CHECKING, Any, List, Optional, Tuple, Type, TypeVar, Union

from beanie import Document
Expand Down Expand Up @@ -58,8 +59,12 @@ async def paginate(
except IndexError:
total = 0
else:
# avoid original query mutation
count_query = copy(query)
query = copy(query)

if raw_params.include_total:
total = await query.find(
total = await count_query.find(
{},
session=session,
ignore_cache=ignore_cache,
Expand Down
4 changes: 2 additions & 2 deletions fastapi_pagination/ext/databases.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

__all__ = ["paginate"]

from typing import Any, List, Optional
from typing import Any, List, Optional, Tuple

from databases import Database
from sqlalchemy.sql import Select
Expand All @@ -16,7 +16,7 @@

async def paginate(
db: Database,
query: Select,
query: Select[Tuple[Any, ...]],
params: Optional[AbstractParams] = None,
*,
transformer: Optional[AsyncItemsTransformer] = None,
Expand Down
6 changes: 3 additions & 3 deletions fastapi_pagination/ext/odmantic.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ async def paginate(


@overload
def paginate( # type: ignore
def paginate(
engine: SyncEngine,
model: Type[Model],
*queries: _Query,
Expand Down Expand Up @@ -136,11 +136,11 @@ def paginate(
func = async_paginate if isinstance(engine, AIOEngine) else sync_paginate

return func(
engine,
engine, # type: ignore[arg-type]
model,
*queries,
sort=sort,
session=session,
session=session, # type: ignore[arg-type]
params=params,
transformer=transformer, # type: ignore[arg-type]
additional_data=additional_data,
Expand Down
33 changes: 18 additions & 15 deletions fastapi_pagination/ext/sqlalchemy.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,8 @@ def __init__(self, *_: Any, **__: Any) -> None:
paging = None # type: ignore[assignment]


AsyncConn: TypeAlias = "Union[AsyncSession, AsyncConnection, async_scoped_session]"
SyncConn: TypeAlias = "Union[Session, Connection, scoped_session]"
AsyncConn: TypeAlias = "Union[AsyncSession, AsyncConnection, async_scoped_session[Any]]"
SyncConn: TypeAlias = "Union[Session, Connection, scoped_session[Any]]"

UnwrapMode: TypeAlias = Literal[
"auto", # default, unwrap only if select is select(model)
Expand All @@ -77,13 +77,16 @@ def __init__(self, *_: Any, **__: Any) -> None:
"unwrap", # always unwrap
]

Selectable: TypeAlias = Union[Select, TextClause, FromStatement, CompoundSelect]
TupleAny: TypeAlias = "Tuple[Any, ...]"
Selectable: TypeAlias = "Union[Select[TupleAny], TextClause, FromStatement[TupleAny], CompoundSelect]"
SelectableOrQuery: TypeAlias = "Union[Selectable, Query[Any]]"

_selectable_classes = (Select, TextClause, FromStatement, CompoundSelect)


@no_type_check
def _should_unwrap_scalars(query: Selectable) -> bool:
if not isinstance(query, get_args(Selectable)):
if not isinstance(query, _selectable_classes):
return False

if isinstance(query, CompoundSelect):
Expand Down Expand Up @@ -134,13 +137,13 @@ def create_count_query_from_text(query: str) -> str:
"please use fastapi_pagination.ext.sqlalchemy.create_paginate_query function instead"
"This function will be removed in the next major release (0.13.0).",
)
def paginate_query(query: Select, params: AbstractParams) -> Select:
def paginate_query(query: Select[TupleAny], params: AbstractParams) -> Select[TupleAny]:
return create_paginate_query(query, params) # type: ignore[return-value]


def _paginate_from_statement(query: FromStatement, params: AbstractParams) -> FromStatement:
query = query._generate() # type: ignore[attr-defined]
query.element = create_paginate_query(query.element, params)
def _paginate_from_statement(query: FromStatement[TupleAny], params: AbstractParams) -> FromStatement[TupleAny]:
query = query._generate()
query.element = create_paginate_query(query.element, params) # type: ignore[arg-type]
return query


Expand All @@ -157,14 +160,14 @@ def create_count_query(query: Selectable, *, use_subquery: bool = True) -> Selec
if isinstance(query, TextClause):
return text(create_count_query_from_text(query.text))
if isinstance(query, FromStatement):
return create_count_query(query.element)
return create_count_query(query.element) # type: ignore[arg-type]

query = query.order_by(None).options(noload("*"))

if use_subquery:
return select(func.count()).select_from(query.subquery())

return query.with_only_columns( # type: ignore[call-arg,union-attr] # noqa: PIE804
return query.with_only_columns( # type: ignore[union-attr]
func.count(),
maintain_column_froms=True,
)
Expand Down Expand Up @@ -245,7 +248,7 @@ def _apply_items_transformer(*args: Any, **kwargs: Any) -> Any:
if not getattr(query, "_order_by_clauses", True):
raise ValueError("Cursor pagination requires ordering")

page = paging.select_page( # type: ignore
page = paging.select_page(
conn, # type: ignore[arg-type]
selectable=query, # type: ignore[arg-type]
per_page=raw_params.size,
Expand Down Expand Up @@ -396,7 +399,7 @@ def _old_paginate_sign(
additional_data: Optional[AdditionalData] = None,
unique: bool = True,
) -> Tuple[
Select,
Select[TupleAny],
Optional[Selectable],
SyncConn,
Optional[AbstractParams],
Expand All @@ -419,14 +422,14 @@ def _old_paginate_sign(
session = query.session

with suppress(AttributeError):
query = query._statement_20() # type: ignore[attr-defined]
query = query._statement_20() # type: ignore[assignment]

return query, None, session, params, transformer, additional_data, unique, subquery_count, unwrap_mode # type: ignore


def _new_paginate_sign(
conn: SyncConn,
query: Select,
query: Select[TupleAny],
params: Optional[AbstractParams] = None,
*,
subquery_count: bool = True,
Expand All @@ -436,7 +439,7 @@ def _new_paginate_sign(
additional_data: Optional[AdditionalData] = None,
unique: bool = True,
) -> Tuple[
Select,
Select[TupleAny],
Optional[Selectable],
SyncConn,
Optional[AbstractParams],
Expand Down
4 changes: 2 additions & 2 deletions fastapi_pagination/ext/sqlalchemy_future.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"paginate",
]

from typing import Any, Optional, Union
from typing import Any, Optional, Tuple, Union

from sqlalchemy.future import Connection
from sqlalchemy.orm import Session
Expand All @@ -23,7 +23,7 @@
)
def paginate(
conn: Union[Connection, Session],
query: Select,
query: Select[Tuple[Any, ...]],
params: Optional[AbstractParams] = None,
*,
transformer: Optional[SyncItemsTransformer] = None,
Expand Down
2 changes: 1 addition & 1 deletion fastapi_pagination/links/bases.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
_link_field = (
Field(examples=["/api/v1/users?limit=1&offset1"])
if IS_PYDANTIC_V2
else Field(example="/api/v1/users?limit=1&offset1")
else Field(example="/api/v1/users?limit=1&offset1") # type: ignore[call-overload]
)


Expand Down
2 changes: 1 addition & 1 deletion fastapi_pagination/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ def get_caller(depth: int = 1) -> Optional[str]:

def create_pydantic_model(model_cls: Type[TModel], /, **kwargs: Any) -> TModel:
if IS_PYDANTIC_V2:
return model_cls.model_validate(kwargs, from_attributes=True) # type: ignore
return model_cls.model_validate(kwargs, from_attributes=True)

return model_cls(**kwargs)

Expand Down
Loading

0 comments on commit cab00f7

Please sign in to comment.