Skip to content

Commit 089d7ee

Browse files
committed
Make path instances hashable
1 parent 8c1e1f5 commit 089d7ee

File tree

2 files changed

+40
-0
lines changed

2 files changed

+40
-0
lines changed

jsonpath_ng/jsonpath.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,9 @@ def __repr__(self):
220220
def __eq__(self, other):
221221
return isinstance(other, Root)
222222

223+
def __hash__(self):
224+
return hash('$')
225+
223226

224227
class This(JSONPath):
225228
"""
@@ -244,6 +247,9 @@ def __repr__(self):
244247
def __eq__(self, other):
245248
return isinstance(other, This)
246249

250+
def __hash__(self):
251+
return hash('this')
252+
247253

248254
class Child(JSONPath):
249255
"""
@@ -302,6 +308,9 @@ def __str__(self):
302308
def __repr__(self):
303309
return '%s(%r, %r)' % (self.__class__.__name__, self.left, self.right)
304310

311+
def __hash__(self):
312+
return hash((self.left, self.right))
313+
305314

306315
class Parent(JSONPath):
307316
"""
@@ -323,6 +332,9 @@ def __str__(self):
323332
def __repr__(self):
324333
return 'Parent()'
325334

335+
def __hash__(self):
336+
return hash('parent')
337+
326338

327339
class Where(JSONPath):
328340
"""
@@ -357,6 +369,9 @@ def __str__(self):
357369
def __eq__(self, other):
358370
return isinstance(other, Where) and other.left == self.left and other.right == self.right
359371

372+
def __hash__(self):
373+
return hash((self.left, self.right))
374+
360375
class Descendants(JSONPath):
361376
"""
362377
JSONPath that matches first the left expression then any descendant
@@ -469,6 +484,9 @@ def __eq__(self, other):
469484
def __repr__(self):
470485
return '%s(%r, %r)' % (self.__class__.__name__, self.left, self.right)
471486

487+
def __hash__(self):
488+
return hash((self.left, self.right))
489+
472490

473491
class Union(JSONPath):
474492
"""
@@ -490,6 +508,12 @@ def is_singular(self):
490508
def find(self, data):
491509
return self.left.find(data) + self.right.find(data)
492510

511+
def __eq__(self, other):
512+
return isinstance(other, Union) and self.left == other.left and self.right == other.right
513+
514+
def __hash__(self):
515+
return hash((self.left, self.right))
516+
493517
class Intersect(JSONPath):
494518
"""
495519
JSONPath for bits that match *both* patterns.
@@ -511,6 +535,12 @@ def is_singular(self):
511535
def find(self, data):
512536
raise NotImplementedError()
513537

538+
def __eq__(self, other):
539+
return isinstance(other, Intersect) and self.left == other.left and self.right == other.right
540+
541+
def __hash__(self):
542+
return hash((self.left, self.right))
543+
514544

515545
class Fields(JSONPath):
516546
"""
@@ -596,6 +626,9 @@ def __repr__(self):
596626
def __eq__(self, other):
597627
return isinstance(other, Fields) and tuple(self.fields) == tuple(other.fields)
598628

629+
def __hash__(self):
630+
return hash(tuple(self.fields))
631+
599632

600633
class Index(JSONPath):
601634
"""
@@ -662,6 +695,9 @@ def _pad_value(self, value):
662695
pad = self.index - len(value) + 1
663696
value += [{} for __ in range(pad)]
664697

698+
def __hash__(self):
699+
return hash(self.index)
700+
665701

666702
class Slice(JSONPath):
667703
"""
@@ -741,6 +777,9 @@ def __repr__(self):
741777
def __eq__(self, other):
742778
return isinstance(other, Slice) and other.start == self.start and self.end == other.end and other.step == self.step
743779

780+
def __hash__(self):
781+
return hash((self.start, self.end, self.step))
782+
744783

745784
def _create_list_key(dict_):
746785
"""

tests/test_jsonpath.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,7 @@ def check_paths(self, test_cases):
183183

184184
for string, data, target in test_cases:
185185
print('parse("%s").find(%s).paths =?= %s' % (string, data, target))
186+
assert hash(parse(string)) == hash(parse(string))
186187
result = parse(string).find(data)
187188
if isinstance(target, list):
188189
assert [str(r.full_path) for r in result] == target

0 commit comments

Comments
 (0)