[Python-Dev] Changing semantics of issubclass when accepting atuple

Tim Peters tim.one at comcast.net
Sun Dec 14 20:33:50 EST 2003


[Brett]
>> But this is a change in semantics.  Tim said I should clear it here
>> first so that is what I am doing.  Anyone have issues if I do this?
>> And if so, any objections of backporting to 2.3?

[Guido]
> Let's not mess with 2.3 semantics.

That's the rub:  the segfaults occur in 2.3 too, of course, so should also
be fixed there.  Looks like isinstance() has the same vulnerability, and
that the code comments don't match the docs.

"""
class C(object):
    pass

classtup = C
for i in xrange(50000):
    classtup = (classtup,)

if 0:	# segfaults on both branches; maybe on your box 50000 is too small
    print issubclass(C, classtup)
else:
    print isinstance(C(), classtup)
"""

The implementations even have this shared prophetic <wink> comment:

		/* Not a general sequence -- that opens up the road to
		   recursion and stack overflow. */

The error messages plainly say that the example segfaulting program isn't a
supported use:

			"isinstance() arg 2 must be a class, type,"
			" or tuple of classes and types"))

					"issubclass() arg 2 must be a class"
					" or tuple of classes"))

The documentation could well have *meant* that, too:

>>> print isinstance.__doc__
isinstance(object, class-or-type-or-tuple) -> bool

Return whether an object is an instance of a class or of a subclass thereof.
With a type as second argument, return whether that is the object's type.
The form using a tuple, isinstance(x, (A, B, ...)), is a shortcut for
isinstance(x, A) or isinstance(x, B) or ... (etc.).
>>> print issubclass.__doc__
issubclass(C, B) -> bool

Return whether class C is a subclass (i.e., a derived class) of class B.
When using a tuple as the second argument issubclass(X, (A, B, ...)),
is a shortcut for issubclass(X, A) or issubclass(X, B) or ... (etc.).
>>>

The idea that arbitrarily nested tuples is allowed comes from that the
docstrings imply it (more accidentally than on purpose, it seems to me), and
that the implementations don't actually check for what its error messages
claim must be the case.

Finally, the docs in the Library Reference Manual are schizophrenic about
the issue at hand.  The issubclass() docs appear to disallow the possibility
of nested tuples, while the isinstance() docs explictly allow them.




More information about the Python-Dev mailing list