[pypy-svn] r49811 - in pypy/branch/clr-module-improvements/pypy/module/clr: . test
regmee at codespeak.net
regmee at codespeak.net
Fri Dec 14 23:11:41 CET 2007
Author: regmee
Date: Fri Dec 14 23:11:39 2007
New Revision: 49811
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/app_importer.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:
Support for Generic classes with a single import for System.Collection.Generic, Few test cases, Import needs slight improvement
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 Fri Dec 14 23:11:39 2007
@@ -14,7 +14,8 @@
'_CliObject_internal': 'interp_clr.W_CliObject',
'call_staticmethod': 'interp_clr.call_staticmethod',
'load_cli_class': 'interp_clr.load_cli_class',
- 'load_valid_namespaces': 'interp_clr.load_valid_namespaces',
+ 'list_of_valid_namespaces': 'interp_clr.list_of_valid_namespaces',
+ '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 Fri Dec 14 23:11:39 2007
@@ -78,6 +78,46 @@
def __get__(self, obj, type_):
return self.fget()
+class MetaGenericCliClassWrapper(type):
+ def __setattr__(cls, name, value):
+ obj = cls.__dict__.get(name, None)
+ if isinstance(obj, StaticProperty):
+ obj.fset(value)
+ 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 :])
+ import clr
+ 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)
+
class MetaCliClassWrapper(type):
def __setattr__(cls, name, value):
obj = cls.__dict__.get(name, None)
@@ -115,7 +155,7 @@
obj.__cliobj__ = cliobj
return obj
-def build_wrapper(namespace, classname, staticmethods, methods, properties, indexers, hasIEnumerable):
+def build_wrapper(namespace, classname, staticmethods, methods, properties, indexers, hasIEnumerable, isClassGeneric):
fullname = '%s.%s' % (namespace, classname)
d = {'__cliclass__': fullname,
'__module__': namespace}
@@ -136,7 +176,10 @@
d['__getitem__'] = d[getter]
if setter:
d['__setitem__'] = d[setter]
- cls = MetaCliClassWrapper(classname, (CliClassWrapper,), d)
+ if isClassGeneric:
+ cls = MetaGenericCliClassWrapper(classname, (CliClassWrapper,), d)
+ else:
+ cls = MetaCliClassWrapper(classname, (CliClassWrapper,), d)
# we must add properties *after* the class has been created
# because we need to store UnboundMethods as getters and setters
Modified: pypy/branch/clr-module-improvements/pypy/module/clr/app_importer.py
==============================================================================
--- pypy/branch/clr-module-improvements/pypy/module/clr/app_importer.py (original)
+++ pypy/branch/clr-module-improvements/pypy/module/clr/app_importer.py Fri Dec 14 23:11:39 2007
@@ -62,6 +62,13 @@
# add it to the modules list
sys.modules[fullname] = mod
+ # treating System.Collections.Generic specially here.
+ # this treatment is done after the empty module insertion
+ if fullname == "System.Collections.Generic":
+ genericClassList = clr.list_of_generic_classes()
+ for genericClass in genericClassList:
+ sys.modules[genericClass[: genericClass.find('`')]] = clr.load_cli_class("System.Collections.Generic", genericClass)
+
return sys.modules[fullname]
class importer(object):
@@ -78,7 +85,7 @@
def __init__(self):
import clr
# this might not be the correct place to load the valid NameSpaces
- self.ValidNameSpaces = clr.load_valid_namespaces()
+ self.ValidNameSpaces = clr.list_of_valid_namespaces()
self.loader = loader()
def find_module(self, fullname, path = 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 Fri Dec 14 23:11:39 2007
@@ -185,7 +185,7 @@
return self.cache.get(fullname, None)
CliClassCache = _CliClassCache()
-def load_valid_namespaces(space):
+def list_of_valid_namespaces(space):
"""
We use this function to play with reflection
and then return useful data to the app_importer module
@@ -206,6 +206,36 @@
w_listOfNamespaces = wrap_list_of_strings(space, listOfNamespaces)
return w_listOfNamespaces
+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
+
def isDotNetType(space, nameFromImporter):
"""
determines if the string input is a DotNetType
@@ -302,6 +332,12 @@
if interface.ToString() == "System.Collections.IEnumerable":
hasIEnumerable = True
+ # this is where we test if the class is Generic
+ # set the flag isClassGeneric
+ isClassGeneric = False
+ if b_type.IsGenericType:
+ isClassGeneric = True
+
w_staticmethods, w_methods = get_methods(space, b_type)
w_properties, w_indexers = get_properties(space, b_type)
return build_wrapper(space,
@@ -311,7 +347,8 @@
w_methods,
w_properties,
w_indexers,
- space.wrap(hasIEnumerable))
+ space.wrap(hasIEnumerable),
+ space.wrap(isClassGeneric))
class W_CliObject(Wrappable):
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 Fri Dec 14 23:11:39 2007
@@ -160,7 +160,7 @@
enum = x.GetEnumerator()
assert enum.MoveNext() is False
- def test_iteration(self):
+ def test_iteration_arrayList(self):
import clr
ArrayList = clr.load_cli_class('System.Collections', 'ArrayList')
x = ArrayList()
@@ -215,3 +215,18 @@
raises(TypeError, x.__setitem__, 4, 4.453)
raises(TypeError, x.__setitem__, "test", 3)
+ def test_generic_class_with_single_import(self):
+ import clr
+ import System.Collections.Generic
+ import List
+ import System.Int32
+ l2 = List[System.Int32]()
+ l2.Add(3)
+ raises(TypeError, l2.Add, "test")
+
+ import Dictionary
+ import System.String
+ d1 = Dictionary[System.Int32,System.String]()
+ d1[1]="test"
+ raises(TypeError, d1.__setitem__, 3, 3)
+
More information about the Pypy-commit
mailing list