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

Reply via email to