From cc072bfb218da760f799ab4f16944a0087625782 Mon Sep 17 00:00:00 2001 From: Orlando Becerra Date: Wed, 21 Jun 2023 18:12:29 +0200 Subject: [PATCH 1/3] Pagination per_page gets wrong value after calling next() #1201 (#1202) Co-authored-by: Orlando Becerra --- CHANGES.rst | 8 ++++++++ src/flask_sqlalchemy/pagination.py | 4 ++++ tests/test_pagination.py | 16 +++++++++++++--- 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 74bdcb1b..a5a04634 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,3 +1,11 @@ +Version 3.0.5 +------------- + +Unreleased + +- ``Pagination.next()`` enforces ``max_per_page``. :issue:`1201` + + Version 3.0.4 ------------- diff --git a/src/flask_sqlalchemy/pagination.py b/src/flask_sqlalchemy/pagination.py index 5957de7f..3d49d6e0 100644 --- a/src/flask_sqlalchemy/pagination.py +++ b/src/flask_sqlalchemy/pagination.py @@ -66,6 +66,9 @@ def __init__( self.per_page: int = per_page """The maximum number of items on a page.""" + self.max_per_page: int | None = max_per_page + """The maximum allowed value for ``per_page``.""" + items = self._query_items() if not items and page != 1 and error_out: @@ -249,6 +252,7 @@ def next(self, *, error_out: bool = False) -> Pagination: p = type(self)( page=self.page + 1, per_page=self.per_page, + max_per_page=self.max_per_page, error_out=error_out, count=False, **self._query_args, diff --git a/tests/test_pagination.py b/tests/test_pagination.py index 64258cc9..14e24a9e 100644 --- a/tests/test_pagination.py +++ b/tests/test_pagination.py @@ -145,7 +145,7 @@ def __call__( @pytest.fixture def paginate(app: Flask, db: SQLAlchemy, Todo: t.Any) -> _PaginateCallable: with app.app_context(): - for i in range(1, 101): + for i in range(1, 251): db.session.add(Todo(title=f"task {i}")) db.session.commit() @@ -158,8 +158,8 @@ def test_paginate(paginate: _PaginateCallable) -> None: assert p.page == 1 assert p.per_page == 20 assert len(p.items) == 20 - assert p.total == 100 - assert p.pages == 5 + assert p.total == 250 + assert p.pages == 13 def test_paginate_qs(paginate: _PaginateCallable) -> None: @@ -173,6 +173,16 @@ def test_paginate_max(paginate: _PaginateCallable) -> None: assert p.per_page == 50 +@pytest.mark.usefixtures("app_ctx") +def test_next_page_size(paginate: _PaginateCallable) -> None: + p = paginate(per_page=110, max_per_page=250) + assert p.page == 1 + assert p.per_page == 110 + p = p.next() + assert p.page == 2 + assert p.per_page == 110 + + def test_no_count(paginate: _PaginateCallable) -> None: p = paginate(count=False) assert p.total is None From 72cbae386c964ca6663e026060d3336b451d63e4 Mon Sep 17 00:00:00 2001 From: Pamela Fox Date: Wed, 21 Jun 2023 09:16:56 -0700 Subject: [PATCH 2/3] Improve type hint (#1226) --- CHANGES.rst | 1 + src/flask_sqlalchemy/extension.py | 2 +- tests/test_view_query.py | 3 ++- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index a5a04634..2d4d28b9 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -4,6 +4,7 @@ Version 3.0.5 Unreleased - ``Pagination.next()`` enforces ``max_per_page``. :issue:`1201` +- Improve type hint for ``get_or_404`` return value to be non-optional. :pr:`1226` Version 3.0.4 diff --git a/src/flask_sqlalchemy/extension.py b/src/flask_sqlalchemy/extension.py index 765196e1..eb2a80d8 100644 --- a/src/flask_sqlalchemy/extension.py +++ b/src/flask_sqlalchemy/extension.py @@ -734,7 +734,7 @@ def get_binds(self) -> dict[sa.Table, sa.engine.Engine]: def get_or_404( self, entity: type[_O], ident: t.Any, *, description: str | None = None - ) -> t.Optional[_O]: + ) -> _O: """Like :meth:`session.get() ` but aborts with a ``404 Not Found`` error instead of returning ``None``. diff --git a/tests/test_view_query.py b/tests/test_view_query.py index 7fe6164a..ddbf1bbc 100644 --- a/tests/test_view_query.py +++ b/tests/test_view_query.py @@ -70,10 +70,11 @@ class Quiz(db.Model): db.create_all() - item: Quiz = Quiz() + item: Quiz = Quiz(topic="Python") db.session.add(item) db.session.commit() result = db.get_or_404(Quiz, 1) + assert result.topic == "Python" assert result is item if hasattr(t, "assert_type"): t.assert_type(result, Quiz) From 26d298dbfaf6d5019cf8315ef980ca6b123c97b7 Mon Sep 17 00:00:00 2001 From: Pamela Fox Date: Wed, 21 Jun 2023 10:08:12 -0700 Subject: [PATCH 3/3] release version 3.0.5 (#1228) --- CHANGES.rst | 2 +- src/flask_sqlalchemy/__init__.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 2d4d28b9..ab3fe7da 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,7 +1,7 @@ Version 3.0.5 ------------- -Unreleased +Released 2023-06-21 - ``Pagination.next()`` enforces ``max_per_page``. :issue:`1201` - Improve type hint for ``get_or_404`` return value to be non-optional. :pr:`1226` diff --git a/src/flask_sqlalchemy/__init__.py b/src/flask_sqlalchemy/__init__.py index 16749f6e..5d530cfc 100644 --- a/src/flask_sqlalchemy/__init__.py +++ b/src/flask_sqlalchemy/__init__.py @@ -4,7 +4,7 @@ from .extension import SQLAlchemy -__version__ = "3.0.4" +__version__ = "3.0.5" __all__ = [ "SQLAlchemy",