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