This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: isinstance documentation: explain behavior when type is a tuple
Type: enhancement Stage: resolved
Components: Documentation Versions: Python 3.6, Python 3.4, Python 3.5, Python 2.7
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: terry.reedy Nosy List: Michael Crouch, docs@python, eryksun, felipevolpone, georg.brandl, python-dev, r.david.murray, terry.reedy
Priority: normal Keywords: easy

Created on 2015-10-17 14:46 by Michael Crouch, last changed 2022-04-11 14:58 by admin. This issue is now closed.

Messages (12)
msg253130 - (view) Author: Michael Crouch (Michael Crouch) Date: 2015-10-17 14:46
In the section on isinstance() in the Python Standard Library documentation Chapter 2 (https://docs.python.org/3.6/library/functions.html#isinstance) , it says that classinfo "may be a tuple of type objects", but it doesn't explain what the semantics are in that case (e.g., that it will return true iff it is an instance of any of the types in the tuple).
msg253136 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2015-10-17 17:06
I don't see any ambiguity here.  There are other Python APIs with the same behavior, and all we say is that it can be a tuple (eg: str.startswith).  That is, I don't see any other way a tuple could be interpreted that would make any sense.
msg253138 - (view) Author: Eryk Sun (eryksun) * (Python triager) Date: 2015-10-17 17:25
Since Python has multiple inheritance, it could be misconstrued as a conjunctive test. For example, if c is an instance of C, which subclasses both A and B, then someone might think isinstance(c, (A, B)) requires c to be an instance of both A and B. The description could clarify that it's a disjunctive test with short circuiting.

    class MetaA(type):
        def __instancecheck__(self, other):
            print('MetaA.__instancecheck__')
            return False

    class A(metaclass=MetaA): pass

    >>> isinstance(1, (A, int))
    MetaA.__instancecheck__
    True
    >>> isinstance(1, (int, A))
    True
msg253153 - (view) Author: Georg Brandl (georg.brandl) * (Python committer) Date: 2015-10-18 12:27
But without using the word "disjunctive".
msg253446 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2015-10-26 00:52
Perhaps add after third sentence (ending with "not accepted)."), "If classinfo is a tuple, isinstance(x, classinfo) is the same as any(isinstance(x, C) for C in flatten(classinfo))".
msg253497 - (view) Author: Felipe Volpone (felipevolpone) Date: 2015-10-26 20:27
I think that the following part could replace the part of the other text that's between ###. It's more objective and easier to understand. 

classinfo may could be a tuple of type objects, or may contains others tuples that contains type objects (other sequence types are not accepted).

Return true if the object argument is an instance of the classinfo argument, or of a (direct, indirect or virtual) subclass thereof. If object is not an object of the given type, the function always returns false. ### If classinfo is not a class (type object), it may be a tuple of type objects, or may recursively contain other such tuples (other sequence types are not accepted). ### If classinfo is not a type or tuple of types and such tuples, a TypeError exception is raised.

What do you think?
msg253502 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2015-10-26 20:37
The fact that nested tuples are accepted is just bizarre, IMO :(.

It could say something like "If classinfo is a (possibly nested) list of types, return True if any of the types match."
msg253503 - (view) Author: Felipe Volpone (felipevolpone) Date: 2015-10-26 21:25
r.david.murray: I liked your way.
msg253504 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2015-10-26 22:13
David, if you are suggesting that the initial negative clause of "If classinfo is not a class (type object)" is not needed, I agree.  If classinfo is a tuple, is is not a class.  'list of types' has to be 'tuple of types'. I think 'match' needs to be expanded to 'is an instance of'. How about

"If classinfo is a tuple of type objects (or recursively, other such tuples), return true if object is an instance of any of the types.

This leaves out the left to right ordering of the tests, but I think that is implied by how Python generally works.  Short circuiting certainly is.
msg253506 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2015-10-26 22:55
Sure, that's fine with me.  I was trying to minimize words, but clarity is good.
msg253589 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2015-10-28 06:57
Doing this now.
msg253590 - (view) Author: Roundup Robot (python-dev) (Python triager) Date: 2015-10-28 07:16
New changeset aaf8a25133ff by Terry Jan Reedy in branch '2.7':
Issue #25432: Explain isinstance behaviour when type is a tuple.
https://hg.python.org/cpython/rev/aaf8a25133ff

New changeset 8b1418e5dcc8 by Terry Jan Reedy in branch '3.4':
Issue #25432: Explain isinstance behaviour when type is a tuple.
https://hg.python.org/cpython/rev/8b1418e5dcc8
History
Date User Action Args
2022-04-11 14:58:22adminsetgithub: 69618
2015-10-28 07:16:54terry.reedysetstatus: open -> closed
resolution: fixed
stage: needs patch -> resolved
2015-10-28 07:16:05python-devsetnosy: + python-dev
messages: + msg253590
2015-10-28 06:57:03terry.reedysetassignee: docs@python -> terry.reedy
messages: + msg253589
2015-10-26 22:55:25r.david.murraysetmessages: + msg253506
2015-10-26 22:13:14terry.reedysetmessages: + msg253504
2015-10-26 21:25:11felipevolponesetmessages: + msg253503
2015-10-26 20:37:45r.david.murraysetmessages: + msg253502
2015-10-26 20:27:29felipevolponesetnosy: + felipevolpone
messages: + msg253497
2015-10-26 00:52:31terry.reedysetversions: + Python 3.4, Python 3.5
type: enhancement

nosy: + terry.reedy
title: isinstance documentation doesn't explain what happens when type is tuple -> isinstance documentation: explain behavior when type is a tuple
messages: + msg253446
stage: needs patch
2015-10-18 12:27:57georg.brandlsetnosy: + georg.brandl
messages: + msg253153
2015-10-17 17:25:21eryksunsetkeywords: + easy
nosy: + eryksun
messages: + msg253138

2015-10-17 17:06:21r.david.murraysetnosy: + r.david.murray
messages: + msg253136
2015-10-17 14:46:04Michael Crouchcreate