2
* $Id: rpymodule.c 515 2008-05-14 13:53:05Z warnes $
3
* Implementation of the module '_rpy' and the 'Robj' type.
6
/* ***** BEGIN LICENSE BLOCK *****
7
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
9
* The contents of this file are subject to the Mozilla Public License Version
10
* 1.1 (the "License"); you may not use this file except in compliance with
11
* the License. You may obtain a copy of the License at
12
* http://www.mozilla.org/MPL/
14
* Software distributed under the License is distributed on an "AS IS" basis,
15
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
16
* for the specific language governing rights and limitations under the
19
* The Original Code is the RPy python module.
21
* The Initial Developer of the Original Code is Walter Moreira.
22
* Portions created by the Initial Developer are Copyright (C) 2002
23
* the Initial Developer. All Rights Reserved.
26
* Gregory R. Warnes <greg@warnes.net> (Maintainer)
28
* Alternatively, the contents of this file may be used under the terms of
29
* either the GNU General Public License Version 2 or later (the "GPL"), or
30
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
31
* in which case the provisions of the GPL or the LGPL are applicable instead
32
* of those above. If you wish to allow use of your version of this file only
33
* under the terms of either the GPL or the LGPL, and not to allow others to
34
* use your version of this file under the terms of the MPL, indicate your
35
* decision by deleting the provisions above and replace them with the notice
36
* and other provisions required by the GPL or the LGPL. If you do not delete
37
* the provisions above, a recipient may use your version of this file under
38
* the terms of any one of the MPL, the GPL or the LGPL.
40
* ***** END LICENSE BLOCK ***** */
43
#if (R_VERSION >= R_Version(2,3,0))
46
# define CSTACK_DEFNS // Enable definitions needed for stack checking control
53
#define NONAMELESSUNION
58
/* Flag indicating whether Numpy/Numeric is available in this session
60
* This is necessary since Numpy/Numeric may not available at run time, even if
61
* it was available at compile time.
63
static int use_numeric=0;
66
/* Local function definitions */
67
DL_EXPORT(void) INIT_RPY(void); /* Module initializer */
68
static PyObject *r_init(PyObject *self, /* Class initializer */
70
static PyObject *r_cleanup(void); /* Clean up R & release resources */
73
static void init_embedded_win32(int argc, char *argv[]);
81
static PyObject *class_table;
82
static PyObject *proc_table;
83
static int default_mode;
84
static PyObject *r_lock;
85
PyObject *RPy_Exception;
86
PyObject *RPy_TypeConversionException;
87
PyObject *RPy_RException;
89
static char RHOME[BUFSIZ];
90
static char RVERSION[BUFSIZ];
91
static char RVER[BUFSIZ];
92
static char RUSER[BUFSIZ];
93
char *defaultargv[] = {"rpy", "-q", "--vanilla"};
94
int defaultargc = sizeof(defaultargv) / sizeof(defaultargv[0]);
96
/* Global interpreter */
97
PyInterpreterState *my_interp;
99
/* Signal whether R is running interactively */
108
static PyObject *Py_transpose;
111
/* Global list to protect R objects from garbage collection */
112
/* This is inspired in $R_SRC/src/main/memory.c */
113
static SEXP R_References;
116
RecursiveRelease(SEXP obj, SEXP list)
119
if (obj == CAR(list))
122
SETCDR(list, RecursiveRelease(obj, CDR(list)));
127
/* Robj methods. Following xxmodule.c from Python distro. */
130
Robj_dealloc(RobjObject *self)
132
/* Remove the object from the list of protected objects */
133
R_References = RecursiveRelease(self->R_obj, R_References);
134
SET_SYMVALUE(install("R.References"), R_References);
140
Robj_new(SEXP robj, int conversion)
143
self = PyObject_New(RobjObject, &Robj_Type);
150
/* Protect the R object */
151
R_References = CONS(robj, R_References);
152
SET_SYMVALUE(install("R.References"), R_References);
155
self->conversion = conversion;
161
Robj_tpnew(PyTypeObject *type, PyObject *args, PyObject *kwds)
165
self = type->tp_alloc(type, 0);
170
/* Type conversion routines. See documentation for details */
172
/* These are auxiliaries for a state machine for converting Python
173
list to the coarsest R vector type */
183
type_to_int(PyObject *obj)
185
if (PyBool_Check(obj))
187
else if (PyInt_Check(obj))
189
else if (PyFloat_Check(obj))
191
else if (PyComplex_Check(obj))
193
else if (PyNumber_Check(obj))
195
else if (PyString_Check(obj))
197
else if (PyUnicode_Check(obj))
199
else if (Robj_Check(obj))
205
/* Make a R list or vector from a Python sequence */
207
seq_to_R(PyObject *obj)
213
/* This matrix defines what mode a vector should take given what
214
it already contains and a new item
216
E.g. Row 0 indicates that if we've seen an any, the vector will
217
always remain an any. Row 3 indicates that if we've seen a
218
float, then seeing an boolean, integer, or float will preserve
219
the vector as a float vector, while seeing a string or an Robj will
220
convert it into an any vector.
223
{0, 0, 0, 0, 0, 0, 0}, // any
224
{0, 1, 2, 3, 4, 0, 0}, // bool
225
{0, 2, 2, 3, 4, 0, 0}, // int
226
{0, 3, 3, 3, 4, 0, 0}, // float
227
{0, 4, 4, 4, 4, 0, 0}, // complex
228
{0, 0, 0, 0, 0, 5, 0}, // string
229
{0, 0, 0, 0, 0, 0, 6} // RObj
232
len = PySequence_Length(obj);
236
PROTECT(robj = NEW_LIST(len));
239
for (i=0; i<len; i++)
241
it = PySequence_GetItem(obj, i);
249
state = type_to_int(it);
251
state = fsm[state][type_to_int(it)];
254
if (rit==NULL || PyErr_Occurred() )
261
SET_VECTOR_ELT(robj, i, rit);
268
robj = AS_INTEGER(robj);
271
robj = AS_LOGICAL(robj);
274
robj = AS_NUMERIC(robj);
277
robj = AS_COMPLEX(robj);
280
robj = AS_CHARACTER(robj);
283
/* Otherwise, it's either an ANY_T or ROBJ_T - we want ANY */
290
/* Make a R named list or vector from a Python dictionary */
292
dict_to_R(PyObject *obj)
295
PyObject *keys, *values;
298
len = PyMapping_Length(obj);
302
/* If 'keys' succeed and 'values' fails this leaks */
303
if (!(keys = PyMapping_Keys(obj)))
305
if (!(values = PyMapping_Values(obj)))
308
robj = seq_to_R(values);
309
names = seq_to_R(keys);
310
if ( robj==NULL || robj==NULL )
318
SET_NAMES(robj, names);
328
/* Convert a Numpy/Numeric array to a R array */
330
to_Rarray(PyObject *o)
332
PyObject *pytl, *nobj;
334
SEXP Rdims, tRdims, Rarray, e;
340
obj = (PyArrayObject *)o;
341
dims = obj->dimensions;
342
type = obj->descr->type_num;
343
size = PyArray_Size( (PyObject*) obj);
345
/* Handle a vector without dimensions, just length */
348
PROTECT(Rdims = allocVector(INTSXP, 1));
349
PROTECT(tRdims = allocVector(INTSXP, 1));
350
INTEGER(Rdims)[0] = size;
351
INTEGER(tRdims)[0] = size;
355
PROTECT(Rdims = allocVector(INTSXP, obj->nd));
356
PROTECT(tRdims = allocVector(INTSXP, obj->nd));
358
for (i=0; i<obj->nd; i++)
365
INTEGER(Rdims)[i] = dims[(obj->nd)-i-1];
366
INTEGER(tRdims)[i] = (obj->nd)-i;
373
/*******************/
374
/* String Variants */
375
/*******************/
376
/* TODO: Add proper handling of NumPy character arrays.
377
The following code DOES NOT WORK:
380
case PyArray_UNICODE:
383
obj = (PyArrayObject *)PyArray_ContiguousFromObject((PyObject *)obj,
384
PyArray_STRING, 0, 0);
387
The problem is that the PyArray call throws an exception,
388
presumably because we haven't given a width specifier.
390
NumPy strings are fixed-width, and may not be null terminated. R only handles
391
null terminated (varying width) strings. We need a separate
392
code path to handle this, as it requires quite different
393
handling than the numeric arrays dealt with below.
397
/******************************************/
398
/* All complex to (double,double) complex */
399
/******************************************/
401
#if WITH_NUMERIC==1 /* Numeric */
403
case PyArray_CDOUBLE:
405
case PyArray_COMPLEX64:
406
case PyArray_COMPLEX128:
408
obj = (PyArrayObject *)PyArray_ContiguousFromObject((PyObject *)obj,
409
PyArray_CDOUBLE, 0, 0);
413
/**********************************************************************************/
414
/* Convert all integers to platform integer (except 64 bit int on 32 bit platforms) */
415
/************************************************************************************/
417
#if WITH_NUMERIC==1 /* Numeric */
423
obj = (PyArrayObject *)PyArray_ContiguousFromObject((PyObject *)obj,
434
#if PyArray_INT==PyArray_INT64 /* 64 bit platform */
438
obj = (PyArrayObject *)PyArray_ContiguousFromObject((PyObject *)obj,
444
/**************************************************/
445
/* All floats (and over-sized integers) to double */
446
/**************************************************/
447
#if WITH_NUMERIC==1 /* Numeric */
451
case PyArray_FLOAT32:
452
case PyArray_FLOAT64:
453
#if PyArray_INT!=PyArray_INT64 /* 32 bit platform */
458
obj = (PyArrayObject *)PyArray_ContiguousFromObject((PyObject *)obj,
459
PyArray_DOUBLE, 0, 0);
464
PyErr_Format(RPy_TypeConversionException,
465
"Numeric/NumPy arrays containing %s are not supported.",
466
obj->ob_type->tp_name);
472
pytl = Py_BuildValue("[i]", size);
473
nobj = PyArray_Reshape(obj, pytl);
484
PROTECT(Rarray = seq_to_R(nobj));
493
SET_DIM(Rarray, Rdims);
495
PROTECT(e = allocVector(LANGSXP, 3));
497
SETCAR(CDR(e), Rarray);
498
SETCAR(CDR(CDR(e)), tRdims);
499
PROTECT(Rarray = do_eval_expr(e));
506
/* Convert a Python object to a R object. An Robj is passed w/o
507
* modifications, an object which provides a '.as_r()' method, is
508
* passed as the result of that method */
510
to_Robj(PyObject *obj)
521
if (obj == Py_None) {
525
to_r_meth = PyObject_GetAttrString(obj, "as_r");
527
obj = PyObject_CallObject(to_r_meth, NULL);
528
Py_DECREF(to_r_meth);
538
PROTECT(robj = ((RobjObject *)obj)->R_obj);
540
else if (PyBool_Check(obj))
542
PROTECT(robj = NEW_LOGICAL(1));
543
LOGICAL_DATA(robj)[0] = (Py_True==obj);
545
else if (PyInt_Check(obj))
547
PROTECT(robj = NEW_INTEGER(1));
548
INTEGER_DATA(robj)[0] = (int) PyInt_AsLong(obj);
550
else if (PyFloat_Check(obj))
552
PROTECT(robj = NEW_NUMERIC(1));
553
NUMERIC_DATA(robj)[0] = PyFloat_AsDouble(obj);
555
else if (PyComplex_Check(obj))
557
PROTECT(robj = NEW_COMPLEX(1));
558
c = PyComplex_AsCComplex(obj);
559
COMPLEX_DATA(robj)[0].r = c.real;
560
COMPLEX_DATA(robj)[0].i = c.imag;
562
else if (PyUnicode_Check(obj))
564
/** Handle Unicode Strings.
566
* Ideally: Python Unicode -> R Unicode,
568
* Unfortunately, the R documentation is not forthcoming on how
571
* So, for the moment:
572
* python Unicode -> Python ASCII -> ordinary string -> R string
575
PROTECT(robj = NEW_STRING(1));
576
SET_STRING_ELT(robj, 0, COPY_TO_USER_STRING(PyString_AsString(PyUnicode_AsASCIIString(obj))));
578
else if (PyString_Check(obj))
580
PROTECT(robj = NEW_STRING(1));
581
SET_STRING_ELT(robj, 0, COPY_TO_USER_STRING(PyString_AsString(obj)));
584
else if (use_numeric && PyArray_Check(obj))
586
PROTECT(robj = to_Rarray(obj));
589
else if ((PySequence_Check(obj)) &&
590
(PySequence_Size(obj) >= 0))
592
PROTECT(robj = seq_to_R(obj)); /* No labels */
594
else if ((PyMapping_Check(obj)) &&
595
(PyMapping_Size(obj) >= 0))
597
PROTECT(robj = dict_to_R(obj));
599
else if (PyNumber_Check(obj)) /* generic number interface */
601
tempObj = PyNumber_Float(obj);
602
if(!tempObj) goto error;
604
PROTECT(robj = NEW_NUMERIC(1));
605
NUMERIC_DATA(robj)[0] = PyFloat_AsDouble(tempObj);
611
PyErr_Format(RPy_TypeConversionException,
612
"cannot convert from type '%s'",
613
obj->ob_type->tp_name);
614
PROTECT(robj = NULL); /* Protected to avoid stack inbalance */
625
/* Convert a R named vector or list to a Python dictionary */
627
to_PyDict(PyObject *obj, SEXP names)
633
if ((len = PySequence_Length(obj)) < 0)
637
for (i=0; i<len; i++) {
638
if (!(it = PyList_GetItem(obj, i)))
641
name = CHAR(STRING_ELT(names, i));
642
if ((PyDict_SetItemString(dict, name, it)) < 0) {
650
/* We need to transpose the list because R makes array by the
653
ltranspose(PyObject *list, int *dims, int *strides,
654
int pos, int shift, int len)
659
if (!(nl = PyList_New(dims[pos])))
663
for (i=0; i<dims[pos]; i++) {
664
if (!(it = PyList_GetItem(list, i*strides[pos]+shift)))
667
if (PyList_SetItem(nl, i, it) < 0)
673
for (i=0; i<dims[pos]; i++) {
674
if (!(it = ltranspose(list, dims, strides, pos+1, shift, len)))
676
if (PyList_SetItem(nl, i, it) < 0)
678
shift += strides[pos];
684
/* Convert a Python list to a Python array (in the form of
685
* list of lists of ...) */
687
to_PyArray(PyObject *obj, int *dims, int l)
692
strides = (int *)PyMem_Malloc(l*sizeof(int));
697
for (i=0; i<l; i++) {
702
list = ltranspose(obj, dims, strides, 0, 0, l);
708
/* Convert a Python sequence to a Numeric array */
711
to_PyNumericArray(PyObject *seq, SEXP dim)
713
PyObject *array, *ret, *dims, *it;
716
array = PyArray_ContiguousFromObject(seq, PyArray_DOUBLE, 0,0);
721
dims = PyList_New(l);
722
for (i=0; i<l; i++) {
723
j = INTEGER(dim)[l-i-1];
730
if (!(it = PyInt_FromLong(j)))
732
if (PyList_SetItem(dims, i, it) < 0)
736
ret = PyArray_Reshape((PyArrayObject *)array, dims);
742
array = PyObject_CallFunction(Py_transpose, "O", ret);
748
/* Convert an R object to a 'basic' Python object (mode 2) */
749
/* NOTE: R vectors of length 1 will yield a python scalar */
751
to_Pyobj_basic(SEXP robj, PyObject **obj)
756
status = to_Pyobj_vector(robj, &tmp, BASIC_CONVERSION);
758
if(status==1 && PyList_Check(tmp) && PyList_Size(tmp) == 1)
760
*obj = PyList_GetItem(tmp, 0);
771
/* Convert an R object to a 'vector' Python object (mode 1) */
772
/* NOTE: R vectors of length 1 will yield a python list of length 1*/
774
to_Pyobj_vector(SEXP robj, PyObject **obj, int mode)
778
int len, *integers, i, type;
779
const char *strings, *thislevel;
787
return -1; /* error */
789
if (robj == R_NilValue) {
792
return 1; /* succeed */
795
len = GET_LENGTH(robj);
796
tmp = PyList_New(len);
799
for (i=0; i<len; i++) {
803
integers = INTEGER(robj);
804
if(integers[i]==NA_INTEGER) /* watch out for NA's */
806
if (!(it = PyInt_FromLong(integers[i])))
810
else if (!(it = PyBool_FromLong(integers[i])))
814
integers = INTEGER(robj);
816
/* Watch for NA's! */
817
if(integers[i]==NA_INTEGER)
818
it = PyString_FromString(CHAR(NA_STRING));
821
thislevel = CHAR(STRING_ELT(GET_LEVELS(robj), integers[i]-1));
822
if (!(it = PyString_FromString(thislevel)))
827
if (!(it = PyInt_FromLong(integers[i])))
833
if (!(it = PyFloat_FromDouble(reals[i])))
837
complexes = COMPLEX(robj);
838
if (!(it = PyComplex_FromDoubles(complexes[i].r,
843
if(STRING_ELT(robj, i)==R_NaString)
844
it = PyString_FromString(CHAR(NA_STRING));
847
strings = CHAR(STRING_ELT(robj, i));
848
if (!(it = PyString_FromString(strings)))
853
if (!(it = to_Pyobj_with_mode(elt(robj, i), mode)))
857
if (!(it = to_Pyobj_with_mode(VECTOR_ELT(robj, i), mode)))
862
return 0; /* failed */
865
if (PyList_SetItem(tmp, i, it) < 0)
870
if (dim != R_NilValue) {
874
array = to_PyNumericArray(tmp, dim);
875
if (array) { /* If the conversion to Numeric succeed.. */
876
*obj = array; /* we are done */
883
len = GET_LENGTH(dim);
884
*obj = to_PyArray(tmp, INTEGER(dim), len);
889
names = GET_NAMES(robj);
890
if (names == R_NilValue)
893
*obj = to_PyDict(tmp, names);
899
/* Search a conversion procedure from the class attribute */
901
from_class_table(SEXP robj)
904
PyObject *lkey, *key, *fun;
907
PROTECT(rclass = GET_CLASS(robj));
910
if (rclass != R_NilValue) {
912
lkey = to_Pyobj_with_mode(rclass, BASIC_CONVERSION);
913
key = PyList_AsTuple(lkey);
920
fun = PyDict_GetItem(class_table, key);
925
for (i=0; i<GET_LENGTH(rclass); i++)
926
if ((fun = PyDict_GetItemString(class_table,
927
CHAR(STRING_ELT(rclass, i)))))
937
/* Search a conversion procedure from the proc table */
939
from_proc_table(SEXP robj, PyObject **fun)
941
PyObject *procs, *proc, *funs, *res, *obj;
945
procs = PyDict_Keys(proc_table);
946
funs = PyDict_Values(proc_table);
947
l = PyMapping_Size(proc_table);
949
obj = (PyObject *)Robj_new(robj, TOP_MODE);
952
for (i=0; i<l; i++) {
953
proc = PyList_GetItem(procs, i);
955
res = PyObject_CallFunction(proc, "O", obj);
960
k = PyObject_IsTrue(res);
963
*fun = PyList_GetItem(funs, i);
977
to_Pyobj_proc(SEXP robj, PyObject **obj)
979
PyObject *fun=NULL, *tmp;
982
i = from_proc_table(robj, &fun);
984
return -1; /* an error occurred */
987
return 0; /* conversion failed */
989
tmp = (PyObject *)Robj_new(robj, TOP_MODE);
990
*obj = PyObject_CallFunction(fun, "O", tmp);
993
return 1; /* conversion succeed */
996
/* Convert a Robj to a Python object via the class table (mode 3) */
997
/* See the docs for conversion rules */
999
to_Pyobj_class(SEXP robj, PyObject **obj)
1001
PyObject *fun, *tmp;
1003
fun = from_class_table(robj);
1006
return 0; /* conversion failed */
1008
tmp = (PyObject *)Robj_new(robj, TOP_MODE);
1009
*obj = PyObject_CallFunction(fun, "O", tmp);
1012
return 1; /* conversion succeed */
1016
to_Pyobj_with_mode(SEXP robj, int mode)
1023
case PROC_CONVERSION:
1024
i = to_Pyobj_proc(robj, &obj);
1025
if (i<0) return NULL;
1027
case CLASS_CONVERSION:
1028
i = to_Pyobj_class(robj, &obj);
1029
if (i<0) return NULL;
1031
case BASIC_CONVERSION:
1032
i = to_Pyobj_basic(robj, &obj);
1033
if (i<0) return NULL;
1035
case VECTOR_CONVERSION:
1036
i = to_Pyobj_vector(robj, &obj, mode=VECTOR_CONVERSION);
1037
if (i<0) return NULL;
1040
obj = (PyObject *)Robj_new(robj, TOP_MODE);
1046
/* Convert a tuple to arguments for a R function */
1048
make_args(int largs, PyObject *args, SEXP *e)
1053
for (i=0; i<largs; i++) {
1054
r = to_Robj(PyTuple_GetItem(args, i));
1055
if (!r || PyErr_Occurred() )
1063
/* Implements the conversion rules for names. See the 'USING' file. We
1064
don't care about '<-' because it doesn't appear in keywords. */
1072
return NULL; /* assume prev PyString_AsString has failed */
1074
r = (char *)PyMem_Malloc(l+1);
1081
if ((l > 1) && (res[l-1] == '_') && (res[l-2] != '_'))
1084
while ((r=strchr(r, '_')))
1090
/* Convert a dict to keywords arguments for a R function */
1092
make_kwds(int lkwds, PyObject *kwds, SEXP *e)
1097
PyObject *citems=NULL, *it;
1101
citems = PyMapping_Items(kwds);
1104
for (i=0; i<lkwds; i++) {
1105
it = PySequence_GetItem(citems, i);
1108
r = to_Robj(PyTuple_GetItem(it, 1));
1110
if (!r || PyErr_Occurred())
1114
kwname = PyTuple_GetItem(it, 0);
1117
if (!PyString_Check(kwname)) {
1118
PyErr_SetString(PyExc_TypeError, "keywords must be strings");
1121
s = dotter(PyString_AsString(kwname));
1125
SET_TAG(*e, Rf_install(s));
1126
PyMem_Free( (void*) s);
1138
/* This is the method to call when invoking an 'Robj' */
1140
Robj_call(PyObject *self, PyObject *args, PyObject *kwds)
1143
int largs, lkwds, conv;
1148
largs = PyObject_Length(args);
1150
lkwds = PyObject_Length(kwds);
1151
if ((largs<0) || (lkwds<0))
1154
/* A SEXP with the function to call and the arguments and keywords. */
1155
PROTECT(exp = allocVector(LANGSXP, largs+lkwds+1));
1157
SETCAR(e, ((RobjObject *)self)->R_obj);
1160
if (!make_args(largs, args, &e)) {
1164
if (!make_kwds(lkwds, kwds, &e)) {
1169
PROTECT(res = do_eval_expr(exp));
1175
if (default_mode < 0)
1176
conv = ((RobjObject *)self)->conversion;
1178
conv = default_mode;
1180
obj = to_Pyobj_with_mode(res, conv);
1183
PrintWarnings(); /* show any warning messages */
1188
/* Convert a sequence of (name, value) pairs to arguments to an R
1191
make_argl(int largl, PyObject *argl, SEXP *e)
1196
PyObject *it, *nobj, *value;
1198
if( !PySequence_Check(argl) ) goto fail_arg;
1200
for (i=0; i<largl; i++) {
1201
it = PySequence_GetItem(argl, i);
1202
if(!it) goto fail_arg;
1203
if( PySequence_Size(it) != 2 )
1208
nobj = PySequence_GetItem(it, 0);
1210
/* Name can be a string, None, or NULL, error otherwise. */
1211
if (PyString_Check(nobj))
1213
name = dotter(PyString_AsString(nobj));
1216
else if (nobj == Py_None)
1221
else if(nobj == NULL)
1231
/* Value can be anything. */
1232
value = PySequence_GetItem(it, 1);
1233
if (!value || PyErr_Occurred() )
1235
PyMem_Free( (void*) name);
1239
rvalue = to_Robj(value);
1243
if(PyErr_Occurred())
1246
/* Add parameter value to call */
1249
/* Add name (if present) */
1250
if (name && strlen(name)>0)
1252
SET_TAG(*e, Rf_install(name));
1253
PyMem_Free((void*) name);
1256
/* Move index to new end of call */
1262
PyErr_SetString(PyExc_ValueError,
1263
"Argument must be a sequence of (\"name\", value) pairs.\n");
1268
/* Methods for the 'Robj' type */
1270
/* Explicitly call an R object with a list containing (name, value) *
1271
* argument pairs. 'name' can be None or '' to provide unnamed
1272
* arguments. This function is necessary when the *order* of named
1273
* arguments needs to be preserved.
1277
Robj_lcall(PyObject *self, PyObject *args)
1280
int largs, largl, conv;
1281
PyObject *obj, *argl;
1283
/* Check arguments, there should be *exactly one* unnamed sequence. */
1286
largs = PyObject_Length(args);
1290
if(largs != 1 || !PySequence_Check(args) )
1292
PyErr_SetString(PyExc_ValueError,
1293
"Argument must be a sequence of (\"name\", value) pairs.\n");
1297
// extract our one argument
1298
argl = PySequence_GetItem(args, 0);
1303
largl = PyObject_Length(argl);
1307
// A SEXP with the function to call and the arguments
1308
PROTECT(exp = allocVector(LANGSXP, largl+1));
1310
SETCAR(e, ((RobjObject *)self)->R_obj);
1313
// Add the arguments to the SEXP
1314
if (!make_argl(largl, argl, &e)) {
1320
PROTECT(res = do_eval_expr(exp));
1327
if (default_mode < 0)
1328
conv = ((RobjObject *)self)->conversion;
1330
conv = default_mode;
1332
obj = to_Pyobj_with_mode(res, conv);
1340
/* Without args return the value of the conversion flag. With an
1341
argument set the conversion flag to the truth value of the argument. */
1343
Robj_autoconvert(PyObject *self, PyObject *args, PyObject *kwds)
1347
char *kwlist[] = {"val", 0};
1349
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:autoconvert", kwlist,
1353
if (conversion > TOP_MODE) {
1354
PyErr_SetString(PyExc_ValueError, "wrong mode");
1358
if (conversion == -2) {
1359
obj = PyInt_FromLong((long)((RobjObject *)self)->conversion);
1361
((RobjObject *)self)->conversion = conversion;
1370
Robj_as_py(PyObject *self, PyObject *args, PyObject *kwds)
1373
char *kwlist[] = {"mode", 0};
1374
int conv=default_mode;
1376
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:as_py", kwlist,
1380
if (conv <= -2 || conv > TOP_MODE) {
1381
PyErr_SetString(PyExc_ValueError, "wrong mode");
1388
obj = to_Pyobj_with_mode(((RobjObject *)self)->R_obj, conv);
1392
static PyMethodDef Robj_methods[] = {
1393
{"autoconvert", (PyCFunction)Robj_autoconvert, METH_VARARGS|METH_KEYWORDS},
1394
{"local_mode", (PyCFunction)Robj_autoconvert, METH_VARARGS|METH_KEYWORDS},
1395
{"as_py", (PyCFunction)Robj_as_py, METH_VARARGS|METH_KEYWORDS},
1396
{"lcall", (PyCFunction)Robj_lcall, METH_VARARGS},
1397
{NULL, NULL} /* sentinel */
1400
/* Sequence protocol implementation */
1404
Robj_len(PyObject *a)
1408
PROTECT(e = allocVector(LANGSXP, 2));
1410
SETCAR(CDR(e), ((RobjObject *)a)->R_obj);
1412
if (!(robj = do_eval_expr(e))) {
1418
return INTEGER_DATA(robj)[0];
1423
Robj_ass_item(PyObject *a, int i, PyObject *v)
1427
PROTECT(e = allocVector(LANGSXP, 4));
1428
ri = NEW_INTEGER(1);
1429
INTEGER_DATA(ri)[0] = i+1;
1430
SETCAR(e, set_item);
1431
SETCAR(CDR(e), ((RobjObject *)a)->R_obj);
1432
SETCAR(CDR(CDR(e)), ri);
1433
SETCAR(CDR(CDR(CDR(e))), to_Robj(v));
1435
if(PyErr_Occurred())
1438
if (!(robj = do_eval_expr(e))) {
1443
((RobjObject *)a)->R_obj = robj;
1450
Robj_item(PyObject *a, int i)
1456
if ((len = Robj_len(a)) < 0)
1458
if (i >= len || i < 0) {
1459
PyErr_SetString(PyExc_IndexError, "R object index out of range");
1463
PROTECT(ri = NEW_INTEGER(1));
1464
INTEGER_DATA(ri)[0] = i+1;
1465
PROTECT(e = allocVector(LANGSXP, 3));
1466
SETCAR(e, get_item);
1467
SETCAR(CDR(e), ((RobjObject *)a)->R_obj);
1468
SETCAR(CDR(CDR(e)), ri);
1470
if (!(robj = do_eval_expr(e))) {
1477
/* If there is a default mode, use it; otherwise, use the top mode. */
1478
if (default_mode < 0)
1482
obj = to_Pyobj_with_mode(robj, c);
1486
/* Get a slice: a[x:y] */
1487
/*FIXME: starting with Python 2.5, ilow and ihigh should probably
1488
* be of type Py_ssize_t.
1491
Robj_slice(PyObject *a, int ilow, int ihigh)
1493
SEXP robj, e, index;
1495
int robjLen, sliceLen, c;
1498
robjLen = Robj_len(a);
1504
PyErr_SetString(PyExc_IndexError,
1505
"R object index out of range (lowest index is negative)");
1508
} else if (ilow > robjLen) {
1509
PyErr_SetString(PyExc_IndexError,
1510
"R object index out of range (lowest index > object length)");
1515
PyErr_SetString(PyExc_IndexError,
1516
"R object index out of range (highest index < lowest index)");
1519
} else if (ihigh > robjLen) {
1520
PyErr_SetString(PyExc_IndexError,
1521
"R object index out of range (highest index > object length)");
1525
sliceLen = ihigh - ilow;
1527
/* if (ilow >= robjLen || ilow < 0) { */
1528
/* PyErr_SetString(PyExc_IndexError, "R object index out of range"); */
1532
PROTECT(index = allocVector(INTSXP, sliceLen));
1534
for (ii = 0; ii < sliceLen; ii++) {
1535
INTEGER_POINTER(index)[ii] = ii + ilow + 1;
1538
PROTECT(e = allocVector(LANGSXP, 3));
1539
SETCAR(e, get_item);
1540
SETCAR(CDR(e), ((RobjObject *)a)->R_obj);
1541
SETCAR(CDR(CDR(e)), index);
1543
if (!(robj = do_eval_expr(e))) {
1550
/* If there is a default mode, use it; otherwise, use the top mode. */
1551
if (default_mode < 0)
1555
obj = to_Pyobj_with_mode(robj, c);
1561
* Python 2.5 will feel happier with ssizeargfunc and ssizessizeargfunc
1563
/* We should implement sq_slice, sq_contains ... */
1564
static PySequenceMethods Robj_as_sequence = {
1565
(inquiry)Robj_len, /* sq_length */
1568
(intargfunc)Robj_item, /* sq_item */
1569
(intintargfunc)Robj_slice, /* sq_slice */
1570
(intobjargproc)Robj_ass_item, /* sq_ass_item */
1571
0, /* sq_ass_slice */
1572
0, /* sq_contains */
1573
0, /* sq_inplace_concat */
1574
0 /* sq_inplace_repeat */
1578
/* The 'Robj' table. When compiled under Python 2.2, the type 'Robj'
1583
Robj_getattr(RobjObject *self, char *name)
1585
return Py_FindMethod(Robj_methods, (PyObject *)self, name);
1589
PyTypeObject Robj_Type = {
1590
/* The ob_type field must be initialized in the module init function
1591
* to be portable to Windows without using C++. */
1592
#if defined(PRE_2_2) || defined(_WIN32) // Matjaz
1593
PyObject_HEAD_INIT(NULL)
1595
PyObject_HEAD_INIT(&PyType_Type)
1599
sizeof(RobjObject), /*tp_basicsize*/
1602
(destructor)Robj_dealloc, /*tp_dealloc*/
1605
(getattrfunc)Robj_getattr,
1613
&Robj_as_sequence, /*tp_as_sequence*/
1614
0, /*tp_as_mapping*/
1616
(ternaryfunc)Robj_call, /*tp_call*/
1618
#if defined(PRE_2_2) || defined(_WIN32)
1621
PyObject_GenericGetAttr, /*tp_getattro*/
1628
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
1634
0, /*tp_richcompare*/
1635
0, /*tp_weaklistoffset*/
1638
Robj_methods, /*tp_methods*/
1645
0, /*tp_dictoffset*/
1650
PyType_GenericAlloc, /*tp_alloc*/
1652
Robj_tpnew, /*tp_new*/
1659
/* Module functions */
1661
/* Obtain an R object via its name. 'autoconvert' is the keyword to
1662
set the autoconversion flag. */
1664
get_fun(PyObject *self, PyObject *args, PyObject *kwds)
1667
int conversion=TOP_MODE;
1670
static char *kwlist[] = {"name", "autoconvert", 0};
1671
if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|i:get", kwlist,
1672
&obj_str, &conversion))
1675
robj = get_fun_from_name(obj_str);
1679
return (PyObject *)Robj_new(robj, conversion);
1683
set_mode(PyObject *self, PyObject *args)
1687
if (!PyArg_ParseTuple(args, "i:set_mode", &i))
1690
if (i<-1 || i>TOP_MODE) {
1691
PyErr_SetString(PyExc_ValueError, "wrong mode");
1701
get_mode(PyObject *self, PyObject *args)
1703
if (!PyArg_ParseTuple(args, ":get_mode"))
1706
return PyInt_FromLong(default_mode);
1710
r_events(PyObject *self, PyObject *args, PyObject *kwds)
1720
static char *kwlist[] = {"usec", 0};
1721
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:r_events",
1726
Py_BEGIN_ALLOW_THREADS
1727
what = R_checkActivity(usec, 0);
1728
R_runHandlers(R_InputHandlers, what);
1729
Py_END_ALLOW_THREADS
1746
r_lock = PyDict_GetItemString(rpy_dict, "_r_lock");
1748
o = PyObject_CallMethod(r_lock, "acquire", NULL);
1761
r_lock = PyDict_GetItemString(rpy_dict, "_r_lock");
1763
o = PyObject_CallMethod(r_lock, "release", NULL);
1769
* Based on code from Rstd_CleanUp();
1770
* from src/unix/sys-std.c
1773
void r_finalize(void)
1775
#if (R_VERSION < R_Version(2,4,0))
1776
unsigned char buf[1024];
1781
R_RunExitFinalizers();
1783
#if (R_VERSION >= R_Version(2,7,0))
1784
Rf_KillAllDevices();
1789
#if (R_VERSION >= R_Version(2,4,0))
1792
if((tmpdir = getenv("R_SESSION_TMPDIR"))) {
1795
snprintf((char *)buf, 1024, "rmdir /S /Q %s", tmpdir);
1797
snprintf((char *)buf, 1024, "rm -rf %s", tmpdir);
1800
R_system((char *)buf);
1804
PrintWarnings(); /* from device close and .Last */
1805
R_gc(); /* Remove any remaining R objects from memory */
1821
PyObject *multiarray, *dict;
1826
multiarray = PyImport_ImportModule(PY_ARRAY_MODULE_NAME);
1828
dict = PyModule_GetDict(multiarray);
1830
Py_transpose = PyDict_GetItemString(dict, "transpose");
1837
r_init(PyObject *self, PyObject *args)
1842
if (!PyArg_ParseTuple(args, "i:r_init", &i))
1859
PyErr_SetString(PyExc_RuntimeError, "Only one R object may be instantiated per session");
1864
/* List of functions defined in the module */
1865
static PyMethodDef rpy_methods[] = {
1866
{"get_fun", (PyCFunction)get_fun, METH_VARARGS | METH_KEYWORDS},
1867
{"set_mode", (PyCFunction)set_mode, METH_VARARGS},
1868
{"get_mode", (PyCFunction)get_mode, METH_VARARGS},
1869
{"set_output", (PyCFunction)set_output, METH_VARARGS},
1870
{"set_input", (PyCFunction)set_input, METH_VARARGS},
1871
{"set_showfiles", (PyCFunction)set_showfiles, METH_VARARGS},
1872
{"get_output", (PyCFunction)get_output, METH_VARARGS},
1873
{"get_input", (PyCFunction)get_input, METH_VARARGS},
1874
{"get_showfiles", (PyCFunction)get_showfiles, METH_VARARGS},
1875
{"r_events", (PyCFunction)r_events, METH_VARARGS | METH_KEYWORDS},
1876
{"r_cleanup", (PyCFunction)r_cleanup, METH_NOARGS},
1877
{"r_init", (PyCFunction)r_init, METH_VARARGS},
1878
{NULL, NULL} /* sentinel */
1882
static void char_message( char *s )
1885
R_WriteConsole(s, strlen(s));
1888
static int char_yesnocancel( char *s )
1894
RPyBusy( int which )
1896
/* set a busy cursor ... in which = 1, unset if which = 0 */
1900
RPyDoNothing( void )
1904
/* initialise embedded R; based on rproxy_impl.c from the R distribution */
1906
init_embedded_win32(int argc,
1915
snprintf( Rversion, 25, "%s.%s", R_MAJOR, R_MINOR );
1916
if( strcmp( getDLLVersion(), Rversion ) != 0 ) {
1917
PyErr_SetString( PyExc_ImportError, "R.DLL version does not match" );
1926
index = strlen(RUSER) - 1;
1928
if (RUSER[index] == '/' || RUSER[index] == '\\')
1929
RUSER[index] = '\0';
1932
Rp->CharacterMode = LinkDLL;
1934
Rp->ReadConsole = (blah1) RPy_ReadConsole; // Matjaz
1935
Rp->WriteConsole = (blah2) RPy_WriteConsole; // Matjaz
1937
Rp->CallBack = (blah3) RPyDoNothing;
1938
#if R_VERSION < 0x20100
1939
Rp->message = char_message;
1940
Rp->yesnocancel = char_yesnocancel;
1943
Rp->ShowMessage = char_message;
1944
Rp->YesNoCancel = char_yesnocancel;
1950
/* run as "interactive", so server won't be killed after an error */
1951
Rp->R_Slave = Rp->R_Verbose = 0;
1952
Rp->R_Interactive = TRUE;
1953
Rp->RestoreAction = SA_NORESTORE; /* no restore */
1954
Rp->SaveAction = SA_NOSAVE; /* no save */
1956
#if R_VERSION < 0x20000 // pre-R-2.0.0
1958
Rp->CommandLineArgs = NULL;
1959
Rp->NumCommandLineArgs = 0;
1961
R_set_command_line_arguments(argc, argv);
1963
R_SetParams(Rp); /* so R_ShowMessage is set */
1973
/* Initialization function for the module */
1978
PyOS_sighandler_t old_int;
1980
PyOS_sighandler_t old_usr1, old_usr2;
1984
/* Get path and version information from environment */
1985
strncpy(RHOME, getenv("RPY_RHOME"), BUFSIZ);
1986
strncpy(RVERSION, getenv("RPY_RVERSION"), BUFSIZ);
1987
strncpy(RVER, getenv("RPY_RVER"), BUFSIZ);
1988
strncpy(RUSER, getenv("RPY_RUSER"), BUFSIZ);
1990
if( !strlen(RHOME) || !strlen(RVERSION) || !strlen(RVER) || !strlen(RUSER))
1992
PyErr_Format(RPy_Exception,
1993
"Unable to load R path or version information");
1997
Robj_Type.ob_type = &PyType_Type;
1998
#if defined( _WIN32 ) && ! defined( PRE_2_2 )
1999
Robj_Type.tp_getattro = PyObject_GenericGetAttr;
2000
Robj_Type.tp_alloc = PyType_GenericAlloc;
2003
/* Initialize the module with its content */
2004
if (PyType_Ready(&Robj_Type) < 0)
2006
m = Py_InitModule3(xstr(RPY_SHNAME),
2008
"Python interface to the R Programming Language");
2009
Py_INCREF(&Robj_Type);
2010
PyModule_AddObject(m, Robj_Type.tp_name,
2011
(PyObject *)&Robj_Type);
2013
d = PyModule_GetDict(m);
2015
/* Save this interpreter */
2016
PyEval_InitThreads();
2017
my_interp = PyThreadState_Get()->interp;
2019
/* Save the Python signal handlers. If R inserts its handlers, we
2020
cannot return to the Python interpreter. */
2021
old_int = PyOS_getsig(SIGINT);
2022
python_sigint = old_int;
2024
old_usr1 = PyOS_getsig(SIGUSR1);
2025
old_usr2 = PyOS_getsig(SIGUSR2);
2029
init_embedded_win32(defaultargc,
2032
Rf_initEmbeddedR(defaultargc,
2038
/* Disable C stack checking, which is incompatible with use as a
2040
R_CStackLimit = (uintptr_t)-1;
2043
/* Restore Python handlers */
2044
PyOS_setsig(SIGINT, old_int);
2046
PyOS_setsig(SIGUSR1, old_usr1);
2047
PyOS_setsig(SIGUSR2, old_usr2);
2050
/* Several new exceptions: */
2051
RPy_Exception = PyErr_NewException("rpy.RPy_Exception", NULL, NULL);
2052
RPy_TypeConversionException = PyErr_NewException("rpy.RPy_TypeConversionException", RPy_Exception, NULL);
2053
RPy_RException = PyErr_NewException("rpy.RPy_RException", RPy_Exception, NULL);
2055
if (!RPy_Exception || !RPy_TypeConversionException || !RPy_RException )
2057
PyErr_Format(RPy_Exception, "Unable create RPy exceptions");
2061
PyDict_SetItemString(d, "RPy_Exception", RPy_Exception);
2062
PyDict_SetItemString(d, "RPy_TypeConversionException", RPy_TypeConversionException);
2063
PyDict_SetItemString(d, "RPy_RException", RPy_RException);
2065
// The conversion table
2066
class_table = PyDict_New();
2067
proc_table = PyDict_New();
2068
PyDict_SetItemString(d, "__class_table__", class_table);
2069
PyDict_SetItemString(d, "__proc_table__", proc_table);
2071
// The globals R objects for the sequence protocol
2072
get_item = get_fun_from_name("[");
2073
set_item = get_fun_from_name("[<-");
2074
length = get_fun_from_name("length");
2076
// Function to transpose arrays
2077
aperm = get_fun_from_name("aperm");
2079
// Initialize the list of protected objects
2080
R_References = R_NilValue;
2081
SET_SYMVALUE(install("R.References"), R_References);
2083
// Initialize the default mode
2086
// Check whether R is interactive or no
2087
interact = do_eval_fun("interactive");
2088
R_interact = INTEGER(interact)[0];
2093
rpy = PyImport_ImportModule("rpy");
2094
rpy_dict = PyModule_GetDict(rpy);
2095
// r_lock = PyDict_GetItemString(rpy_dict, "_r_lock");
2096
// PyObject_Print(r_lock, stderr, Py_PRINT_RAW);
2099
if( Py_AtExit( r_finalize ) )
2101
fprintf(stderr, "Warning: Unable to set R finalizer.");