Revision: 547 http://rpy.svn.sourceforge.net/rpy/?rev=547&view=rev Author: lgautier Date: 2008-06-07 00:01:08 -0700 (Sat, 07 Jun 2008)
Log Message: ----------- rinterface: - replaced call to Rf_initEmbeddedR with its content (easier to tweak) - dealloc for Sexp split into two functions: clear and dealloc - PyObject_New and PyObject_Del are out (causing segfault when subclassing) - init for Sexp moved around (and early type declaration with staticforward) - trivial fixes in the init for VectorSexp, ClosureSexp, EnvironmentSexp - restored --quiet as a default starting option Modified Paths: -------------- branches/rpy_nextgen/rpy/rinterface/rinterface.c Modified: branches/rpy_nextgen/rpy/rinterface/rinterface.c =================================================================== --- branches/rpy_nextgen/rpy/rinterface/rinterface.c 2008-06-05 18:07:04 UTC (rev 546) +++ branches/rpy_nextgen/rpy/rinterface/rinterface.c 2008-06-07 07:01:08 UTC (rev 547) @@ -71,7 +71,7 @@ #include "array.h" #include "r_utils.h" -#define RPY_VERBOSE +//#define RPY_VERBOSE /* Back-compatibility with Python 2.4 */ #if (PY_VERSION_HEX < 0x02050000) @@ -230,14 +230,11 @@ } - int status = Rf_initEmbeddedR(n_args, options); - /* FIXME: setup_Rmainloop causes ipython to crash - *(bug in ipython ?) - */ -/* int status = 1; */ -/* Rf_initialize_R(n_args, options); */ -/* R_Interactive = TRUE; Rf_initialize_R set this based on isatty */ -/* setup_Rmainloop(); */ + /* int status = Rf_initEmbeddedR(n_args, options);*/ + int status = 1; + Rf_initialize_R(n_args, options); + R_Interactive = TRUE; + setup_Rmainloop(); Py_XDECREF(embeddedR_isInitialized); embeddedR_isInitialized = Py_True; @@ -326,18 +323,15 @@ * Access to R objects through Python objects */ - static void -Sexp_dealloc(PySexpObject *self) +Sexp_clear(PySexpObject *self) { RPY_DECREF(self); - #ifdef RPY_VERBOSE printf("Python:%p / R:%p -- sexp count is %i\n", self, RPY_SEXP(self), RPY_COUNT(self)); #endif - printf("dealloc-count--->\n"); if ((RPY_COUNT(self) == 0) && RPY_SEXP(self)) { #ifdef RPY_VERBOSE printf("freeing SEXP resources...\n"); @@ -352,12 +346,20 @@ printf("done.\n"); #endif } - printf("dealloc-del--->\n"); - PyObject_Del(self); - printf("dealloc-ok--->\n"); + } +static void +Sexp_dealloc(PySexpObject *self) +{ + Sexp_clear(self); + self->ob_type->tp_free((PyObject*)self); + + //PyObject_Del(self); +} + + static PyObject* Sexp_repr(PyObject *self) { @@ -429,79 +431,9 @@ }; +staticforward PyTypeObject Sexp_Type; static PyObject* -Sexp_new(PyTypeObject *type, PyObject *args, PyObject *kwds); - -static int -Sexp_init(PyObject *self, PyObject *args, PyObject *kwds); - -/* - * Generic Sexp_Type. It represents SEXP objects at large. - */ -static PyTypeObject Sexp_Type = { - /* The ob_type field must be initialized in the module init function - * to be portable to Windows without using C++. */ - PyObject_HEAD_INIT(NULL) - 0, /*ob_size*/ - "rinterface.Sexp", /*tp_name*/ - sizeof(PySexpObject), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - /* methods */ - (destructor)Sexp_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_compare*/ - Sexp_repr, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash*/ - 0, /*tp_call*/ - 0,//Sexp_str, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /*tp_flags*/ - 0, /*tp_doc*/ - 0, /*tp_traverse*/ - 0, /*tp_clear*/ - 0, /*tp_richcompare*/ - 0, /*tp_weaklistoffset*/ - 0, /*tp_iter*/ - 0, /*tp_iternext*/ - Sexp_methods, /*tp_methods*/ - 0, /*tp_members*/ - 0,//Sexp_getset, /*tp_getset*/ - 0, /*tp_base*/ - 0, /*tp_dict*/ - 0, /*tp_descr_get*/ - 0, /*tp_descr_set*/ - 0, /*tp_dictoffset*/ - (initproc)Sexp_init, /*tp_init*/ - 0, /*tp_alloc*/ - Sexp_new, /*tp_new*/ - 0, /*tp_free*/ - 0, /*tp_is_gc*/ -}; - - -/* static PyObject* */ -/* Sexp_new(PyTypeObject *type, PyObject *args) */ -/* { */ -/* PyObject object, res; */ -/* if (!PyArg_ParseTuple(args, "O:new", */ -/* &object)) */ -/* PyErr_Format(PyExc_ValueError, "Can only instanciate from PySexpObject"); */ -/* return NULL; */ -/* res = (PySexpObject *)_PyObject_New(&Sexp_Type); */ -/* if (!res) */ -/* PyErr_NoMemory(); */ -/* res->sexp = sexp; */ -/* return res; */ -/* } */ -static PyObject* Sexp_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { @@ -509,21 +441,23 @@ //unsigned short int rpy_only = 1; #ifdef RPY_VERBOSE - printf("new object @...\n"); + printf("new '%s' object @...\n", type->tp_name); #endif - //self = (PySexpObject *)_PyObject_New(&type); + //self = (PySexpObject *)PyObject_New(PySexpObject, type); self = (PySexpObject *)type->tp_alloc(type, 0); #ifdef RPY_VERBOSE - printf(" Python:%p / R:%p ...\n", self, R_NilValue); + printf(" Python:%p / R:%p (R_NilValue) ...\n", self, R_NilValue); #endif if (! self) PyErr_NoMemory(); self->sObj = (SexpObject *)calloc(1, sizeof(SexpObject)); - if (! self->sObj) + if (! self->sObj) { + Py_DECREF(self); PyErr_NoMemory(); + } RPY_COUNT(self) = 1; RPY_SEXP(self) = R_NilValue; @@ -537,7 +471,6 @@ } - static int Sexp_init(PyObject *self, PyObject *args, PyObject *kwds) { @@ -547,8 +480,13 @@ #endif PyObject *sourceObject; + + Py_INCREF(Py_True); PyObject *copy = Py_True; - Py_INCREF(Py_True); + + SexpObject *tmpSexpObject; + + static char *kwlist[] = {"sexp", "copy", NULL}; //FIXME: handle the copy argument @@ -569,15 +507,13 @@ } if (PyObject_IsTrue(copy)) { - //SEXP oldSexp; - //oldSexp = RPY_SEXP((PySexpObject *)sourceObject); - //RPY_SEXP(self) = oldSexp; - free(((PySexpObject *)self)->sObj); + tmpSexpObject = ((PySexpObject *)self)->sObj; ((PySexpObject *)self)->sObj = ((PySexpObject *)sourceObject)->sObj; + free(tmpSexpObject); RPY_INCREF((PySexpObject *)self); #ifdef RPY_VERBOSE - printf("%p: sexp count is increased to %i.\n", - (PySexpObject *)self, RPY_COUNT((PySexpObject *)self)); + printf("Python: %p / R: %p - sexp count is now %i.\n", + (PySexpObject *)self, RPY_SEXP((PySexpObject *)self), RPY_COUNT((PySexpObject *)self)); #endif } else { @@ -588,7 +524,7 @@ Py_DECREF(Py_True); #ifdef RPY_VERBOSE - printf("done\n."); + printf("done.\n"); #endif @@ -596,7 +532,75 @@ } +/* + * Generic Sexp_Type. It represents SEXP objects at large. + */ +static PyTypeObject Sexp_Type = { + /* The ob_type field must be initialized in the module init function + * to be portable to Windows without using C++. */ + PyObject_HEAD_INIT(NULL) + 0, /*ob_size*/ + "rinterface.Sexp", /*tp_name*/ + sizeof(PySexpObject), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + /* methods */ + (destructor)Sexp_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + Sexp_repr, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash*/ + 0, /*tp_call*/ + 0,//Sexp_str, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /*tp_flags*/ + 0, /*tp_doc*/ + 0, /*tp_traverse*/ + Sexp_clear, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + Sexp_methods, /*tp_methods*/ + 0, /*tp_members*/ + 0,//Sexp_getset, /*tp_getset*/ + 0, /*tp_base*/ + 0, /*tp_dict*/ + 0, /*tp_descr_get*/ + 0, /*tp_descr_set*/ + 0, /*tp_dictoffset*/ + (initproc)Sexp_init, /*tp_init*/ + 0, /*tp_alloc*/ + Sexp_new, /*tp_new*/ + 0, /*tp_free*/ + 0, /*tp_is_gc*/ +}; + +/* static PyObject* */ +/* Sexp_new(PyTypeObject *type, PyObject *args) */ +/* { */ +/* PyObject object, res; */ +/* if (!PyArg_ParseTuple(args, "O:new", */ +/* &object)) */ +/* PyErr_Format(PyExc_ValueError, "Can only instanciate from PySexpObject"); */ +/* return NULL; */ +/* res = (PySexpObject *)_PyObject_New(&Sexp_Type); */ +/* if (!res) */ +/* PyErr_NoMemory(); */ +/* res->sexp = sexp; */ +/* return res; */ +/* } */ + + + + /* * Closure-type Sexp. */ @@ -822,7 +826,7 @@ "); static int -ClosureSexp_init(PySexpObject *self, PyObject *args, PyObject *kwds); +ClosureSexp_init(PyObject *self, PyObject *args, PyObject *kwds); static PyTypeObject ClosureSexp_Type = { @@ -874,7 +878,7 @@ static int -ClosureSexp_init(PySexpObject *self, PyObject *args, PyObject *kwds) +ClosureSexp_init(PyObject *self, PyObject *args, PyObject *kwds) { PyObject *object; PyObject *copy; @@ -889,7 +893,7 @@ if (PyObject_IsInstance(object, (PyObject*)&ClosureSexp_Type)) { //call parent's constructor - if (Sexp_init(self, args, kwds) == -1) { + if (Sexp_init(self, args, NULL) == -1) { PyErr_Format(PyExc_RuntimeError, "Error initializing instance."); return -1; } @@ -1093,7 +1097,7 @@ " is done at zero."); static int -VectorSexp_init(PySexpObject *self, PyObject *args, PyObject *kwds); +VectorSexp_init(SexpObject *self, PyObject *args, PyObject *kwds); static PyTypeObject VectorSexp_Type = { /* The ob_type field must be initialized in the module init function @@ -1144,7 +1148,7 @@ static int -VectorSexp_init(PySexpObject *self, PyObject *args, PyObject *kwds) +VectorSexp_init(SexpObject *self, PyObject *args, PyObject *kwds) { #ifdef RPY_VERBOSE printf("%p: VectorSexp initializing...\n", self); @@ -1165,31 +1169,30 @@ return -1; } - if ((sexptype < 0) || (sexptype > maxValidSexpType) || - (! validSexpType[sexptype])) { - PyErr_Format(PyExc_ValueError, "Invalid SEXP type."); - return -1; - } if (PyObject_IsInstance(object, (PyObject*)&VectorSexp_Type)) { - //call parent's constructor if (Sexp_init(self, args, NULL) == -1) { //PyErr_Format(PyExc_RuntimeError, "Error initializing instance."); return -1; } - } else { - if (sexptype == -1) { - //FIXME: implemement automagic type - //(RPy has something). - - PyErr_Format(PyExc_ValueError, "Missing type."); + } else if (PySequence_Check(object)) { + if ((sexptype < 0) || (sexptype > maxValidSexpType) || + (! validSexpType[sexptype])) { + PyErr_Format(PyExc_ValueError, "Invalid SEXP type."); return -1; } - RPY_SEXP(self) = newSEXP(object, sexptype); + //FIXME: implemement automagic type ? + //(RPy has something)... or leave it to extensions ? + + RPY_SEXP((PySexpObject *)self) = newSEXP(object, sexptype); + } else { + PyErr_Format(PyExc_ValueError, "Invalid sexpvector."); + return -1; } + #ifdef RPY_VERBOSE - printf("done.\n"); + printf("done (VectorSexp_init).\n"); #endif return 0; @@ -1445,7 +1448,7 @@ if (PyObject_IsInstance(object, (PyObject*)&EnvironmentSexp_Type)) { //call parent's constructor - if (Sexp_init(self, args, kwds) == -1) { + if (Sexp_init(self, args, NULL) == -1) { PyErr_Format(PyExc_RuntimeError, "Error initializing instance."); return -1; } @@ -1578,9 +1581,15 @@ { SEXP sexp; PyObject *seq_object, *item; + +#ifdef RPY_VERBOSE + printf(" new SEXP for Python:%p.\n", object); +#endif + seq_object = PySequence_Fast(object, "Cannot create R object from non-sequence Python object."); //FIXME: Isn't the call above supposed to fire an Exception ? + if (! seq_object) { return NULL; } @@ -1589,7 +1598,6 @@ PROTECT(sexp = allocVector(rType, length)); int i; - switch(rType) { case REALSXP: for (i = 0; i < length; ++i) { @@ -1682,6 +1690,10 @@ sexp = NULL; } UNPROTECT(1); +#ifdef RPY_VERBOSE + printf(" new SEXP for Python:%p is %p.\n", object, sexp); +#endif + return sexp; } @@ -1904,7 +1916,7 @@ ); PYASSERT_ZERO( PyList_SetItem(initOptions, 1, - PyString_FromString("--verbose")) + PyString_FromString("--quiet")) ); PYASSERT_ZERO( PyList_SetItem(initOptions, 2, This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. ------------------------------------------------------------------------- Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://sourceforge.net/services/buy/index.php _______________________________________________ rpy-list mailing list rpy-list@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/rpy-list