Skip to content
Merged
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
54 changes: 54 additions & 0 deletions Lib/test/test_itertools.py
Original file line number Diff line number Diff line change
Expand Up @@ -734,6 +734,60 @@ def keyfunc(obj):
keyfunc.skip = 1
self.assertRaises(ExpectedError, gulp, [None, None], keyfunc)

def test_groupby_reentrant_eq_does_not_crash(self):
# regression test for gh-143543
class Key:
def __init__(self, do_advance):
self.do_advance = do_advance

def __eq__(self, other):
if self.do_advance:
self.do_advance = False
next(g)
return NotImplemented
return False

def keys():
yield Key(True)
yield Key(False)

g = itertools.groupby([None, None], keys().send)
next(g)
next(g) # must pass with address sanitizer

@unittest.expectedFailure # TODO: RUSTPYTHON; AssertionError: 4 != 1
def test_grouper_reentrant_eq_does_not_crash(self):
# regression test for gh-146613
grouper_iter = None

class Key:
__hash__ = None

def __init__(self, do_advance):
self.do_advance = do_advance

def __eq__(self, other):
nonlocal grouper_iter
if self.do_advance:
self.do_advance = False
if grouper_iter is not None:
try:
next(grouper_iter)
except StopIteration:
pass
return NotImplemented
return True

def keyfunc(element):
if element == 0:
return Key(do_advance=True)
return Key(do_advance=False)

g = itertools.groupby(range(4), keyfunc)
key, grouper_iter = next(g)
items = list(grouper_iter)
self.assertEqual(len(items), 1)

def test_filter(self):
self.assertEqual(list(filter(isEven, range(6))), [0,2,4])
self.assertEqual(list(filter(None, [0,1,0,2,0])), [1,2])
Expand Down
Loading