11import enum
2+ from base64 import b64decode
23from dataclasses import dataclass
34from functools import cached_property
45from typing import Any , Dict , List , Optional
56
6- from cursor_pagination import CursorPage , CursorPaginator
7+ from cursor_pagination import CursorPage , CursorPaginator , InvalidCursor
78from django .db .models import QuerySet
89
910from codecov .commands .exceptions import ValidationError
@@ -181,6 +182,7 @@ def page_info(self) -> Dict[str, Any]:
181182
182183
183184class DictCursorPaginator (CursorPaginator ):
185+ NULL_VALUE_REPR = "\x1f "
184186 """
185187 WARNING: DictCursorPaginator does not work for dict objects where a key contains the following string: "__"
186188 TODO: if instance is a dictionary and not an object, don't split the ordering
@@ -205,6 +207,17 @@ class DictCursorPaginator(CursorPaginator):
205207 if the dict access fails then it throws an exception, although it would be a different
206208 """
207209
210+ def decode_cursor (self , cursor ):
211+ try :
212+ orderings = b64decode (cursor .encode ("ascii" )).decode ("utf8" )
213+ orderings = orderings .split (self .delimiter )
214+ return [
215+ None if ordering == self .NULL_VALUE_REPR else ordering
216+ for ordering in orderings
217+ ]
218+ except (TypeError , ValueError ):
219+ raise InvalidCursor (self .invalid_cursor_message )
220+
208221 def position_from_instance (self , instance ):
209222 position = []
210223 for order in self .ordering :
@@ -219,7 +232,7 @@ def position_from_instance(self, instance):
219232 except (KeyError , TypeError ):
220233 raise attr_err from None
221234 parts .pop (0 )
222- position .append (str (attr ))
235+ position .append (self . NULL_VALUE_REPR if attr is None else str (attr ))
223236 return position
224237
225238
0 commit comments