Revision: 504
http://rpy.svn.sourceforge.net/rpy/?rev=504&view=rev
Author: lgautier
Date: 2008-04-28 02:56:55 -0700 (Mon, 28 Apr 2008)
Log Message:
-----------
rinterface:
- Added array to map R's SEXP types to their short names
- Added Python-level function to get the short name for a given SEXP
type
- Added test of SEXP validity when instanciating a vector (and fixed
the pending unit test)
- Fixes in existing tests
- Proper type casting for *_init functions
- Added macros RPY_SEXP and RPY_COUNT
robjects:
- Fixed robjects to accomodate changes in rinterface
(that lead to the simplification of the ugly idiosyncratic
self._sexp[0])
- Added test modules for RObject and REnvironment
- Edited the other tests
others:
- Updated demos/radmin.py to the recent changes
Modified Paths:
--------------
branches/rpy_nextgen/README
branches/rpy_nextgen/demos/radmin.py
branches/rpy_nextgen/rpy/rinterface/array.c
branches/rpy_nextgen/rpy/rinterface/rinterface.c
branches/rpy_nextgen/rpy/rinterface/rinterface.h
branches/rpy_nextgen/rpy/rinterface/tests/test_SexpVector.py
branches/rpy_nextgen/rpy/robjects/__init__.py
branches/rpy_nextgen/rpy/robjects/tests/__init__.py
branches/rpy_nextgen/rpy/robjects/tests/testRFunction.py
branches/rpy_nextgen/rpy/robjects/tests/testRVector.py
branches/rpy_nextgen/rpy/robjects/tests/testRobjects.py
Added Paths:
-----------
branches/rpy_nextgen/rpy/robjects/tests/testREnvironment.py
branches/rpy_nextgen/rpy/robjects/tests/testRObject.py
Removed Paths:
-------------
branches/rpy_nextgen/rpy/rinterface/__init__.py
Modified: branches/rpy_nextgen/README
===================================================================
--- branches/rpy_nextgen/README 2008-04-24 14:07:58 UTC (rev 503)
+++ branches/rpy_nextgen/README 2008-04-28 09:56:55 UTC (rev 504)
@@ -1,7 +1,7 @@
-All this is under development.
+All this is under development, getting quickly to an alpha stage.
-The development is currently done with Python 2.5.1 and R-2.7.0-devel
+The development is currently done with Python 2.5.2 and R-2.7.0-devel
Compatibility with Python 2.4.x should be ok, now or later (might already be
ok).
Modified: branches/rpy_nextgen/demos/radmin.py
===================================================================
--- branches/rpy_nextgen/demos/radmin.py 2008-04-24 14:07:58 UTC (rev
503)
+++ branches/rpy_nextgen/demos/radmin.py 2008-04-28 09:56:55 UTC (rev
504)
@@ -1,3 +1,8 @@
+"""
+A front-end to R's packags, and help/documentation systems
+"""
+
+import os
import pygtk
pygtk.require('2.0')
import gtk
@@ -63,7 +68,7 @@
installedLibraries = robjects.r["installed.packages"]()
nrows = robjects.r.nrow(installedLibraries)[0]
ncols = robjects.r.ncol(installedLibraries)[0]
- for i in range(1, nrows._sexp[0]+1):
+ for i in range(1, nrows + 1):
row = []
pack = installedLibraries.subset(i, 1)._sexp[0]
row.append(pack)
@@ -114,6 +119,8 @@
PACKAGE_I = 0
ITEM_I = 1
+ _vignettes = None
+
def __init__(self):
super(VignetteExplorer, self).__init__()
self._table = gtk.ListStore(str, str, str)
@@ -156,10 +163,12 @@
def updateKnownVignettes(self):
self._table.clear()
+
vignettes = robjects.r["vignette"]().subset("results")[0]
- nrows = robjects.r.nrow(vignettes)[0]
- ncols = robjects.r.ncol(vignettes)[0]
- for i in range(1, nrows._sexp[0]+1):
+
+ nrows = robjects.baseNameSpaceEnv["nrow"](vignettes)[0]
+ ncols = robjects.baseNameSpaceEnv["ncol"](vignettes)[0]
+ for i in range(1, nrows + 1):
row = []
pack = vignettes.subset(i, 1)._sexp[0]
row.append(pack)
@@ -168,6 +177,8 @@
pack = vignettes.subset(i, 4)._sexp[0]
row.append(pack)
self._table.append(row)
+
+ self._vignettes = vignettes
def viewAction(self, widget, data=None):
# Get the selection in the gtk.TreeView
@@ -179,9 +190,14 @@
self.PACKAGE_I)
vigName = self._table.get_value(selection_iter,
self.ITEM_I)
- robjects.r.vignette(vigName, package = packName)
-
+
+ pdffile = robjects.r.vignette(vigName, package = packName)
+ pdffile = pdffile.subset("file")[0][0]
+ pdfviewer = robjects.baseNameSpaceEnv["options"]("pdfviewer")[0][0]
+ pid = os.spawnl(os.P_NOWAIT, pdfviewer, pdffile)
+
+
class GraphicalDeviceExplorer(gtk.VBox):
def __init__(self):
@@ -223,17 +239,17 @@
self._table.clear()
devices = robjects.r["dev.list"]()
names = robjects.r["names"](devices)
- current_device = robjects.r["dev.cur"]()._sexp[0]
+ current_device = robjects.r["dev.cur"]()[0]
try:
nrows = len(devices)
except:
return
for dev, name in itertools.izip(devices, names):
- if current_device == dev._sexp[0]:
+ if current_device == dev[0]:
cur = "X"
else:
cur = ""
- row = [cur, dev._sexp[0], name._sexp[0], ""]
+ row = [cur, dev[0], name[0], ""]
self._table.append(row)
def searchOpenedDevices(self, widget, data = None):
@@ -293,7 +309,7 @@
#import pdb; pdb.set_trace()
nrows = robjects.r.nrow(matches)[0]
ncols = robjects.r.ncol(matches)[0]
- for i in range(1, nrows._sexp[0]+1):
+ for i in range(1, nrows + 1):
row = []
pack = matches.subset(i, 1)._sexp[0]
row.append(pack)
Deleted: branches/rpy_nextgen/rpy/rinterface/__init__.py
===================================================================
--- branches/rpy_nextgen/rpy/rinterface/__init__.py 2008-04-24 14:07:58 UTC
(rev 503)
+++ branches/rpy_nextgen/rpy/rinterface/__init__.py 2008-04-28 09:56:55 UTC
(rev 504)
@@ -1,6 +0,0 @@
-# This file is automatically generated when installing rpy2
-# For permanent changes, edit __init__py.in in the source directory.
-
-import os
-
-from rinterface import *
Modified: branches/rpy_nextgen/rpy/rinterface/array.c
===================================================================
--- branches/rpy_nextgen/rpy/rinterface/array.c 2008-04-24 14:07:58 UTC (rev
503)
+++ branches/rpy_nextgen/rpy/rinterface/array.c 2008-04-28 09:56:55 UTC (rev
504)
@@ -99,9 +99,9 @@
PyObject*
-array_struct_get(SexpObject *self)
+array_struct_get(PySexpObject *self)
{
- SEXP sexp = self->sexp;
+ SEXP sexp = RPY_SEXP(self);
if (!sexp) {
PyErr_SetString(PyExc_AttributeError, "Null sexp");
return NULL;
Modified: branches/rpy_nextgen/rpy/rinterface/rinterface.c
===================================================================
--- branches/rpy_nextgen/rpy/rinterface/rinterface.c 2008-04-24 14:07:58 UTC
(rev 503)
+++ branches/rpy_nextgen/rpy/rinterface/rinterface.c 2008-04-28 09:56:55 UTC
(rev 504)
@@ -79,6 +79,8 @@
typedef intobjargproc ssizeobjargproc;
#endif
+static const int maxValidSexpType = 99;
+static char **validSexpType;
//FIXME: see the details of error handling
static PyObject *ErrorObject;
@@ -147,9 +149,9 @@
embeddedR_isInitialized = PyBool_FromLong((long)1);
- RPY_GETSEXP(globalEnv) = R_GlobalEnv;
+ RPY_SEXP(globalEnv) = R_GlobalEnv;
- RPY_GETSEXP(baseNameSpaceEnv) = R_BaseNamespace;
+ RPY_SEXP(baseNameSpaceEnv) = R_BaseNamespace;
PyObject *res = PyInt_FromLong(status);
@@ -183,8 +185,8 @@
/* */
Rf_endEmbeddedR((int)fatal);
- RPY_GETSEXP(globalEnv) = R_EmptyEnv;
- RPY_GETSEXP(baseNameSpaceEnv) = R_EmptyEnv;
+ RPY_SEXP(globalEnv) = R_EmptyEnv;
+ RPY_SEXP(baseNameSpaceEnv) = R_EmptyEnv;
Py_RETURN_NONE;
}
@@ -249,16 +251,16 @@
RPY_DECREF(self);
#ifdef RPY_VERBOSE
- printf("%p: sexp count is %i\n", self, RPY_GETCOUNT(self));
+ printf("%p: sexp count is %i\n", self, RPY_COUNT(self));
#endif
- if ((RPY_GETCOUNT(self) == 0) && RPY_GETSEXP(self)) {
+ if ((RPY_COUNT(self) == 0) && RPY_SEXP(self)) {
#ifdef RPY_VERBOSE
printf("freeing SEXP resources...");
#endif
- if (RPY_GETSEXP(self) != R_NilValue) {
- R_ReleaseObject(RPY_GETSEXP(self));
+ if (RPY_SEXP(self) != R_NilValue) {
+ R_ReleaseObject(RPY_SEXP(self));
}
free(self->sObj);
////self->ob_type->tp_free((PyObject*)self);
@@ -274,7 +276,7 @@
Sexp_repr(PyObject *self)
{
//FIXME: make sure this is making any sense
- SEXP sexp = RPY_GETSEXP((PySexpObject *)self);
+ SEXP sexp = RPY_SEXP((PySexpObject *)self);
if (! sexp) {
PyErr_Format(PyExc_ValueError, "NULL SEXP.");
return NULL;
@@ -289,7 +291,7 @@
static PyObject*
Sexp_typeof(PyObject *self)
{
- SEXP sexp = RPY_GETSEXP(((PySexpObject*)self));
+ SEXP sexp = RPY_SEXP(((PySexpObject*)self));
if (! sexp) {
PyErr_Format(PyExc_ValueError, "NULL SEXP.");
return NULL;;
@@ -304,7 +306,7 @@
static PyObject*
Sexp_do_slot(PyObject *self, PyObject *name)
{
- SEXP sexp = RPY_GETSEXP(((PySexpObject*)self));
+ SEXP sexp = RPY_SEXP(((PySexpObject*)self));
if (! sexp) {
PyErr_Format(PyExc_ValueError, "NULL SEXP.");
return NULL;;
@@ -331,6 +333,7 @@
the method.\n");
+
static PyMethodDef Sexp_methods[] = {
{"typeof", (PyCFunction)Sexp_typeof, METH_NOARGS,
Sexp_typeof_doc},
@@ -430,8 +433,8 @@
if (! self->sObj)
PyErr_NoMemory();
- RPY_GETCOUNT(self) = 1;
- RPY_GETSEXP(self) = R_NilValue;
+ RPY_COUNT(self) = 1;
+ RPY_SEXP(self) = R_NilValue;
#ifdef RPY_VERBOSE
printf("done.\n");
@@ -472,11 +475,11 @@
if (PyObject_IsTrue(copy)) {
SEXP oldSexp;
- oldSexp = RPY_GETSEXP((PySexpObject *)sourceObject);
- RPY_GETSEXP(self) = oldSexp;
+ oldSexp = RPY_SEXP((PySexpObject *)sourceObject);
+ RPY_SEXP(self) = oldSexp;
RPY_INCREF(self);
#ifdef RPY_VERBOSE
- printf("%p: sexp count is increased to %i.\n", self, RPY_GETCOUNT(self));
+ printf("%p: sexp count is increased to %i.\n", self, RPY_COUNT(self));
#endif
} else {
@@ -571,7 +574,7 @@
/* A SEXP with the function to call and the arguments and keywords. */
PROTECT(c_R = call_R = allocList(largs+lkwds+1));
SET_TYPEOF(c_R, LANGSXP);
- fun_R = RPY_GETSEXP((PySexpObject *)self);
+ fun_R = RPY_SEXP((PySexpObject *)self);
if (! fun_R) {
PyErr_Format(PyExc_ValueError, "NULL SEXP.");
goto fail;
@@ -591,7 +594,7 @@
Py_DECREF(tmp_obj);
goto fail;
}
- tmp_R = RPY_GETSEXP((PySexpObject *)tmp_obj);
+ tmp_R = RPY_SEXP((PySexpObject *)tmp_obj);
if (! tmp_R) {
PyErr_Format(PyExc_ValueError, "NULL SEXP.");
Py_DECREF(tmp_obj);
@@ -633,7 +636,7 @@
goto fail;
}
Py_DECREF(tmp_obj);
- tmp_R = RPY_GETSEXP((PySexpObject *)argValue);
+ tmp_R = RPY_SEXP((PySexpObject *)argValue);
if (! tmp_R) {
PyErr_Format(PyExc_ValueError, "NULL SEXP.");
Py_DECREF(tmp_obj);
@@ -680,7 +683,7 @@
Sexp_closureEnv(PyObject *self)
{
SEXP closureEnv, sexp;
- sexp = RPY_GETSEXP((PySexpObject*)self);
+ sexp = RPY_SEXP((PySexpObject*)self);
if (! sexp) {
PyErr_Format(PyExc_ValueError, "NULL SEXP.");
return NULL;
@@ -753,7 +756,7 @@
0, /*tp_descr_get*/
0, /*tp_descr_set*/
0, /*tp_dictoffset*/
- ClosureSexp_init, /*tp_init*/
+ (initproc)ClosureSexp_init, /*tp_init*/
0, /*tp_alloc*/
0,//Sexp_new, /*tp_new*/
0, /*tp_free*/
@@ -765,7 +768,6 @@
ClosureSexp_init(PySexpObject *self, PyObject *args, PyObject *kwds)
{
PyObject *object;
- int sexptype = -1;
PyObject *copy;
static char *kwlist[] = {"sexpclos", "copy", NULL};
//FIXME: handle the copy argument
@@ -797,7 +799,7 @@
{
Py_ssize_t len;
//FIXME: sanity checks.
- SEXP sexp = RPY_GETSEXP((PySexpObject *)object);
+ SEXP sexp = RPY_SEXP((PySexpObject *)object);
if (! sexp) {
PyErr_Format(PyExc_ValueError, "NULL SEXP.");
return -1;
@@ -812,7 +814,7 @@
{
PyObject* res;
R_len_t i_R;
- SEXP *sexp = &(RPY_GETSEXP((PySexpObject *)object));
+ SEXP *sexp = &(RPY_SEXP((PySexpObject *)object));
if (! sexp) {
PyErr_Format(PyExc_ValueError, "NULL SEXP.");
@@ -880,7 +882,7 @@
return -1;
}
- SEXP *sexp = &(RPY_GETSEXP((PySexpObject *)object));
+ SEXP *sexp = &(RPY_SEXP((PySexpObject *)object));
if (i >= GET_LENGTH(*sexp)) {
PyErr_Format(PyExc_IndexError, "Index out of range.");
return -1;
@@ -897,7 +899,7 @@
"type 'Sexp_Type'.");
return -1;
}
- SEXP *sexp_val = &(RPY_GETSEXP((PySexpObject *)val));
+ SEXP *sexp_val = &(RPY_SEXP((PySexpObject *)val));
if (! sexp_val) {
PyErr_Format(PyExc_ValueError, "NULL SEXP.");
return -1;
@@ -1054,6 +1056,12 @@
&PyBool_Type, ©)) {
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)) {
@@ -1070,7 +1078,7 @@
PyErr_Format(PyExc_ValueError, "Missing type.");
return -1;
}
- RPY_GETSEXP(self) = newSEXP(object, sexptype);
+ RPY_SEXP(self) = newSEXP(object, sexptype);
}
#ifdef RPY_VERBOSE
printf("done.\n");
@@ -1092,7 +1100,7 @@
return NULL;
}
- const SEXP rho_R = RPY_GETSEXP((PySexpObject *)self);
+ const SEXP rho_R = RPY_SEXP((PySexpObject *)self);
if (! rho_R) {
PyErr_Format(PyExc_ValueError, "NULL SEXP.");
return NULL;
@@ -1134,7 +1142,7 @@
name = PyString_AsString(key);
- SEXP rho_R = RPY_GETSEXP((PySexpObject *)self);
+ SEXP rho_R = RPY_SEXP((PySexpObject *)self);
if (! rho_R) {
PyErr_Format(PyExc_ValueError, "NULL SEXP.");
return NULL;
@@ -1172,14 +1180,14 @@
name = PyString_AsString(key);
- SEXP rho_R = RPY_GETSEXP((PySexpObject *)self);
+ SEXP rho_R = RPY_SEXP((PySexpObject *)self);
if (! rho_R) {
PyErr_Format(PyExc_ValueError, "The environment has NULL SEXP.");
return -1;
}
SEXP sexp_copy;
- SEXP sexp = RPY_GETSEXP((PySexpObject *)value);
+ SEXP sexp = RPY_SEXP((PySexpObject *)value);
if (! sexp) {
PyErr_Format(PyExc_ValueError, "The value has NULL SEXP.");
return -1;
@@ -1193,7 +1201,7 @@
static Py_ssize_t EnvironmentSexp_length(PyObject *self)
{
- SEXP rho_R = RPY_GETSEXP((PySexpObject *)self);
+ SEXP rho_R = RPY_SEXP((PySexpObject *)self);
if (! rho_R) {
PyErr_Format(PyExc_ValueError, "The environment has NULL SEXP.");
return -1;
@@ -1205,7 +1213,7 @@
return len;
}
-static PyMappingMethods EnvironmentSexp_mappignMethods = {
+static PyMappingMethods EnvironmentSexp_mappingMethods = {
(lenfunc)EnvironmentSexp_length, /* mp_length */
(binaryfunc)EnvironmentSexp_subscript, /* mp_subscript */
(objobjargproc)EnvironmentSexp_ass_subscript /* mp_ass_subscript */
@@ -1214,7 +1222,7 @@
static PyObject*
EnvironmentSexp_iter(PyObject *sexpEnvironment)
{
- SEXP rho_R = RPY_GETSEXP((PySexpObject *)sexpEnvironment);
+ SEXP rho_R = RPY_SEXP((PySexpObject *)sexpEnvironment);
if (! rho_R) {
PyErr_Format(PyExc_ValueError, "The environment has NULL SEXP.");
@@ -1267,7 +1275,7 @@
0, /*tp_repr*/
0, /*tp_as_number*/
0, /*tp_as_sequence*/
- &EnvironmentSexp_mappignMethods,
/*tp_as_mapping*/
+ &EnvironmentSexp_mappingMethods,/*tp_as_mapping*/
0, /*tp_hash*/
0, /*tp_call*/
0,//Sexp_str, /*tp_str*/
@@ -1290,7 +1298,7 @@
0, /*tp_descr_get*/
0, /*tp_descr_set*/
0, /*tp_dictoffset*/
- EnvironmentSexp_init, /*tp_init*/
+ (initproc)EnvironmentSexp_init, /*tp_init*/
0, /*tp_alloc*/
//FIXME: add new method
0, //EnvironmentSexp_new, /*tp_new*/
@@ -1302,7 +1310,6 @@
EnvironmentSexp_init(PySexpObject *self, PyObject *args, PyObject *kwds)
{
PyObject *object;
- int sexptype = -1;
PyObject *copy;
static char *kwlist[] = {"sexpenv", "copy", NULL};
//FIXME: handle the copy argument
@@ -1442,7 +1449,7 @@
return NULL;
}
//PyObject_Init(&object, &ClosureSexp_Type);
- RPY_GETSEXP(object) = sexp_ok;
+ RPY_SEXP(object) = sexp_ok;
//FIXME: Increment reference ?
//Py_INCREF(object);
return object;
@@ -1531,7 +1538,7 @@
"type 'Sexp_Type'.");
return NULL;
}
- SET_ELEMENT(sexp, i, RPY_GETSEXP((PySexpObject *)item));
+ SET_ELEMENT(sexp, i, RPY_SEXP((PySexpObject *)item));
Py_DECREF(item);
}
}
@@ -1564,7 +1571,7 @@
/* --- Find a variable in an environment --- */
-
+//FIXME: is this any longer useful ?
static PySexpObject*
EmbeddedR_findVar(PyObject *self, PyObject *args)
{
@@ -1589,9 +1596,31 @@
PyDoc_STRVAR(EmbeddedR_findVar_doc,
"Find a variable in R's .GlobalEnv.");
+static PyObject*
+EmbeddedR_sexpType(PyObject *self, PyObject *args)
+{
+ int sexp_i;
+ if (! PyArg_ParseTuple(args, "i", &sexp_i)) {
+ //PyErr_Format(PyExc_LookupError, "Value should be an integer");
+ return NULL;
+ }
+ const char *sexp_type = validSexpType[sexp_i];
+
+ if ((sexp_i < 0) || (sexp_i > maxValidSexpType) || (! sexp_type)) {
+
+ PyErr_Format(PyExc_LookupError, "'%i' is not a valid SEXP value.", sexp_i);
+ return NULL;
+ }
+ //FIXME: store python strings when initializing validSexpType instead
+ PyObject *res = PyString_FromString(sexp_type);
+ return res;
+
+}
+
+
/* --- List of functions defined in the module --- */
static PyMethodDef EmbeddedR_methods[] = {
@@ -1603,6 +1632,8 @@
EmbeddedR_setWriteConsole_doc},
{"findVarEmbeddedR", (PyCFunction)EmbeddedR_findVar, METH_VARARGS,
EmbeddedR_findVar_doc},
+ {"sexpTypeEmbeddedR", (PyCFunction)EmbeddedR_sexpType, METH_VARARGS,
+ "Return the SEXP name tag corresponding to an integer."},
{NULL, NULL} /* sentinel */
};
@@ -1692,7 +1723,7 @@
Py_DECREF(pyargstup);
if (PyObject_IsInstance((PyObject*)pyres,
(PyObject*)&Sexp_Type)) {
- res = RPY_GETSEXP((PySexpObject*)pyres);
+ res = RPY_SEXP((PySexpObject*)pyres);
}
else {
res = mkPyObject(pyres);
@@ -1711,7 +1742,10 @@
/* --- Initialize the module ---*/
-#define ADD_INT_CONSTANT(module, name) PyModule_AddIntConstant(module, #name,
name)
+#define ADD_INT_CONSTANT(module, name) \
+ PyModule_AddIntConstant(module, #name, name)
+#define ADD_VALID_SEXP(name) \
+ validSexpType[name] = #name
PyMODINIT_FUNC
@@ -1761,7 +1795,7 @@
globalEnv = (PySexpObject *)Sexp_new(&EnvironmentSexp_Type,
Py_None, Py_None);
- RPY_GETSEXP(globalEnv) = R_EmptyEnv;
+ RPY_SEXP(globalEnv) = R_EmptyEnv;
//SexpObject *sObj = globalEnv->sObj;
//SEXP sexp = sObj->sexp;
//sexp = R_EmptyEnv;
@@ -1773,36 +1807,65 @@
baseNameSpaceEnv = (PySexpObject*)Sexp_new(&EnvironmentSexp_Type,
Py_None, Py_None);
- RPY_GETSEXP(baseNameSpaceEnv) = R_EmptyEnv;
+ RPY_SEXP(baseNameSpaceEnv) = R_EmptyEnv;
if (PyDict_SetItemString(d, "baseNameSpaceEnv", (PyObject
*)baseNameSpaceEnv) < 0)
return;
/* //FIXME: DECREF ? */
/* Py_DECREF(baseNameSpaceEnv); */
+
/* Add SXP types */
+ validSexpType = calloc(maxValidSexpType, sizeof(char *));
+ if (! validSexpType) {
+ PyErr_NoMemory();
+ return;
+ }
ADD_INT_CONSTANT(m, NILSXP);
+ ADD_VALID_SEXP(NILSXP);
ADD_INT_CONSTANT(m, SYMSXP);
+ ADD_VALID_SEXP(SYMSXP);
ADD_INT_CONSTANT(m, LISTSXP);
+ ADD_VALID_SEXP(LISTSXP);
ADD_INT_CONSTANT(m, CLOSXP);
+ ADD_VALID_SEXP(CLOSXP);
ADD_INT_CONSTANT(m, ENVSXP);
+ ADD_VALID_SEXP(ENVSXP);
ADD_INT_CONSTANT(m, PROMSXP);
+ ADD_VALID_SEXP(PROMSXP);
ADD_INT_CONSTANT(m, LANGSXP);
+ ADD_VALID_SEXP(LANGSXP);
ADD_INT_CONSTANT(m, SPECIALSXP);
+ ADD_VALID_SEXP(SPECIALSXP);
ADD_INT_CONSTANT(m, BUILTINSXP);
+ ADD_VALID_SEXP(BUILTINSXP);
ADD_INT_CONSTANT(m, CHARSXP);
+ ADD_VALID_SEXP(CHARSXP);
ADD_INT_CONSTANT(m, STRSXP);
+ ADD_VALID_SEXP(STRSXP);
ADD_INT_CONSTANT(m, LGLSXP);
+ ADD_VALID_SEXP(LGLSXP);
ADD_INT_CONSTANT(m, INTSXP);
+ ADD_VALID_SEXP(INTSXP);
ADD_INT_CONSTANT(m, REALSXP);
+ ADD_VALID_SEXP(REALSXP);
ADD_INT_CONSTANT(m, CPLXSXP);
+ ADD_VALID_SEXP(CPLXSXP);
ADD_INT_CONSTANT(m, DOTSXP);
+ ADD_VALID_SEXP(DOTSXP);
ADD_INT_CONSTANT(m, ANYSXP);
+ ADD_VALID_SEXP(ANYSXP);
ADD_INT_CONSTANT(m, VECSXP);
+ ADD_VALID_SEXP(VECSXP);
ADD_INT_CONSTANT(m, EXPRSXP);
+ ADD_VALID_SEXP(EXPRSXP);
ADD_INT_CONSTANT(m, BCODESXP);
+ ADD_VALID_SEXP(BCODESXP);
ADD_INT_CONSTANT(m, EXTPTRSXP);
+ ADD_VALID_SEXP(EXTPTRSXP);
ADD_INT_CONSTANT(m, RAWSXP);
+ ADD_VALID_SEXP(RAWSXP);
ADD_INT_CONSTANT(m, S4SXP);
+ ADD_VALID_SEXP(S4SXP);
/* longuest integer for R indexes */
ADD_INT_CONSTANT(m, R_LEN_T_MAX);
@@ -1825,7 +1888,7 @@
PySexpObject *na_string = (PySexpObject *)Sexp_new(&VectorSexp_Type,
Py_None, Py_None);
- RPY_GETSEXP(na_string) = NA_STRING;
+ RPY_SEXP(na_string) = NA_STRING;
if (PyDict_SetItemString(d, "NA_STRING", (PyObject *)na_string) < 0)
return;
/* //FIXME: DECREF ? */
Modified: branches/rpy_nextgen/rpy/rinterface/rinterface.h
===================================================================
--- branches/rpy_nextgen/rpy/rinterface/rinterface.h 2008-04-24 14:07:58 UTC
(rev 503)
+++ branches/rpy_nextgen/rpy/rinterface/rinterface.h 2008-04-28 09:56:55 UTC
(rev 504)
@@ -24,9 +24,9 @@
} PySexpObject;
-#define RPY_GETCOUNT(obj) (((obj)->sObj)->count)
-#define RPY_GETSEXP(obj) (((obj)->sObj)->sexp)
-//#define RPY_GETSEXP(obj) ((obj)->sexp)
+#define RPY_COUNT(obj) (((obj)->sObj)->count)
+#define RPY_SEXP(obj) (((obj)->sObj)->sexp)
+//#define RPY_SEXP(obj) ((obj)->sexp)
#define RPY_INCREF(obj) ((obj->sObj)->count++)
#define RPY_DECREF(obj) ((obj->sObj)->count--)
Modified: branches/rpy_nextgen/rpy/rinterface/tests/test_SexpVector.py
===================================================================
--- branches/rpy_nextgen/rpy/rinterface/tests/test_SexpVector.py
2008-04-24 14:07:58 UTC (rev 503)
+++ branches/rpy_nextgen/rpy/rinterface/tests/test_SexpVector.py
2008-04-28 09:56:55 UTC (rev 504)
@@ -1,4 +1,5 @@
import unittest
+import sys
import rpy2.rinterface as rinterface
try:
@@ -87,8 +88,8 @@
def testNew_InvalidType(self):
- self.assertTrue(False) #FIXME: invalid type causes a segfault
self.assertRaises(ValueError, rinterface.SexpVector, [1, ], -1)
+ self.assertRaises(ValueError, rinterface.SexpVector, [1, ], 250)
def testGetItem(self):
letters_R = rinterface.globalEnv.get("letters")
@@ -97,21 +98,24 @@
for l, i in letters:
self.assertTrue(letters_R[i] == l)
- as_list_R = rinterface.globalEnv.get("as.list")
+ Rlist = rinterface.globalEnv.get("list")
seq_R = rinterface.globalEnv.get("seq")
mySeq = seq_R(rinterface.SexpVector([0, ], rinterface.INTSXP),
rinterface.SexpVector([10, ], rinterface.INTSXP))
- myList = as_list_R(mySeq)
-
- for i, li in enumerate(myList):
- self.assertEquals(i, myList[i][0])
+ myList = Rlist(s=mySeq, l=letters_R)
+ idem = rinterface.globalEnv.get("identical")
+ self.assertTrue(idem(mySeq, myList[0]))
+ self.assertTrue(idem(letters_R, myList[1]))
+
def testGetItemOutOfBound(self):
myVec = rinterface.SexpVector([0, 1, 2, 3, 4, 5], rinterface.INTSXP)
self.assertRaises(IndexError, myVec.__getitem__, 10)
- self.assertRaises(IndexError, myVec.__getitem__,
rinterface.R_LEN_T_MAX+1)
+ if (sys.maxint > rinterface.R_LEN_T_MAX):
+ self.assertRaises(IndexError, myVec.__getitem__,
+ rinterface.R_LEN_T_MAX+1)
def testAssignItemDifferentType(self):
c_R = rinterface.globalEnv.get("c")
Modified: branches/rpy_nextgen/rpy/robjects/__init__.py
===================================================================
--- branches/rpy_nextgen/rpy/robjects/__init__.py 2008-04-24 14:07:58 UTC
(rev 503)
+++ branches/rpy_nextgen/rpy/robjects/__init__.py 2008-04-28 09:56:55 UTC
(rev 504)
@@ -65,15 +65,16 @@
def repr_robject(o):
s = r.deparse(o)
- s = str.join(os.linesep, o)
+ s = str.join(os.linesep, s)
return s
-class Robject(rinterface.Sexp):
+class Robject(object):
name = None
+ _sexp = None
def __init__(self, sexp, copy=True):
- super(Robject, self).__init__(sexp, copy=copy)
+ self._sexp = rinterface.Sexp(sexp, copy=copy)
def __str__(self):
tmp = r.fifo("")
@@ -88,7 +89,24 @@
def __repr__(self):
return repr_robject(self)
-class Rvector(rinterface.SexpVector):
+ def __setattr__(self, name, value):
+ if name == '_sexp':
+ if not isinstance(value, rinterface.Sexp):
+ raise ValueError("_attr must contain an object " +\
+ "that inherits from rinterface.Sexp" +\
+ "(not from %s)" %type(value))
+ super(Robject, self).__setattr__(name, value)
+
+ def getSexp(self):
+ return self._sexp
+
+ def typeof(self):
+ return self._sexp.typeof()
+
+ def do_slot(self, name):
+ return self._sexp.do_slot(name)
+
+class Rvector(Robject):
""" R vector-like object. Items in those instances can
be accessed with the method "__getitem__" ("[" operator),
or with the method "subset"."""
@@ -96,7 +114,8 @@
def __init__(self, o):
if not isinstance(o, rinterface.SexpVector):
o = mapperPy2R(o)
- super(Rvector, self).__init__(o)
+ o = o.getSexp()
+ self._sexp = o
def subset(self, *args, **kwargs):
@@ -119,71 +138,85 @@
res = r["["](*([self, ] + [x for x in args]), **kwargs)
return res
+ def __getitem__(self, i):
+ res = self._sexp[i]
+ if isinstance(res, rinterface.Sexp):
+ res = mapperR2Py(res)
+ return res
+
def __repr__(self):
return repr_robject(self)
def __add__(self, x):
- res = r.get("+")(self, x)
+ res = r.get("+")(self.getSexp(), x)
return res
def __sub__(self, x):
- res = r.get("-")(self, x)
+ res = r.get("-")(self.getSexp(), x)
return res
def __mul__(self, x):
- res = r.get("*")(self, x)
+ res = r.get("*")(self.getSexp(), x)
return res
def __div__(self, x):
- res = r.get("/")(self, x)
+ res = r.get("/")(self.getSexp(), x)
return res
def __divmod__(self, x):
- res = r.get("%%")(self, x)
+ res = r.get("%%")(self.getSexp(), x)
return res
def __or__(self, x):
- res = r.get("|")(self, x)
+ res = r.get("|")(self.getSexp(), x)
return res
def __and__(self, x):
- res = r.get("&")(self, x)
+ res = r.get("&")(self.getSexp(), x)
return res
def __len__(self):
- return len(sexp)
+ return len(self._sexp)
-class Rfunction(rinterface.SexpClosure):
+class Rfunction(Robject):
""" An R function (aka "closure").
"""
- def __init__(self, o):
- super(Rfunction, self).__init__(o)
+ def __init__(self, sexp):
+ # arbirtary python functions for v-2.1
+ self._sexp = rinterface.SexpClosure(sexp)
def __call__(self, *args, **kwargs):
- new_args = [mapperPy2R(a)._sexp for a in args]
+ new_args = [mapperPy2R(a).getSexp() for a in args]
new_kwargs = {}
for k, v in kwargs.iteritems():
- new_kwargs[k] = mapperPy2R(v)._sexp
- res = self._sexp(*new_args, **new_kwargs)
+ new_kwargs[k] = mapperPy2R(v).getSexp()
+ res = self.getSexp()(*new_args, **new_kwargs)
res = mapperR2Py(res)
return res
+ #def getSexp(self):
+ # return super(rinterface.SexpClosure, self).__init__(self)
-class Renvironment(rinterface.SexpEnvironment):
+class Renvironment(Robject):
""" An R environement. """
- def __init__(self, o):
- super(Renvironment, self).__init__(o)
+ def __init__(self, o=None):
+ if o is None:
+ o =
rinterface.baseNameSpaceEnv["new.env"](hash=rinterface.SexpVector([True, ],
rinterface.LGLSXP))
+ self._sexp = rinterface.SexpEnvironment(o)
def __getitem__(self, item):
- res = super(Renvironment, self).__getitem__(item)
+ res = self._sexp[item]
res = mapperR2Py(res)
return res
def __setitem__(self, item, value):
- self[item] = robj
+ robj = mapperPy2R(value)
+ self._sexp[item] = robj.getSexp()
+ def __iter__(self):
+ return iter(self._sexp)
class RS4(Robject):
def __init__(self, o):
Modified: branches/rpy_nextgen/rpy/robjects/tests/__init__.py
===================================================================
--- branches/rpy_nextgen/rpy/robjects/tests/__init__.py 2008-04-24 14:07:58 UTC
(rev 503)
+++ branches/rpy_nextgen/rpy/robjects/tests/__init__.py 2008-04-28 09:56:55 UTC
(rev 504)
@@ -1,9 +1,22 @@
import unittest
+
+import testRObject
+import testRVector
+import testRFunction
+import testREnvironment
import testRobjects
def suite():
+ suite_RObject = testRObject.suite()
+ suite_RVector = testRVector.suite()
+ suite_RFunction = testRFunction.suite()
+ suite_REnvironment = testREnvironment.suite()
suite_Robjects = testRobjects.suite()
- alltests = unittest.TestSuite([suite_Robjects, ])
+ alltests = unittest.TestSuite([suite_RObject,
+ suite_RVector,
+ suite_RFunction,
+ suite_REnvironment,
+ suite_Robjects ])
return alltests
def main():
Added: branches/rpy_nextgen/rpy/robjects/tests/testREnvironment.py
===================================================================
--- branches/rpy_nextgen/rpy/robjects/tests/testREnvironment.py
(rev 0)
+++ branches/rpy_nextgen/rpy/robjects/tests/testREnvironment.py 2008-04-28
09:56:55 UTC (rev 504)
@@ -0,0 +1,22 @@
+import unittest
+import rpy2.robjects as robjects
+rinterface = robjects.rinterface
+import array
+
+class REnvironmentTestCase(unittest.TestCase):
+ def testNew(self):
+ env = robjects.Renvironment()
+ self.assertEquals(rinterface.ENVSXP, env.getSexp().typeof())
+ self.assertRaises(ValueError, robjects.Renvironment, 'a')
+
+ def testSetItem(self):
+ env = robjects.Renvironment()
+ env['a'] = 123
+ self.assertTrue('a' in env)
+
+def suite():
+ suite = unittest.TestLoader().loadTestsFromTestCase(REnvironmentTestCase)
+ return suite
+
+if __name__ == '__main__':
+ unittest.main()
Property changes on: branches/rpy_nextgen/rpy/robjects/tests/testREnvironment.py
___________________________________________________________________
Name: svn:eol-style
+ native
Modified: branches/rpy_nextgen/rpy/robjects/tests/testRFunction.py
===================================================================
--- branches/rpy_nextgen/rpy/robjects/tests/testRFunction.py 2008-04-24
14:07:58 UTC (rev 503)
+++ branches/rpy_nextgen/rpy/robjects/tests/testRFunction.py 2008-04-28
09:56:55 UTC (rev 504)
@@ -5,20 +5,24 @@
class RFunctionTestCase(unittest.TestCase):
def testNew(self):
+ identical = rinterface.baseNameSpaceEnv["identical"]
self.assertRaises(ValueError, robjects.Rfunction, 'a')
ri_f = rinterface.baseNameSpaceEnv.get('help')
ro_f = robjects.Rfunction(ri_f)
+
+ self.assertTrue(identical(ri_f, ro_f.getSexp()))
- #self.assertEquals(ro_v.typeof(), rinterface.INTSXP)
+ def testCall(self):
+ ri_f = rinterface.baseNameSpaceEnv.get('sum')
+ ro_f = robjects.Rfunction(ri_f)
- #ri_v = rinterface.SexpVector(py_a)
- #ri_o = rinterface.Sexp(ri_v)
+ ro_v = robjects.Rvector(array.array('i', [1,2,3]))
- #r_v_new = robject.Rvector(ri_v)
- #r_v_new = robject.Rvector(ro_v)
-
+ s = ro_f(ro_v)
+
+
def suite():
suite = unittest.TestLoader().loadTestsFromTestCase(RFunctionTestCase)
return suite
Added: branches/rpy_nextgen/rpy/robjects/tests/testRObject.py
===================================================================
--- branches/rpy_nextgen/rpy/robjects/tests/testRObject.py
(rev 0)
+++ branches/rpy_nextgen/rpy/robjects/tests/testRObject.py 2008-04-28
09:56:55 UTC (rev 504)
@@ -0,0 +1,31 @@
+import unittest
+import rpy2.robjects as robjects
+rinterface = robjects.rinterface
+import array
+
+class RObjectTestCase(unittest.TestCase):
+ def testNew(self):
+
+ identical = rinterface.baseNameSpaceEnv["identical"]
+ py_a = array.array('i', [1,2,3])
+ self.assertRaises(ValueError, robjects.Robject, py_a)
+
+ ri_v = rinterface.SexpVector(py_a, rinterface.INTSXP)
+ ro_v = robjects.Robject(ri_v)
+
+ self.assertTrue(identical(ro_v._sexp, ri_v)[0])
+
+ #FIXME: why isn't this working ?
+ #del(ri_v)
+ self.assertEquals(rinterface.INTSXP, ro_v.typeof())
+
+ def testRepr(self):
+ prt = rinterface.baseNameSpaceEnv["print"]
+ s = prt.__repr__()
+
+def suite():
+ suite = unittest.TestLoader().loadTestsFromTestCase(RObjectTestCase)
+ return suite
+
+if __name__ == '__main__':
+ unittest.main()
Property changes on: branches/rpy_nextgen/rpy/robjects/tests/testRObject.py
___________________________________________________________________
Name: svn:eol-style
+ native
Modified: branches/rpy_nextgen/rpy/robjects/tests/testRVector.py
===================================================================
--- branches/rpy_nextgen/rpy/robjects/tests/testRVector.py 2008-04-24
14:07:58 UTC (rev 503)
+++ branches/rpy_nextgen/rpy/robjects/tests/testRVector.py 2008-04-28
09:56:55 UTC (rev 504)
@@ -3,17 +3,70 @@
rinterface = robjects.rinterface
import array
+rlist = robjects.baseNameSpaceEnv["list"]
+
class RvectorTestCase(unittest.TestCase):
def testNew(self):
+ identical = rinterface.baseNameSpaceEnv["identical"]
py_a = array.array('i', [1,2,3])
ro_v = robjects.Rvector(py_a)
self.assertEquals(ro_v.typeof(), rinterface.INTSXP)
- ri_v = rinterface.SexpVector(py_a)
+ ri_v = rinterface.SexpVector(py_a, rinterface.INTSXP)
+ ro_v = robjects.Rvector(ri_v)
+
+ self.assertTrue(identical(ro_v._sexp, ri_v)[0])
+
+ #FIXME: why isn't this working ?
+ #del(ri_v)
+ self.assertEquals(rinterface.INTSXP, ro_v.typeof())
- #r_v_new = robject.Rvector(ri_v)
- #r_v_new = robject.Rvector(ro_v)
+ def testOperators(self):
+ seq_R = robjects.r["seq"]
+ mySeq = seq_R(0, 10)
+ mySeqAdd = mySeq + 2
+ for i, li in enumerate(mySeq):
+ self.assertEquals(i + 2, mySeqAdd[i])
+
+ mySeqAdd = mySeq + mySeq
+ for i, li in enumerate(mySeq):
+ self.assertEquals(mySeq[i] * 2, mySeqAdd[i])
+
+ def testSubset(self):
+ seq_R = robjects.baseNameSpaceEnv["seq"]
+ mySeq = seq_R(0, 10)
+ # R indexing starts at one
+ myIndex = robjects.Rvector(array.array('i', range(1, 11, 2)))
+
+ mySubset = mySeq.subset(myIndex)
+ for i, si in enumerate(myIndex):
+ self.assertEquals(mySeq[si-1], mySubset[i])
+
+ # recycling rule
+ v = robjects.Rvector(array.array('i', range(1, 23)))
+ m = robjects.r.matrix(v, ncol = 2)
+ col = m.subset(True, 1)
+ self.assertEquals(11, len(col))
+
+ # list
+ letters = robjects.baseNameSpaceEnv["letters"]
+ myList = rlist(l=letters, f="foo")
+ idem = robjects.baseNameSpaceEnv["identical"]
+ self.assertTrue(idem(letters, myList.subset("l")[0]))
+ self.assertTrue(idem("foo", myList.subset("f")[0]))
+
+ def testGetItem(self):
+ letters = robjects.baseNameSpaceEnv["letters"]
+ self.assertEquals('a', letters[0])
+ self.assertEquals('z', letters[25])
+ self.assertRaises(IndexError, letters.__getitem__, 26)
+
+ mylist = rlist(letters, "foo")
+ idem = robjects.baseNameSpaceEnv["identical"]
+ self.assertTrue(idem(letters, mylist[0]))
+ self.assertTrue(idem("foo", mylist[1]))
+
def suite():
suite = unittest.TestLoader().loadTestsFromTestCase(RvectorTestCase)
return suite
Modified: branches/rpy_nextgen/rpy/robjects/tests/testRobjects.py
===================================================================
--- branches/rpy_nextgen/rpy/robjects/tests/testRobjects.py 2008-04-24
14:07:58 UTC (rev 503)
+++ branches/rpy_nextgen/rpy/robjects/tests/testRobjects.py 2008-04-28
09:56:55 UTC (rev 504)
@@ -22,38 +22,9 @@
for i, li in enumerate(myList):
self.assertEquals(i, myList[i][0])
- def testOperators(self):
- seq_R = robjects.r["seq"]
- mySeq = seq_R(0, 10)
- mySeqAdd = mySeq + 2
- for i, li in enumerate(mySeq):
- self.assertEquals(i + 2, mySeqAdd[i])
- mySeqAdd = mySeq + mySeq
- for i, li in enumerate(mySeq):
- self.assertEquals(mySeq[i] * 2, mySeqAdd[i])
-
- def testSubset(self):
- seq_R = robjects.r["seq"]
- mySeq = seq_R(0, 10)
- # R indexing starts at one
- myIndex = robjects.Rvector(array.array('i', range(1, 11, 2)))
- mySubset = mySeq.subset(myIndex)
- #import pdb; pdb.set_trace()
- for i, si in enumerate(myIndex):
- self.assertEquals(mySeq[si-1], mySubset[i])
-
- # recycling rule
- v = robjects.Rvector(array.array('i', range(1, 23)))
- m = robjects.r.matrix(v, ncol = 2)
- col = m.subset(True, 1)
- #import pdb; pdb.set_trace()
- self.assertEquals(11, len(col))
-
-
-
def testMapperR2Python(self):
sexp = rinterface.globalEnv.get("letters")
ob = robjects.defaultRobjects2PyMapper(sexp)
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
-------------------------------------------------------------------------
This SF.net email is sponsored by the 2008 JavaOne(SM) Conference
Don't miss this year's exciting event. There's still time to save $100.
Use priority code J8TL2D2.
http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone
_______________________________________________
rpy-list mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/rpy-list