GrahamDumpleton / wrapt

A Python module for decorators, wrappers and monkey patching.
BSD 2-Clause "Simplified" License
2.06k stars 231 forks source link

metaclass conflict when decorating a base class #123

Closed jlinoff closed 6 years ago

jlinoff commented 6 years ago

Thank you, this is a fantastic package. The blogs are just great.

The following code generates a metaclass conflict error in python2.7. It appears that something is confusing the metaclass resolution in the decorator. Do you have any suggestions about how this can be fixed? Other than the removing the decorator. I am afraid that that option is not available to me.

Code

#!/usr/bin/env python2.7
import abc
import wrapt

@wrapt.decorator
def pass_through(wrapped, instance, args, kwargs):
    return wrapped(*args, **kwargs)

@pass_through
class Metric(object):
    __metaclass__ = abc.ABCMeta

class ItemwiseMetric(Metric):
    __metaclass__ = abc.ABCMeta

Error Message

$ python2.7 /tmp/i1.py
Traceback (most recent call last):
  File "/tmp/i1.py", line 15, in <module>
    class ItemwiseMetric(Metric):
  File "/opt/cr/lib/python2.7/abc.py", line 87, in __new__
    cls = super(ABCMeta, mcls).__new__(mcls, name, bases, namespace)
TypeError: Error when calling the metaclass bases
    metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases
GrahamDumpleton commented 6 years ago

Known issue:

No real solution unless you can suggest one.

jlinoff commented 6 years ago

Thanks for pointer. It is much appreciated. I missed that.