Revision: 621
          http://rpy.svn.sourceforge.net/rpy/?rev=621&view=rev
Author:   lgautier
Date:     2008-08-08 13:29:24 +0000 (Fri, 08 Aug 2008)

Log Message:
-----------
- Overflow issues on Python 2.4/64 bits when indexing R vector with very large 
integers.

- Handling of negative indexes for :class:`SexpVector`'s :meth:`__getitem__` 
and :meth:`__setitem__` was missing

Modified Paths:
--------------
    branches/rpy_nextgen/NEWS
    branches/rpy_nextgen/doc/source/overview.rst
    branches/rpy_nextgen/rpy/rinterface/rinterface.c
    branches/rpy_nextgen/rpy/rinterface/rinterface.h
    branches/rpy_nextgen/rpy/rinterface/tests/test_SexpVector.py

Modified: branches/rpy_nextgen/NEWS
===================================================================
--- branches/rpy_nextgen/NEWS   2008-08-07 17:33:42 UTC (rev 620)
+++ branches/rpy_nextgen/NEWS   2008-08-08 13:29:24 UTC (rev 621)
@@ -19,6 +19,16 @@
 
 - :class:`R` remains a singleton, but does not throw an exception when 
multiple instances are requested
 
+Bugs fixed
+----------
+
+- Unable to compile on Python2.4 (definition of aliases to Python2.5-specific 
were not where they should be).
+
+- Overflow issues on Python 2.4/64 bits when indexing R vector with very large 
integers.
+
+- Handling of negative indexes for :class:`SexpVector`'s :meth:`__getitem__` 
and :meth:`__setitem__` was missing
+
+
 Release 2.0.0a2
 ===============
 

Modified: branches/rpy_nextgen/doc/source/overview.rst
===================================================================
--- branches/rpy_nextgen/doc/source/overview.rst        2008-08-07 17:33:42 UTC 
(rev 620)
+++ branches/rpy_nextgen/doc/source/overview.rst        2008-08-08 13:29:24 UTC 
(rev 621)
@@ -44,10 +44,6 @@
 This is developped with R-2.7.1 and Python-2.5.2.
 R-2.8.0-dev is sometimes tested, and it does seem to work well.
 
-Compatibility with Python 2.4 is expected but it was observed to segfault on 
rare occasions
-(and the cause is not yet identified).
-
-
 Download
 ^^^^^^^^
 

Modified: branches/rpy_nextgen/rpy/rinterface/rinterface.c
===================================================================
--- branches/rpy_nextgen/rpy/rinterface/rinterface.c    2008-08-07 17:33:42 UTC 
(rev 620)
+++ branches/rpy_nextgen/rpy/rinterface/rinterface.c    2008-08-08 13:29:24 UTC 
(rev 621)
@@ -1237,7 +1237,7 @@
 VectorSexp_item(PyObject *object, Py_ssize_t i)
 {
   PyObject* res;
-  R_len_t i_R;
+  R_len_t i_R, len_R;
   SEXP *sexp = &(RPY_SEXP((PySexpObject *)object));
 
   if (! sexp) {
@@ -1245,12 +1245,27 @@
     return NULL;
   }
 
-  /* R is still with int for indexes */
+  /* On 64bits, Python is apparently able to use larger integer
+   * than R for indexing. */
   if (i >= R_LEN_T_MAX) {
     PyErr_Format(PyExc_IndexError, "Index value exceeds what R can handle.");
     res = NULL;
+    return;
   }
-  else if (i >= GET_LENGTH(*sexp)) {
+
+  len_R = GET_LENGTH(*sexp);
+  
+  if (i < 0) {
+    i = len_R - i;
+  }
+
+  if (i < 0) {
+    PyErr_Format(PyExc_IndexError, 
+                "Mysterious error: likely an integer overflow.");
+    res = NULL;
+    return;
+  }
+  if ((i >= GET_LENGTH(*sexp))) {
     PyErr_Format(PyExc_IndexError, "Index out of range.");
     res = NULL;
   }
@@ -1302,16 +1317,22 @@
 static int
 VectorSexp_ass_item(PyObject *object, Py_ssize_t i, PyObject *val)
 {
-  R_len_t i_R;
+  R_len_t i_R, len_R;
 
-  /* R is still with int for indexes */
+  /* Check for 64 bits platforms */
   if (i >= R_LEN_T_MAX) {
     PyErr_Format(PyExc_IndexError, "Index value exceeds what R can handle.");
     return -1;
   }
 
   SEXP *sexp = &(RPY_SEXP((PySexpObject *)object));
-  if (i >= GET_LENGTH(*sexp)) {
+  len_R = GET_LENGTH(*sexp);
+  
+  if (i < 0) {
+    i = len_R - i;
+  }
+
+  if (i >= len_R) {
     PyErr_Format(PyExc_IndexError, "Index out of range.");
     return -1;
   }

Modified: branches/rpy_nextgen/rpy/rinterface/rinterface.h
===================================================================
--- branches/rpy_nextgen/rpy/rinterface/rinterface.h    2008-08-07 17:33:42 UTC 
(rev 620)
+++ branches/rpy_nextgen/rpy/rinterface/rinterface.h    2008-08-08 13:29:24 UTC 
(rev 621)
@@ -7,6 +7,8 @@
 
 /* Back-compatibility with Python 2.4 */
 #if (PY_VERSION_HEX < 0x02050000)
+#define PY_SSIZE_T_MAX INT_MAX
+#define PY_SSIZE_T_MIN INT_MIN
 typedef int Py_ssize_t;
 typedef inquiry lenfunc;
 typedef intargfunc ssizeargfunc;

Modified: branches/rpy_nextgen/rpy/rinterface/tests/test_SexpVector.py
===================================================================
--- branches/rpy_nextgen/rpy/rinterface/tests/test_SexpVector.py        
2008-08-07 17:33:42 UTC (rev 620)
+++ branches/rpy_nextgen/rpy/rinterface/tests/test_SexpVector.py        
2008-08-08 13:29:24 UTC (rev 621)
@@ -108,6 +108,14 @@
         self.assertTrue(idem(mySeq, myList[0]))
         self.assertTrue(idem(letters_R, myList[1]))
 
+        letters_R = ri.globalEnv.get("letters")
+        self.assertEquals('z', letters_R[-1])
+
+    def testGetItemNegativeOutOfBound(self):
+        letters_R = ri.globalEnv.get("letters")
+        self.assertRaises(IndexError, letters_R.__getitem__,
+                          -100)
+
     def testGetItemOutOfBound(self):
         myVec = ri.SexpVector([0, 1, 2, 3, 4, 5], ri.INTSXP)
         self.assertRaises(IndexError, myVec.__getitem__, 10)
@@ -118,10 +126,9 @@
     def testAssignItemDifferentType(self):
         c_R = ri.globalEnv.get("c")
         myVec = c_R(ri.SexpVector([0, 1, 2, 3, 4, 5], ri.INTSXP))
-        #import pdb; pdb.set_trace()
         self.assertRaises(ValueError, myVec.__setitem__, 0, 
                           ri.SexpVector(["a", ], ri.STRSXP))
-        
+
     def testAssignItemOutOfBound(self):
         c_R = ri.globalEnv.get("c")
         myVec = c_R(ri.SexpVector([0, 1, 2, 3, 4, 5], ri.INTSXP))
@@ -137,6 +144,9 @@
         myVec[3] = ri.SexpVector([100, ], ri.INTSXP)
         self.assertTrue(myVec[3] == 100)
 
+        myVec[-1] = ri.SexpVector([200, ], ri.INTSXP)
+        self.assertTrue(myVec[5] == 200)
+
     def testAssignItemReal(self):
         c_R = ri.globalEnv.get("c")
         myVec = c_R(ri.SexpVector([0.0, 1.0, 2.0, 3.0, 4.0, 5.0], 


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 Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
rpy-list mailing list
rpy-list@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/rpy-list

Reply via email to