Revision: 402 http://rpy.svn.sourceforge.net/rpy/?rev=402&view=rev Author: lgautier Date: 2008-01-27 06:15:16 -0800 (Sun, 27 Jan 2008)
Log Message: ----------- - Added getslice methods for Robject - Added unit-tests for it - Added unit-tests for getItem Modified Paths: -------------- trunk/rpy/src/rpymodule.c trunk/rpy/tests/test_robj.py Modified: trunk/rpy/src/rpymodule.c =================================================================== --- trunk/rpy/src/rpymodule.c 2008-01-25 20:14:00 UTC (rev 401) +++ trunk/rpy/src/rpymodule.c 2008-01-27 14:15:16 UTC (rev 402) @@ -1475,16 +1475,91 @@ return obj; } +/* Get a slice: a[x:y] */ +/*FIXME: starting with Python 2.5, ilow and ihigh should probably + * be of type Py_ssize_t. + */ +static PyObject * +Robj_slice(PyObject *a, int ilow, int ihigh) +{ + SEXP robj, e, index; + PyObject *obj; + int robjLen, sliceLen, c; + + robjLen = Robj_len(a); + + if (robjLen < 0) + return NULL; + + if (ilow < 0) { + PyErr_SetString(PyExc_IndexError, + "R object index out of range (lowest index is negative)"); + return NULL; + //ilow = 0; + } else if (ilow > robjLen) { + PyErr_SetString(PyExc_IndexError, + "R object index out of range (lowest index > object length)"); + return NULL; + //ilow = robjLen; + } + if (ihigh < ilow) { + PyErr_SetString(PyExc_IndexError, + "R object index out of range (highest index < lowest index)"); + return NULL; + //ihigh = ilow; + } else if (ihigh > robjLen) { + PyErr_SetString(PyExc_IndexError, + "R object index out of range (highest index > object length)"); + //return NULL; + ihigh = robjLen; + } + sliceLen = ihigh - ilow; + + /* if (ilow >= robjLen || ilow < 0) { */ + /* PyErr_SetString(PyExc_IndexError, "R object index out of range"); */ + /* return NULL; */ + /* } */ + + PROTECT(index = allocVector(INTSXP, sliceLen)); + int ii; + for (ii = 0; ii < sliceLen; ii++) { + INTEGER_POINTER(index)[ii] = ii + ilow + 1; + } + + PROTECT(e = allocVector(LANGSXP, 3)); + SETCAR(e, get_item); + SETCAR(CDR(e), ((RobjObject *)a)->R_obj); + SETCAR(CDR(CDR(e)), index); + + if (!(robj = do_eval_expr(e))) { + UNPROTECT(2); + return NULL; + } + + UNPROTECT(2); + + /* If there is a default mode, use it; otherwise, use the top mode. */ + if (default_mode < 0) + c = TOP_MODE; + else + c = default_mode; + obj = to_Pyobj_with_mode(robj, c); + return obj; +} + + /* We should implement sq_slice, sq_contains ... */ static PySequenceMethods Robj_as_sequence = { (inquiry)Robj_len, /* sq_length */ - 0, /* sq_concat */ - 0, /* sq_repeat */ - (intargfunc)Robj_item, /* sq_item */ - 0, /* sq_slice */ - (intobjargproc)Robj_ass_item, /* sq_ass_item */ - 0, /* sq_ass_slice */ - 0, /* sq_contains */ + 0, /* sq_concat */ + 0, /* sq_repeat */ + (ssizeargfunc)Robj_item, /* sq_item */ + (ssizessizeargfunc)Robj_slice, /* sq_slice */ + (intobjargproc)Robj_ass_item, /* sq_ass_item */ + 0, /* sq_ass_slice */ + 0, /* sq_contains */ + 0, /* sq_inplace_concat */ + 0 /* sq_inplace_repeat */ }; Modified: trunk/rpy/tests/test_robj.py =================================================================== --- trunk/rpy/tests/test_robj.py 2008-01-25 20:14:00 UTC (rev 401) +++ trunk/rpy/tests/test_robj.py 2008-01-27 14:15:16 UTC (rev 402) @@ -19,6 +19,33 @@ def testCall(self): self.failUnless(callable(r.seq)) + def testGetItem(self): + r.seq.autoconvert(NO_CONVERSION) + step = 10 + pySeq = range(10, 50+step, step) + d = r.seq(10, 50, by = step) + for i in range(len(pySeq)): + self.assertTrue(pySeq[i] == d[i]) + self.assertTrue(pySeq[-1] == d[-1]) + + def testGetItemSlice(self): + r.seq.autoconvert(NO_CONVERSION) + step = 10 + pySeq = range(10, 50+step, step) + d = r.seq(10, 50, by=step) + self.assertTrue(pySeq[0:4] == d[0:4]) + self.assertTrue(pySeq[:4] == d[:4]) + self.assertTrue(pySeq[1:] == d[1:]) + self.assertTrue(pySeq[2:5] == d[2:5]) + # FIXME: + # The one below deserves attention: a one-element slice + # should return a one-element sequence. + # However, the conversion system in RPy is making it + # somewhat problematic (or is it me ?)-- Laurent + # self.assertTrue(pySeq[0:1] == d[0:1]) + self.assertRaises(IndexError, d.__getslice__, -1, 2) + self.assertRaises(IndexError, d.__getslice__, 5, 2) + def testKeywordParameters(self): r.list.autoconvert(BASIC_CONVERSION) d = r.list(foo='foo', bar_foo='bar.foo', 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