[Python] Problem if two inherited __init_subclass__s have the same argument name

Discussão em 'Python' iniciado por Stack, Março 24, 2025.

  1. Stack

    Stack Membro Participativo

    I'm trying to use two classes, A and B, as mixing classes of AB. They both have __init_subclass__ methods. The problem is that both __init__sublass__ methods have the same argument msg. Therefore I've used an adaptor class B_ to rename B's argument msg_b. But I'm having trouble!

    The nearest I have got is:

    class A:
    def __init_subclass__(cls, msg, **kwargs):
    print(f'{cls=} A: {msg}')
    super().__init_subclass__(**kwargs)

    class B:
    def __init_subclass__(cls, msg, **kwargs):
    print(f'{cls=} B: {msg}')
    super().__init_subclass__(**kwargs)

    # Adaptor class `B_` needed because both `A` and `B` have an argument `msg`.
    class B_:
    # Rename `msg` to `msg_b`.
    def __init_subclass__(cls, msg_b, **kwargs):
    # `B.__init_subclass__(msg_b, **kwargs)` sets the subclass as `B` not `cls`, but otherwise works.
    B.__init_subclass__.__func__(cls, msg=msg_b, **kwargs)

    # Still need a `B`.
    def __init__(self, *args, **kwargs):
    self.b = B(*args, **kwargs)

    # Forward all the attributes to `self.b`.
    def __getattr__(self, item):
    return getattr(self.b, item)

    class AB(A, B_, msg='Hello.', msg_b='Also, hello.' ):
    ...

    print(f'{AB()=}, {isinstance(AB(), A)=}, {isinstance(AB(), B_)=}, {isinstance(AB(), B)=}')


    Which does call both __init_sublass__s with the correct class argument, it prints:

    cls=<class '__main__.AB'> A: Hello.
    cls=<class '__main__.AB'> B: Also, hello.


    But then you get the error:

    Traceback (most recent call last):
    File <definition of AB>, in <module>
    class AB(A, B_, msg='Hello.', msg_b='Also, hello.' ):
    File <A's>, in __init_subclass__
    super().__init_subclass__(**kwargs)
    File <B_'s>, in __init_subclass__
    B.__init_subclass__.__func__(cls, msg=msg_b, **kwargs)
    File <B's>, in __init_subclass__
    super().__init_subclass__(**kwargs)
    ^^^^^^^^^^^^^^^^^^^^^^^^^
    TypeError: super(type, obj): obj must be an instance or subtype of type


    Presumably because B is not a super type of AB (B_ is). I’m not clear why super wants subtypes matching though!

    Any ideas on how to fix this?

    Continue reading...

Compartilhe esta Página