Polymorphism and wrapping Python

Hasan Aljudy hasan.aljudy at gmail.com
Sat Jun 3 17:47:26 PDT 2006


Kirk McDonald wrote:
> I'm currently writing a family of classes that wrap the object layers of 
> the Python/C API. The class hierarchy looks something like this:
> 
> DPyObject
>   DPyNumber
>     DPyInteger
>     DPyFloat
>     (etc)
>   DPySequence
>     DPyString
>     DPyList
>     (etc)
>   DPyMapping
>     DPyDict
>   (etc)
> 
> All of the classes on the second level are declared as "abstract," and 
> (appropriately) represent the Python/C API's abstract objects layer. 
> DPyObject and the classes on the third level are not abstract and 
> represent the concrete objects layer. (Though I think I may eventually 
> make DPyObject abstract, too.)
> 
> Behind this is a factory function that takes a PyObject* (the Python/C 
> API's usual way of representing a Python object) and returns a instance 
> of the proper subclass of DPyObject.
> 
> I have a question, then, of polymorphism, and how closely I should try 
> to emulate Python.
> 
> In Python, if you try to (for example) add two instances of a class that 
> doesn't have the __add__ method (Python's equivalent of opAdd) defined, 
> Python will raise a TypeError. If you try to do this in D, it is a 
> compile-time error.
> 
> At the moment, DPyObject doesn't define opAdd. DPyNumber does, like this:
> 
> DPyNumber opAdd(DPyNumber rhs) {
>     return make_dpyobject(PyNumber_Add(m_ptr, rhs.m_ptr));
> }
> 
> (If you're unfamiliar with the Python/C API, PyNumber_Add takes two 
> PyObject* arguments and returns a new PyObject* with the result. m_ptr 
> is the only member of DPyObject, and is a PyObject*. make_dpyobject is 
> my factory function that returns the proper subclass of DPyObject based 
> on the type of the PyObject* passed to it.)
> 
> If we have:
> 
> DPyObject o = new DPyInteger(5);
> DPyObject p = new DPyInteger(10);
> DPyObject q = o + p; // Error! DPyObject doesn't define opAdd.
> 
> I'm trying to decide if this is a problem. I can easily define this for 
> DPyObject:
> 
> DPyObject opAdd(DPyObject rhs) { assert(false); }
> 
> Then the above example would work, but I'm not totally sure that this is 
> desirable behavior. In Python it certainly would be: that language is 
> all about the duck typing. It would certainly simplify the API, in that 
> all DPyObject-derived classes would have the same interface (now there's 
> an idea, I should write an interface...). But I still have this 
> irrational fear that it is a bad idea.
> 
> Anyone have more insight than I can currently muster?
> 
> -Kirk McDonald

I think one possibility is to use a d-to-d translator that inspects code 
and adds dummy functions to the DPyObject class as needed .. just like

DPyObject function_that_may_not_exist___who_knows( DPyObject[] params ... )
{
     assert(false);
}

Then this translator would pass the "modified" code to the actual dmd 
compiler.




More information about the Digitalmars-d mailing list