I would like to encapsulate the expressions to be evaluated in Python function & compile that function at runtime, somewhat as below.
Expression to eval put in Python function
def isSizeSmall(size,vol,ADV,prod):
if ( (size < 1000) & (vol < (0.001 * ADV)) & (prod=="Stock")): print "OK"; return 10
else: print "NOK"; return 11
Then, I want to evaluate the PyObject returned by Py_CompileString multiple times in my program using the user input as the variables to the above function.
This I tried using two different approaches - 1) PyEval_evalCode, & 2) PyObject_CallObject.
1) When using PyEval_evalCode: The function call to PyEval_evalCode was ok, but it did not return any output.
2) Whereas, when I used this object with PyObject_CallObject, it failed with error as given below.
Any help will be great. Many thanks in advance for your help.
Warm Regards,
Ganesh
//***********************************************//
Output of my test program:
Expression to eval =
"def isSizeSmall(size,vol,ADV,prod):
if ( (size < 1000) & (vol < (0.001 * ADV)) & (prod=="Stock")): print "OK"; return 10
else: print "NOK"; return 11"
str compiled fine with stdin & Py_file_input, calling PyEval_EvalCode
None ok [0] size [-1]
str compiled fine with stdin & Py_file_input, calling PyFunction_New & then PyObject_CallObject
Getting PyFunction_New
Calling PyObject_CallObject
func is callable
TypeError: ?() takes no arguments (4 given)
My test program having both above approaches is as below:
Expand|Select|Wrap|Line Numbers
- main(int argc, char **argv)
- {
- /* Pass argv[0] to the Python interpreter */
- Py_SetProgramName(argv[0]);
- /* Initialize the Python interpreter. Required. */
- Py_Initialize();
- PyRun_SimpleString("import sys\n");
- char szExpr[2048];
- memset(szExpr,'\0',sizeof(szExpr));
- sprintf(szExpr,"def isSizeSmall(size,vol,ADV,prod):\n if ( (size < 1000) & (vol < (0.001 * ADV)) & (prod==\"Stock\")): print \"OK\"; return 10\n else: print \"NOK\"; return 11\n\n\n");
- printf("Expression to eval = \n[%s]\n",szExpr);
- OrderValues ordval;
- ordval.size = 100;
- ordval.ADV = 100000;
- ordval.vol = 1000;
- memset(ordval.prod,'\0',sizeof(ordval.prod));
- sprintf(ordval.prod,"Stock");
- PyObject *glb, *loc;
- glb = PyDict_New();
- PyDict_SetItemString(glb, "__builtins__", PyEval_GetBuiltins());
- loc = PyDict_New();
- PyObject* tuple = PyTuple_New(4);
- PyObject* val = 0;
- val = PyInt_FromLong(ordval.size);
- PyTuple_SetItem(tuple,0,val);
- PyDict_SetItemString(loc,"size",val);
- val = PyInt_FromLong(ordval.vol);
- PyTuple_SetItem(tuple,1,val);
- PyDict_SetItemString(loc,"vol",val);
- val = PyInt_FromLong(ordval.ADV);
- PyTuple_SetItem(tuple,2,val);
- PyDict_SetItemString(loc,"ADV",val);
- val = PyString_FromString(ordval.prod);
- PyTuple_SetItem(tuple,3,val);
- PyDict_SetItemString(loc,"prod",val);
- /*** with string & Py_file_input ***/
- PyObject* result = NULL;
- result = Py_CompileString(szExpr,"<string>", Py_file_input);
- if(result!=NULL && !PyErr_Occurred()){
- printf("str compiled fine with stdin & Py_file_input, calling PyEval_EvalCode\n");
- PyCodeObject *pyCo = (PyCodeObject *)result;
- PyObject* evalret = NULL;
- evalret = PyEval_EvalCode(pyCo,glb,loc);
- if(!evalret || PyErr_Occurred())
- PyErr_Print();
- else
- printf("ok [%d] size [%d]\n",PyObject_Print(evalret,stdout,0),PyObject_Size(evalret));
- // Try to get function obj of this...
- printf("Getting PyFunction_New\n");
- PyObject* func = PyFunction_New(result,glb);
- if(!func || PyErr_Occurred()){
- printf("Failed to get Function..\n");
- PyErr_Print();
- } else {
- printf("Calling PyObject_CallObject\n");
- if(PyCallable_Check(func))
- printf("func is callable\n");
- PyObject* ret = PyObject_CallObject(func, tuple);
- //PyObject* ret = PyObject_CallObject(func, NULL);
- if(!ret || PyErr_Occurred())
- PyErr_Print();
- else
- printf("PyObject_CallObject evaluated..\n");
- }
- } else {
- printf("Py_CompileString-1 returned NULL\n");
- PyErr_Print();
- }
- exit(100);
- }