41

I wanted to create a class out of two: collections.OrderedDict and collections.DefaultDict. So that I can get an ordered dictionary and have a default value for non existing keys being accessed. Whats are some ways to do this?

My solution was to create another class around the 2 classes I stated above. This makes an error due to a method in each class having the same name I think?

from collections import defaultdict, OrderedDict
class owndic(OrderedDict, defaultdict):
    pass

producing

TypeError: multiple bases have instance lay-out conflict

Cheers!

4
  • What version of Python are you using? I can't reproduce the error on Python 3.4.2 Commented Jan 7, 2018 at 9:57
  • Regardless of the cause of your TypeError if you want to use both functionalities you better use OrderedDict and it's setdefault() attribute which has a same functionality as defaultdict. Commented Jan 7, 2018 at 9:58
  • The error seems to be because both defaultdict and OrderedDict inherit from built-in dict type (their only base type) and this not allowed in python. Commented Jan 7, 2018 at 10:10
  • Its python 3 in hackerrank - Doesn't say the exact version. Lovely I will try setdefault thanks! Commented Jan 7, 2018 at 10:16

1 Answer 1

48

"Instance lay-out conflict" is a fancy way of saying that you're trying to inherit from multiple – in this case built-in – types that cannot cooperate with each other quite well. More technically these classes have conflict in functionality of their common attributes.

In this case both OrderedDict and defaultdict are two dictionary-like types with their own unique __setitem__ attributes and also different ways of handling the keys and values.

At C level this error happens when the best_base function fails to calculate the best base amongst multiple base classes. There are multiple other reasons that can cause this function fail to calculate the best base or winner among other bases but in this case the error occurs when neither of following conditions happen. winner is not None, winner is not a subtype of candidate*, candidate is not a subtype of winner.

candidate = solid_base(base_i);
if (winner == NULL) {
    winner = candidate;
    base = base_i;
}
else if (PyType_IsSubtype(winner, candidate))
    ;
else if (PyType_IsSubtype(candidate, winner)) {
    winner = candidate;
    base = base_i;
}
else {
    PyErr_SetString(
        PyExc_TypeError,
        "multiple bases have "
        "instance lay-out conflict");
    return NULL;

}

However, if you want to benefit from both defaultdict() and OrderedDict()'s functionalities, you can simply use an OrderedDict and its built-in setdefault attribute.

Here is an example:

In [13]: d = OrderedDict()

In [14]: for i, j in enumerate(['k', 'r', 'k', 'j', 'j', 't']):
             d.setdefault(j, []).append(i)
   ....:     

In [15]: d
Out[15]: OrderedDict([('k', [0, 2]), ('r', [1]), ('j', [3, 4]), ('t', [5])])

* `candidate` is the solid base of `base_i`,one of the bases passed to the class caller, that is calculated using [`solid_base`](https://github.com/python/cpython/blob/ce5b0e9db1b9698e6ffc43ae41cf3a22ca5a6ba6/Objects/typeobject.c#L2086) function.
Sign up to request clarification or add additional context in comments.

3 Comments

I've got this when I started to introduce __slots__ to pypdf
Got into this issue when I tried to give, class D(C,B) and class C(A) and class B(A) all __slots__ including class A. I could resolve it by changing the mro so that it turned to be class D(C) and class C(B) and class B(A). This way I was able to implement __slots__ or I had to drop __slots__ in class A.
I still don't quite understand the details for which cases are allowed and which cases aren't. It would be good if you could provide an example illustrating what causes best_base to fail in this case, and why it doesn't fail in cases where multiple inheritance is allowed.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.