Menu

#5 Possible bug in genericutil.cs (static Register method), and some support questions

v1.0_(example)
unread
nobody
None
5
2015-01-19
2013-10-29
No

This is my first time trying Python for .NET and I must say that this is an excellent resource. This is also my first time developing with Python, so I have a couple of questions at the end of this request. I am, however, a very seasoned C# and C/C++ developer.

For reference, I am using Visual Studio Ultimate 2012 (with Update 3) and the .Net 4.0 32-bit runtime, Python 2.7.5 through the latest Spyder and Python(x,y) downloads. I downloaded the latest source snapshot for Python for .NET, and debugged through both the clrmodule.il and Python.Runtime source to find the cause of this error. I'm not sure that the fix I put in is correct, but here is what I was seeing...

After the following Python source line:

import clr

I was receiving the console output message:

SystemError: dynamic module not initialized properly

I have my very short Python source file (Test.py) and the Python for .NET dll, pdb, and clr.pyd in the same folder (along with my C# dll in the same folder).

I traced the error all the way into the GenericUtil.Register(Type t) static method when it was trying to Register the EmptyArray`1 type name (By the way, this is the only type name that was trying to register with a Namepace == null)

The EmptyArray`1 Type has the Namespace property (string) set to null.

The code in the Register method that tries to get the Namespace value:

mapping.TryGetValue(t.Namespace, out nsmap);

causes an ArgumentNullException when the key value (t.Namespace) is null.

To fix the error, I just check for t.Namespace == null at the top of the method and immediately return from the method if it is null:

   //====================================================================
    // Register a generic type that appears in a given namespace.
    //====================================================================

    internal static void Register(Type t) {
        if (t.Namespace == null) {
            return;
        }
        Dictionary<string, List<string>> nsmap = null;
        mapping.TryGetValue(t.Namespace, out nsmap);
        if (nsmap == null) {
            nsmap = new Dictionary<string, List<string>>();
            mapping[t.Namespace] = nsmap;
        }
        string basename = t.Name;
        int tick = basename.IndexOf("`");
        if (tick > -1) {
            basename = basename.Substring(0, tick);
        }
        List<string> gnames = null;
        nsmap.TryGetValue(basename, out gnames);
        if (gnames == null) {
            gnames = new List<string>();
            nsmap[basename] = gnames;
        }
        gnames.Add(t.Name);
    }

This fix allowed me to then successfully import and use the Python for .NET functionality. I'm not sure how to get this fix into the source and/or binaries for general use. So, I'll leave that up to you.

I don't want to take too much of your time, but I do have some questions (and these are due to the fact that I'm not a Python developer, yet):

Here is my simple Test.py code:

-- coding: utf-8 --

"""
Created on Thu Oct 24 16:08:49 2013

@author: dwittma
"""

import clr

from System import *

clr.AddReference("CoreTypes")

from QuantaSoft import ProcessedWriter

print ProcessedWriter.doc

pr = ProcessedWriter.OverloadsString, String, Boolean, String, Nullable[DateTime], Boolean

pr.Close()

and here is the console output:

runfile('D:/MyPython/Test.py', wdir=r'D:/MyPython')
Void .ctor(System.String, Boolean)
Void .ctor(System.String, System.String, Boolean, System.String, System.Nullable`1[System.DateTime], Boolean)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Python27\lib\site-packages\spyderlib\widgets\externalshell\sitecustomize.py", line 540, in runfile
execfile(filename, namespace)
File "D:/MyPython/Test.py", line 18, in <module>
pr = ProcessedWriter.OverloadsString, String, Boolean, String, Nullable[DateTime], Boolean
TypeError: no constructor matches given arguments

My C# overloaded constructor looks like this:

public ProcessedWriter(string fileName, string channelDescriptor, bool columnBasedAcquisitionOrder,
string fileComments = QLBFileConst.EmptyString, DateTime? dateTime = null, bool appendChecksum = false)

My questions are:

How do I handle the Nullable<DateTime> (or DateTime?) type and how to pass an equivalent Python null argument for this type?

And, as you can see, I have optional defaulted parameters in the constructor. How does Python for .NET handle these? (i.e., how to specify that they are optional, or must I pass in all arguments, even if the parameters are defaulted and optional)

Thanks,

-Dean

Discussion


Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.