Message237126
I admit this case is rather convoluted, but I have been debugging a few hours so I think I should share my findings.
I have a metaclass MetaA that provides to the classes constructed with it have a dictionary interface. Of all the functions only __len__ is important. In some cases, the result of __len__ is 0 and that is what triggers the error
class MetaA(type):
def __len__(self):
return 0
class A(metaclass=MetaA):
pass
class AA(A):
pass
Now, I construct a function with single dispatch and register the case of class A but not the class AA
@singledispatch
def fun(a):
print('base case')
@fun.register(A)
def _(a):
print('fun A')
And then, call fun with an object of class AA
fun(AA())
This should call the function for the class up in the hierarchy, A
Instead it raises an exception
RuntimeError: Inconsistent hierarchy
in function functools._c3_merge
because in the line
if not candidate:
raise RuntimeError("Inconsistent hierarchy")
"not candidate" evaluates to True due to __len__ returning 0
This can be avoided by:
* adding __nonzero__ to MetaA
* not adding the map interface to a class in the first place
* changing the code in _c3_merge
I'm not really sure, but instead of:
if not candidate:
raise RuntimeError("Inconsistent hierarchy")
would this work?
if candidate is None:
raise RuntimeError("Inconsistent hierarchy")
I attach a test case |
|
Date |
User |
Action |
Args |
2015-03-03 12:17:09 | Sergio Pascual | set | recipients:
+ Sergio Pascual |
2015-03-03 12:17:09 | Sergio Pascual | set | messageid: <1425385029.2.0.304023107943.issue23572@psf.upfronthosting.co.za> |
2015-03-03 12:17:09 | Sergio Pascual | link | issue23572 messages |
2015-03-03 12:17:08 | Sergio Pascual | create | |
|