[pypy-svn] r50634 - in pypy/branch/clr-module-improvements/pypy/module/clr: . test

antocuni at codespeak.net antocuni at codespeak.net
Tue Jan 15 16:48:30 CET 2008


Author: antocuni
Date: Tue Jan 15 16:48:29 2008
New Revision: 50634

Modified:
   pypy/branch/clr-module-improvements/pypy/module/clr/__init__.py
   pypy/branch/clr-module-improvements/pypy/module/clr/app_clr.py
   pypy/branch/clr-module-improvements/pypy/module/clr/boxing_rules.py
   pypy/branch/clr-module-improvements/pypy/module/clr/interp_clr.py
   pypy/branch/clr-module-improvements/pypy/module/clr/test/test_clr.py
Log:
(antocuni, pdg)

make generic clasess really work.



Modified: pypy/branch/clr-module-improvements/pypy/module/clr/__init__.py
==============================================================================
--- pypy/branch/clr-module-improvements/pypy/module/clr/__init__.py	(original)
+++ pypy/branch/clr-module-improvements/pypy/module/clr/__init__.py	Tue Jan 15 16:48:29 2008
@@ -15,7 +15,6 @@
         'call_staticmethod': 'interp_clr.call_staticmethod',
         'load_cli_class': 'interp_clr.load_cli_class',
         'get_extra_type_info': 'interp_clr.get_extra_type_info',
-        #'list_of_generic_classes': 'interp_clr.list_of_generic_classes',
         'isDotNetType': 'interp_clr.isDotNetType',
         'load_assembly': 'interp_clr.load_assembly',
         'list_of_loadedAssemblies': 'interp_clr.list_of_loadedAssemblies',

Modified: pypy/branch/clr-module-improvements/pypy/module/clr/app_clr.py
==============================================================================
--- pypy/branch/clr-module-improvements/pypy/module/clr/app_clr.py	(original)
+++ pypy/branch/clr-module-improvements/pypy/module/clr/app_clr.py	Tue Jan 15 16:48:29 2008
@@ -78,7 +78,24 @@
     def __get__(self, obj, type_):
         return self.fget()
 
+def _qualify(t):
+    return '%s, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' % t
+
 class MetaGenericCliClassWrapper(type):
+    _cli_types = {
+        int: _qualify('System.Int32'),
+        str: _qualify('System.String'),
+        bool: _qualify('System.Boolean'),
+        float: _qualify('System.Double'),
+        }
+    _System_Object = _qualify('System.Object')
+
+    def _cli_name(cls, ttype):
+        if isinstance(ttype, MetaCliClassWrapper):
+            return '[%s]' % ttype.__fullyqualifiedname__
+        else:
+            return '[%s]' % cls._cli_types.get(ttype, cls._System_Object)
+    
     def __setattr__(cls, name, value):
         obj = cls.__dict__.get(name, None)
         if isinstance(obj, StaticProperty):
@@ -86,37 +103,19 @@
         else:
             type.__setattr__(cls, name, value)
 
-    def __getitem__(cls,*args):
-        #cls.__cliclass__ ='System.Collections.Generic.Dictionary`2'
-        rightDot = cls.__cliclass__.rfind('.')
-        rightTilde = cls.__cliclass__.rfind('`')
-        load_cli_class_leftArg = cls.__cliclass__[:rightDot]
-        genClassName = cls.__cliclass__[rightDot+1: rightTilde] 
-        genClassNumArgs = int(cls.__cliclass__[rightTilde +1 :])
+    def __getitem__(cls, type_or_tuple):
         import clr
+        if isinstance(type_or_tuple, tuple):
+            types = type_or_tuple
+        else:
+            types = (type_or_tuple,)
+        namespace, generic_class = cls.__cliclass__.rsplit('.', 1)
+        generic_params = [cls._cli_name(t) for t in types]        
+        instance_class = '%s[%s]' % (generic_class, ','.join(generic_params))
         try:
-            ln = len(args[0])
-            # put a check for the number of arguments passed for the Generic class
-            if ln != genClassNumArgs:
-                raise "InvalidArgumentList"
-            else:
-                lindex = str(args[0][0]).find('\'')
-                rindex = str(args[0][0]).rfind('\'')
-                load_cli_class_rightArg = genClassName 
-                load_cli_class_rightArg += "`%s[%s"%(ln,str(args[0][0])[lindex+1:rindex])
-                for i in range(1,ln):
-                    lindex = str(args[0][i]).find('\'')
-                    rindex = str(args[0][i]).rfind('\'')
-                    load_cli_class_rightArg += ",%s"%str(args[0][i])[lindex+1:rindex]
-                load_cli_class_rightArg += "]"
-                return clr.load_cli_class(load_cli_class_leftArg,load_cli_class_rightArg)
-        except:
-            # it's a single arg passed
-            lindex = str(args[0]).find('\'')
-            rindex = str(args[0]).rfind('\'')
-            load_cli_class_rightArg = genClassName 
-            load_cli_class_rightArg += "`1[%s]"%(str(args[0])[lindex+1:rindex])
-            return clr.load_cli_class(load_cli_class_leftArg,load_cli_class_rightArg)
+            return clr.load_cli_class(namespace, instance_class)
+        except ImportError:
+            raise TypeError, "Cannot load type %s.%s" % (namespace, instance_class)
 
 class MetaCliClassWrapper(type):
     def __setattr__(cls, name, value):
@@ -155,9 +154,12 @@
     obj.__cliobj__ = cliobj
     return obj
 
-def build_wrapper(namespace, classname, staticmethods, methods, properties, indexers, hasIEnumerable, isClassGeneric):
+def build_wrapper(namespace, classname, assembly_qualified_name,
+                  staticmethods, methods, properties, indexers,
+                  hasIEnumerable, isClassGeneric):
     fullname = '%s.%s' % (namespace, classname)
     d = {'__cliclass__': fullname,
+         '__fullyqualifiedname__': assembly_qualified_name,
          '__module__': namespace}
     for name in staticmethods:
         d[name] = StaticMethodWrapper(fullname, name)

Modified: pypy/branch/clr-module-improvements/pypy/module/clr/boxing_rules.py
==============================================================================
--- pypy/branch/clr-module-improvements/pypy/module/clr/boxing_rules.py	(original)
+++ pypy/branch/clr-module-improvements/pypy/module/clr/boxing_rules.py	Tue Jan 15 16:48:29 2008
@@ -1,3 +1,4 @@
+from pypy.tool.pairtype import extendabletype
 from pypy.interpreter.baseobjspace import W_Root
 from pypy.objspace.std.intobject import W_IntObject
 from pypy.objspace.std.floatobject import W_FloatObject
@@ -6,33 +7,47 @@
 from pypy.objspace.std.stringobject import W_StringObject
 from pypy.translator.cli.dotnet import box
 
-def tocli(self):
-    return box(self)
-W_Root.tocli = tocli
-
-def tocli(self):
-    return box(self.intval)
-W_IntObject.tocli = tocli
-
-def tocli(self):
-    return box(self.floatval)
-W_FloatObject.tocli = tocli
-
-def tocli(self):
-    return None
-W_NoneObject.tocli = tocli
-
-def tocli(self):
-    return box(self.boolval)
-W_BoolObject.tocli = tocli
-
-def tocli(self):
-    return box(self._value)
-W_StringObject.tocli = tocli
+class __extend__(W_Root):
+    __metaclass__ = extendabletype
+
+    def tocli(self):
+        return box(self)
+
+class __extend__(W_IntObject):
+    __metaclass__ = extendabletype
+
+    def tocli(self):
+        return box(self.intval)
+
+class __extend__(W_FloatObject):
+    __metaclass__ = extendabletype
+
+    def tocli(self):
+        return box(self.floatval)
+
+class __extend__(W_NoneObject):
+    __metaclass__ = extendabletype
+
+    def tocli(self):
+        return None
+
+class __extend__(W_BoolObject):
+    __metaclass__ = extendabletype
+
+    def tocli(self):
+        return box(self.boolval)
+
+class __extend__(W_StringObject):
+    __metaclass__ = extendabletype
+
+    def tocli(self):
+        return box(self._value)
 
 from pypy.objspace.fake.objspace import W_Object as W_Object_Fake
 from pypy.rlib.nonconst import NonConstant
 
-def tocli(self):
-    return NonConstant(None)
-W_Object_Fake.tocli = tocli
+class __extend__(W_Object_Fake):
+    __metaclass__ = extendabletype
+
+    def tocli(self):
+        return NonConstant(None)

Modified: pypy/branch/clr-module-improvements/pypy/module/clr/interp_clr.py
==============================================================================
--- pypy/branch/clr-module-improvements/pypy/module/clr/interp_clr.py	(original)
+++ pypy/branch/clr-module-improvements/pypy/module/clr/interp_clr.py	Tue Jan 15 16:48:29 2008
@@ -218,42 +218,15 @@
                     namespaces[temp_name] = None
             if type.get_IsGenericType():
                 fullname = type.get_FullName()
-                index = fullname.rfind("`")
-                assert index != -1
-                generics.append((fullname[0:index], fullname))
+                if '+' not in fullname:
+                    # else it's a nested type, ignore it
+                    index = fullname.rfind("`")
+                    assert index != -1
+                    generics.append((fullname[0:index], fullname))
     w_listOfNamespaces = wrap_list_of_strings(space, namespaces.keys())
     w_generic_mappings = wrap_list_of_pairs(space, generics)
     return space.newtuple([w_listOfNamespaces, w_generic_mappings])
-
-#def list_of_generic_classes(space):
-#    """
-#    use reflection to get a list of generic classes 
-#
-#    Return: List of generic classes
-#    e.g. [Dictionary`2 , List`1 , IEnumerator`1 , IEnumerable`1]
-#    """
-#    listOfGenericTypes = []
-#    currentDomain = System.AppDomain.get_CurrentDomain()
-#    assems = currentDomain.GetAssemblies()
-#    for loadedAssembly in assems:
-#        typesInAssembly = loadedAssembly.GetTypes()
-#        for type in typesInAssembly:
-#            namespace = type.get_Namespace()
-#            type_str = type.ToString()
-#            if namespace == "System.Collections.Generic":
-#                rightDot = type_str.rfind('.')
-#                rightTilde = type_str.rfind('`')
-#                firstSqBracket = type_str.find('[')
-#                firstPlus = type_str.find('+')
-#                if rightDot != -1 and rightTilde != -1:
-#                    if firstPlus == -1:
-#                        nameToPush = type_str[rightDot+1 : firstSqBracket] 
-#                    else:
-#                        nameToPush = type_str[rightDot+1 : firstPlus] 
-#                    if nameToPush not in listOfGenericTypes:
-#                        listOfGenericTypes.append(nameToPush) 
-#    w_listOfGenericTypes = wrap_list_of_strings(space, listOfGenericTypes)
-#    return w_listOfGenericTypes
+get_extra_type_info.unwrap_spec = [ObjSpace]
 
 def isDotNetType(space, nameFromImporter):
     """
@@ -351,11 +324,13 @@
     if b_type.IsGenericType:
         isClassGeneric = True
 
+    assembly_qualified_name = b_type.get_AssemblyQualifiedName()
     w_staticmethods, w_methods = get_methods(space, b_type)
     w_properties, w_indexers = get_properties(space, b_type)
     return build_wrapper(space,
                          space.wrap(namespace),
                          space.wrap(classname),
+                         space.wrap(assembly_qualified_name),
                          w_staticmethods,
                          w_methods,
                          w_properties,

Modified: pypy/branch/clr-module-improvements/pypy/module/clr/test/test_clr.py
==============================================================================
--- pypy/branch/clr-module-improvements/pypy/module/clr/test/test_clr.py	(original)
+++ pypy/branch/clr-module-improvements/pypy/module/clr/test/test_clr.py	Tue Jan 15 16:48:29 2008
@@ -215,18 +215,46 @@
         raises(TypeError, x.__setitem__, 4, 4.453)
         raises(TypeError, x.__setitem__, "test", 3)
 
-    def test_generic_class_with_single_import(self):
+    def test_generic_metaclass_list(self):
         import clr
-        import System.Collections.Generic
-        import List
+        from System.Collections.Generic import List
         import System.Int32
-        l2 = List[System.Int32]()
-        l2.Add(3)
-        raises(TypeError, l2.Add, "test")
+        lst = List[System.Int32]()
+        lst.Add(42)
+        assert lst[0] == 42
+        raises(TypeError, lst.Add, "test")
 
-        import Dictionary
+        lst = List[int]()
+        lst.Add(42)
+        assert lst[0] == 42
+        raises(TypeError, lst.Add, "test")        
+
+    def test_generic_metaclass_dict(self):
+        import clr
+        from System.Collections.Generic import Dictionary
+        import System.Int32
         import System.String
-        d1 = Dictionary[System.Int32,System.String]()
-        d1[1]="test"
-        raises(TypeError, d1.__setitem__, 3, 3)
+        d1 = Dictionary[System.Int32, System.String]()
+        d1[42]="test"
+        assert d1[42] == "test"
+        raises(TypeError, d1.__setitem__, 42, 42)
+
+        d1 = Dictionary[int, str]()
+        d1[42]="test"
+        assert d1[42] == "test"
+        raises(TypeError, d1.__setitem__, 42, 42)
 
+    def test_generic_metaclass_object(self):
+        import clr
+        from System.Collections.Generic import List
+        class Foo(object):
+            pass
+        lst = List[Foo]()
+        f = Foo()
+        lst.Add(f)
+        assert lst[0] is f
+
+    def test_generic_metaclass_typeerror(self):
+        import clr
+        from System.Collections.Generic import List
+        raises(TypeError, "List[int, int]")



More information about the Pypy-commit mailing list