0

This Condition leads to infinite recursion.

if self.page == 1:
            return self

I trying to handle a paginated response from an API, So I created PaginatedResponse class to manage it. I wanted my class to iterable so I add a __iter__ method inside and returned the self or next page depending on Page attribute in my instance now I face the problem that I am stuck in the first next() and I can't seem to fix it.

from math import ceil


class PaginatedResponse:
    def __init__(self, response) -> None:
        self.response = response
        self.attrs = response.body()
        self.total_results = self.attrs.get("total_results")
        self.page = self.attrs.get("page")
        self.per_page = self.attrs.get("per_page")
        self.prev_page = self.attrs.get("prev_page")
        self.next_page = self.attrs.get("next_page")

    def total_pages(self) -> int:
        return ceil(self.total_results / self.per_page)

    def __iter__(self):
        return self

    def __next__(self):
        if self.page > self.total_pages():
            return StopIteration
        print(self.page, end=" -> ")
        if self.page == 1:
            return self
        return self.get_next_page()

    def get_next_page(self):
        if not self.next_page:
            return None
        self._request.params = {
            "page": self.page + 1,
        }
        self = PaginatedResponse(self._request.send())
        return self

    def get_prev_page(self):
        if not self.prev_page:
            return None
        self._request.params = {
            "page": self.page - 1,
        }
        self = PaginatedResponse(self._request.send())
        return self

    @property
    def _request(self):
        return self.response.request

I tried to change the conditions, but I can't manage to make it work. I did try to make it always return self.get_next_page() but that led to my skipping page 1 of the response.

Vy Do
  • 46,709
  • 59
  • 215
  • 313
Hushm
  • 31
  • 1
  • 7
  • you should edit your `__next__` method to always return the next page as a new `PaginatedResponse` instance. – Freeman Aug 22 '23 at 07:53
  • @Freeman Then I will always skip the first page. – Hushm Aug 22 '23 at 07:56
  • so check if the current page is greater than the total number of pages before raising the `StopIteration` exception!!! let me fix your code... – Freeman Aug 22 '23 at 07:58
  • 2
    Use `raise StopIteration`. Not `return StopIteration`. – 9769953 Aug 22 '23 at 08:00
  • It is not recursion; it is a loop. It happens because there is *nothing in this code that could ever cause the value of `self.page` to change* once initially set; and `__next__` is *called repeatedly until* a `StopIteration` is `raise`d (*not* `return`ed). – Karl Knechtel Aug 24 '23 at 16:53

0 Answers0