"""Original filter scenarios, pinned to the CPython 3.9.6 oracle."""
print(list(filter(None, [0, 1, -2, 0, 3])))
print(list(filter(bool, ['', 'é', '', '雪', '😀'])))
print(list(filter(None, b'\x00\x01\x80\xff')))
print(list(filter(None, (False, True, False, True))))
print(list(filter(lambda value: value % 3 == 1, range(-4, 8))))
print(list(filter(None, reversed([0, 2, 0, 4]))))
def nested(start, stop):
    return list(range(start, stop))
print(list(filter(None, [nested(0, 0), nested(1, 2), nested(0, 0), nested(2, 4)])))

events = []
def predicate(value):
    events.append(value)
    return value % 2
values = [0, 1, 2, 3]
cursor = filter(predicate, values)
alias = cursor
print(type(cursor).__name__, iter(cursor) is cursor, cursor.__iter__() is cursor, events)
values.append(5)
print(cursor.__next__(), events)
print(next(alias), events)
print(list(cursor), next(alias, -1), events)

saved_filter = filter
saved_bool = bool
print(saved_filter is filter, type(saved_filter).__name__, saved_filter.__name__, saved_filter.__module__)
print(isinstance(cursor, filter), isinstance(cursor, object), isinstance(cursor, reversed))
print(isinstance(filter, type), issubclass(filter, object), issubclass(filter, filter))
print(type(saved_bool).__name__, saved_bool.__name__, saved_bool.__module__)
print(isinstance(saved_bool, type), issubclass(saved_bool, int), isinstance(True, saved_bool))
print(list(saved_filter(saved_bool, [0, 7, 0, 9])), saved_bool(), saved_bool('x'))
print(list(saved_filter(*(None, [0, 4, 0, 6]))))

original = ValueError('predicate failed')
def sometimes(value):
    if value == 2:
        raise original
    return True
cursor2 = filter(sometimes, [1, 2, 3])
print(next(cursor2))
try:
    next(cursor2)
except ValueError as error:
    print(error is original, str(error))
print(next(cursor2), next(cursor2, -1))

stopped = StopIteration('predicate stopped')
def stopping(value):
    if value == 2:
        raise stopped
    return True
cursor3 = filter(stopping, [1, 2, 3, 4])
print(next(cursor3))
try:
    next(cursor3)
except StopIteration as error:
    print(error is stopped, str(error))
print(list(cursor3))
cursor4 = filter(stopping, [1, 2, 3, 4])
print(list(cursor4), list(cursor4))

source = iter(range(6))
empty = filter(None, zip(source, []))
print(list(empty), next(source))
print(list(empty), next(source))
