Hi Serge,

I see what you're saying. It would think that bit just needs to be moved until after we're sure python has been initialized so it works in both cases. I don't see any need to move it into a separate python module; having it compiled into one is cleaner IMHO. If you're not subclassing .NET classes in python and so don't need python methods/properties reflected to .net you won't need it anyway, so you could just remove that bit of code from your fork for now.

I'll take a look, but if you get round to it before I do then please feel free to submit a pull request. I'll create an issue in github so it doesn't get forgotten.

thanks,
Tony


On Tue, Sep 30, 2014 at 11:59 AM, Serge WEINSTOCK <serge.weinstock@uk.bnpparibas.com> wrote:

Hi Tony,

 

You recently made a change which prevents me using the library in an embedded Python interpreter.

 

In pythonengine.cs, you “inject” decorators with the following code:

 

//=================================================================

public static void Initialize() {

.....

IntPtr globals = Runtime.PyEval_GetGlobals();

PyDict locals = new PyDict();

try

{

    IntPtr builtins = Runtime.PyEval_GetBuiltins();

    Runtime.PyDict_SetItemString(locals.Handle, "__builtins__", builtins);

 

    var assembly = Assembly.GetExecutingAssembly();

    using (Stream stream = assembly.GetManifestResourceStream("Python.Runtime.resources.clr.py"))

    using (StreamReader reader = new StreamReader(stream))

    {

        // add the contents of clr.py to the module

        string clr_py = reader.ReadToEnd();

        PyObject result = RunString(clr_py, globals, locals.Handle);

        if (null == result)

            throw new PythonException();

        result.Dispose();

    }

//=================================================================

When running from a Python script, it’s fine because the Python interpreter has already been initialized and global variables have been defined.

 

The issue is that when running from an embedded interpreter. As I must first initialize the Python engine using PythonEngine.Initialize().

 

So when we reach this piece of code, there is no script running, no “Python context”, so “PyEval_GetGlobals” returns null and “RunString” fails.

 

We could create an artificial global dictionary but it won’t be available to the rest of the code.

 

I think it should be best to move this code into a Python module. If run from a script (PyEval_GetGlobals() != null), you could inject the decorators with a simple “from decorators_pythonnet import *”. If run from an embedded interpreter, we could add a line for running the same code once the engine has been initialized.

 

What do you think?

 

Serge Weinstock

 


___________________________________________________________
This e-mail may contain confidential and/or privileged information. If you are not the intended recipient (or have received this e-mail in error) please notify the sender immediately and delete this e-mail. Any unauthorised copying, disclosure or distribution of the material in this e-mail is prohibited.

Please refer to http://www.bnpparibas.co.uk/en/email-disclaimer/ for additional disclosures.


_________________________________________________
Python.NET mailing list - PythonDotNet@python.org
https://mail.python.org/mailman/listinfo/pythondotnet