[Python.NET] Adding PyRun_String to Runtime

Michael Eddington meddington at gmail.com
Wed Aug 24 20:12:09 CEST 2005


Brian,

I upgraded to the latest distribution but still had issues with the
RunString included.  Seems GetGlobals also has issues.  I ended up
re-writing the implementation as such follows.  This seems to work
reliably.  One difference from the two implementations is I'm sending
__builtin__ as the globals dictionary  Searching through the Python mail
archives I found a couple of references that this is the correct thing
todo.  Also, I'm keeping the locals dictionary around, seems like the
right things todo, but not sure.

    protected static PyDict    locals = null;

    public static PyObject RunString(string code)
    {
        PyDict globals = new
PyDict(Runtime.PyModule_GetDict(ImportModule("__builtin__").Handle));
       
        if(locals == null)
        {
            locals = new PyDict(Runtime.PyDict_New());
        }
       
        IntPtr flag = (IntPtr)257; /* Py_file_input */
        IntPtr result = Runtime.PyRun_String(code, flag, globals.Handle,
locals.Handle);
       
        if (result == IntPtr.Zero)
        {
            return null;
        }
       
        return new PyObject(result);
    }


Brian Lloyd wrote:

>Hi Michael - I assume you're running an older version of 
>Python for NET? The current version has an implementation 
>of RunString:
>
>	public static PyObject RunString(string code) {
>	    IntPtr globals = Runtime.PyEval_GetGlobals();
>	    IntPtr locals = Runtime.PyDict_New();
>
>	    IntPtr builtins = Runtime.PyEval_GetBuiltins();
>	    Runtime.PyDict_SetItemString(locals, "__builtins__", builtins);
>
>	    IntPtr flag = (IntPtr)257; /* Py_file_input */
>	    IntPtr result = Runtime.PyRun_String(code, flag, globals, locals);
>	    Runtime.Decref(locals);
>	    if (result == IntPtr.Zero) {
>		return null;
>	    }
>	    return new PyObject(result);
>	}
>
>The trick is that for various reasons you can't depend on the 
>PyEval_GetLocals call to return anything meaningful, so you have 
>to build the locals dict manually.
>
>HTH,
>
>
>Brian Lloyd        brian at zope.com
>V.P. Engineering   540.361.1716              
>Zope Corporation   http://www.zope.com 
>
>
>  
>
>>-----Original Message-----
>>From: pythondotnet-bounces at python.org
>>[mailto:pythondotnet-bounces at python.org]On Behalf Of Michael Eddington
>>Sent: Sunday, August 14, 2005 1:36 AM
>>To: pythondotnet at python.org
>>Subject: [Python.NET] Adding PyRun_String to Runtime
>>
>>
>>I would like to run Python strings and get an object return from .NET.
>> To this end I added PyRun_String to the Runtime object and another
>>method to PythonEngine ala the existing SimpleString implementation.
>>
>>Everything compiles, but  Runtime.PyRun_String always returns a NULL,
>>and it does not look like the code is being run.
>>
>>Is there any trick to adding new methods to the Runtime?
>>
>>// From Runtime.cs
>>
>>	[DllImport(Runtime.dll, CallingConvention=CallingConvention.Cdecl,
>>		   ExactSpelling=true, CharSet=CharSet.Ansi)]
>>        internal unsafe static extern IntPtr
>>        PyRun_String(string code, int start, IntPtr globals, 
>>IntPtr locals);
>>  
>>
>>// From Python.cs
>>
>>		public static PyObject RunString(string code)
>>		{
>>			IntPtr globals = Runtime.PyEval_GetGlobals();
>>			IntPtr locals = Runtime.PyEval_GetLocals();
>>			IntPtr ret;
>>
>>			ret = Runtime.PyRun_String(code, 
>>257,globals, locals);
>>			
>>			Runtime.Decref(globals);
>>			Runtime.Decref(locals);
>>
>>			if (ret == IntPtr.Zero) 
>>			{
>>				throw new PythonException();
>>			}
>>
>>			return new PyObject(ret);
>>		}
>>_________________________________________________
>>Python.NET mailing list - PythonDotNet at python.org
>>http://mail.python.org/mailman/listinfo/pythondotnet
>>
>>    
>>
>
>  
>



More information about the PythonDotNet mailing list