PyIter_Check appears to be the C-level equivalent of isinstance(..., collections.abc.Iterator), testing whether the python next() or the C PyIter_Next will succeed. However, PyIter_Check disagrees with collections.abc.Iterator and next about whether a given object is an iterator.
$ cat test_iterator.pyx from cpython.iterator cimport PyIter_Check def is_iterator(obj: object) -> bool: """Check whether obj is an iterator. Should agree with isinstance(obj, collections.abc.Iterator). Parameters ---------- obj : object Returns ------- bool """ return PyIter_Check(obj) $ cythonize --build --inplace test_iterator.pyx running build_ext $ python Python 3.9.10 (main, Jan 20 2022, 21:37:52) [GCC 11.2.0] on cygwin Type "help", "copyright", "credits" or "license" for more information. >>> import test_iterator, os, fractions, collections.abc >>> test_iterator.is_iterator(os.environ) True >>> isinstance(os.environ, collections.abc.Iterator) False >>> next(os.environ) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: '_Environ' object is not an iterator >>> test_iterator.is_iterator(fractions.Fraction(0, 1)) True >>> isinstance(fractions.Fraction(0, 1), collections.abc.Iterator) False >>> next(fractions.Fraction(0, 1)) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'Fraction' object is not an iterator On Linux, the test function using PyIter_Check agrees with collections.abc.Iterator and next. The test case that led me to this behaviour works the same in Windows as on Linux. Is this expected behavior?
-- Problem reports: https://cygwin.com/problems.html FAQ: https://cygwin.com/faq/ Documentation: https://cygwin.com/docs.html Unsubscribe info: https://cygwin.com/ml/#unsubscribe-simple