Revision: 548
          http://rpy.svn.sourceforge.net/rpy/?rev=548&view=rev
Author:   lgautier
Date:     2008-06-07 00:05:04 -0700 (Sat, 07 Jun 2008)

Log Message:
-----------
robjects:
- changed class names (now upper-case after the R prefix;
e.g., RVector, RFunction, etc...)
- refactored the classes:
  - attribute _sexp, constaining the rinterface.Sexp, is gone
  - classes inherit from their rinterface counterpart
  - a mixin class RObjectMixin provides common methods

Modified Paths:
--------------
    branches/rpy_nextgen/rpy/robjects/__init__.py
    branches/rpy_nextgen/rpy/robjects/tests/testRArray.py
    branches/rpy_nextgen/rpy/robjects/tests/testREnvironment.py
    branches/rpy_nextgen/rpy/robjects/tests/testRFunction.py
    branches/rpy_nextgen/rpy/robjects/tests/testRObject.py
    branches/rpy_nextgen/rpy/robjects/tests/testRVector.py
    branches/rpy_nextgen/rpy/robjects/tests/testRobjects.py

Modified: branches/rpy_nextgen/rpy/robjects/__init__.py
===================================================================
--- branches/rpy_nextgen/rpy/robjects/__init__.py       2008-06-07 07:01:08 UTC 
(rev 547)
+++ branches/rpy_nextgen/rpy/robjects/__init__.py       2008-06-07 07:05:04 UTC 
(rev 548)
@@ -13,26 +13,28 @@
 
 #FIXME: close everything when leaving (check RPy for that).
 
-def defaultRobjects2PyMapper(o):
-    if isinstance(o, rinterface.SexpVector):
-        res = Rvector(o)
+def default_ri2py(o):
+    if isinstance(o, RObject):
+        res = o
+    elif isinstance(o, rinterface.SexpVector):
+        res = RVector(o)
     elif isinstance(o, rinterface.SexpClosure):
-        res = Rfunction(o)
+        res = RFunction(o)
     elif isinstance(o, rinterface.SexpEnvironment):
-        res = Renvironment(o)
+        res = REnvironment(o)
     elif isinstance(o, rinterface.SexpS4):
         res = RS4(o)
     else:
-        res = Robject(o)
+        res = RObject(o)
     return res
 
 #FIXME: clean and nice mechanism to allow user-specified mapping function
 #FIXME: better names for the functions
-mapperR2Py = defaultRobjects2PyMapper
+ri2py = default_ri2py
 
-def defaultPy2Rinterface(o):
-    if isinstance(o, Robject):
-        return o._sexp
+def default_py2ri(o):
+    if isinstance(o, RObject):
+        res = rinterface.Sexp(o)
     if isinstance(o, rinterface.Sexp):
         res = o
     elif isinstance(o, array.array):
@@ -51,31 +53,30 @@
     elif isinstance(o, str):
         res = rinterface.SexpVector([o, ], rinterface.STRSXP)
     elif isinstance(o, list):
-        res = r.list(*[defaultPy2RobjectsMapper(x) for x in o])
+        res = r.list(*[ri2py(py2ri(x)) for x in o])
     else:
         raise(ValueError("Nothing can be done for this type at the moment."))
     return res
 
-def defaultPy2RobjectsMapper(o):
-    res = defaultPy2Rinterface(o)
-    return mapperR2Py(res)
+py2ri = default_py2ri
 
-mapperPy2R = defaultPy2RobjectsMapper
 
+def default_py2ro(o):
+    res = default_py2ri(o)
+    return default_ri2py(res)
 
+py2ro = default_py2ro
+
+
 def repr_robject(o):
     s = r.deparse(o)
     s = str.join(os.linesep, s)
     return s
 
 
-class Robject(object):
+class RObjectMixin(object):
     name = None
-    _sexp = None
 
-    def __init__(self, sexp, copy=True):
-        self._sexp = rinterface.Sexp(sexp, copy=copy)
-
     def __str__(self):
         tmp = baseNameSpaceEnv["fifo"]("")
         baseNameSpaceEnv["sink"](tmp)
@@ -89,36 +90,36 @@
     def __repr__(self):
         return repr_robject(self)
 
+    def typeof(self):
+        return super(rinterface.Sexp, self).typeof()
+
+    def do_slot(self, name):
+        return super(rinterface.Sexp, self).do_slot(name)
+
+    def rclass(self):
+        return baseNameSpaceEnv["class"](self)
+
+
+class RObject(rinterface.Sexp, RObjectMixin):
     def __setattr__(self, name, value):
         if name == '_sexp':
             if not isinstance(value, rinterface.Sexp):
                 raise ValueError("_attr must contain an object " +\
                                      "that inherits from rinterface.Sexp" +\
                                      "(not from %s)" %type(value))
-        super(Robject, self).__setattr__(name, value)
+        super(RObject, self).__setattr__(name, value)
+    
 
-    def getSexp(self):
-        return self._sexp
 
-    def typeof(self):
-        return self._sexp.typeof()
-
-    def do_slot(self, name):
-        return self._sexp.do_slot(name)
-
-    def rclass(self):
-        return baseNameSpaceEnv["class"](self.getSexp())
-
-class Rvector(Robject):
+class RVector(rinterface.SexpVector, RObjectMixin):
     """ R vector-like object. Items in those instances can
        be accessed with the method "__getitem__" ("[" operator),
        or with the method "subset"."""
 
     def __init__(self, o):
         if not isinstance(o, rinterface.SexpVector):
-            o = mapperPy2R(o)
-            o = o.getSexp()
-        self._sexp = o
+            o = py2ri(o)
+        super(RVector, self).__init__(o)
             
 
     def subset(self, *args, **kwargs):
@@ -134,73 +135,68 @@
         #for a in args:
         #    if not isinstance(a, Rvector):
         #        raise(TypeError("Subset only take R vectors"))
-        args = [mapperPy2R(x) for x in args]
+        args = [py2ro(x) for x in args]
         for k, v in kwargs.itervalues():
-            args[k] = mapperPy2R(v)
+            args[k] = py2ro(v)
         
         res = r["["](*([self, ] + [x for x in args]), **kwargs)
         return res
 
     def __getitem__(self, i):
-        res = self._sexp[i]
+        res = super(RVector, self).__getitem__(i)
         if isinstance(res, rinterface.Sexp):
-            res = mapperR2Py(res)
+            res = ri2py(res)
         return res
 
-    def __repr__(self):
-        return repr_robject(self)
-        
     def __add__(self, x):
-        res = r.get("+")(self.getSexp(), x)
+        res = r.get("+")(self, x)
         return res
 
     def __sub__(self, x):
-        res = r.get("-")(self.getSexp(), x)
+        res = r.get("-")(self, x)
         return res
 
     def __mul__(self, x):
-        res = r.get("*")(self.getSexp(), x)
+        res = r.get("*")(self, x)
         return res
 
     def __div__(self, x):
-        res = r.get("/")(self.getSexp(), x)
+        res = r.get("/")(self, x)
         return res
 
     def __divmod__(self, x):
-        res = r.get("%%")(self.getSexp(), x)
+        res = r.get("%%")(self, x)
         return res
 
     def __or__(self, x):
-        res = r.get("|")(self.getSexp(), x)
+        res = r.get("|")(self, x)
         return res
 
     def __and__(self, x):
-        res = r.get("&")(self.getSexp(), x)
+        res = r.get("&")(self, x)
         return res
 
-    def __len__(self):
-        return len(self.getSexp())
-
     def getNames(self):
-        res = r.names(self.getSexp())
+        res = r.names(self)
         return res
 
-class RArray(Rvector):
+class RArray(RVector):
     """ An R array """
     def __init__(self, o):
         super(RArray, self).__init__(o)
-        if not r["is.array"](self.getSexp())[0]:
+        #import pdb; pdb.set_trace()
+        if not r["is.array"](self)[0]:
             raise(TypeError("The object must be reflecting an R array"))
 
     def __getattr__(self, name):
         if name == 'dim':
-            res = r.dim(self.getSexp())
-            res = mapperR2Py(res)
+            res = r.dim(self)
+            res = ri2py(res)
             return res
 
     def __setattr__(self, name, value):
         if name == 'dim':
-            value = mapperPy2R
+            value = py2ro(value)
             res = r["dim<-"](value)
         
 
@@ -215,67 +211,53 @@
         """ Number of columns """
         return self.dim[1]
 
-class DataFrame(Rvector):
+class DataFrame(RVector):
     #FIXME: not implemented
     def __init__(self, o):
-        if not isinstance(o, rinterface.SexpVector):
-            o = mapperPy2R(o)
-            o = o.getSexp()
-        self._sexp = o
+        raise Exception("not implemented.")
 
 
 
-class Rfunction(Robject):
+class RFunction(rinterface.SexpClosure, RObjectMixin):
     """ An R function (aka "closure").
     
     """
-    def __init__(self, sexp):
-        # arbirtary python functions for v-2.1
-        self._sexp = rinterface.SexpClosure(sexp)
 
     def __call__(self, *args, **kwargs):
-        new_args = [mapperPy2R(a).getSexp() for a in args]
+        new_args = [py2ri(a) for a in args]
        new_kwargs = {}
         for k, v in kwargs.iteritems():
-            new_kwargs[k] = mapperPy2R(v).getSexp()
-        res = self.getSexp()(*new_args, **new_kwargs)
-        res = mapperR2Py(res)
+            new_kwargs[k] = py2ri(v)
+        res = super(RFunction, self).__call__(*new_args, **new_kwargs)
+        res = ri2py(res)
         return res
 
     #def getSexp(self):
     #    return super(rinterface.SexpClosure, self).__init__(self)
 
-class Renvironment(Robject):
+class REnvironment(rinterface.SexpEnvironment, RObjectMixin):
     """ An R environement. """
     
     def __init__(self, o=None):
         if o is None:
             o = 
rinterface.baseNameSpaceEnv["new.env"](hash=rinterface.SexpVector([True, ], 
rinterface.LGLSXP))
-        self._sexp = rinterface.SexpEnvironment(o)
+        super(REnvironment, self).__init__(o)
 
     def __getitem__(self, item):
-        res = self._sexp[item]
-        res = mapperR2Py(res)
+        res = super(REnvironment, self).__getitem__(item)
+        res = ri2py(res)
         return res
 
     def __setitem__(self, item, value):
-        robj = mapperPy2R(value)
-        self._sexp[item] = robj.getSexp()
+        robj = py2ro(value)
+        super(REnvironment, self).__setitem__(item, robj)
 
-    def __iter__(self):
-        return iter(self._sexp)
-
     def get(self, item):
-        res = self.getSexp().get(item)
-        res = mapperR2Py(res)
+        res = super(REnvironment, self).get(item)
+        res = ri2py(res)
         return res
 
-class RS4(Robject):
-    def __init__(self, o):
-        if (isinstance(o, rinterface.SexpS4)):
-            self._sexp = o
-        else:
-            raise(ValueError("Cannot instantiate"))
+class RS4(rinterface.SexpS4, RObjectMixin):
 
     def __getattr__(self, attr):
         res = r.get("@")(self, attr)
@@ -297,7 +279,7 @@
 
     def __getitem__(self, item):
         res = rinterface.globalEnv.get(item)
-       res = mapperR2Py(res)
+       res = ri2py(res)
         return res
 
     #FIXME: check that this is properly working
@@ -317,6 +299,6 @@
 
 r = R()
 
-globalEnv = mapperR2Py(rinterface.globalEnv)
-baseNameSpaceEnv = mapperR2Py(rinterface.baseNameSpaceEnv)
+globalEnv = ri2py(rinterface.globalEnv)
+baseNameSpaceEnv = ri2py(rinterface.baseNameSpaceEnv)
 

Modified: branches/rpy_nextgen/rpy/robjects/tests/testRArray.py
===================================================================
--- branches/rpy_nextgen/rpy/robjects/tests/testRArray.py       2008-06-07 
07:01:08 UTC (rev 547)
+++ branches/rpy_nextgen/rpy/robjects/tests/testRArray.py       2008-06-07 
07:05:04 UTC (rev 548)
@@ -10,7 +10,8 @@
         self.assertRaises(TypeError, robjects.RArray, letters)
         m = robjects.r.matrix(1, nrow=5, ncol=3)
         a = robjects.RArray(m)
-        
+        # only tests that it runs.
+
     def testDim(self):
         m = robjects.r.matrix(1, nrow=5, ncol=3)
         a = robjects.RArray(m)

Modified: branches/rpy_nextgen/rpy/robjects/tests/testREnvironment.py
===================================================================
--- branches/rpy_nextgen/rpy/robjects/tests/testREnvironment.py 2008-06-07 
07:01:08 UTC (rev 547)
+++ branches/rpy_nextgen/rpy/robjects/tests/testREnvironment.py 2008-06-07 
07:05:04 UTC (rev 548)
@@ -5,12 +5,12 @@
 
 class REnvironmentTestCase(unittest.TestCase):
     def testNew(self):
-        env = robjects.Renvironment()
-        self.assertEquals(rinterface.ENVSXP, env.getSexp().typeof())
-        self.assertRaises(ValueError, robjects.Renvironment, 'a')
+        env = robjects.REnvironment()
+        self.assertEquals(rinterface.ENVSXP, env.typeof())
+        self.assertRaises(ValueError, robjects.REnvironment, 'a')
 
     def testSetItem(self):
-        env = robjects.Renvironment()
+        env = robjects.REnvironment()
         env['a'] = 123
         self.assertTrue('a' in env)
 

Modified: branches/rpy_nextgen/rpy/robjects/tests/testRFunction.py
===================================================================
--- branches/rpy_nextgen/rpy/robjects/tests/testRFunction.py    2008-06-07 
07:01:08 UTC (rev 547)
+++ branches/rpy_nextgen/rpy/robjects/tests/testRFunction.py    2008-06-07 
07:05:04 UTC (rev 548)
@@ -6,19 +6,19 @@
 class RFunctionTestCase(unittest.TestCase):
     def testNew(self):
         identical = rinterface.baseNameSpaceEnv["identical"]
-        self.assertRaises(ValueError, robjects.Rfunction, 'a')
+        self.assertRaises(ValueError, robjects.RFunction, 'a')
 
         ri_f = rinterface.baseNameSpaceEnv.get('help')
         
-        ro_f = robjects.Rfunction(ri_f)
+        ro_f = robjects.RFunction(ri_f)
         
-        self.assertTrue(identical(ri_f, ro_f.getSexp()))
+        self.assertTrue(identical(ri_f, ro_f))
 
     def testCall(self):
         ri_f = rinterface.baseNameSpaceEnv.get('sum')
-        ro_f = robjects.Rfunction(ri_f)
+        ro_f = robjects.RFunction(ri_f)
         
-        ro_v = robjects.Rvector(array.array('i', [1,2,3]))
+        ro_v = robjects.RVector(array.array('i', [1,2,3]))
         
         s = ro_f(ro_v)
 

Modified: branches/rpy_nextgen/rpy/robjects/tests/testRObject.py
===================================================================
--- branches/rpy_nextgen/rpy/robjects/tests/testRObject.py      2008-06-07 
07:01:08 UTC (rev 547)
+++ branches/rpy_nextgen/rpy/robjects/tests/testRObject.py      2008-06-07 
07:05:04 UTC (rev 548)
@@ -8,12 +8,12 @@
 
         identical = rinterface.baseNameSpaceEnv["identical"]
         py_a = array.array('i', [1,2,3])
-        self.assertRaises(ValueError, robjects.Robject, py_a)
+        self.assertRaises(ValueError, robjects.RObject, py_a)
         
         ri_v = rinterface.SexpVector(py_a, rinterface.INTSXP)
-        ro_v = robjects.Robject(ri_v)
+        ro_v = robjects.RObject(ri_v)
 
-        self.assertTrue(identical(ro_v._sexp, ri_v)[0])
+        self.assertTrue(identical(ro_v, ri_v)[0])
 
         #FIXME: why isn't this working ?
         #del(ri_v)

Modified: branches/rpy_nextgen/rpy/robjects/tests/testRVector.py
===================================================================
--- branches/rpy_nextgen/rpy/robjects/tests/testRVector.py      2008-06-07 
07:01:08 UTC (rev 547)
+++ branches/rpy_nextgen/rpy/robjects/tests/testRVector.py      2008-06-07 
07:05:04 UTC (rev 548)
@@ -5,18 +5,18 @@
 
 rlist = robjects.baseNameSpaceEnv["list"]
 
-class RvectorTestCase(unittest.TestCase):
+class RVectorTestCase(unittest.TestCase):
 
     def testNew(self):
         identical = ri.baseNameSpaceEnv["identical"]
         py_a = array.array('i', [1,2,3])
-        ro_v = robjects.Rvector(py_a)
+        ro_v = robjects.RVector(py_a)
         self.assertEquals(ro_v.typeof(), ri.INTSXP)
         
         ri_v = ri.SexpVector(py_a, ri.INTSXP)
-        ro_v = robjects.Rvector(ri_v)
+        ro_v = robjects.RVector(ri_v)
 
-        self.assertTrue(identical(ro_v._sexp, ri_v)[0])
+        self.assertTrue(identical(ro_v, ri_v)[0])
 
         del(ri_v)
         self.assertEquals(ri.INTSXP, ro_v.typeof())
@@ -37,14 +37,14 @@
         seq_R = robjects.baseNameSpaceEnv["seq"]
         mySeq = seq_R(0, 10)
         # R indexing starts at one
-        myIndex = robjects.Rvector(array.array('i', range(1, 11, 2)))
+        myIndex = robjects.RVector(array.array('i', range(1, 11, 2)))
 
         mySubset = mySeq.subset(myIndex)
         for i, si in enumerate(myIndex):
             self.assertEquals(mySeq[si-1], mySubset[i])
 
         # recycling rule
-        v = robjects.Rvector(array.array('i', range(1, 23)))
+        v = robjects.RVector(array.array('i', range(1, 23)))
         m = robjects.r.matrix(v, ncol = 2)
         col = m.subset(True, 1)
         self.assertEquals(11, len(col))
@@ -68,7 +68,7 @@
         self.assertTrue(idem("foo", mylist[1]))
 
     def testGetNames(self):
-        vec = robjects.Rvector(array.array('i', [1,2,3]))
+        vec = robjects.RVector(array.array('i', [1,2,3]))
         v_names = [robjects.baseNameSpaceEnv["letters"][x] for x in (0,1,2)]
         #FIXME: simplify this
         r_names = robjects.baseNameSpaceEnv["c"](*v_names)
@@ -77,7 +77,7 @@
             self.assertEquals(v_names[i], vec.getNames()[i])
 
 def suite():
-    suite = unittest.TestLoader().loadTestsFromTestCase(RvectorTestCase)
+    suite = unittest.TestLoader().loadTestsFromTestCase(RVectorTestCase)
     return suite
 
 if __name__ == '__main__':

Modified: branches/rpy_nextgen/rpy/robjects/tests/testRobjects.py
===================================================================
--- branches/rpy_nextgen/rpy/robjects/tests/testRobjects.py     2008-06-07 
07:01:08 UTC (rev 547)
+++ branches/rpy_nextgen/rpy/robjects/tests/testRobjects.py     2008-06-07 
07:05:04 UTC (rev 548)
@@ -7,7 +7,7 @@
 
     def testGetItem(self):
         letters_R = robjects.r["letters"]
-        self.assertTrue(isinstance(letters_R, robjects.Rvector))
+        self.assertTrue(isinstance(letters_R, robjects.RVector))
         letters = (('a', 0), ('b', 1), ('c', 2), ('x', 23), ('y', 24), ('z', 
25))
         for l, i in letters:
             self.assertTrue(letters_R[i] == l)
@@ -22,42 +22,65 @@
         for i, li in enumerate(myList):
             self.assertEquals(i, myList[i][0])
 
-
         
 
-    def testMapperR2Python(self):
+    def testMapperR2Python_string(self):
         sexp = rinterface.globalEnv.get("letters")
-        ob = robjects.defaultRobjects2PyMapper(sexp)
+        ob = robjects.default_ri2py(sexp)
         self.assertTrue(isinstance(ob, 
-                                   robjects.Rvector))
+                                   robjects.RVector))
 
+    def testMapperR2Python_boolean(self):
         sexp = rinterface.globalEnv.get("T")
-        ob = robjects.defaultRobjects2PyMapper(sexp)
+        ob = robjects.default_ri2py(sexp)
         self.assertTrue(isinstance(ob, 
-                                   robjects.Rvector))
+                                   robjects.RVector))
 
+    def testMapperR2Python_function(self):
         sexp = rinterface.globalEnv.get("plot")
-        ob = robjects.defaultRobjects2PyMapper(sexp)
+        ob = robjects.default_ri2py(sexp)
         self.assertTrue(isinstance(ob, 
-                                   robjects.Rfunction))
+                                   robjects.RFunction))
 
+    def testMapperR2Python_environment(self):
         sexp = rinterface.globalEnv.get(".GlobalEnv")
-        self.assertTrue(isinstance(robjects.defaultRobjects2PyMapper(sexp), 
robjects.Renvironment))
+        self.assertTrue(isinstance(robjects.default_ri2py(sexp), 
+                                   robjects.Renvironment))
 
         #FIXME: test S4
 
-    def testMapperPy2R(self):
+    def testMapperPy2R_integer(self):
         py = 1
-        rob = robjects.defaultPy2RobjectsMapper(py)
-        self.assertTrue(isinstance(rob, robjects.Rvector))
-        
+        rob = robjects.default_py2ro(py)
+        self.assertTrue(isinstance(rob, robjects.RVector))
+
+    def testMapperPy2R_boolean(self):        
         py = True
-        rob = robjects.defaultPy2RobjectsMapper(py)
-        self.assertTrue(isinstance(rob, robjects.Rvector))
+        rob = robjects.default_py2ro(py)
+        self.assertTrue(isinstance(rob, robjects.RVector))
         self.assertEquals(rinterface.LGLSXP, rob.typeof())
 
         #FIXME: more tests
 
+    def testOverride_ri2py(self):
+        class Density(object):
+            def __init__(self, x):
+                self._x = x
+
+        def f(obj):
+            pyobj = robjects.default_ri2py(obj)
+            inherits = rinterface.baseNameSpaceEnv["inherits"]
+            classname = rinterface.SexpVector(["density", ], 
+                                              rinterface.STRSXP)
+            if inherits(pyobj, classname)[0]:
+                pyobj = Density(pyobj)
+            return pyobj
+        robjects.ri2py = f
+        x = robjects.r.rnorm(100)
+        d = robjects.r.density(x)
+
+        self.assertTrue(isinstance(d, Density))
+
 def suite():
     suite = unittest.TestLoader().loadTestsFromTestCase(RObjectTestCase)
     return suite


This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.

-------------------------------------------------------------------------
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services for
just about anything Open Source.
http://sourceforge.net/services/buy/index.php
_______________________________________________
rpy-list mailing list
rpy-list@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/rpy-list

Reply via email to