Revision: 441 http://rpy.svn.sourceforge.net/rpy/?rev=441&view=rev Author: lgautier Date: 2008-03-15 07:16:23 -0700 (Sat, 15 Mar 2008)
Log Message: ----------- - implemented item assignment in SexpVector - added unit tests for that (currently the code is not passing all of them) Modified Paths: -------------- trunk/sandbox/rpy_nextgen/rpy/rinterface/rinterface.c trunk/sandbox/rpy_nextgen/rpy/rinterface/tests/test_SexpVector.py Modified: trunk/sandbox/rpy_nextgen/rpy/rinterface/rinterface.c =================================================================== --- trunk/sandbox/rpy_nextgen/rpy/rinterface/rinterface.c 2008-03-15 12:24:10 UTC (rev 440) +++ trunk/sandbox/rpy_nextgen/rpy/rinterface/rinterface.c 2008-03-15 14:16:23 UTC (rev 441) @@ -730,7 +730,81 @@ return res; } +/* a[i] = val */ +static PyObject * +VectorSexp_ass_item(PyObject *object, Py_ssize_t i, PyObject *val) +{ + PyObject* res; + R_len_t i_R; + /* R is still with int for indexes */ + if (i >= R_LEN_T_MAX) { + PyErr_Format(PyExc_IndexError, "Index value exceeds what R can handle."); + return NULL; + } + + SEXP *sexp = &(((SexpObject *)object)->sexp); + if (i >= GET_LENGTH(*sexp)) { + PyErr_Format(PyExc_IndexError, "Index out of range."); + return NULL; + } + + if (! sexp) { + PyErr_Format(PyExc_ValueError, "NULL SEXP."); + return NULL; + } + + int is_SexpObject = PyObject_TypeCheck(val, &Sexp_Type); + if (! is_SexpObject) { + PyErr_Format(PyExc_ValueError, "Any new value must be of " + "type 'Sexp_Type'."); + return NULL; + } + SEXP *sexp_val = &(((SexpObject *)val)->sexp); + if (! sexp_val) { + PyErr_Format(PyExc_ValueError, "NULL SEXP."); + return NULL; + } + + if (TYPEOF(*sexp_val) != TYPEOF(*sexp)) { + PyErr_Format(PyExc_ValueError, "The type for the new value cannot be different."); + return NULL; + } + + if ((TYPEOF(*sexp_val) != VECSXP) & (LENGTH(*sexp_val) != 1)) { + PyErr_Format(PyExc_ValueError, "The new value must be of length 1."); + return NULL; + } + + i_R = (R_len_t)i; + switch (TYPEOF(*sexp)) { + case REALSXP: + (NUMERIC_POINTER(*sexp))[i_R] = (NUMERIC_POINTER(*sexp_val))[0]; + break; + case INTSXP: + (INTEGER_POINTER(*sexp))[i_R] = (INTEGER_POINTER(*sexp_val))[0]; + break; + case LGLSXP: + (LOGICAL_POINTER(*sexp))[i_R] = (LOGICAL_POINTER(*sexp_val))[0]; + break; + case CPLXSXP: + (COMPLEX_POINTER(*sexp))[i_R] = (COMPLEX_POINTER(*sexp_val))[0]; + break; + case STRSXP: + SET_STRING_ELT(*sexp, i_R, *sexp_val); + break; + case VECSXP: + SET_VECTOR_ELT(*sexp, i_R, *sexp_val); + break; + default: + PyErr_Format(PyExc_ValueError, "cannot handle type %d", + TYPEOF(*sexp)); + res = NULL; + break; + } + return res; +} + static PySequenceMethods VectorSexp_sequenceMethods = { (lenfunc)VectorSexp_len, /* sq_length */ 0, /* sq_concat */ @@ -740,7 +814,7 @@ //FIXME: implement 0, //(ssizessizeargfunc)VectorSexp_slice, /* sq_slice */ //FIXME: implement - 0, //(ssizeobjargproc)VectorSexp_ass_item, /* sq_ass_item */ + (ssizeobjargproc)VectorSexp_ass_item, /* sq_ass_item */ 0, /* sq_ass_slice */ 0, /* sq_contains */ 0, /* sq_inplace_concat */ @@ -1178,7 +1252,6 @@ } } break; - //FIXME: add complex default: PyErr_Format(PyExc_ValueError, "cannot handle type %d", rType); sexp = NULL; Modified: trunk/sandbox/rpy_nextgen/rpy/rinterface/tests/test_SexpVector.py =================================================================== --- trunk/sandbox/rpy_nextgen/rpy/rinterface/tests/test_SexpVector.py 2008-03-15 12:24:10 UTC (rev 440) +++ trunk/sandbox/rpy_nextgen/rpy/rinterface/tests/test_SexpVector.py 2008-03-15 14:16:23 UTC (rev 441) @@ -4,6 +4,9 @@ #FIXME: can starting and stopping an embedded R be done several times ? rinterface.initEmbeddedR("foo", "--vanilla", "--no-save", "--quiet") +def floatEqual(x, y, epsilon = 0.00000001): + return abs(x - y) < epsilon + class SexpVectorTestCase(unittest.TestCase): #def setUpt(self): # rinterface.initEmbeddedR("foo", "--no-save") @@ -59,6 +62,7 @@ ok = isList(sexp)[0] self.assertTrue(ok) + self.assertEquals(2, len(sexp)) def testNew_InvalidType(self): @@ -84,5 +88,70 @@ for i, li in enumerate(myList): self.assertEquals(i, myList[i][0]) + def testAssignItemDifferentType(self): + c_R = rinterface.globalEnv.get("c") + myVec = c_R(rinterface.SexpVector([0, 1, 2, 3, 4, 5], rinterface.INTSXP)) + self.assertRaises(ValueError, myVec.__setitem__, 0, rinterface.SexpVector(["a", ], rinterface.STRSXP)) + + def testAssignItemOutOfBound(self): + c_R = rinterface.globalEnv.get("c") + myVec = c_R(rinterface.SexpVector([0, 1, 2, 3, 4, 5], rinterface.INTSXP)) + self.assertRaises(ValueError, myVec.__setitem__, 10, rinterface.SexpVector([1, ], rinterface.INTSXP)) + + def testAssignItemInt(self): + c_R = rinterface.globalEnv.get("c") + myVec = c_R(rinterface.SexpVector([0, 1, 2, 3, 4, 5], rinterface.INTSXP)) + myVec[0] = rinterface.SexpVector([100, ], rinterface.INTSXP) + self.assertTrue(myVec[0] == 100) + + myVec[3] = rinterface.SexpVector([100, ], rinterface.INTSXP) + self.assertTrue(myVec[3] == 100) + + def testAssignItemReal(self): + c_R = rinterface.globalEnv.get("c") + myVec = c_R(rinterface.SexpVector([0.0, 1.0, 2.0, 3.0, 4.0, 5.0], rinterface.REALSXP)) + myVec[0] = rinterface.SexpVector([100.0, ], rinterface.REALSXP) + self.assertTrue(floatEqual(myVec[0], 100.0)) + + myVec[3] = rinterface.SexpVector([100.0, ], rinterface.REALSXP) + self.assertTrue(floatEqual(myVec[3], 100.0)) + + def testAssignItemLogical(self): + c_R = rinterface.globalEnv.get("c") + myVec = c_R(rinterface.SexpVector([True, False, True, True, False], rinterface.LGLSXP)) + myVec[0] = rinterface.SexpVector([False, ], rinterface.LGLSXP) + self.assertFalse(myVec[0]) + + myVec[3] = rinterface.SexpVector([False, ], rinterface.LGLSXP) + self.assertFalse(myVec[3]) + + def testAssignItemComplex(self): + c_R = rinterface.globalEnv.get("c") + myVec = c_R(rinterface.SexpVector([1.0+2.0j, 2.0+2.0j, 3.0+2.0j, 4.0+2.0j, 5.0+2.0j], rinterface.CPLXSXP)) + myVec[0] = rinterface.SexpVector([100.0+200.0j, ], rinterface.CPLXSXP) + self.assertTrue(floatEqual(myVec[0].real, 100.0)) + self.assertTrue(floatEqual(myVec[0].imag, 200.0)) + + myVec[3] = rinterface.SexpVector([100.0+200.0j, ], rinterface.CPLXSXP) + self.assertTrue(floatEqual(myVec[3].real, 100.0)) + self.assertTrue(floatEqual(myVec[3].imag, 200.0)) + + def testAssignItemList(self): + myVec = rinterface.SexpVector([rinterface.SexpVector(["a", ], rinterface.STRSXP), + rinterface.SexpVector([1, ], rinterface.INTSXP), + rinterface.SexpVector([3, ], rinterface.INTSXP)], rinterface.VECSXP) + + myVec[0] = rinterface.SexpVector([rinterface.SexpVector([100.0, ], rinterface.REALSXP), ], rinterface.VECSXP) + self.assertTrue(floatEqual(myVec[0][0][0], 100.0)) + + myVec[2] = rinterface.SexpVector([rinterface.SexpVector(["a", ], rinterface.STRSXP), ], rinterface.VECSXP) + self.assertTrue(myVec[2][0][0] == "a") + + def testAssignItemString(self): + letters_R = rinterface.globalEnv.get("letters") + #FIXME: segfaults + #letters_R[0] = rinterface.SexpVector(["z", ], rinterface.STRSXP) + self.assertTrue(letters_R[0] == "z") + if __name__ == '__main__': unittest.main() 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: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2008. http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/ _______________________________________________ rpy-list mailing list rpy-list@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/rpy-list