/usr/lib/python3/dist-packages/rpy2/robjects/robject.py is in python3-rpy2 2.8.5-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 | import os, sys
import tempfile
import weakref
import rpy2.rinterface
rpy2.rinterface.initr()
from . import conversion
class RSlots(object):
""" Attributes of an R object as a Python mapping.
The parent proxy to the underlying R object is held as a
weak reference. The attributes are therefore not protected
from garbage collection unless bound to a Python symbol or
in an other container.
"""
__slots__ = ['_robj', ]
def __init__(self, robj):
self._robj = weakref.proxy(robj)
def __getitem__(self, key):
value = self._robj.do_slot(key)
return conversion.ri2ro(value)
def __setitem__(self, key, value):
rpy2_value = conversion.py2ri(value)
self._robj.do_slot_assign(key, rpy2_value)
def __len__(self):
return len(self._robj.list_attrs())
def keys(self):
for k in self._robj.list_attrs():
yield k
__iter__=keys
def items(self):
for k in self._robj.list_attrs():
v = self[k]
yield (k, v)
def values(self):
for k in self._robj.list_attrs():
v = self[k]
yield v
def _reduce_robjectmixin(rdumps, rtypeof,
rinterface_factory,
rpy2type):
rinterface_level=rinterface_factory(rdumps, rtypeof)
return rpy2type(rinterface_level)
class RObjectMixin(object):
""" Class to provide methods common to all RObject instances """
__rname__ = None
__tempfile = rpy2.rinterface.baseenv.get("tempfile")
__file = rpy2.rinterface.baseenv.get("file")
__fifo = rpy2.rinterface.baseenv.get("fifo")
__sink = rpy2.rinterface.baseenv.get("sink")
__close = rpy2.rinterface.baseenv.get("close")
__readlines = rpy2.rinterface.baseenv.get("readLines")
__unlink = rpy2.rinterface.baseenv.get("unlink")
__rclass = rpy2.rinterface.baseenv.get("class")
__rclass_set = rpy2.rinterface.baseenv.get("class<-")
__show = rpy2.rinterface.baseenv.get("show")
__slots = None
@property
def slots(self):
""" Attributes of the underlying R object as a Python mapping.
The attributes can accessed and assigned by name (as if they
were in a Python `dict`)."""
if self.__slots is None:
self.__slots = RSlots(self)
return self.__slots
def __repr__(self):
try:
rclasses = ('R object with classes: {} mapped to:'
.format(tuple(self.rclass)))
except:
rclasses = 'Unable to fetch R classes.' + os.linesep
res = os.linesep.join((rclasses,
super(RObjectMixin, self).__repr__()))
return res
def __str__(self):
if sys.platform == 'win32':
tmpf = tempfile.NamedTemporaryFile(mode="w+", delete=False)
tfname = tmpf.name
tmp = self.__file(rpy2.rinterface.StrSexpVector([tfname,]),
open=rpy2.rinterface.StrSexpVector(["r+", ]))
self.__sink(tmp)
else:
writeconsole = rpy2.rinterface.get_writeconsole_regular()
s = []
def f(x):
s.append(x)
rpy2.rinterface.set_writeconsole_regular(f)
self.__show(self)
if sys.platform == 'win32':
self.__sink()
s = tmpf.readlines()
tmpf.close()
self.__close(tmp)
try:
del tmpf
os.unlink(tfname)
except WindowsError:
if os.path.exists(tfname):
print('Unable to unlink tempfile %s' % tfname)
s = str.join(os.linesep, s)
else:
rpy2.rinterface.set_writeconsole_regular(writeconsole)
s = str.join('', s)
return s
def r_repr(self):
""" String representation for an object that can be
directly evaluated as R code.
"""
return repr_robject(self, linesep='\n')
def _rclass_get(self):
try:
res = self.__rclass(self)
#res = conversion.ri2py(res)
return res
except rpy2.rinterface.RRuntimeError as rre:
if self.typeof == rpy2.rinterface.SYMSXP:
#unevaluated expression: has no class
return (None, )
else:
raise rre
def _rclass_set(self, value):
if isinstance(value, str):
value = (value, )
new_cls = rpy2.rinterface.StrSexpVector(value)
res = self.__rclass_set(self, new_cls)
self.__sexp__ = res.__sexp__
rclass = property(_rclass_get, _rclass_set, None,
"""
R class for the object, stored as an R string vector.
When setting the rclass, the new value will be:
- wrapped in a Python tuple if a string (the R class
is a vector of strings, and this is made for convenience)
- wrapped in a StrSexpVector
Note that when setting the class R may make a copy of
the whole object (R is mostly a functional language).
If this must be avoided, and if the number of parent
classes before and after the change are compatible,
the class name can be changed in-place by replacing "
vector elements.
""")
# Python 3-only
if sys.version_info[0] == 2:
def __reduce__(self):
"""
robjects-level `__reduce__()`, calling the parent class'
`__reduce__()` before substituting the current high-level
class as a constructor.
"""
t = super(RObjectMixin, self).__reduce__()
# fix the constructor and parameters
l = list(t)
l[1] = (l[1][0], l[1][1], l[0], type(self))
l[0] = _reduce_robjectmixin
return tuple(l)
elif sys.version_info[0] == 3:
def __reduce__(self):
"""
robjects-level `__reduce__()`, calling the parent class'
`__reduce__()` before substituting the current high-level
class as a constructor.
"""
t = super().__reduce__()
# fix the constructor and parameters
l = list(t)
l[1] = (l[1][0], l[1][1], l[0], type(self))
l[0] = _reduce_robjectmixin
return tuple(l)
def repr_robject(o, linesep=os.linesep):
s = rpy2.rinterface.baseenv.get("deparse")(o)
s = str.join(linesep, s)
return s
class RObject(RObjectMixin, rpy2.rinterface.Sexp):
""" Base class for all R objects. """
def __setattr__(self, name, value):
if name == '_sexp':
if not isinstance(value, rpy2.rinterface.Sexp):
raise ValueError("_attr must contain an object " +\
"that inherits from rpy2.rinterface.Sexp" +\
"(not from %s)" %type(value))
super(RObject, self).__setattr__(name, value)
|