Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Impossible to specify a metaclass for a Generic class #449

Closed
rowillia opened this issue Jul 14, 2017 · 4 comments
Closed

Impossible to specify a metaclass for a Generic class #449

rowillia opened this issue Jul 14, 2017 · 4 comments

Comments

@rowillia
Copy link

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

@ilevkivskyi
Copy link
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

@bwo
Copy link

bwo commented Apr 18, 2018

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?

@ilevkivskyi
Copy link
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.

@ilevkivskyi
Copy link
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
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants