[Python.NET] changes to Python.Runtime.Converter and Python.Runtime.Object

Cameron Hayne cameron.hayne at introspect.ca
Thu Mar 26 01:49:28 CET 2015


I have been using the version of PythonDotNet from https://github.com/renshawbay/pythonnet
for embedding - i.e. to call Python code in C# programs.

I have made a few changes to the source code in order to make using Python objects in C# easier, or to fix problems.
Here are the changes:
1) In the source file “converter.cs” which defines the class Python.Runtime.Converter,
I added the following to the switch case ‘TypeCode.Object’ in the ‘ToPython’ function:

	case TypeCode.Object:
		// The following ‘if’ clause is needed (as suggested by Patrick Stewart) to make the examples in the README work.
		if (value is IEnumerable)
                {
                    using (var resultlist = new PyList())
                    {
                        foreach (object o in (IEnumerable)value)
                        {
                            Type oType = o.GetType();
                            TypeCode oTc = Type.GetTypeCode(oType);
                            //  The following 'if' clause for Object entries is needed so that the entries
                            //  in lists of Python objects don't lose their types.
                            //  I.e. so that if you do something like:
                            //     dynamic obj1 = myPythonClass();
                            //     List<dynamic> myList = new List<dynamic> { obj1 };
                            //     myPythonFunc(myList);
                            //  then the type of myList[0] inside myPythonFunc will be the same as the type of obj1
                            //  whereas the 'else' clause would make it be of type Python.Runtime.PyObject
                            if (oTc == TypeCode.Object)
                            {
                                resultlist.Append((PyObject)o);
                            }
                            else
                            {
                                using (var p = new PyObject(ToPython(o, oType)))
                                    resultlist.Append(p);
                            }
                        }
                        Runtime.Incref(resultlist.Handle);
                        return resultlist.Handle;
                    }
                }

2) In the source file “pyobject.cs” which defines the class Python.Runtime.PyObject,
I replaced the line:

	   this.SetAttr(binder.Name, (PyObject)value);

in the ‘if (this.HasAttr(binder.Name))’ clause in the function ‘TrySetMember’ with the following:

            //  Use ‘ToPython’ if an exception occurs when casting to (PyObject)
            //  Without this, get exception e.g. when assign a C# String to a Python member
            //  like:   myPyObj.name = name;
            PyObject pyValue;
            try
            {
                pyValue = (PyObject)value;
            }
            catch (Exception)
            {
                pyValue = value.ToPython();
            }
            this.SetAttr(binder.Name, pyValue);

I would be interested in any comments about these changes - especially if there are better ways of fixing the problems.
I am also interested to hear if anyone has other improvements to suggest.

--
Cameron Hayne
cameron.hayne at introspect.ca





More information about the PythonDotNet mailing list