[issue24161] PyIter_Check returns false positive for objects of type instance

2015-05-11 Thread Raymond Hettinger

Changes by Raymond Hettinger :


--
resolution:  -> fixed
status: open -> closed

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue24161] PyIter_Check returns false positive for objects of type instance

2015-05-11 Thread Roundup Robot

Roundup Robot added the comment:

New changeset 0f7795edca65 by Raymond Hettinger in branch '2.7':
Issue #24161:  Document that PyIter_Check() returns false positives for 
old-style instances.
https://hg.python.org/cpython/rev/0f7795edca65

--
nosy: +python-dev

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue24161] PyIter_Check returns false positive for objects of type instance

2015-05-10 Thread Raymond Hettinger

Changes by Raymond Hettinger :


--
keywords: +patch
Added file: http://bugs.python.org/file39338/doc_iter_check.diff

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue24161] PyIter_Check returns false positive for objects of type instance

2015-05-10 Thread Raymond Hettinger

Raymond Hettinger added the comment:

> but then, what would be the use case of PyIter_Check
> outside of python core?

You could still use it anywhere.  It will give a correct result in the cases of 
extension modules, builtin types, and new-style classes.  It will give a false 
positive in the case of old-style classes.  The latter case doesn't seem to be 
of much consequence (there is a still a TypeError raised when next() is 
called), so you just find out a bit later than you otherwise would (I believe 
that is why this is why we haven't gotten a bug report in the 13+ years this 
code has existed).

The feature is imperfect, incomplete and not as useful as it could be.
But this ship sailed a long time ago.  It is far too late for redesign (and 
risking unintended breakage).

FWIW, PyIter_Check() is used several times in the Python core: sqlite, cPickle, 
and iter().  In those examples, there seem to be no adverse consequences for 
the false positive because we still get a TypeError downstream when the actual 
call is made to next().

--
assignee:  -> docs@python
components: +Documentation -Interpreter Core
nosy: +docs@python
priority: normal -> low
stage:  -> needs patch

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue24161] PyIter_Check returns false positive for objects of type instance

2015-05-10 Thread behzad nouri

behzad nouri added the comment:

> That works for builtin types but not for user defined classes

> Rather than using PyIter_Check(), extensions should just call next() on 
> object and see whether it succeeds

but then, what would be the use case of PyIter_Check outside of python core?

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue24161] PyIter_Check returns false positive for objects of type instance

2015-05-10 Thread Raymond Hettinger

Raymond Hettinger added the comment:

The PyIter_Check() macro in Include/abstract.h does a quick test to see whether 
the tp_iternext slot is null or marked as not implemented.  That works for 
builtin types but not for user defined classes (heap types).

Old-style instances, see Objects/classobject.c::instance_iternext(), all define 
iternext with code that attempts lookup and call to the next() method, and if 
not it is not found, raises the TypeError you are seeing.

The conflict is that PyIter_Check() aims to be a fast check of a static slot 
entry while instance_iternext() aims for a dynamic call-it-and-see-if-it-works 
check much like PyObject_HasAttr() does.

Since this code is very old (back to Python 2.2) and has been mostly harmless 
(as far as we know), one resolution would be to just document this as a known 
limitation of PyIter_Check().  Rather than using PyIter_Check(), extensions 
should just call next() on object and see whether it succeeds.

--
nosy: +rhettinger

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue24161] PyIter_Check returns false positive for objects of type instance

2015-05-10 Thread behzad nouri

New submission from behzad nouri:

- python 2 only, not reproducible on python 3

Attached file makes an extension module which just returns PyIter_Check value 
on passed object.

Calling the function with an object of type "instance" returns true, even 
though the object is not iterator:


>>> import spam
>>> class Foo:
... pass
... 
>>> foo = Foo()
>>> type(foo)

>>> spam.isiter(foo)  #  ?!
1
>>> next(foo)
TypeError: instance has no next() method

--
components: Interpreter Core
files: spammodule.c
messages: 242866
nosy: behzad.nouri
priority: normal
severity: normal
status: open
title: PyIter_Check returns false positive for objects of type instance
type: behavior
versions: Python 2.7
Added file: http://bugs.python.org/file39335/spammodule.c

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com