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
[email protected]
https://lists.sourceforge.net/lists/listinfo/rpy-list