Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

A django model that subclasses an abc, gives a metaclass conflict

I have a following model and abstract base class

import abc
from django.db import models


class AbstractBase():
    __metaclass__ = abc.ABCMeta

    @abc.abstractmethod
    def my_method(self):
        return


class MyModel(models.Model, AbstractBase):
    @abc.abstractmethod
    def my_method(self):
        return 1

But I am getting the following error.

metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases

I think the problem here is (As it is described here http://code.activestate.com/recipes/204197-solving-the-metaclass-conflict/) that two base class has two different metaclasses so python cannot decide which metaclass to use for child object.

In order to solve this I removed multiple inheritence and use following register method to register child class

abc.register(Child)

But I did not really like this approach since it looks like monkey patching.

Is there another way to solve this problem?

I try to assign Model metaclass to Child explicitly but it did not work. I am not looking for a way to solve it by writing code. I think this must be solved by changing my class structure.

like image 371
yilmazhuseyin Avatar asked Jan 04 '12 07:01

yilmazhuseyin


1 Answers

Apart from creating a new metaclass that inherits from both ABCMeta and ModelBase, or making ABCMeta inherit from ModelBase, there isn't much you can do.

However, possibly a different registration pattern might be appropriate? Maybe something like contrib.admin.autodiscover? Or a class decorator? Or a loop at the bottom of the .py file which calls register on the appropriate classes (ex, for var in globals().values(): if isinstance(var, type) and issubclass(var, AbastractBase): register(var))?

Edit: D'oh. I'd assumed that ABCMeta was an example, not ABCMeta. That's what I get for browsing StackOverflow on too little sleep.

like image 180
David Wolever Avatar answered Oct 24 '22 01:10

David Wolever