On Mon, Jan 26, 2009 at 3:22 AM, Laurent Gautier <lgaut...@gmail.com> wrote:
> Nathaniel Smith wrote:
>>
>> There are a number of callbacks in rinterface that one can set to
>> control R's console -- setWriteConsole, setReadConsole, etc. This
>> patch fixes to limitations with the current API:
>
> Thanks.
> Can you sent it again ? The patch seems to have gotten eaten on the way.
Sigh. Sorry, here you go.
> Indeed. I agree.
> I have been also considering putting all callbacks as attributes of a
> structure (since there are more callbacks in the dev version). Now I see
> that this could also solve the issue you are describing.
True, that might be a prettier solution. It might be more tiresome to
code up at the C level, but then I find writing against the Python/C
api directly impossibly tiresome to start with ("once you Pyrex you
never go back"), so my impression isn't worth much :-).
> It is set to NULL at the C-level to cut corners (limited development time),
> and getting back to NULL should not be done (it might end in a segfault).
> The Python-level __init__.py in rinterface is immediately setting a value.
The code I saw checked seemed to correctly check for NULL, but okay.
> It should build. Is that a checkout from the tip at bitbucket ?
> What platform are you on (OS, R version, Python version).
Yes, from the tip, on Debian stable x86-64 with packaged python 2.5
and own-built R 2.8.0. The curious thing is that it builds correctly,
and ldd says that it is linked to libR.so, but when imported it has
symbols it can't find.
-- Nathaniel
diff -r b08b47242d73 rpy/rinterface/rinterface.c
--- a/rpy/rinterface/rinterface.c Sat Jan 24 15:14:10 2009 +0100
+++ b/rpy/rinterface/rinterface.c Mon Jan 26 01:38:36 2009 -0800
@@ -176,14 +176,18 @@
if ( PyArg_ParseTuple(args, "O:console",
&function)) {
- if (!PyCallable_Check(function)) {
+ if (function != Py_None && !PyCallable_Check(function)) {
PyErr_SetString(PyExc_TypeError, "parameter must be callable");
return NULL;
}
Py_XDECREF(*target);
- Py_XINCREF(function);
- *target = function;
+ if (function == Py_None) {
+ *target = NULL;
+ } else {
+ Py_XINCREF(function);
+ *target = function;
+ }
Py_INCREF(Py_None);
result = Py_None;
} else {
@@ -193,6 +197,23 @@
}
+static inline PyObject* EmbeddedR_getAnyCallback(PyObject *self,
+ PyObject *args,
+ PyObject *target)
+{
+ PyObject *result = NULL;
+
+ if (PyArg_ParseTuple(args, "")) {
+ if (target == NULL)
+ result = NULL;
+ else
+ result = target;
+ Py_INCREF(result);
+ }
+ return result;
+}
+
+
static PyObject* writeConsoleCallback = NULL;
static PyObject* EmbeddedR_setWriteConsole(PyObject *self,
@@ -203,8 +224,18 @@
PyDoc_STRVAR(EmbeddedR_setWriteConsole_doc,
"Set how to handle output from the R console.\n\n"
- ":param f: callback function such as"
- "None <- f(output)\n");
+ ":param f: callback function such as"
+ "None <- f(output), or None.\n");
+
+static PyObject * EmbeddedR_getWriteConsole(PyObject *self,
+ PyObject *args)
+{
+ return EmbeddedR_getAnyCallback(self, args, writeConsoleCallback);
+}
+
+PyDoc_STRVAR(EmbeddedR_getWriteConsole_doc,
+ "Retrieve current R console output handler (see setWriteConsole).");
+
static void
@@ -250,6 +281,15 @@
PyDoc_STRVAR(EmbeddedR_setShowMessage_doc,
"Use the function to handle R's alert messages.");
+
+static PyObject * EmbeddedR_getShowMessage(PyObject *self,
+ PyObject *args)
+{
+ return EmbeddedR_getAnyCallback(self, args, showMessageCallback);
+}
+
+PyDoc_STRVAR(EmbeddedR_getShowMessage_doc,
+ "Retrieve current R console output handler (see setShowMessage).");
static void
EmbeddedR_ShowMessage(const char *buf)
@@ -299,6 +339,14 @@
":param f: a callback function such as "
"result <- f(prompt) \n");
+static PyObject * EmbeddedR_getReadConsole(PyObject *self,
+ PyObject *args)
+{
+ return EmbeddedR_getAnyCallback(self, args, readConsoleCallback);
+}
+
+PyDoc_STRVAR(EmbeddedR_getReadConsole_doc,
+ "Retrieve current R console output handler (see setReadConsole).");
static int
EmbeddedR_ReadConsole(const char *prompt, unsigned char *buf,
@@ -363,9 +411,18 @@
}
PyDoc_STRVAR(EmbeddedR_setFlushConsole_doc,
- "Set the behavior for ensuring that the console buffer is flushed.\n\n"
- ":param f: callback function such as "
- "None <- f()\n");
+ "Set the behavior for ensuring that the console buffer is flushed.\n\n"
+ ":param f: callback function such as "
+ "None <- f()\n");
+
+static PyObject * EmbeddedR_getFlushConsole(PyObject *self,
+ PyObject *args)
+{
+ return EmbeddedR_getAnyCallback(self, args, flushConsoleCallback);
+}
+
+PyDoc_STRVAR(EmbeddedR_getFlushConsole_doc,
+ "Retrieve current R console output handler (see setFlushConsole).");
static void
EmbeddedR_FlushConsole(void)
@@ -390,6 +447,14 @@
PyDoc_STRVAR(EmbeddedR_setChooseFile_doc,
"Use the function to handle R's requests for choosing a file.");
+static PyObject * EmbeddedR_getChooseFile(PyObject *self,
+ PyObject *args)
+{
+ return EmbeddedR_getAnyCallback(self, args, chooseFileCallback);
+}
+
+PyDoc_STRVAR(EmbeddedR_getChooseFile_doc,
+ "Retrieve current R console output handler (see setChooseFile).");
static int
EmbeddedR_ChooseFile(int new, char *buf, int len)
@@ -443,6 +508,14 @@
PyDoc_STRVAR(EmbeddedR_setShowFiles_doc,
"Use the function to display files.");
+static PyObject * EmbeddedR_getShowFiles(PyObject *self,
+ PyObject *args)
+{
+ return EmbeddedR_getAnyCallback(self, args, showFilesCallback);
+}
+
+PyDoc_STRVAR(EmbeddedR_getShowFiles_doc,
+ "Retrieve current R console output handler (see setShowFiles).");
static int
EmbeddedR_ShowFiles(int nfile, const char **file, const char **title,
@@ -2777,17 +2850,29 @@
EmbeddedR_end_doc},
{"setWriteConsole", (PyCFunction)EmbeddedR_setWriteConsole, METH_VARARGS,
EmbeddedR_setWriteConsole_doc},
- {"setReadConsole", (PyCFunction)EmbeddedR_setReadConsole, METH_VARARGS,
+ {"getWriteConsole", (PyCFunction)EmbeddedR_getWriteConsole, METH_VARARGS,
+ EmbeddedR_getWriteConsole_doc},
+ {"setReadConsole", (PyCFunction)EmbeddedR_setReadConsole, METH_VARARGS,
EmbeddedR_setReadConsole_doc},
- {"setFlushConsole", (PyCFunction)EmbeddedR_setFlushConsole, METH_VARARGS,
+ {"getReadConsole", (PyCFunction)EmbeddedR_getReadConsole, METH_VARARGS,
+ EmbeddedR_getReadConsole_doc},
+ {"setFlushConsole", (PyCFunction)EmbeddedR_setFlushConsole, METH_VARARGS,
EmbeddedR_setFlushConsole_doc},
- {"setShowMessage", (PyCFunction)EmbeddedR_setShowMessage, METH_VARARGS,
+ {"getFlushConsole", (PyCFunction)EmbeddedR_getFlushConsole, METH_VARARGS,
+ EmbeddedR_getFlushConsole_doc},
+ {"setShowMessage", (PyCFunction)EmbeddedR_setShowMessage, METH_VARARGS,
EmbeddedR_setShowMessage_doc},
- {"setChooseFile", (PyCFunction)EmbeddedR_setChooseFile, METH_VARARGS,
+ {"getShowMessage", (PyCFunction)EmbeddedR_getShowMessage, METH_VARARGS,
+ EmbeddedR_getShowMessage_doc},
+ {"setChooseFile", (PyCFunction)EmbeddedR_setChooseFile, METH_VARARGS,
EmbeddedR_setChooseFile_doc},
- {"setShowFiles", (PyCFunction)EmbeddedR_setShowFiles, METH_VARARGS,
+ {"getChooseFile", (PyCFunction)EmbeddedR_getChooseFile, METH_VARARGS,
+ EmbeddedR_getChooseFile_doc},
+ {"setShowFiles", (PyCFunction)EmbeddedR_setShowFiles, METH_VARARGS,
EmbeddedR_setShowFiles_doc},
- {"findVarEmbeddedR", (PyCFunction)EmbeddedR_findVar, METH_VARARGS,
+ {"getShowFiles", (PyCFunction)EmbeddedR_getShowFiles, METH_VARARGS,
+ EmbeddedR_getShowFiles_doc},
+ {"findVarEmbeddedR", (PyCFunction)EmbeddedR_findVar, METH_VARARGS,
EmbeddedR_findVar_doc},
{"process_revents", (PyCFunction)EmbeddedR_ProcessEvents, METH_NOARGS,
EmbeddedR_ProcessEvents_doc},
diff -r b08b47242d73 rpy/rinterface/tests/test_EmbeddedR.py
--- a/rpy/rinterface/tests/test_EmbeddedR.py Sat Jan 24 15:14:10 2009 +0100
+++ b/rpy/rinterface/tests/test_EmbeddedR.py Mon Jan 26 01:38:36 2009 -0800
@@ -12,6 +12,7 @@
buf.append(x)
rinterface.setWriteConsole(f)
+ self.assertEquals(rinterface.getWriteConsole(), f)
code = rinterface.SexpVector(["3", ], rinterface.STRSXP)
rinterface.baseNameSpaceEnv["print"](code)
self.assertEquals('[1] "3"\n', str.join('', buf))
@@ -23,6 +24,7 @@
flush['count'] = flush['count'] + 1
rinterface.setFlushConsole(f)
+ self.assertEquals(rinterface.getFlushConsole(), f)
rinterface.baseNameSpaceEnv.get("flush.console")()
self.assertEquals(1, flush['count'])
rinterface.setWriteConsole(rinterface.consoleFlush)
@@ -32,6 +34,7 @@
def sayyes(prompt):
return yes
rinterface.setReadConsole(sayyes)
+ self.assertEquals(rinterface.getReadConsole(), sayyes)
res = rinterface.baseNameSpaceEnv["readline"]()
self.assertEquals(yes.strip(), res[0])
rinterface.setReadConsole(rinterface.consoleRead)
@@ -44,6 +47,7 @@
def chooseMe(prompt):
return me
rinterface.setChooseFile(chooseMe)
+ self.assertEquals(rinterface.getChooseFile(), chooseMe)
res = rinterface.baseNameSpaceEnv["file.choose"]()
self.assertEquals(me, res[0])
rinterface.setChooseFile(rinterface.chooseFile)
------------------------------------------------------------------------------
This SF.net email is sponsored by:
SourcForge Community
SourceForge wants to tell your story.
http://p.sf.net/sfu/sf-spreadtheword
_______________________________________________
rpy-list mailing list
rpy-list@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/rpy-list