Skip to content

Unexpected behaviour of __subclasshook__ with abc  #126604

@SimonKoop

Description

@SimonKoop

Bug report

Bug description:

When using __subclasshook__ on a childclass of another class, this can lead to unexpected behaviour for issubclass when used on a parent class or sibling class as shown in the following two code examples:

import abc

class X(metaclass=abc.ABCMeta):
    pass

class Y(X):
    pass

class Z(X):
    pass

define_magic = True  # try toggling this value
if define_magic:
    class Magic(Y):
        @classmethod
        def __subclasshook__(cls, maybe_subclass):
            if issubclass(maybe_subclass, Z):
                return True
            return NotImplemented
    
assert issubclass(Z, Y) == define_magic

and

import abc

use_meta:bool = False  # try toggling this

if use_meta:
    class Module(metaclass=abc.ABCMeta):
        pass
else:
    class Module:
        pass 

class StatefulModule(Module):
    pass


class RegularLayer(Module):
    pass

class MaybeStatefulLayer(StatefulModule):
    pass

class SpecificRegularLayer(RegularLayer):
    pass

class SpecialModuleCollection(Module, metaclass=abc.ABCMeta):
    @classmethod
    def __subclasshook__(cls, maybe_subclass):
        if issubclass(maybe_subclass, (RegularLayer, MaybeStatefulLayer)):
            return True
        return NotImplemented
    pass
    
class SpecificSpecialModule(StatefulModule, SpecialModuleCollection):
    pass
    
assert issubclass(SpecificRegularLayer, StatefulModule) == use_meta

The code examples are based on patrick-kidger/equinox#893

CPython versions tested on:

3.10, 3.11, 3.13

Operating systems tested on:

Linux, Windows

Metadata

Metadata

Assignees

No one assigned

    Labels

    extension-modulesC modules in the Modules dirstdlibStandard Library Python modules in the Lib/ directory

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions