Revision: 531 http://rpy.svn.sourceforge.net/rpy/?rev=531&view=rev Author: lgautier Date: 2008-05-23 12:22:03 -0700 (Fri, 23 May 2008)
Log Message: ----------- rpy "classic" (v-1.x): - fixes. Now roughly working rinterface: - Fixes around Py_True and Py_False (ref counting) - Functions are now evaluated in their enclosing environments (previously was in globalEnv)... and there is a new test for that. Modified Paths: -------------- branches/rpy_nextgen/rpy/rinterface/rinterface.c branches/rpy_nextgen/rpy/rinterface/tests/test_SexpClosure.py branches/rpy_nextgen/rpy/rpy_classic.py Modified: branches/rpy_nextgen/rpy/rinterface/rinterface.c =================================================================== --- branches/rpy_nextgen/rpy/rinterface/rinterface.c 2008-05-22 20:29:40 UTC (rev 530) +++ branches/rpy_nextgen/rpy/rinterface/rinterface.c 2008-05-23 19:22:03 UTC (rev 531) @@ -197,7 +197,6 @@ if (result == NULL) { return; - //return NULL; } Py_DECREF(result); @@ -237,7 +236,9 @@ /* R_Interactive = TRUE; Rf_initialize_R set this based on isatty */ /* setup_Rmainloop(); */ - embeddedR_isInitialized = PyBool_FromLong((long)1); + Py_XDECREF(embeddedR_isInitialized); + embeddedR_isInitialized = Py_True; + Py_INCREF(Py_True); #ifdef R_INTERFACE_PTRS /* Redirect R console output */ @@ -288,6 +289,11 @@ RPY_SEXP(globalEnv) = R_EmptyEnv; RPY_SEXP(baseNameSpaceEnv) = R_EmptyEnv; + //FIXME: Is it possible to reinitialize R later ? + //Py_XDECREF(embeddedR_isInitialized); + //embeddedR_isInitialized = Py_False; + //Py_INCREF(Py_False); + Py_RETURN_NONE; } PyDoc_STRVAR(EmbeddedR_end_doc, @@ -728,8 +734,8 @@ } //FIXME: R_GlobalContext ? - PROTECT(res_R = do_eval_expr(call_R, R_GlobalEnv)); - //PROTECT(res_R = do_eval_expr(call_R, CLOENV(fun_R))); + //PROTECT(res_R = do_eval_expr(call_R, R_GlobalEnv)); + PROTECT(res_R = do_eval_expr(call_R, CLOENV(fun_R))); /* if (!res) { */ /* UNPROTECT(2); */ @@ -781,7 +787,6 @@ {NULL, NULL} /* sentinel */ }; -//FIXME: write more doc PyDoc_STRVAR(ClosureSexp_Type_doc, "A R object that is a closure, that is a function. \ In R a function is defined within an enclosing \ @@ -1053,7 +1058,6 @@ }; -//FIXME: write more doc PyDoc_STRVAR(VectorSexp_Type_doc, "R object that is a vector." " R vectors start their indexing at one," @@ -1062,10 +1066,6 @@ "In the hope to avoid confusion, the indexing" " from the Python subset operator (__getitem__)" " is done at zero."); -/* ", while an other method to perform\ */ -/* it at one is provided (_not yet implemented_).\ */ -/* That other method is also performing indexing."); */ -//FIXME: implement offset-one indexing. static int VectorSexp_init(PySexpObject *self, PyObject *args, PyObject *kwds); @@ -1902,7 +1902,9 @@ Py_INCREF(ErrorObject); PyModule_AddObject(m, "RobjectNotFound", ErrorObject); - embeddedR_isInitialized = PyBool_FromLong((long)0); + embeddedR_isInitialized = Py_False; + Py_INCREF(Py_False); + if (PyModule_AddObject(m, "isInitialized", embeddedR_isInitialized) < 0) return; //FIXME: DECREF ? Modified: branches/rpy_nextgen/rpy/rinterface/tests/test_SexpClosure.py =================================================================== --- branches/rpy_nextgen/rpy/rinterface/tests/test_SexpClosure.py 2008-05-22 20:29:40 UTC (rev 530) +++ branches/rpy_nextgen/rpy/rinterface/tests/test_SexpClosure.py 2008-05-23 19:22:03 UTC (rev 531) @@ -28,7 +28,23 @@ letters = rinterface.baseNameSpaceEnv["letters"] self.assertRaises(RuntimeError, sum, letters) + def testClosureEnv(self): + parse = rinterface.baseNameSpaceEnv["parse"] + exp = parse(text = rinterface.SexpVector(["function(x) { x[y] }", ], + rinterface.STRSXP)) + fun = rinterface.baseNameSpaceEnv["eval"](exp) + vec = rinterface.baseNameSpaceEnv["letters"] + self.assertRaises(RuntimeError, fun, vec) + fun.closureEnv()["y"] = rinterface.SexpVector([1, ], + rinterface.INTSXP) + self.assertEquals('a', fun(vec)[0]) + + fun.closureEnv()["y"] = rinterface.SexpVector([2, ], + rinterface.INTSXP) + self.assertEquals('b', fun(vec)[0]) + + def suite(): suite = unittest.TestLoader().loadTestsFromTestCase(SexpClosureTestCase) return suite Modified: branches/rpy_nextgen/rpy/rpy_classic.py =================================================================== --- branches/rpy_nextgen/rpy/rpy_classic.py 2008-05-22 20:29:40 UTC (rev 530) +++ branches/rpy_nextgen/rpy/rpy_classic.py 2008-05-23 19:22:03 UTC (rev 531) @@ -5,8 +5,9 @@ import rpy2.rinterface as ri import array +# +RPY_VERSION = '1.x' - # --- options in 'rpy_options.py' rpy_options = { @@ -67,25 +68,9 @@ # --- "CONVERSION" system -class ModuleMode(object): - # same default as in "rpymodule.c" - __mode = -1 +# same default as in "rpymodule.c" +default_mode = -1 - def __init__(self): - pass - - @classmethod - def __eq__(self, val): - return ModuleMode.__mode == val - @classmethod - def set_mode(val): - ModuleMode.__mode == val - @classmethod - def get_mode(): - return ModuleMode.__mode - -default_mode = ModuleMode() - # Wrap a function in safe modes to avoid infinite recursion when # called from within the conversion system def with_mode(i, fun): @@ -104,10 +89,12 @@ raise ValueError("mode should be an int.") if (mode < -1) or (mode > TOP_MODE): raise ValueError("wrong mode.") - default_mode.set_mode(mode) + global default_mode + default_mode = mode def get_default_mode(): - return default_mode.get_mode() + global default_mode + return default_mode @@ -161,19 +148,24 @@ def rpy2py_basic(obj): if hasattr(obj, '__len__'): - if obj.typeof() in [ri.INTSXP, ri.REALSXP, ri.CPLSXP, + if obj.typeof() in [ri.INTSXP, ri.REALSXP, ri.CPLXSXP, ri.STRSXP]: res = [x for x in obj] elif obj.typeof() in [ri.VECSXP]: - res = [rpy2py for x in obj] + res = [rpy2py(x) for x in obj] else: raise ValueError("Invalid type for 'obj'.") - return res - raise ValueError("Invalid type for 'obj'.") + else: + res = Robj(obj) + return res + #raise ValueError("Invalid type for 'obj'.") -def rpy2py(obj, mode=default_mode): +def rpy2py(obj, mode=None): + """ Transform RPy objects into pure python objects. """ + if mode is None: + mode = default_mode if mode == NO_CONVERSION: - res = obj + res = Robj(obj) return res if mode == BASIC_CONVERSION: res = rpy2py_basic(obj) @@ -217,6 +209,7 @@ kwargs_r[a_n] = a #import pdb; pdb.set_trace() res = self.__sexp(*args_r, **kwargs_r) + res = rpy2py(res) return res def __getitem__(self, item): @@ -228,9 +221,9 @@ def getSexp(self): return self.__sexp - def __repr__(self): - res = rpy2r(self) - return res + #def __repr__(self): + # res = rpy2py(self) + # return res def as_py(mode = default_mode): res = rpy2py(self, mode) @@ -258,6 +251,7 @@ def __getitem__(self, name): #FIXME: "get function only" vs "get anything" + # wantFun = True ? res = ri.globalEnv.get(name) res = rpy2py(res) return res @@ -269,8 +263,9 @@ helpobj.helpfun(*arg, **kw) def __repr__(self): - rversion = self.__getitem__('R.version.sting') - res = 'RPy version %s [%s]' %(rpy_version, r_version) + r_version = ri.baseNameSpaceEnv['R.version.string'][0] + res = 'RPy version %s with %s' %(RPY_VERSION, r_version) + return res def __str__(self): return repr(self) 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