[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-svn
mailing list