Python.Net for Python3: bug when using an embedded interpreter
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.
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
Should be fixed now. Please re-open if it's still a problem ( https://github.com/renshawbay/pythonnet/issues/13). cheers, Tony On Tue, Sep 30, 2014 at 4:57 PM, Tony Roberts <tony@pyxll.com> wrote:
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
Thanks, it’s working fine. I’ve created a pull request for handling Python3 int conversion to int32 in 32 bits python interpreters. Could you have a look at it? Serge From: pythondotnet-bounces+serge.weinstock=uk.bnpparibas.com@python.org [mailto:pythondotnet-bounces+serge.weinstock=uk.bnpparibas.com@python.org] Sent: 30 September 2014 19:16 To: pythondotnet@python.org Subject: Re: [Python.NET] Python.Net for Python3: bug when using an embedded interpreter Should be fixed now. Please re-open if it's still a problem (https://github.com/renshawbay/pythonnet/issues/13). cheers, Tony On Tue, Sep 30, 2014 at 4:57 PM, Tony Roberts <tony@pyxll.com<mailto:tony@pyxll.com>> wrote: 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<mailto: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<http://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<mailto:PythonDotNet@python.org> https://mail.python.org/mailman/listinfo/pythondotnet ___________________________________________________________ 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.
participants (2)
-
Serge WEINSTOCK
-
Tony Roberts