[Python.NET] Python.Net for Python3: bug when converting a PyLong to a System.Int32

Serge WEINSTOCK serge.weinstock at uk.bnpparibas.com
Fri Sep 26 17:52:40 CEST 2014


Hi Tony,

I've found a bug when trying to use Python integer as .Net int32. For example:
//=======================================================================
using System;
using Python.Runtime;

namespace TestPythonNet
{
    public class ATest
    {
        public long a64;
        public int a32;
        public void f32(int a) { Console.WriteLine("got int {0}", a);}
        public void f64(long a) { Console.WriteLine("got long {0}", a); }
    }


    class Program
    {
        static void Main(string[] args)
        {
            PythonEngine.PythonHome = @"D:\src\scratch\TestPythonNet\TestPythonNet\PythonRuntime";
            PythonEngine.ProgramName = "PythonRuntime";
            PythonEngine.Initialize();
            PythonEngine.ImportModule("clr");
            using (Py.GIL())
            {
                try
                {
                    PythonEngine.RunSimpleString(
                        @"
import clr

clr.AddReference('TestPythonNet')
from TestPythonNet import ATest

f = ATest();
f.a64 = 10 # OK
f.a32 = 10 # Fails!
f.f64(-1) # OK
f.f32(-1) # Fails!

print('all fine!')
");

                }
                catch (PythonException e)
                {
                    Console.WriteLine(e);
                }
            }
        }
    }
}
//=======================================================================
All the call from python using integer as .Net int will fail. This is due to the fact that python3 has only one type of integer: int64.

Furthermore, in the Python C API, all the conversion functions from or to int32 have disappeared.

I think that the following patch fixes the issue:
Src/runtime/converter.cs
//=======================================================================
static bool ToPrimitive(IntPtr value, Type obType, out Object result,
                        bool setError) {

    IntPtr overflow = Exceptions.OverflowError;
    TypeCode tc = Type.GetTypeCode(obType);
    result = null;
   IntPtr op;
    int ival;

    switch(tc) {

    case TypeCode.String:
        string st = Runtime.GetManagedString(value);
        if (st == null) {
            goto type_error;
        }
        result = st;
        return true;

    case TypeCode.Int32:
        // Trickery to support 64-bit platforms.
        if (IntPtr.Size == 4) {
            //------ FIX START
            // convert it to an python int64
            op = Runtime.PyNumber_Long(value);

            // if the conversion fails
            if (op == IntPtr.Zero) {
                if (Exceptions.ExceptionMatches(overflow)) {
                    goto overflow;
                }
              goto type_error;
            }

            // convert it to an int64
            long lval = (long)Runtime.PyLong_AsLongLong(op);

            // and try to convert it to an int32
            if ((lval < int.MinValue) || (int.MaxValue < lval))
            {
                Runtime.Decref(op);
                if (Exceptions.ExceptionMatches(overflow))
                {
                    goto overflow;
                }
                goto type_error;
            }
            Runtime.Decref(op);
            result = unchecked((int)lval);
            return true;
            //------ FIX END
        }
        else {
            op = Runtime.PyNumber_Long(value)
//=======================================================================

I will send a pull request to the github repo . Could you have a look at it?

Thanks,
Serge


___________________________________________________________
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.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/pythondotnet/attachments/20140926/8d13eb89/attachment.html>


More information about the PythonDotNet mailing list