Commit 67a65352 authored by cyrush's avatar cyrush

added optional 'args' argument to the PythonQuery() cli method, a flexible way...

added optional 'args' argument to the PythonQuery() cli method, a flexible way to pass arguments into a python query filter. This fixes #193

git-svn-id: http://visit.ilight.com/svn/visit/trunk/src@11850 18c085ea-50e0-402c-830e-de6fd14e8384
parent 5cc2a39e
......@@ -49,8 +49,15 @@
using namespace std;
// static vars
PythonInterpreter *avtPythonFilterEnvironment::pyi=NULL;
// (pickle related)
bool avtPythonFilterEnvironment::pickleReady=false;
PyObject *avtPythonFilterEnvironment::pickleDumps=NULL;
PyObject *avtPythonFilterEnvironment::pickleLoads=NULL;
// ****************************************************************************
// Method: avtPythonFilterEnvironment constructor
//
......@@ -317,3 +324,95 @@ avtPythonFilterEnvironment::FetchPythonError(string &msg_out)
}
return res;
}
// ****************************************************************************
// Method: avtPythonScriptExpression::Pickle
//
// Purpose:
// Pickles a python object to a string.
//
// Programmer: Cyrus Harrison
// Creation: Fri Jul 9 13:54:40 PDT 2010
//
// ****************************************************************************
std::string
avtPythonFilterEnvironment::Pickle(PyObject *py_obj)
{
if(!pickleReady)
PickleInit();
PyObject *res_obj = PyObject_CallFunctionObjArgs(pickleDumps,py_obj,NULL);
if(res_obj == NULL)
{
debug5 << "avtPythonFilterEnvironment::Pickle Error - "
<< "could not pickle object." << endl;
return std::string("");
}
char *res_cstr = PyString_AS_STRING(res_obj);
std::string res(res_cstr);
Py_DECREF(res_obj);
return res;
}
// ****************************************************************************
// Method: avtPythonScriptExpression::Unpickle
//
// Purpose:
// Unpickles a python object from a string.
//
// Programmer: Cyrus Harrison
// Creation: Fri Jul 9 13:54:40 PDT 2010
//
// ****************************************************************************
PyObject *
avtPythonFilterEnvironment::Unpickle(const std::string &s)
{
PyObject *res = NULL;
if(!pickleReady)
PickleInit();
PyObject *py_str_obj = PyString_FromString(s.c_str());
res = PyObject_CallFunctionObjArgs(pickleLoads,py_str_obj,NULL);
if(res == NULL)
{
debug5 << "avtPythonFilterEnvironment::Pickle Error - "
<< "could not unpickle given string." << endl;
}
Py_DECREF(py_str_obj);
return res;
}
// ****************************************************************************
// Method: avtPythonScriptExpression::PickleInit
//
// Purpose:
// Loads the pickle module for use with Pickle() & Unpickle()
//
// Programmer: Cyrus Harrison
// Creation: Fri Jul 9 13:54:40 PDT 2010
//
// ****************************************************************************
void
avtPythonFilterEnvironment::PickleInit()
{
if(!pickleReady)
{
PyObject *pickleModule = PyImport_ImportModule("pickle"); // new ref
PyObject *pickleDict = PyModule_GetDict(pickleModule); // borrowed
pickleDumps = PyDict_GetItemString(pickleDict, "dumps"); // borrowed
pickleLoads = PyDict_GetItemString(pickleDict, "loads"); // borrowed
Py_INCREF(pickleDumps);
Py_INCREF(pickleLoads);
Py_DECREF(pickleModule);
pickleReady = true;
}
}
......@@ -60,6 +60,9 @@
// Use a singleton instance of the interpreter b/c python setup & teardown
// does not work reliably w/ c modules that use static vars.
//
// Cyrus Harrison,
// Added pickle support.
//
// ****************************************************************************
class AVTPYTHON_FILTERS_API avtPythonFilterEnvironment
{
......@@ -71,6 +74,9 @@ public:
bool LoadFilter(const std::string &py_script);
bool FetchPythonError(std::string &msg_out);
std::string Pickle(PyObject *py_obj);
PyObject *Unpickle(const std::string &s);
PyObject *WrapVTKObject(void *obj,
const std::string &obj_type);
......@@ -81,9 +87,17 @@ public:
avtPythonFilter *Filter() { return pyFilter;}
private:
static void PickleInit();
static PythonInterpreter *pyi;
static bool pickleReady;
static PyObject *pickleLoads;
static PyObject *pickleDumps;
avtPythonFilter *pyFilter;
};
......
......@@ -364,7 +364,7 @@ avtPythonQuery::UpdateContract()
if(py_exe == NULL)
PYQUERY_ERROR("avtPythonQuery::UpdateContract Error - "
"Error preparing for call of 'modify_contract' method.");
// call with py_dsets, py_domids
PyObject *py_exe_res = PyObject_CallMethodObjArgs(py_filter,
py_exe,
......@@ -410,6 +410,17 @@ avtPythonQuery::UpdateContract()
"'input_var_names' list.");
}
// get any other args
std::string args_str = varNames[varNames.size()-1];
if(args_str != "")
{
PyObject *py_args = pyEnv->Unpickle(args_str);
if(!pyEnv->Filter()->SetAttribute("arguments",py_args))
PYQUERY_ERROR("avtPythonQuery::UpdateContract Error - "
"Unable to set Python Query 'arguments' attribute.");
Py_DECREF(py_args);
}
// set "float_format"
if(!pyEnv->Filter()->SetAttribute("float_format",queryAtts.GetFloatFormat()))
PYQUERY_ERROR("avtPythonQuery::UpdateContract Error - "
......
......@@ -450,6 +450,11 @@ typedef struct
static std::map<std::string, AnnotationObjectRef> localObjectMap;
// pickle related
bool pickleReady=false;
PyObject *pickleDumps=NULL;
PyObject *pickleLoads=NULL;
#ifdef THREADS
#if defined(_WIN32)
static CRITICAL_SECTION mutex;
......@@ -895,6 +900,35 @@ GetDoubleArrayFromPyObject(PyObject *obj, double *array, int maxLen)
return retval;
}
// ****************************************************************************
// Method: PickleInit
//
// Purpose:
// Sets up pointer to pickle.dumps & pickle.loads methods.
//
//
// Programmer: Cyrus Harrison
// Creation: Fri Jul 9 14:27:52 PDT 2010
//
// Modifications:
//
// ****************************************************************************
void PickleInit()
{
if(!pickleReady)
{
PyObject *pickleModule = PyImport_ImportModule("pickle"); // new ref
PyObject *pickleDict = PyModule_GetDict(pickleModule); // borrowed
pickleDumps = PyDict_GetItemString(pickleDict, "dumps"); // borrowed
pickleLoads = PyDict_GetItemString(pickleDict, "loads"); // borrowed
Py_INCREF(pickleDumps);
Py_INCREF(pickleLoads );
Py_DECREF(pickleModule);
pickleReady = true;
}
}
// ****************************************************************************
// Method: FillDBOptionsFromDictionary
......@@ -10642,6 +10676,8 @@ visit_Query(PyObject *self, PyObject *args)
// Creation: Wed Mar 17 11:07:35 PDT 2010
//
// Modifications:
// Cyrus Harrison, Fri Jul 9 11:49:44 PDT 2010
// Support passing of arbitary arguments via "args" keyword.
//
// ****************************************************************************
......@@ -10653,16 +10689,19 @@ visit_PythonQuery(PyObject *self, PyObject *args, PyObject *kwargs)
char *source_text = NULL;
char *source_file = NULL;
PyObject *py_vars_tuple = NULL;
PyObject *py_args = NULL;
static char *kwlist[] = {"source", "file", "vars",NULL};
static char *kwlist[] = {"source", "file", "vars","args",NULL};
// keyword arguments
// source: string containg the python filter source
// file: string containing the location of a script file
// vars: tuple containing variable names
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ssO", kwlist,
&source_text, &source_file, &py_vars_tuple))
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ssOO", kwlist,
&source_text, &source_file,
&py_vars_tuple,
&py_args))
return NULL;
stringVector vars;
......@@ -10672,6 +10711,27 @@ visit_PythonQuery(PyObject *self, PyObject *args, PyObject *kwargs)
GetStringVectorFromPyObject(py_vars_tuple, vars);
}
if(py_args != NULL)
{
debug5 << "Using passed 'args' as Python Query arguments" << endl;
if(!pickleReady)
PickleInit();
PyObject *res = PyObject_CallFunctionObjArgs(pickleDumps,py_args,NULL);
if(res == NULL)
{
PyErr_SetString(VisItError,
"PythonQuery: Failed to pickle passed 'args' value.");
return NULL;
}
char *res_str = PyString_AS_STRING(res);
vars.push_back(res_str);
}
else
{
// if there were no args, use blank string as a place holder.
vars.push_back("");
}
if(source_text != NULL)
{
debug5 << "Using passed source text as Python Query script" << endl;
......
......@@ -2,12 +2,14 @@
# Python Module: filters
#
# Purpose: Base classes for embedded python filters.
#
#
# Programmer: Cyrus Harrison
# Creation: Thu Mar 5 09:25:47 PST 2009
#
#
# Modifications:
# Cyrus Harrison, Fri Jul 9 14:25:32 PDT 2010
# Added 'arguments' member to python query base class.
#
###############################################################################
......@@ -126,6 +128,7 @@ class PythonQuery(PythonFilter):
self.result_obj = None
self.float_format = "%g"
self.input_var_names = []
self.arguments = []
def pre_execute(self):
"""
Called before streamining execute of all chunks.
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment