I am recoding PyCXX which is a C++ wrapper for Python.
The original (working) implementation for adding methods to a new style class involved creating an "extern C" handler function for each, populating a PyMethodDef table with pointers to these handlers, and placing the PyTypeObject's table->tp_methods to this table.
Instead I'm replacing the mechanism with one that overrides getattro, searches my own data to see if this attribute has a corresponding C++ method, if so packages it up into a Callable Python object and returns it, otherwise defers to PyObject_GenericGetAttr.
This technique works if I create an instance of new_style_class:
# new_style_class is a C++ class deriving from ExtObj_new
_new_style_class = simple.new_style_class()
_new_style_class.func_noargs()
However, if I attempt to derive from new style class and invoke func_noargs() from the base, like this:
print( '--- Derived func ---' )
class Derived(simple.new_style_class):
def __init__( self ):
simple.new_style_class.__init__( self )
def derived_func( self ):
print( 'derived_func' )
print( vars(super()) )
super().func_noargs() # <-- AttributeError: 'super' object has no attribute 'func_noargs'
d = Derived()
d.derived_func()
... it returns AttributeError: 'super' object has no attribute 'func_noargs'.
I'm wondering whether the problem comes from the fact that I am overriding getattro rather than getattr.
Is it possible that CPython, when it attempts to invoke a base attribute, looks straight to base.getattr and misses base.getattro entirely?
If so? Does that qualify as a bug?