[pypy-dev] adding support for Generic classes in the "/module/clr"

Antonio Cuni anto.cuni at gmail.com
Wed Dec 12 12:23:02 CET 2007


On Dec 12, 2007 2:11 AM, amit <regmi.amit at gmail.com> wrote:
> Support for generic classes
>
> ---IronPythonic way---------
> from System.Collections.Generic import *
> l = List[str]()
> l.Add("Hello")
> l.Add("Hi")
> l.Add(3)        # fails with ValueError:
>
> d = Dictionary[str, int]()
> d.Add('abc', 1)
> d.Add('def', 2)
> for i in d.Keys:
>     print d[i]
>
> So here in pypy-clr what we'd like to do is
>
>     import System.Collections.Generic.LinkedList<str>

we can't use this syntax, because the parser would complain. We need
to use the same trick as IronPython, i.e. use square brackets.

>     l= System.Collections.Generic.LinkedList<str>()
>     l.Add("hello")
>     l.Add("hi")
>     l.Add(3)        # throw ValueError exception
>
> the import is to be analysed if its an import for a Generic Class and
> loaded as
>
>
> clr.load_cli_generic_class('System.Collections.Generic','LinkedList<str>')

No, I don't think we want to do so. I think the best is to mimic
IronPython as much as possible. I.e., let the user to import the
generic class by itself, e.g. "import
System.Collections.Generic.List"; then, if you do "List[str]" it
returns a concrete class that can be istantiated as in IronPython.

> The implementation of load_cli_generic_class is a BlackBox to me as of now.
>
>  From the import line we can check if the class is a "generic" and then
> reflection can be used to determine:
> a) Generic type
> b) type arguments
> c) Parameter attributes
> .... and more
>
> I hope somehow the existing build_wrapper could be used after putting
> some checks but I am not sure how.

well, basically you have to check whether a class is generic; if it
is, we need to construct it by using another metaclass which has
support for __getitem__; something like this:

class MetaGenericCliClassWrapper(...):
     def __getitem__(self, *types):
         # do something
         return load_cli_class(...)

But before you can use this metaclass, you need to ensure that
load_cli_class works fine with concrete instantiations of generic
classes. So, the first thing to do is to write a test like this:

def test_generic_class(self):
    ListInt = load_cli_class("System.Collections.Generic", "List`1<int32>")
    x = ListInt()
    x.Add(42)
    # etc...

Then we need to write other tests for the error cases (e.g., test that
if you put a string inside x it raises ValueError).
Maybe these test swould work out of the box, I don't know. After that,
all we need to do is to provide some nice syntactic sugar like square
brackets & co.

ciao Anto



More information about the Pypy-dev mailing list