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.ha...@introspect.ca



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

Reply via email to