Revision: 363 http://rpy.svn.sourceforge.net/rpy/?rev=363&view=rev Author: warnes Date: 2007-11-12 15:27:48 -0800 (Mon, 12 Nov 2007)
Log Message: ----------- - Add three new exceptions: RPyException Base exception class for all RPy Exceptions RPyTypeConversionException Error in conversion between R and Python RPyRException Error raised within R (RException is set equal to RPyException for backwards compatibility) - Properly handle all Numeric/NumPy array types - Solve 64 bit problems converting Numeric/NumPy arrays Modified Paths: -------------- trunk/rpy/TODO trunk/rpy/rpy.py trunk/rpy/setup.py trunk/rpy/src/RPy.h trunk/rpy/src/R_eval.c trunk/rpy/src/rpymodule.c trunk/rpy/tests/test_array.py trunk/rpy/tests/test_numeric.py trunk/rpy/tests/test_robj.py trunk/rpy/tests/test_tor.py trunk/rpy/tests/test_util.py Modified: trunk/rpy/TODO =================================================================== --- trunk/rpy/TODO 2007-11-06 16:49:53 UTC (rev 362) +++ trunk/rpy/TODO 2007-11-12 23:27:48 UTC (rev 363) @@ -1,6 +1,10 @@ C=Critical, I=Important, U=Useful, O=Optional +I* Update install instructions to include information about use of 'RHOMES' + +I* Ensure that either Numarray, Numeric, or NumPy can be used + C* Properly clean up R when python exits, even if the user hasn't called 'q()' U* Posibility to pass Python functions to R functions Modified: trunk/rpy/rpy.py =================================================================== --- trunk/rpy/rpy.py 2007-11-06 16:49:53 UTC (rev 362) +++ trunk/rpy/rpy.py 2007-11-12 23:27:48 UTC (rev 363) @@ -169,9 +169,21 @@ def get_default_mode(): return _rpy.get_mode() -# The new exception -RException = _rpy.RException +# Three new exceptions +# base exception +RPyException = _rpy.RPy_Exception; +# R <-> Python conversion exception +RPyTypeConversionException = _rpy.RPy_TypeConversionException; + +# Exception raised by R +RPyRException = _rpy.RPy_RException + +# for backwards compatibility +RException = RPyException + + + # I/O setters set_rpy_output = _rpy.set_output set_rpy_input = _rpy.set_input Modified: trunk/rpy/setup.py =================================================================== --- trunk/rpy/setup.py 2007-11-06 16:49:53 UTC (rev 362) +++ trunk/rpy/setup.py 2007-11-12 23:27:48 UTC (rev 363) @@ -30,6 +30,8 @@ See the files INSTALL.UNIX and INSTALL.WINDOWS for more details. """ +DEBUG=True + import os, os.path, sys, shutil from distutils.core import setup, Extension from distutils.sysconfig import * @@ -48,6 +50,7 @@ RHOMES = [] print "RHOMES=", RHOMES +print "DEBUG=", DEBUG if not RHOMES: if sys.platform=="win32": @@ -65,8 +68,12 @@ RHOME = RHOME.strip() - # to avoid strict prototypes errors from R includes - get_config_vars()['OPT'] = '-DNDEBUG -g -O3 -Wall' + if DEBUG: + # to avoid strict prototypes errors from R includes + get_config_vars()['OPT'] = '-g -Wall' + else: + # to avoid strict prototypes errors from R includes + get_config_vars()['OPT'] = '-DNDEBUG -g -O3 -Wall' # get the Python version if sys.version[:3] >= '2.2': @@ -137,12 +144,12 @@ extra_compile_args=["-shared"] source_files = source_files + ["src/setenv.c"] - # check whether NumPy is present - try: + # Discover which array packages are present + try: import numpy DEFINE.append(('WITH_NUMERIC', '3')) DEFINE.append(('PY_ARRAY_TYPES_PREFIX', 'PyArray_')) - include_dirs.append(numpy.get_numpy_include()) + include_dirs.append(numpy.get_include()) except ImportError: # fall back to Numeric try: @@ -164,6 +171,9 @@ DEFINE.append( ('RPY_SHNAME', shlib_name)) DEFINE.append( ('INIT_RPY', 'init_rpy%s' % RVER ) ) + + # add debugging + modules.append( Extension( shlib_name, source_files, Modified: trunk/rpy/src/RPy.h =================================================================== --- trunk/rpy/src/RPy.h 2007-11-06 16:49:53 UTC (rev 362) +++ trunk/rpy/src/RPy.h 2007-11-12 23:27:48 UTC (rev 363) @@ -130,10 +130,12 @@ SEXP do_eval_fun(char *); SEXP get_fun_from_name(char *); -/* A new exception */ -extern PyObject *RPyExc_Exception; +/* Three new exception */ +extern PyObject *RPy_Exception; /* Base RPy exception */ +extern PyObject *RPy_TypeConversionException; /* R<->Python conversion errors */ +extern PyObject *RPy_RException; /* Errors from R */ -char *get_last_error_msg(void); +const char *get_last_error_msg(void); /* For initializing R */ extern int Rf_initEmbeddedR(int argc, char *argv[]); Modified: trunk/rpy/src/R_eval.c =================================================================== --- trunk/rpy/src/R_eval.c 2007-11-06 16:49:53 UTC (rev 362) +++ trunk/rpy/src/R_eval.c 2007-11-12 23:27:48 UTC (rev 363) @@ -115,7 +115,7 @@ PyErr_SetNone(PyExc_KeyboardInterrupt); } else - PyErr_SetString(RPyExc_Exception, get_last_error_msg()); + PyErr_SetString(RPy_RException, get_last_error_msg()); return NULL; } @@ -151,11 +151,11 @@ /* For R not to throw an error, we must check the identifier is neither null nor greater than MAXIDSIZE */ if (!*ident) { - PyErr_SetString(RPyExc_Exception, "attempt to use zero-length variable name"); + PyErr_SetString(RPy_Exception, "attempt to use zero-length variable name"); return NULL; } if (strlen(ident) > MAXIDSIZE) { - PyErr_SetString(RPyExc_Exception, "symbol print-name too long"); + PyErr_SetString(RPy_Exception, "symbol print-name too long"); return NULL; } @@ -182,14 +182,14 @@ #endif if (obj == R_UnboundValue) { - PyErr_Format(RPyExc_Exception, "R Function \"%s\" not found", ident); + PyErr_Format(RPy_Exception, "R Function \"%s\" not found", ident); return NULL; } return obj; } /* Obtain the text of the last R error message */ -char *get_last_error_msg() { +const char *get_last_error_msg() { SEXP msg; msg = do_eval_fun("geterrmessage"); Modified: trunk/rpy/src/rpymodule.c =================================================================== --- trunk/rpy/src/rpymodule.c 2007-11-06 16:49:53 UTC (rev 362) +++ trunk/rpy/src/rpymodule.c 2007-11-12 23:27:48 UTC (rev 363) @@ -47,9 +47,9 @@ #include <stdlib.h> #include <string.h> -/* Flag indicating whether Numeric is available in this session +/* Flag indicating whether Numpy/Numeric is available in this session * - * This is necessary Numeric may not available at run time, even if + * This is necessary since Numpy/Numeric may not available at run time, even if * it was available at compile time. */ static int use_numeric=0; @@ -74,7 +74,9 @@ static PyObject *proc_table; static int default_mode; static PyObject *r_lock; -PyObject *RPyExc_Exception; +PyObject *RPy_Exception; +PyObject *RPy_TypeConversionException; +PyObject *RPy_RException; static char RHOME[BUFSIZ]; static char RVERSION[BUFSIZ]; @@ -224,22 +226,32 @@ PROTECT(robj = NEW_LIST(len)); state = -1; - for (i=0; i<len; i++) { - if (!(it = PySequence_GetItem(obj, i))) - goto exception; + for (i=0; i<len; i++) + { + it = PySequence_GetItem(obj, i); + if (it==NULL) + { + UNPROTECT(1); + return NULL; + } + + if (state < 0) + state = type_to_int(it); + else + state = fsm[state][type_to_int(it)]; + + rit = to_Robj(it); + if (rit==NULL || PyErr_Occurred() ) + { + Py_XDECREF(it); + UNPROTECT(1); + return NULL; + } + + SET_VECTOR_ELT(robj, i, rit); + Py_XDECREF(it); + } - if (state < 0) - state = type_to_int(it); - else - state = fsm[state][type_to_int(it)]; - - if (!(rit = to_Robj(it))) - goto exception; - - SET_VECTOR_ELT(robj, i, rit); - Py_XDECREF(it); - } - switch(state) { case INT_T: @@ -263,11 +275,6 @@ UNPROTECT(1); return robj; - -exception: - Py_XDECREF(it); - UNPROTECT(1); - return NULL; } /* Make a R named list or vector from a Python dictionary */ @@ -287,27 +294,28 @@ return NULL; if (!(values = PyMapping_Values(obj))) return NULL; - - if (!(robj = seq_to_R(values))) - goto fail; - if (!(names = seq_to_R(keys))) - goto fail; + + robj = seq_to_R(values); + names = seq_to_R(keys); + if ( robj==NULL || robj==NULL ) + { + Py_DECREF(keys); + Py_DECREF(values); + return NULL; + } + PROTECT(robj); SET_NAMES(robj, names); + Py_DECREF(keys); Py_DECREF(values); UNPROTECT(1); return robj; - - fail: - Py_DECREF(keys); - Py_DECREF(values); - return NULL; } #ifdef WITH_NUMERIC -/* Convert a Numeric array to a R array */ +/* Convert a Numpy/Numeric array to a R array */ SEXP to_Rarray(PyObject *o) { @@ -316,40 +324,146 @@ SEXP Rdims, tRdims, Rarray, e; n_intp *dims; int i; - long tl; + int type; + long size; obj = (PyArrayObject *)o; dims = obj->dimensions; - tl = 1; - PROTECT(Rdims = allocVector(INTSXP, obj->nd)); - PROTECT(tRdims = allocVector(INTSXP, obj->nd)); - for (i=0; i<obj->nd; i++) { - if (dims[i] == 0) { + type = obj->descr->type_num; + size = PyArray_Size( (PyObject*) obj); + + /* Handle a vector without dimensions, just length */ + if(obj->nd==0) + { + PROTECT(Rdims = allocVector(INTSXP, 1)); + PROTECT(tRdims = allocVector(INTSXP, 1)); + INTEGER(Rdims)[0] = size; + INTEGER(tRdims)[0] = size; + } + else + { + PROTECT(Rdims = allocVector(INTSXP, obj->nd)); + PROTECT(tRdims = allocVector(INTSXP, obj->nd)); + + for (i=0; i<obj->nd; i++) + { + if (dims[i] == 0) + { + UNPROTECT(2); + return R_NilValue; + } + INTEGER(Rdims)[i] = dims[(obj->nd)-i-1]; + INTEGER(tRdims)[i] = (obj->nd)-i; + } + } + + switch(type) + { + + /*******************/ + /* String Variants */ + /*******************/ +#ifdef PyArray_UNICODE /* NumPy */ + case PyArray_UNICODE: + case PyArray_STRING: + case PyArray_CHAR: + obj = (PyArrayObject *)PyArray_ContiguousFromObject((PyObject *)obj, + PyArray_STRING, 0, 0); +#endif + + /******************************************/ + /* All complex to (double,double) complex */ + /******************************************/ +#ifdef PyArray_COMPLEX64 + case PyArray_COMPLEX64: + case PyArray_COMPLEX128: +#endif + case PyArray_CFLOAT: + case PyArray_CDOUBLE: + obj = (PyArrayObject *)PyArray_ContiguousFromObject((PyObject *)obj, + PyArray_CDOUBLE, 0, 0); + break; + +#ifdef PyArray_BOOL + /************************/ + /* Booleans to booleans */ + /************************/ + case PyArray_BOOL: + obj = (PyArrayObject *)PyArray_ContiguousFromObject((PyObject *)obj, + PyArray_BOOL, 0, 0); + break; +#endif + + /********************************************************************************/ + /* All integers (except perhaps 64 bit integers on 32 bit platforms) to integer */ + /********************************************************************************/ + case PyArray_UBYTE: + case PyArray_SBYTE: + case PyArray_SHORT: + case PyArray_INT: + case PyArray_LONG: +#ifdef PyArray_INT8 + case PyArray_INT8: + case PyArray_UINT8: + case PyArray_INT16: + case PyArray_UINT16: + case PyArray_INT32: + case PyArray_UINT32: +#endif +#if SIZEOF_INT == 8 && defined(PyArray_INT64) /* NumPy on 64 bit platform */ + case PyArray_INT64: + case PyArray_UINT64: +#endif + obj = (PyArrayObject *)PyArray_ContiguousFromObject((PyObject *)obj, + PyArray_INT, 0, 0); + break; + + /**************************************************/ + /* All floats (and over-sized integers) to double */ + /**************************************************/ + case PyArray_FLOAT: + case PyArray_DOUBLE: +#ifdef PyArray_FLOAT32 + case PyArray_FLOAT32: + case PyArray_FLOAT64: +#endif +#if SIZEOF_INT == 4 && defined(PyArray_INT64) /* NumPy on 32 bit platform */ + case PyArray_INT64: + case PyArray_UINT64: +#endif + obj = (PyArrayObject *)PyArray_ContiguousFromObject((PyObject *)obj, + PyArray_DOUBLE, 0, 0); + break; + + default: UNPROTECT(2); + PyErr_SetString(RPy_TypeConversionException, "Unhandled type in array, unable to convert to R object"); return R_NilValue; + break; + } - tl *= dims[i]; - INTEGER(Rdims)[i] = dims[(obj->nd)-i-1]; - INTEGER(tRdims)[i] = (obj->nd)-i; - } -/* if (!(pytl = PyList_New(1))) */ -/* goto exception; */ -/* if (!(it = PyInt_FromLong(tl))) */ -/* goto exception; */ -/* if (PyList_SetItem(pytl, 0, it) < 0) */ -/* goto exception; */ - pytl = Py_BuildValue("[i]", tl); - obj = (PyArrayObject *)PyArray_ContiguousFromObject((PyObject *)obj, - PyArray_NOTYPE, 0, 0); + pytl = Py_BuildValue("[i]", size); nobj = PyArray_Reshape(obj, pytl); Py_XDECREF(pytl); Py_XDECREF(obj); - if (!nobj) - goto exception; + if (nobj == NULL) + { + UNPROTECT(2); + return R_NilValue; + } + + PROTECT(Rarray = seq_to_R(nobj)); + if (Rarray == NULL) + { + UNPROTECT(3); + return R_NilValue; + } + + Py_XDECREF(nobj); SET_DIM(Rarray, Rdims); @@ -361,10 +475,6 @@ UNPROTECT(5); return Rarray; - - exception: - UNPROTECT(2); - return NULL; } #endif @@ -379,7 +489,7 @@ PyObject *to_r_meth; int do_decref = 0; - if (!obj) + if (obj==NULL) return NULL; if (obj == Py_None) { @@ -390,7 +500,7 @@ if (to_r_meth) { obj = PyObject_CallObject(to_r_meth, NULL); Py_DECREF(to_r_meth); - if (!obj) + if (obj==NULL) return NULL; do_decref = 1; } @@ -445,7 +555,6 @@ SET_STRING_ELT(robj, 0, COPY_TO_USER_STRING(PyString_AsString(obj))); } #ifdef WITH_NUMERIC - //else if (PyArray_Check(obj)) else if (use_numeric && PyArray_Check(obj)) { PROTECT(robj = to_Rarray(obj)); @@ -457,15 +566,15 @@ PROTECT(robj = seq_to_R(obj)); /* No labels */ } else if ((PyMapping_Check(obj)) && - (PyMapping_Size(obj) >= 0)) + (PyMapping_Size(obj) >= 0)) { PROTECT(robj = dict_to_R(obj)); } else { - PyErr_Format(RPyExc_Exception, "cannot convert from type '%s'", + PyErr_Format(RPy_TypeConversionException, "cannot convert from type '%s'", obj->ob_type->tp_name); - PROTECT(robj = NULL); /* Protected to avoid stack inbalance */ + PROTECT(robj = NULL); /* Protected to avoid stack inbalance */ } if (do_decref) @@ -482,7 +591,7 @@ { int len, i; PyObject *it, *dict; - char *name; + const char *name; if ((len = PySequence_Length(obj)) < 0) return NULL; @@ -567,7 +676,7 @@ PyObject *array, *ret, *dims, *it; int l, i, j; - array = PyArray_ContiguousFromObject(seq, PyArray_NOTYPE, 0,0); + array = PyArray_ContiguousFromObject(seq, PyArray_DOUBLE, 0,0); if (!array) return NULL; @@ -630,7 +739,7 @@ PyObject *it, *tmp; SEXP names, dim; int len, *integers, i, type; - char *strings, *thislevel; + const char *strings, *thislevel; double *reals; Rcomplex *complexes; #ifdef WITH_NUMERIC @@ -906,7 +1015,7 @@ for (i=0; i<largs; i++) { r = to_Robj(PyTuple_GetItem(args, i)); - if (!r) + if (!r || PyErr_Occurred() ) return 0; SETCAR(*e, r); *e = CDR(*e); @@ -916,7 +1025,7 @@ /* Implements the conversion rules for names. See the 'USING' file. We don't care about '<-' because it doesn't appear in keywords. */ -char * +const char * dotter(char *s) { char *r, *res; @@ -946,7 +1055,7 @@ make_kwds(int lkwds, PyObject *kwds, SEXP *e) { SEXP r; - char *s; + const char *s; int i; PyObject *citems=NULL, *it; PyObject *kwname; @@ -961,7 +1070,7 @@ goto fail; r = to_Robj(PyTuple_GetItem(it, 1)); Py_DECREF(it); - if (!r) + if (!r || PyErr_Occurred()) goto fail; SETCAR(*e, r); @@ -977,7 +1086,7 @@ goto fail; SET_TAG(*e, Rf_install(s)); - PyMem_Free(s); + PyMem_Free( (void*) s); *e = CDR(*e); } Py_XDECREF(citems); @@ -1045,7 +1154,7 @@ make_argl(int largl, PyObject *argl, SEXP *e) { SEXP rvalue; - char *name; + const char *name; int i; PyObject *it, *nobj, *value; @@ -1084,17 +1193,19 @@ /* Value can be anything. */ value = PySequence_GetItem(it, 1); - if (!value) + if (!value || PyErr_Occurred() ) { - PyMem_Free(name); + PyMem_Free( (void*) name); goto fail; } rvalue = to_Robj(value); Py_DECREF(value); - Py_DECREF(it); + if(PyErr_Occurred()) + goto fail; + /* Add parameter value to call */ SETCAR(*e, rvalue); @@ -1102,7 +1213,7 @@ if (name && strlen(name)>0) { SET_TAG(*e, Rf_install(name)); - PyMem_Free(name); + PyMem_Free((void*) name); } /* Move index to new end of call */ @@ -1196,7 +1307,7 @@ { PyObject *obj; int conversion=-2; - static char *kwlist[] = {"val", 0}; + char *kwlist[] = {"val", 0}; if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:autoconvert", kwlist, &conversion)) @@ -1222,7 +1333,7 @@ Robj_as_py(PyObject *self, PyObject *args, PyObject *kwds) { PyObject *obj; - static char *kwlist[] = {"mode", 0}; + char *kwlist[] = {"mode", 0}; int conv=default_mode; if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:as_py", kwlist, @@ -1284,6 +1395,9 @@ SETCAR(CDR(CDR(e)), ri); SETCAR(CDR(CDR(CDR(e))), to_Robj(v)); + if(PyErr_Occurred()) + return -1; + if (!(robj = do_eval_expr(e))) { UNPROTECT(1); return -1; @@ -1741,7 +1855,7 @@ if( !strlen(RHOME) || !strlen(RVERSION) || !strlen(RVER) || !strlen(RUSER)) { - PyErr_Format(RPyExc_Exception, + PyErr_Format(RPy_Exception, "Unable to load R path or version information"); return; } @@ -1789,11 +1903,21 @@ PyOS_setsig(SIGUSR2, old_usr2); #endif - /* The new exception */ - RPyExc_Exception = PyErr_NewException("rpy.RException", NULL, NULL); - if (RPyExc_Exception) - PyDict_SetItemString(d, "RException", RPyExc_Exception); + /* Several new exceptions: */ + RPy_Exception = PyErr_NewException("rpy.RPy_Exception", NULL, NULL); + RPy_TypeConversionException = PyErr_NewException("rpy.RPy_TypeConversionException", RPy_Exception, NULL); + RPy_RException = PyErr_NewException("rpy.RPy_RException", RPy_Exception, NULL); + if (!RPy_Exception || !RPy_TypeConversionException || !RPy_RException ) + { + PyErr_Format(RPy_Exception, "Unable create RPy exceptions"); + return; + } + + PyDict_SetItemString(d, "RPy_Exception", RPy_Exception); + PyDict_SetItemString(d, "RPy_TypeConversionException", RPy_TypeConversionException); + PyDict_SetItemString(d, "RPy_RException", RPy_RException); + // The conversion table class_table = PyDict_New(); proc_table = PyDict_New(); Modified: trunk/rpy/tests/test_array.py =================================================================== --- trunk/rpy/tests/test_array.py 2007-11-06 16:49:53 UTC (rev 362) +++ trunk/rpy/tests/test_array.py 2007-11-12 23:27:48 UTC (rev 363) @@ -15,6 +15,12 @@ idx.autoconvert(BASIC_CONVERSION) return o +def all(vec): + for i in range(len(vec)): + if not vec[i]: return False + return True + + class ArrayTestCase(unittest.TestCase): def setUp(self): @@ -28,7 +34,7 @@ r.array.autoconvert(BASIC_CONVERSION) def testConversionToPy(self): - self.failUnless((self.py == self.ra.as_py()).all(), + self.failUnless(all(self.py == self.ra.as_py()), 'wrong conversion to Python') def testConversionToR(self): @@ -52,7 +58,7 @@ self.failUnlessRaises(IndexError, lambda: self.py[5][5][5]) def testROutOfBounds(self): - self.failUnlessRaises(RException, lambda: idx(self.ra, 5,5,5)) + self.failUnlessRaises(RPyException, lambda: idx(self.ra, 5,5,5)) def testBigArray(self): a = r.array(range(100000), dim=(100,1000)) Modified: trunk/rpy/tests/test_numeric.py =================================================================== --- trunk/rpy/tests/test_numeric.py 2007-11-06 16:49:53 UTC (rev 362) +++ trunk/rpy/tests/test_numeric.py 2007-11-12 23:27:48 UTC (rev 363) @@ -1,14 +1,14 @@ from __future__ import nested_scopes import unittest +import sys try: from numpy import * except ImportError: try: from Numeric import * except ImportError: - print 'Numeric not available. Skipping.\n' - import sys + print '\nNumeric not available. Skipping.\n' sys.exit(0) import sys @@ -75,10 +75,102 @@ def testPyOutOfBounds(self): self.failUnlessRaises(IndexError, lambda: self.py_c[5,5,5]) - + def testROutOfBounds(self): - self.failUnlessRaises(RException, lambda: idx(self.ra_c, 5,5,5)) + self.failUnlessRaises(RPyException, lambda: idx(self.ra_c, 5,5,5)) + def test64BitIntArrays(self): + # 64 bit ints + try: + a = array( [1,2,3], 'Int64' ) + except: + try: + a = array( [1,2,3], Int64 ) + except: + print "\nInt64 Not found. Skipping this test.\n" + return + + b = r.c(a[1]) + b = r.c(a) + + def test32BitIntArrays(self): + + # 32 bit ints + try: + a = array( [1,2,3], 'Int32' ) + except: + a = array( [1,2,3], Int32 ) + + b = r.c(a[1]) + b = r.c(a) + + def test16BitIntArrays(self): + + # 16 bit ints + try: + a = array( [1,2,3], 'Int16' ) + except: + a = array( [1,2,3], Int16 ) + + b = r.c(a[1]) + b = r.c(a) + + def test8BitIntArrays(self): + + # 8 bit ints + try: + a = array( [1,2,3], 'Int8' ) + except: + a = array( [1,2,3], Int8 ) + b = r.c(a[1]) + b = r.c(a) + + def test64BitFloatArrays(self): + + # 64 bit ints + try: + a = array( [1,2,3], 'Float64' ) + except: + try: + a = array( [1,2,3], Float64 ) + except: + print "Float64 Not found. Skipping this test." + return + + b = r.c(a[1]) + b = r.c(a) + + def test32BitFloatArrays(self): + + # 32 bit ints + try: + a = array( [1,2,3], 'Float32' ) + except: + a = array( [1,2,3], Float32 ) + + b = r.c(a[1]) + b = r.c(a) + + def testCharArrays(self): + + try: + a = array( ['A','B', 'C'], 'Char' ) + except: + a = array( ['A','B', 'C'], Character ) + + self.failUnlessRaises(RPyTypeConversionException, lambda: r.c(a) ) + + def testObjArrays(self): + + try: + a = array( ['A','B', 'C'], 'PyObject' ) + except: + a = array( ['A','B', 'C'], PyObject ) + + self.failUnlessRaises(RPyTypeConversionException, lambda: r.c(a) ) + + + if __name__ == '__main__': unittest.main() Modified: trunk/rpy/tests/test_robj.py =================================================================== --- trunk/rpy/tests/test_robj.py 2007-11-06 16:49:53 UTC (rev 362) +++ trunk/rpy/tests/test_robj.py 2007-11-12 23:27:48 UTC (rev 363) @@ -57,7 +57,7 @@ r.attr__ is r['attr<-']) def testNotFound(self): - self.failUnlessRaises(RException, lambda: r.foo) + self.failUnlessRaises(RPyException, lambda: r.foo) def testNameLengthOne(self): self.failUnless(r.T) Modified: trunk/rpy/tests/test_tor.py =================================================================== --- trunk/rpy/tests/test_tor.py 2007-11-06 16:49:53 UTC (rev 362) +++ trunk/rpy/tests/test_tor.py 2007-11-12 23:27:48 UTC (rev 363) @@ -77,13 +77,13 @@ with_c(f) def testNotConvertible(self): - self.failUnlessRaises(RException, lambda: r.c(range)) + self.failUnlessRaises(RPyTypeConversionException, lambda: r.c(range)) def testInstancesNotConvertible(self): class Foo: pass a = Foo() - self.failUnlessRaises(RException, lambda: r.c(a)) + self.failUnlessRaises(RPyTypeConversionException, lambda: r.c(a)) def testAs_rMethod(self): r.c.autoconvert(BASIC_CONVERSION) @@ -94,9 +94,12 @@ self.failUnless(r.c(b) == 'foo') self.failUnless(r.c(d)(1,3) == [1,2,3]) - def testMaxintToR(self): + def testNAFromR(self): + ''' R defines NA value (currently from limits.h MAX_INT) + For 64 bit systems this will not be the same as sys.maxint + ''' with_mode(BASIC_CONVERSION, - lambda: self.failUnless(r.is_na(-sys.maxint-1)))() + lambda: self.failUnless(r.is_na(r.NA)))() def testInfToR(self): with_mode(BASIC_CONVERSION, lambda: Modified: trunk/rpy/tests/test_util.py =================================================================== --- trunk/rpy/tests/test_util.py 2007-11-06 16:49:53 UTC (rev 362) +++ trunk/rpy/tests/test_util.py 2007-11-12 23:27:48 UTC (rev 363) @@ -28,8 +28,8 @@ def testRCode(self): with_mode(BASIC_CONVERSION, lambda: self.failUnless(r("c(4,5)") == [4,5]))() - self.failUnlessRaises(RException, lambda: r("foo")) - self.failUnlessRaises(RException, lambda: r("[$%^")) + self.failUnlessRaises(RPyRException, lambda: r("foo")) + self.failUnlessRaises(RPyRException, lambda: r("[$%^")) if __name__ == '__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: Splunk Inc. Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/ _______________________________________________ rpy-list mailing list rpy-list@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/rpy-list