Brian Lloyd
Thursday, April 13, 2006
Python + .NET: Meta-model mashup
I'm happy to say its been a pretty busy month in Python for .NET-land ;^)
There is now a 1.0 branch for the .NET 1.x compatible version of the bridge, and development for the .NET 2.x compatible version is proceeding on the trunk. The goals for the 1.x and 2.x finals are solid stability, support for the features of the respective runtime versions and code-compatibility with IronPython, which has been making great strides lately. Some improvements that have now landed on both branches:
  • Refactored import syntax: now you can use un-prefixed namespace names ( "from System import *") instead of the old "magic CLR module" syntax ("from CLR.System...). The old "CLR." syntax is still supported until 3.0, but now officially deprecated. This was the main compatibility problem with code targeted for IP.
  • Method overload selection using [] syntax. You can now select a specific overload of a method using syntax like: System.Console.WriteLine[System.String](...) or System.Console.WriteLine[System.Boolean](...) rather than rely on the default "find the best match behavior" for method invokation. For IP compatibility, both branches also support mapping of builtin Python type names to corresponding .NET types in this case (System.Console.WriteLine[str](...) System.Console.WriteLine[bool](...)).
  • A few leaks fixed and various obvious performance improvements.
The trunk (.NET 2.x compatible) also contains basic support for generic methods and generic types. There is still a little bit of work to do on this - I hope to be able to make an RC3 release of 1.0 and a beta of 2.0 quite soon.

Implementing support for generics has posed some interesting issues. From the beginning of this project, I've really been pleasantly surprised and impressed with the symmetry of the meta-models of Python and the CLR (though the details are, of course, a bit different). Like Jim's anecdote about starting IronPython, I also started Python for .NET with the mindset of "how far can I go with this before I hit the inevitable brick wall?"

To my surprise (and pleasure), I kept finding that each time I hit an apparent wall it meant that I just wasn't being clever enough and I would eventually find a way to make things work, work well, work fast, and remain Pythonic (yes, I'm hell-bent for aesthetics).

But with 2.x generics, there appear to be some trade-offs to be made. This is the first must-support feature that doesn't have an obvious corollary or perfect solution in the Python meta-model. Jim and his team came up with the nifty subscript syntax for binding generic types (Dictionary[string, int]) which works well in the common case, but which raises a bunch of issues for (not-so) edge cases.

The heart of the issue is that CLR uses name mangling to disambiguate generic types. In C#, when you say

"System.Collections.Generic.Dictionary<TKey, TValue>"

it is translated to the type name


in IL. This is a perfectly good and reasonable design for compiled CLR-targeted languages, but poses a problem for Python.

A concrete example in the BCL 2.x: there is a "System.Nullable<T>" generic type and a "System.Nullable" (non-generic) type in the same namespace.
When you say "from System import Nullable", which did you mean? The <> syntax obviously won't work in Python (you also can't import or reference the type by its mangled name, which is also illegal as a Python name) , and there aren't many tricks left to use to disambiguate here.

One approach would be to have whatever represents the name "Nullable" be willing to support both direct invocation (Nullable(), to instantiate the non-generic type) and the [] syntax (Nullable[int], to bind and return a type Nullable of Int32). This is what I have at the moment, but it still leaves some edge cases unresolved, if we assume that we'd like to disambiguate constructors in the same way that we disambiguate methods .

Example: say in the namespace "System.Spam" we have a non-generic class with two constructors (Spam(int) and Spam(string)). In the same namespace we also have a generic type "System.Spam`1" (System.Spam<T>). What does "System.Spam[int]" mean from Python?"

It could mean either:
  • construct an instance of the non-generic "Spam" with an argument of type "int"
  • produce a closed generic type from the generic type definition "Spam<T>" with the type param "int"
Likewise, say that you have a (non-generic) type "System.Spam" that defines a (non-generic) method "SayHello(int)" and a generic method "SayHello<T>(T arg)". If you say from Python "object.SayHello[int](...)" - what did you mean? The generic, or the non-generic? The method implementations could be semantically different, but the [] syntax does not give us a way to clearly state what we want.

This is a pretty tough problem, since there are few other options (within existing Python syntax) that we can exploit, yet the [] syntax still leaves holes in the new meta-model mashup.

Update: Thanks to Seo for pointing out to me that this seems to be mostly resolved with IP beta 5 (I'd been using b4). So now the unadorned [] syntax is used only for binding generic types and methods, and a magic "__overloads__" attribute is used to select methods / ctors by signature.

From the IP workspace site:
    public class Foo {
public void Bar(int arg) {}
public void Bar<T>(int arg) {}

We can call the non-generic version with any of:

And the generic one with any of:

Monday, March 13, 2006
Python for .NET update
This is a recap of a post to the mailing list,
designed to increase the google-fu of the message to make it more easily findable ;^)

Its been a while (far too long) since I've been active on the list. The
reason is that I've recently changed companies so things have been a little
hectic and I also had to make sure the 'paperwork was in order' regarding
open source projects like pythonnet.

Now that things have settled down a bit, I have been able to spend some
time moving Python for .NET development over to sourceforge. I hope that this
will make it easier for others to contribute and remove me as the main
bottleneck to progress ;^)

The new Python for .NET homepage is now:

The Python for .NET SourceForge project homepage is at:

I've imported the current (.NET 1.x) code into CVS. What I'd like to do this week is make a pythonnet-1_0-branch for continuing .NET 1.x compatible work, and open the trunk for .NET 2.x compatible work such as Michael Eddington has been doing.

You can reach me at or if you're interested in participating or are otherwise wondering why I'm not returning your mail from the old zope address :^)
Friday, December 16, 2005

If you are a "dog person", you know that a dog really does become a part of your family, as silly as that may sound to non-dog-people. We're dog people -- always have been, always will be.

Few things in life hurt more than having to kiss a member of your family goodbye for what you know will be the last time. One of them is breaking the news to a 5-year-old little boy.

Rest in peace girl, we will miss you.
Tuesday, March 29, 2005
Python for .NET 1.0 beta 5 released

Python for .NET 1.0 beta 5 is now available - you can download
it from:

Python for .NET is a near-seamless integration of Python with the
.NET common language runtime. For more details, see the

The beta 5 release features a refactoring of thread management
support, making the runtime stable for multi-threaded applications,
as well as several improvements and bug-fixes.

Special thanks to all who sent in thread-related scenarios and test
cases! I have tried to incorporate as many of these as possible into
the unit tests - if you still have problems that you suspect may be
related to threading or interpreter lock issues, please let me know

There is also now a mailing list for discussion, questions and
issues related to Python for .NET at:
To subscribe to the mailing list or read the online archives, see:

Tuesday, March 22, 2005
Paris sprint
Many thanks to the guys at Nuxeo for their hospitality last week at the Paris / Five sprint. I think we made some important progress there in that we integrated the Five project into Zope 2.8 and integrated a subset of Zope 3 into the Zope core.

This should provide the beginnings of a migration path for current Zope 2 developers and hopefully actually accelerate the adoption and use of Zope 3 (since Z2 developers will now be able to take advantage of Z3 technologies in Z2 applications).

It was a pleasure to meet and work with so many of the superstars of the Zope community in the same room - I hope to be able to do it again in the future!

Planning for Python for .NET beta 5
I'm trying to re-commit myself to communicating better about Python for .NET ;) To that end, here is the list of high priorities for beta 5:
  • Thread sanity. It seems that the PyGILState_* APIs in Python 2.3 were buggy and could lead to deadlocks. Completely coincidentally, there have been reports of deadlocks in Python for .NET as well ;)
  • Better public API for managed-language programmers. A lot of questions on the mailing list have been from C# and VB programmers trying to use my woefully underdocumented APIs. I hope to improve that for beta 5.
  • Did I mention thread sanity? :)


March 2005
December 2005
March 2006
April 2006