[Python.NET] Naming and resolution of generic types (complete!)

Brian Lloyd Brian.Lloyd at revolution.com
Fri Mar 31 22:42:53 CEST 2006

Hi all - I'm cross-posting this to the IP list as the subject seems to
be an open issue there too.

I'm working on generics support for Python for .NET, and there a couple
of thorny issues that could use some discussion regarding naming and
resolution of generic types.

In C# you can explicitly name a generic type, a la Dictionary<,>. That
syntax won't work in Python, of course. Looking at IP, it seems to allow
the apparent Python name to be the unmangled IL name so you can
naturally use the name.

The problem is that the mangled name is illegal as a python name, and
the unmangled name isn't guaranteed to be unique - you can potentially
have any number of generic types as well as a non-generic type with the
same base name in the same namespace:

namespace Spam {

    public class SpamCan {}
    public class SpamCan<T> {}
    public class SpamCan<T, V> {}

I imagine that maybe IP has enough information available at compile-time
to do the right thing for some common usage (binding and instantiating
the types), but the overloaded name can still be ambiguous. A real-life
example of this is System.IComparable - in IP, it doesn't seem possible
to get to the non-generic version of IComparable anymore (or at least it
was not obvious to me how to do it):

>>> import System
>>> System.IComparable
<type 'IComparable`1'>

It seems like we need to figure out some acceptable way of spelling
generic type names explicitly in Python (an equivalent to IComparable<>
in C#) that works within the existing syntax. 

There don't appear to be a lot of great options :( It has to be a valid
Python name to work in an import statement, so that rules out strange
operator shenanigans akin to the [] hack used for generic type binding. 

One would be to mimic the existing IL mangling in some way, a la:

>From System import IComparable   # the non-generic type
>From System import IComparable_1 # the 1-param generic 

# or
from System import IComparable_T
from System.Collections.Generic import Dictionary_TT

These are all pretty gross, and still don't totally prevent hiding of
legit non-generic classes with those names (though it makes it less
likely that names will be hidden than the current approach).

I suppose another approach would be to continue to have only one type
end up with the simple name, but provide a way to disambiguate it after
the fact:

>>> import System
>>> System.IComparable
<type 'IComparable`1'>

>>> # abandon all hope, ye who enter here...
>>> NonGenericIComparable = System.IComparable<<0 
>>> OneParamGenericIComparable = System.IComparable<<1
>>> TwoParamVersionIfThereWasOne = System.IComparable<<2

That feels to me like it violates Python Zen in several ways, though.



More information about the PythonDotNet mailing list