Lookup of operator builtins can fail with multiple inheritance
When looking up a method that implements an operator (such as __int__() or __lshift__()) on an object who's class uses multiple inheritance, and an earlier base classes is a native type that does not implement that operator, then an implementation of the required method will not be found in a later base class that does implement it.
Take for instance the following example:
class Foo:
def __int__(self):
return 123
class Bar(Foo, list):
pass
class Baz(list, Foo):
pass
print(int(Bar([])))
print(int(Baz([])))
On C Python this prints the expected:
123
123
On Micropython the second call raises a TypeError:
123
Traceback (most recent call last):
File "<stdin>", line 12, in <module>
TypeError: can't convert list to int
This is because mp_obj_class_lookup() checks to see if a native type has the necessary unary_op or binary_op function pointer but does not check to see if the specific operator code is implemented. If a native type is found that has the required operator function pointer the search for an implementation stops there, even if it doesn't implement the desired operator code, preventing a later, usable implementation from being found.
To support multiple inheritance, should filter out "object" from base class spec and handle it as implicit fallback
We're not going to get proper Python MRO any time soon (#525), but to at least not break multiple inheritance (MI) in obvious way, we should at least do following:
- Filter out "object" from any explicit base class specification. (turn
class Foo(object)intoclass Foo). - Look up attributes in "object" as a fallback.
This will emulate the fact that in Python3, "object" is always the last type in MRO.
Failing to do the above may mean, that with our naive depth-first MRO, "object" ultimate base of first superclass in MI case may seize method call destined to another superclass, if "object" has such method. With #520 & #606, object now implements __new__ and __init__, so any other multi-superclass will be denied construction and initialization.