[Python-3000] ABC PEP isinstance issue Was: PEP 31XX: A Type Hierarchy for Numbers (and other algebraic entities)

Guido van Rossum guido at python.org
Thu Apr 26 22:36:46 CEST 2007


On 4/26/07, Guido van Rossum <guido at python.org> wrote:
> I now have a proposal to allow overloading isinstance() and
> issubclass(), by defining special (class) methods on the second
> argument. See http://python.org/sf/1708353. Does this need a PEP? The
> unit test shows that it can be used to support the use case described
> above:
>
>
> class ABC(type):
>
>     def __instancecheck__(cls, inst):
>         """Implement isinstance(inst, cls)."""
>         return any(cls.__subclasscheck__(c)
>                    for c in {type(inst), inst.__class__})
>
>     def __subclasscheck__(cls, sub):
>         """Implement issubclass(sub, cls)."""
>         candidates = cls.__dict__.get("__subclass__", set())
>         return any(c in candidates for c in sub.mro())
>
>
> class Integer(metaclass=ABC):
>
>     __subclass__ = {int}

That example has a bug. Try this instead:


class ABC(type):

    def __instancecheck__(cls, inst):
        """Implement isinstance(inst, cls)."""
        return any(cls.__subclasscheck__(c)
                   for c in {type(inst), inst.__class__})

    def __subclasscheck__(cls, sub):
        """Implement issubclass(sub, cls)."""
        candidates = cls.__dict__.get("__subclass__", set()) | {cls}
        return any(c in candidates for c in sub.mro())


class Integer(metaclass=ABC):

    __subclass__ = {int}


To complete the example:

isinstance(42, Integer) and issubclass(int, Integer) now both return
True, while isinstance(3.14, Integer) and issubclass(float, Integer)
return False. Of course, isinstance(Integer(), Integer) and
issubclass(Integer, Integer) are both True. If you subclass Integer,
int won't be considered a subclass of it!

-- 
--Guido van Rossum (home page: http://www.python.org/~guido/)


More information about the Python-3000 mailing list