Hi Andi,

Please find attached the patch that adds the eval to JCC.

It uses PyRun_SimpleString which returns 0 or -1, I have verified it
works, on errors it returns -1, unless one sends "raise
SystemException()" -- then it tears down all VMs

For better reporting I'd have to use
http://docs.python.org/c-api/veryhigh.html#PyRun_String

Could you give me some pointers on how to obtain  *globals *locals
parameters? I can modify the patch to use PyRun_String (it would be
nice to have the exceptions -- i think that exceptions will be
reported automatically when the native method is declared as throwing
them)

something like...?

PyObject *module = PyImport_ImportModule("__builtin__");
PyObject *globalFunction = PyObject_GetAttrString(module, "globals");
PyObject *globals = *PyObject_CallFunction(globalFunction, NULL);


Thanks,

  Roman



On Mon, Nov 14, 2011 at 6:12 PM, Andi Vajda <va...@apache.org> wrote:
>
>  Hi Roman,
>
> On Mon, 14 Nov 2011, Roman Chyla wrote:
>
>> so after reading
>> http://docs.python.org/c-api/init.html#PySys_SetArgvEx and the source
>> code for _PythonVM_init i figured it out
>>
>> I have to do:
>>
>> PythonVM.start("/dvt/workspace/montysolr/src/python/montysolr");
>>
>> and the sys.path then contains the parent folder (above montysolr) and
>> i can then set more things by loading some boostrap module
>>
>> but something like
>> http://docs.python.org/c-api/veryhigh.html#PyRun_SimpleString would be
>> much more flexible. Is it something that could be added? I can prepare
>> a patch (as it seems really trivial my knowledge might be sufficient
>> for this :))
>
> Yes, adding an 'eval' method on PythonVM, like the 'instantiate' method,
> would make sense. A patch is welcome !
>
> Andi..
>
>>
>> roman
>>
>> On Mon, Nov 14, 2011 at 1:12 PM, Roman Chyla <roman.ch...@gmail.com>
>> wrote:
>>>
>>> On Mon, Nov 14, 2011 at 4:25 AM, Andi Vajda <va...@apache.org> wrote:
>>>>
>>>> On Sun, 13 Nov 2011, Roman Chyla wrote:
>>>>
>>>>> I am using JCC to run Python inside Java. For unittest, I'd like to
>>>>> set PYTHONPATH environment variable programmatically. I can change env
>>>>> vars inside Java (using
>>>>>
>>>>>
>>>>> http://stackoverflow.com/questions/318239/how-do-i-set-environment-variables-from-java)
>>>>> and System.getenv("PYTHONPATH") shows correct values
>>>>>
>>>>> However, I am still getting "ImportError: no module named...."
>>>>>
>>>>> If I set PYTHONPATH before starting unittest, it works fine
>>>>>
>>>>> Is it possible what I would like to do?
>>>>
>>>> Why mess with the environment instead of setting sys.path directly
>>>> instead ?
>>>
>>> That would be great, but I don't know how. I am doing roughly this:
>>>
>>> PythonVM.start(programName)
>>> vm = PythonVM.get()
>>> vm.instantiate(moduleName, className);
>>>
>>> I tried also:
>>> PythonVM.start(programName, new String[]{"-c", "import
>>> sys;sys.path.insert(0, \'/dvt/workspace/montysolr/src/python\'"});
>>>
>>> it is failing on vm.instantiate.... when Python cannot find the module
>>>
>>>>
>>>>> Alternatively, if JCC could execute/eval python string, I could set
>>>>> sys.argv that way
>>>>
>>>> I'm not sure what you mean here but JCC's Java PythonVM.init() method
>>>> takes
>>>> an array of strings that is fed into sys.argv. See _PythonVM_Init()
>>>> sources
>>>> in jcc.cpp for details.
>>>
>>> sorry, i meant sys.path, not sys.argv
>>>
>>> roman
>>>
>>>>
>>>> Andi..
>>>>
>>>
>>
>
Index: jcc/sources/jcc.cpp
===================================================================
--- jcc/sources/jcc.cpp	(revision 1201881)
+++ jcc/sources/jcc.cpp	(working copy)
@@ -602,6 +602,20 @@
     return jobj;
 }
 
+
+static jint _PythonVM_eval(JNIEnv *vm_env, jobject self,
+                              jstring pythonCommand)
+{
+    PythonGIL gil(vm_env);
+
+    const char *pyStr = vm_env->GetStringUTFChars(pythonCommand, JNI_FALSE);
+    jint ret = PyRun_SimpleString((char *) pyStr);
+    vm_env->ReleaseStringUTFChars(pythonCommand, pyStr);
+
+    return ret;
+}
+
+
 extern "C" {
 
     JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved)
@@ -626,6 +640,13 @@
         return _PythonVM_instantiate(vm_env, self, moduleName, className);
     }
 
+
+    JNIEXPORT jint JNICALL Java_org_apache_jcc_PythonVM_eval(JNIEnv *vm_env, jobject self, jstring pythonCommand)
+    {
+        return _PythonVM_eval(vm_env, self, pythonCommand);
+    }
+
+
     JNIEXPORT jint JNICALL Java_org_apache_jcc_PythonVM_acquireThreadState(JNIEnv *vm_env)
     {
         PyGILState_STATE state = PyGILState_Ensure();
Index: java/org/apache/jcc/PythonVM.java
===================================================================
--- java/org/apache/jcc/PythonVM.java	(revision 1201881)
+++ java/org/apache/jcc/PythonVM.java	(working copy)
@@ -109,4 +109,11 @@
      * than zero signals an error.
      */
     public native int releaseThreadState();
+
+    /**
+     * Evaluates the string using python exec() call, it returns 0 on
+     * success and -1 on error. No exception is raised. If there was an
+     * unchecked SystemExit exception, the VM is likely destroyed
+     */
+    public native int eval(String pythonCommand);
 }

Reply via email to