Skip to content

Commit

Permalink
Minor list index improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
moomoohk authored Jun 12, 2024
1 parent 6e7ae79 commit ac48a07
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 14 deletions.
6 changes: 3 additions & 3 deletions dpath/segments.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

from dpath import options
from dpath.exceptions import InvalidGlob, InvalidKeyName, PathNotFound
from dpath.types import PathSegment, Creator, Hints, Glob, Path, SymmetricInt
from dpath.types import PathSegment, Creator, Hints, Glob, Path, ListIndex


def make_walkable(node) -> Iterator[Tuple[PathSegment, Any]]:
Expand All @@ -22,8 +22,8 @@ def make_walkable(node) -> Iterator[Tuple[PathSegment, Any]]:
except AttributeError:
try:
indices = range(len(node))
# Convert all list indices to object so negative indexes are supported.
indices = map(lambda i: SymmetricInt(i, len(node)), indices)
# Convert all list indices to objects so negative indices are supported.
indices = map(lambda i: ListIndex(i, len(node)), indices)
return zip(indices, node)
except TypeError:
# This can happen in cases where the node isn't leaf(node) == True,
Expand Down
19 changes: 8 additions & 11 deletions dpath/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,29 @@
from typing import Union, Any, Callable, Sequence, Tuple, List, Optional, MutableMapping


class SymmetricInt(int):
"""Same as a normal int but mimicks the behavior of list indexes (can be compared to a negative number)."""
class ListIndex(int):
"""Same as a normal int but mimics the behavior of list indices (can be compared to a negative number)."""

def __new__(cls, value: int, max_value: int, *args, **kwargs):
if value >= max_value:
def __new__(cls, value: int, list_length: int, *args, **kwargs):
if value >= list_length:
raise TypeError(
f"Tried to initiate a {cls.__name__} with a value ({value}) "
f"greater than the provided max value ({max_value})"
f"greater than the provided max value ({list_length})"
)

obj = super().__new__(cls, value)
obj.max_value = max_value
obj.list_length = list_length

return obj

def __eq__(self, other):
if not isinstance(other, int):
return False

if other >= self.max_value or other <= -self.max_value:
return False

return int(self) == (self.max_value + other) % self.max_value
return other == int(self) or self.list_length + other == int(self)

def __repr__(self):
return f"<{self.__class__.__name__} {int(self)}%{self.max_value}>"
return f"<{self.__class__.__name__} {int(self)}/{self.list_length}>"

def __str__(self):
return str(int(self))
Expand Down

0 comments on commit ac48a07

Please sign in to comment.