Skip to content

Impossible to specify a metaclass for a Generic class #449

Description

@rowillia

Below is a contrived example. In the real world I might not actually control the metaclass for Foo or I may be inheriting from some other class that also has a metaclass.

from typing import Generic, TypeVar

class FooMeta(type):
    pass

_T = TypeVar('_T')

class Foo(Generic[_T], metaclass=FooMeta):
    pass

This passes MyPy just fine, but fails at runtime with:

$ python3.6 test_generics.py
Traceback (most recent call last):
  File "test_generics.py", line 8, in <module>
    class Foo(Generic[_T], metaclass=FooMeta):
TypeError: metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases

Moved from python/mypy#3720

Activity

  1. ilevkivskyi commented on Jul 18, 2017

    @ilevkivskyi
    Member

    As a workaround in cases where possible, one can just do:

    from typing import Generic, TypeVar, GenericMeta
    
    class FooMeta(type):
        pass
    
    class GenericFooMeta(GenericMeta, FooMeta):
        pass
    
    T = TypeVar('T')
    
    class Foo(Generic[T], metaclass=GenericFooMeta):
        pass
  2. bwo commented on Apr 18, 2018

    @bwo

    We recently encountered this in a case where a superclass we don't control used ABCMeta as its metaclass. The answer seems to be to use __extra__, but this doesn't appear to be documented anywhere. Should it be treated as an implementation detail not to be relied on?

  3. ilevkivskyi commented on Apr 18, 2018

    @ilevkivskyi
    Member

    Should it be treated as an implementation detail not to be relied on?

    Yes. Moreover GenericMeta is completely removed in Python 3.7. Generic will no more have a non-trivial metaclass, type(Generic) is now type.

  4. ilevkivskyi commented on Jun 20, 2019

    @ilevkivskyi
    Member

    This is fixed in Python 3.7+ and we can't really do anything for older versions, so I think this can be closed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions