diff --git a/docs/index.rst b/docs/index.rst index 32d928f..a883e67 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -102,7 +102,12 @@ instance may choose to return less results than you requested. The responses returned by paginated endpoints contain a "link" header that specifies which parameters to use to get the next and previous pages. Mastodon.py parses these and stores them (if present) in the first (for the previous page) and last (for the -next page) item of the returned list as _pagination_prev and _pagination_next. +next page) item of the returned list as _pagination_prev and _pagination_next. They +are accessible only via attribute-style access, and are not considered in determining +dict equality (meaning their presence will not affect any tests of wheter two dicts +are the same, or whether a specific dict is in a list). Note that this also means that +if you want to persist pagination info with your data, you'll have to take care of that +manually (or persist objects, not just dicts). There are convenience functions available for fetching the previous and next page of a paginated request as well as for fetching all pages starting from a first page. @@ -188,7 +193,8 @@ you can also just write description = mastodon.account_verify_credentials().source.note -and everything will work as intended. +and everything will work as intended. The class used for this is exposed as +`AttribAccessDict`. User dicts diff --git a/mastodon/Mastodon.py b/mastodon/Mastodon.py index 2adc82e..e365ce1 100644 --- a/mastodon/Mastodon.py +++ b/mastodon/Mastodon.py @@ -82,7 +82,7 @@ class AttribAccessDict(dict): return self[attr] else: raise AttributeError("Attribute not found: " + str(attr)) - + def __setattr__(self, attr, val): if attr in self: raise AttributeError("Attribute-style access is read only") @@ -1480,8 +1480,8 @@ class Mastodon: Returns the next page or None if no further data is available. """ if isinstance(previous_page, list) and len(previous_page) != 0: - if '_pagination_next' in previous_page[-1]: - params = copy.deepcopy(previous_page[-1]['_pagination_next']) + if hasattr(previous_page[-1], '_pagination_next'): + params = copy.deepcopy(previous_page[-1]._pagination_next) else: return None else: @@ -1504,8 +1504,8 @@ class Mastodon: Returns the previous page or None if no further data is available. """ if isinstance(next_page, list) and len(next_page) != 0: - if '_pagination_prev' in next_page[0]: - params = copy.deepcopy(next_page[0]['_pagination_prev']) + if hasattr(next_page[0], '_pagination_prev'): + params = copy.deepcopy(next_page[0]._pagination_prev) else: return None else: @@ -1655,7 +1655,6 @@ class Mastodon: Internal API request helper. """ response = None - headers = None remaining_wait = 0 # "pace" mode ratelimiting: Assume constant rate of requests, sleep a little less long than it # would take to not hit the rate limit at that request rate. @@ -1804,7 +1803,7 @@ class Mastodon: next_params['max_id'] = int(matchgroups.group(1)) if "since_id" in next_params: del next_params['since_id'] - response[-1]['_pagination_next'] = next_params + response[-1]._pagination_next = next_params if url['rel'] == 'prev': # Be paranoid and extract since_id specifically @@ -1818,7 +1817,7 @@ class Mastodon: prev_params['since_id'] = int(matchgroups.group(1)) if "max_id" in prev_params: del prev_params['max_id'] - response[0]['_pagination_prev'] = prev_params + response[0]._pagination_prev = prev_params return response diff --git a/mastodon/__init__.py b/mastodon/__init__.py index 787d4e8..21de9ae 100644 --- a/mastodon/__init__.py +++ b/mastodon/__init__.py @@ -1,4 +1,4 @@ -from mastodon.Mastodon import Mastodon, MastodonError, MastodonVersionError, MastodonIllegalArgumentError, MastodonIOError, MastodonFileNotFoundError, MastodonNetworkError, MastodonAPIError, MastodonNotFoundError, MastodonUnauthorizedError, MastodonRatelimitError, MastodonMalformedEventError +from mastodon.Mastodon import Mastodon, AttribAccessDict, MastodonError, MastodonVersionError, MastodonIllegalArgumentError, MastodonIOError, MastodonFileNotFoundError, MastodonNetworkError, MastodonAPIError, MastodonNotFoundError, MastodonUnauthorizedError, MastodonRatelimitError, MastodonMalformedEventError from mastodon.streaming import StreamListener, CallbackStreamListener -__all__ = ['Mastodon', 'StreamListener', 'CallbackStreamListener', 'MastodonError', 'MastodonVersionError', 'MastodonIllegalArgumentError', 'MastodonIOError', 'MastodonFileNotFoundError', 'MastodonNetworkError', 'MastodonAPIError', 'MastodonNotFoundError', 'MastodonUnauthorizedError', 'MastodonRatelimitError', 'MastodonMalformedEventError'] +__all__ = ['Mastodon', 'AttribAccessDict', 'StreamListener', 'CallbackStreamListener', 'MastodonError', 'MastodonVersionError', 'MastodonIllegalArgumentError', 'MastodonIOError', 'MastodonFileNotFoundError', 'MastodonNetworkError', 'MastodonAPIError', 'MastodonNotFoundError', 'MastodonUnauthorizedError', 'MastodonRatelimitError', 'MastodonMalformedEventError'] diff --git a/tests/test_pagination.py b/tests/test_pagination.py index 44fafa1..599b2f4 100644 --- a/tests/test_pagination.py +++ b/tests/test_pagination.py @@ -31,9 +31,9 @@ def test_fetch_next_previous_from_pagination_info(api): account = api.account_verify_credentials() with many_statuses(api): statuses = api.account_statuses(account['id'], limit=5) - next_statuses = api.fetch_next(statuses[-1]['_pagination_next']) + next_statuses = api.fetch_next(statuses[-1]._pagination_next) assert next_statuses - previous_statuses = api.fetch_previous(next_statuses[0]['_pagination_prev']) + previous_statuses = api.fetch_previous(next_statuses[0]._pagination_prev) assert previous_statuses