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