From the documentation
The attribute lookup super(B, obj).m searches obj.class.mro for the base class A immediately following B and then returns A.dict['m'].get(obj, B). If not a descriptor, m is returned unchanged. If not in the dictionary, m reverts to a search using object.getattribute().
It seems that at least in some cases this leads to counterintuitive behaviour, and falling back to A.__dict__['m'].__get__(obj, A) (note the change in owner from B to A) seems preferable. Is that a particular case for pyfields because we have a descriptor for the __init__ method and therefore would like it to "stay" on A once called, or would this be preferable in all cases ?
class AInitDescriptor(object):
def __get__(self, instance, owner):
print("called on instance %s - creating init for owner class %s" % (instance, owner.__name__))
def __init__():
pass
# Assign the __init__ method to the class
if owner.__name__ != 'A':
raise ValueError("This is the __init__ descriptor for A, not for %s!" % owner.__name__)
owner.__init__ = __init__
# finally return
return __init__
class A(object):
__init__ = AInitDescriptor()
class B(A):
def __init__(self):
super(B, self).__init__()
# this leads to an error
b = B()
Note that trivial workarounds for this specific example can be found, but the general question remains interesting to discuss.
See smarie/python-pyfields#53 (comment)
From the documentation
It seems that at least in some cases this leads to counterintuitive behaviour, and falling back to
A.__dict__['m'].__get__(obj, A)(note the change in owner from B to A) seems preferable. Is that a particular case forpyfieldsbecause we have a descriptor for the__init__method and therefore would like it to "stay" on A once called, or would this be preferable in all cases ?Note that trivial workarounds for this specific example can be found, but the general question remains interesting to discuss.
See smarie/python-pyfields#53 (comment)