[PYTHON C++-SIG] Typecasts to/from PyObject?

Geoffrey Furnish furnish at laura.llnl.gov
Mon Feb 24 17:45:37 CET 1997


Johann Hibschman writes:
 > Hi all,
 > 
 > I have a style question.  If I define a class around the usual PyObject 
 > pointer, like
 > 
 >    class CPyObject {
 >       PyObject *obj;
 >    public:
 >       CPyObject( PyObject *o ) : obj(o) {}
 >    }
 > 
 > would it be a good idea to also define C++->CPyObject data conversions, 
 > like adding,
 > 
 >       CPyObject( double x ) { obj = PyBuildValue("d", d); }
 > 
 > or CPyObject->C++ conversions, like
 > 
 >       operator double() {
 >          double x;
 >          PyArg_Parse( obj, "d", &x );   // add appropriate error handling...
 >          return x;
 >       }
 > 
 > or would it just provide a source of confusing bugs?

I think it is a good idea, so we intend to do things like this.

 > I'm looking at this in the context of creating a PyDict class.  If I 
 > define the type conversions, I could write:
 > 
 >    PyList plist;
 >    plist["spam"] = 3.0;
 >    x = y + plist["spam"];

That is nice, if it works.  However, I am not sure how you avoid
having multiple available conversions, and what effect that has on the
matching rules.  

 > while otherwise I would have to write something like
 > 
 >    plist[ toPyObject("spam") ] = toPyObject(3.0);
 >    x= y + PyObjectToDouble( plist[ toPyObject("spam") ] );

That is something we would like to avoid.

 > Conversions are dangerous, in that they might do unexpected things, but 
 > they would make the syntax a lot nicer.

One way to approach this is to mark the potentially ambiguous
conversions explicit, so that the compiler won't use them implicitly.
Then the user would have to use the conversions directly, and this
would moreover, provide a place for an assertion.

 > As an example of the bad effects, if a program had a reference to a 
 > floating-point python object, like
 > 
 >    CPyObject pi( PyBuildValue("d", 3.14159 ) );
 > 
 > then this code would give an error of some kind (I believe):
 > 
 >    double x, y=3.14;
 >    int i, j;
 >    x = 2.0 + pi;   // fine, converts CPyObject to double
 >    x = 2 + pi;     // Would this try to convert CPyObject to int or double?
 >    i = 2 + pi;     // Would the attempted CPyObject to int conversion work?
 >    i = 2 + y;      // This is fine, but loses information...
 > 
 > Opinions?

class CPyObject {
// internal state
  public:
    explicit operator double()
    {
        // Check that it really is a double.
        return <double value of this PyObject>;
    }
};

I think this would result in code like:

x = 2.0 + double(pi);
x = 2 + int(pi);

both of which could bbe made to work robustly and are much less ugly
than the equivalent C code.

 > - Johann
 > 
 > P.S.  Yes, in a real version, these conversions would probably be 
 > implemented through traits-style templates, but I haven't quite thought 
 > my way all the way through that yet.

Please elaborate.

-- 
Geoffrey Furnish		email: furnish at llnl.gov
LLNL X/ICF			phone: 510-424-4227	fax: 510-423-0925

_______________
C++-SIG - SIG for Development of a C++ Binding to Python

send messages to: c++-sig at python.org
administrivia to: c++-sig-request at python.org
_______________



More information about the Cplusplus-sig mailing list