Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions jmespath/functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,10 @@ def _func_to_number(self, arg):

@signature({'types': ['array', 'string']}, {'types': []})
def _func_contains(self, subject, search):
if isinstance(subject, list):
# 2026-10-11: Import after initialization to share comparator equality.
from jmespath.visitor import _equals
return any(_equals(element, search) for element in subject)
return search in subject

@signature({'types': ['string', 'array', 'object']})
Expand Down
19 changes: 19 additions & 0 deletions tests/test_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,22 @@ def test_variadic_is_pluralized(self):
self.assertEqual(
str(exception),
'Expected at least 1 argument for function not_null(), received 0')

def test_contains_array_distinguishes_booleans_from_numbers(self):
# 2026-10-11: Array membership must use JMESPath scalar equality.
for value, search in [(True, 1), (False, 0), (1, True), (0, False),
(True, 1.0), (False, 0.0)]:
with self.subTest(value=value, search=search):
data = {'values': [value], 'search': search}
self.assertFalse(jmespath.search('contains(values, search)', data))

def test_contains_array_preserves_valid_matches(self):
# 2026-10-11: Preserve numeric equivalence and matching JSON types.
for value, search in [(1, 1.0), (0, 0.0), (True, True),
(False, False), (None, None), ('one', 'one')]:
with self.subTest(value=value, search=search):
data = {'values': [value], 'search': search}
self.assertTrue(jmespath.search('contains(values, search)', data))
self.assertFalse(jmespath.search('contains(@, `true`)', []))
self.assertTrue(jmespath.search('contains(@, `true`)', [1, True]))
self.assertTrue(jmespath.search("contains(@, 'bar')", 'foobar'))