classification
Title: Make isinstance/issubclass overloadable for PEP 3119
Type: Stage:
Components: Interpreter Core Versions: Python 3.0
process
Status: closed Resolution: accepted
Dependencies: Superseder:
Assigned To: gvanrossum Nosy List: georg.brandl, gvanrossum
Priority: normal Keywords: patch

Created on 2007-04-26 20:16 by gvanrossum, last changed 2008-01-06 22:29 by admin. This issue is now closed.

Files
File name Uploaded Description Edit
typechecks.diff gvanrossum, 2007-04-26 20:16 First attempt
typechecks.diff gvanrossum, 2007-04-26 20:34 Version 2 fixes important test issue
typechecks.diff gvanrossum, 2007-05-11 14:16 Version 3 for gcc 2.96
Messages (7)
msg52529 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2007-04-26 20:16
I came up with a fairly simple way to overload isinstance() and issubclass().  The class that is the second argument can define a (class) method named __instancecheck__ or __subclasscheck__ which, if present, will be called *instead* of the normal approach.

The names are different to remind users that the calling convention is the opposite -- isinstance(x, C) maps to C.__instancecheck__(x).
msg52530 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2007-04-26 20:34
Oops, forget the first attempt; isinstance(Integer(), Integer) would be False!  Now it's True, and more tests are added.
File Added: typechecks.diff
msg52531 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2007-04-26 21:27
I'll add a description and motivation for this to PEP 3119.
msg52532 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2007-05-11 14:16
Version 3 compiles with older C89 compilers like gcc 2.96.
File Added: typechecks.diff
msg52533 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2007-05-11 21:40
FWIW, this can run into unchecked infinite recursion easily:

class C:
    # There's no @classmethod decorator here as there should have been
    def __instancecheck__(self, arg):
        return False

isinstance(42, C)

The reason is that on line 372 in classobject.c there's a call to PyObject_IsInstance(self, klass).
msg52534 - (view) Author: Georg Brandl (georg.brandl) * (Python committer) Date: 2007-05-12 19:27
Probably a warning would be good for the non-classmethod case.
msg52535 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2007-05-25 22:15
Checked in. The recursion bug is warded off by a standard recursion check -- you'll now get an inexplicable RuntimeError exception instead of an inexplicable SegFault. :-)
History
Date User Action Args
2008-01-06 22:29:46adminsetkeywords: - py3k
versions: + Python 3.0
2007-04-26 20:16:58gvanrossumcreate