[pypy-svn] r50762 - in pypy/branch/clr-module-improvements/pypy/module/clr: . test
antocuni at codespeak.net
antocuni at codespeak.net
Fri Jan 18 21:47:22 CET 2008
Author: antocuni
Date: Fri Jan 18 21:47:21 2008
New Revision: 50762
Added:
pypy/branch/clr-module-improvements/pypy/module/clr/assemblyname.py (contents, props changed)
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
pypy/branch/clr-module-improvements/pypy/module/clr/test/test_importer.py
Log:
support for external assemblies
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 Jan 18 21:47:21 2008
@@ -15,7 +15,7 @@
'call_staticmethod': 'interp_clr.call_staticmethod',
'load_cli_class': 'interp_clr.load_cli_class',
'get_assemblies_info': 'interp_clr.get_assemblies_info',
- 'isDotNetType': 'interp_clr.isDotNetType',
+ 'AddReferenceByPartialName': 'interp_clr.AddReferenceByPartialName',
}
def startup(self, space):
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 Jan 18 21:47:21 2008
@@ -79,7 +79,8 @@
return self.fget()
def _qualify(t):
- return '%s, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' % t
+ mscorlib = 'mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'
+ return '%s, %s' % (t, mscorlib)
class MetaGenericCliClassWrapper(type):
_cli_types = {
@@ -113,7 +114,7 @@
generic_params = [cls._cli_name(t) for t in types]
instance_class = '%s[%s]' % (generic_class, ','.join(generic_params))
try:
- return clr.load_cli_class(namespace, instance_class)
+ return clr.load_cli_class(cls.__assemblyname__, namespace, instance_class)
except ImportError:
raise TypeError, "Cannot load type %s.%s" % (namespace, instance_class)
@@ -154,12 +155,14 @@
obj.__cliobj__ = cliobj
return obj
-def build_wrapper(namespace, classname, assembly_qualified_name,
+def build_wrapper(namespace, classname, assemblyname,
staticmethods, methods, properties, indexers,
hasIEnumerable, isClassGeneric):
fullname = '%s.%s' % (namespace, classname)
+ assembly_qualified_name = '%s, %s' % (fullname, assemblyname)
d = {'__cliclass__': fullname,
'__fullyqualifiedname__': assembly_qualified_name,
+ '__assemblyname__': assemblyname,
'__module__': namespace}
for name in staticmethods:
d[name] = StaticMethodWrapper(fullname, name)
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 Jan 18 21:47:21 2008
@@ -22,9 +22,9 @@
def find_module(self, fullname, path=None):
import clr
- namespaces, generic_map = clr.get_assemblies_info()
+ namespaces, classes, generics = clr.get_assemblies_info()
- if fullname in namespaces or fullname in generic_map or clr.isDotNetType(fullname):
+ if fullname in namespaces or fullname in classes:
return self # fullname is a .NET Module
else:
return None # fullname is not a .NET Module
@@ -54,18 +54,13 @@
'''
# If it is a call for a Class then return with the Class reference
import clr
- namespaces, generic_map = clr.get_assemblies_info()
+ namespaces, classes, generics = clr.get_assemblies_info()
- if clr.isDotNetType(fullname) or fullname in generic_map:
- ''' Task is to breakup System.Collections.ArrayList and call
- clr.load_cli_class('System.Collections','ArrayList')
- '''
- fullname = generic_map.get(fullname, fullname)
- rindex = fullname.rfind('.')
- if rindex != -1:
- leftStr = fullname[:rindex]
- rightStr = fullname[rindex+1:]
- sys.modules[fullname] = clr.load_cli_class(leftStr, rightStr)
+ if fullname in classes:
+ assemblyname = classes[fullname]
+ fullname = generics.get(fullname, fullname)
+ ns, classname = fullname.rsplit('.', 1)
+ sys.modules[fullname] = clr.load_cli_class(assemblyname, ns, classname)
else: # if not a call for actual class (say for namespaces) assign an empty module
if fullname not in sys.modules:
mod = CLRModule(fullname)
Added: pypy/branch/clr-module-improvements/pypy/module/clr/assemblyname.py
==============================================================================
--- (empty file)
+++ pypy/branch/clr-module-improvements/pypy/module/clr/assemblyname.py Fri Jan 18 21:47:21 2008
@@ -0,0 +1,2 @@
+mscorlib = 'mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'
+System = 'System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'
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 Jan 18 21:47:21 2008
@@ -1,4 +1,5 @@
import os.path
+from pypy.module.clr import assemblyname
from pypy.interpreter.baseobjspace import ObjSpace, W_Root, Wrappable
from pypy.interpreter.error import OperationError
from pypy.interpreter.gateway import interp2app, ApplevelClass
@@ -8,6 +9,7 @@
new_array, init_array, typeof
System = CLR.System
+Assembly = CLR.System.Reflection.Assembly
TargetInvocationException = NativeException(CLR.System.Reflection.TargetInvocationException)
AmbiguousMatchException = NativeException(CLR.System.Reflection.AmbiguousMatchException)
@@ -111,7 +113,8 @@
return space.wrap(strval)
else:
namespace, classname = split_fullname(b_type.ToString())
- w_cls = load_cli_class(space, namespace, classname)
+ assemblyname = b_type.get_Assembly().get_FullName()
+ w_cls = load_cli_class(space, assemblyname, namespace, classname)
cliobj = W_CliObject(space, b_obj)
return wrapper_from_cliobj(space, w_cls, cliobj)
@@ -177,6 +180,8 @@
properties.append((b_prop.get_Name(), get_name, set_name, is_static))
else:
indexers.append((b_prop.get_Name(), get_name, set_name, is_static))
+ if len(indexers) > 1:
+ import pdb;pdb.set_trace()
w_properties = wrap_list_of_tuples(space, properties)
w_indexers = wrap_list_of_tuples(space, indexers)
return w_properties, w_indexers
@@ -195,16 +200,22 @@
class _AssembliesInfo:
w_namespaces = None
- w_generic_map = None
- w_info = None # a tuple containing (w_namespaces, w_generic_map)
+ w_classes = None
+ w_generics = None
+ w_info = None # a tuple containing (w_namespaces, w_classes, w_generics)
AssembliesInfo = _AssembliesInfo()
def save_info_for_assembly(space, b_assembly):
info = AssembliesInfo
b_types = b_assembly.GetTypes()
+ w_assemblyName = space.wrap(b_assembly.get_FullName())
for i in range(len(b_types)):
b_type = b_types[i]
- namespace = b_type.get_Namespace()
+ namespace = str(b_type.get_Namespace())
+ fullname = str(b_type.get_FullName())
+ if '+' in fullname:
+ # it's an internal type, skip it
+ continue
if namespace is not None:
# builds all possible sub-namespaces
# (e.g. 'System', 'System.Windows', 'System.Windows.Forms')
@@ -215,41 +226,47 @@
temp_name += "."+chunk
space.setitem(info.w_namespaces, space.wrap(temp_name), space.w_None)
if b_type.get_IsGenericType():
- fullname = b_type.get_FullName()
- if '+' not in fullname:
- index = fullname.rfind("`")
- assert index >= 0
- pyName = fullname[0:index]
- space.setitem(info.w_generic_map, space.wrap(pyName), space.wrap(fullname))
+ index = fullname.rfind("`")
+ assert index >= 0
+ pyName = fullname[0:index]
+ space.setitem(info.w_classes, space.wrap(pyName), w_assemblyName)
+ space.setitem(info.w_generics, space.wrap(pyName), space.wrap(fullname))
+ else:
+ space.setitem(info.w_classes, space.wrap(fullname), w_assemblyName)
+
-def save_info_for_all_assemblies(space):
- b_currentDomain = System.AppDomain.get_CurrentDomain()
- b_assems = b_currentDomain.GetAssemblies()
- for i in range(len(b_assems)):
- save_info_for_assembly(space, b_assems[i])
+def save_info_for_std_assemblies(space):
+ # in theory we should use Assembly.Load, but it doesn't work with
+ # pythonnet because it thinks it should use the Load(byte[]) overload
+ b_mscorlib = Assembly.LoadWithPartialName(assemblyname.mscorlib)
+ b_System = Assembly.LoadWithPartialName(assemblyname.System)
+ save_info_for_assembly(space, b_mscorlib)
+ save_info_for_assembly(space, b_System)
def get_assemblies_info(space):
info = AssembliesInfo
if info.w_info is None:
info.w_namespaces = space.newdict()
- info.w_generic_map = space.newdict()
- info.w_info = space.newtuple([info.w_namespaces, info.w_generic_map])
- save_info_for_all_assemblies(space) # cache info for all standard assemblies
+ info.w_classes = space.newdict()
+ info.w_generics = space.newdict()
+ info.w_info = space.newtuple([info.w_namespaces, info.w_classes, info.w_generics])
+ save_info_for_std_assemblies(space)
return info.w_info
get_assemblies_info.unwrap_spec = [ObjSpace]
-def isDotNetType(space, nameFromImporter):
- """
- determines if the string input is a DotNetType
+#_______________________________________________________________________________
+# AddReference* methods
- Return:
- Boolean
- """
- return space.wrap(System.Type.GetType(nameFromImporter) is not None)
-isDotNetType.unwrap_spec = [ObjSpace, str]
+# AddReference', 'AddReferenceByName', 'AddReferenceByPartialName', 'AddReferenceToFile', 'AddReferenceToFileAndPath'
+
+def AddReferenceByPartialName(space, name):
+ b_assembly = Assembly.LoadWithPartialName(name)
+ if b_assembly is not None:
+ save_info_for_assembly(space, b_assembly)
+AddReferenceByPartialName.unwrap_spec = [ObjSpace, str]
-def load_cli_class(space, namespace, classname):
+def load_cli_class(space, assemblyname, namespace, classname):
"""
Load the given .NET class into the PyPy interpreter and return a
Python class referencing to it.
@@ -264,13 +281,14 @@
fullname = '%s.%s' % (namespace, classname)
w_cls = CliClassCache.get(fullname)
if w_cls is None:
- w_cls = build_cli_class(space, namespace, classname, fullname)
+ w_cls = build_cli_class(space, namespace, classname, fullname, assemblyname)
CliClassCache.put(fullname, w_cls)
return w_cls
-load_cli_class.unwrap_spec = [ObjSpace, str, str]
+load_cli_class.unwrap_spec = [ObjSpace, str, str, str]
-def build_cli_class(space, namespace, classname, fullname):
- b_type = System.Type.GetType(fullname)
+def build_cli_class(space, namespace, classname, fullname, assemblyname):
+ assembly_qualified_name = '%s, %s' % (fullname, assemblyname)
+ b_type = System.Type.GetType(assembly_qualified_name)
if b_type is None:
raise OperationError(space.w_ImportError, space.wrap("Cannot load .NET type: %s" % fullname))
@@ -278,19 +296,18 @@
# set the flag hasIEnumerable if IEnumerable interface has been by the class
hasIEnumerable = b_type.GetInterface("System.Collections.IEnumerable") is not None
- # this is where we test if the class is Generic
+ # this is where we test if the class is Generic
# set the flag isClassGeneric
isClassGeneric = False
if b_type.get_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),
+ space.wrap(assemblyname),
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 Fri Jan 18 21:47:21 2008
@@ -1,10 +1,13 @@
from pypy.conftest import gettestobjspace
+mscorlib = 'mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'
+
class AppTestDotnet:
def setup_class(cls):
space = gettestobjspace(usemodules=('clr',))
cls.space = space
-
+ cls.w_mscorlib = space.wrap(mscorlib)
+
def test_cliobject(self):
import clr
obj = clr._CliObject_internal('System.Collections.ArrayList', [])
@@ -13,17 +16,17 @@
def test_cache(self):
import clr
- ArrayList = clr.load_cli_class('System.Collections', 'ArrayList')
- ArrayList2 = clr.load_cli_class('System.Collections', 'ArrayList')
+ ArrayList = clr.load_cli_class(self.mscorlib, 'System.Collections', 'ArrayList')
+ ArrayList2 = clr.load_cli_class(self.mscorlib, 'System.Collections', 'ArrayList')
assert ArrayList is ArrayList2
def test_load_fail(self):
import clr
- raises(ImportError, clr.load_cli_class, 'Foo', 'Bar')
+ raises(ImportError, clr.load_cli_class, self.mscorlib, 'Foo', 'Bar')
def test_ArrayList(self):
import clr
- ArrayList = clr.load_cli_class('System.Collections', 'ArrayList')
+ ArrayList = clr.load_cli_class(self.mscorlib, 'System.Collections', 'ArrayList')
obj = ArrayList()
obj.Add(42)
obj.Add(43)
@@ -32,13 +35,13 @@
def test_ArrayList_error(self):
import clr
- ArrayList = clr.load_cli_class('System.Collections', 'ArrayList')
+ ArrayList = clr.load_cli_class(self.mscorlib, 'System.Collections', 'ArrayList')
obj = ArrayList()
raises(StandardError, obj.get_Item, 0)
def test_float_conversion(self):
import clr
- ArrayList = clr.load_cli_class('System.Collections', 'ArrayList')
+ ArrayList = clr.load_cli_class(self.mscorlib, 'System.Collections', 'ArrayList')
obj = ArrayList()
obj.Add(42.0)
item = obj.get_Item(0)
@@ -46,7 +49,7 @@
def test_bool_conversion(self):
import clr
- ArrayList = clr.load_cli_class('System.Collections', 'ArrayList')
+ ArrayList = clr.load_cli_class(self.mscorlib, 'System.Collections', 'ArrayList')
obj = ArrayList()
obj.Add(True)
obj.Add(False)
@@ -59,14 +62,14 @@
def test_getitem(self):
import clr
- ArrayList = clr.load_cli_class('System.Collections', 'ArrayList')
+ ArrayList = clr.load_cli_class(self.mscorlib, 'System.Collections', 'ArrayList')
obj = ArrayList()
obj.Add(42)
assert obj[0] == 42
def test_property(self):
import clr
- ArrayList = clr.load_cli_class('System.Collections', 'ArrayList')
+ ArrayList = clr.load_cli_class(self.mscorlib, 'System.Collections', 'ArrayList')
obj = ArrayList()
obj.Add(42)
assert obj.Count == 1
@@ -75,20 +78,20 @@
def test_unboundmethod(self):
import clr
- ArrayList = clr.load_cli_class('System.Collections', 'ArrayList')
+ ArrayList = clr.load_cli_class(self.mscorlib, 'System.Collections', 'ArrayList')
obj = ArrayList()
ArrayList.Add(obj, 42)
assert obj.get_Item(0) == 42
def test_unboundmethod_typeerror(self):
import clr
- ArrayList = clr.load_cli_class('System.Collections', 'ArrayList')
+ ArrayList = clr.load_cli_class(self.mscorlib, 'System.Collections', 'ArrayList')
raises(TypeError, ArrayList.Add)
raises(TypeError, ArrayList.Add, 0)
def test_overload(self):
import clr
- ArrayList = clr.load_cli_class('System.Collections', 'ArrayList')
+ ArrayList = clr.load_cli_class(self.mscorlib, 'System.Collections', 'ArrayList')
obj = ArrayList()
for i in range(10):
obj.Add(i)
@@ -97,12 +100,12 @@
def test_wrong_overload(self):
import clr
- Math = clr.load_cli_class('System', 'Math')
+ Math = clr.load_cli_class(self.mscorlib, 'System', 'Math')
raises(TypeError, Math.Abs, "foo")
def test_staticmethod(self):
import clr
- Math = clr.load_cli_class('System', 'Math')
+ Math = clr.load_cli_class(self.mscorlib, 'System', 'Math')
res = Math.Abs(-42)
assert res == 42
assert type(res) is int
@@ -112,14 +115,14 @@
def test_constructor_args(self):
import clr
- ArrayList = clr.load_cli_class('System.Collections', 'ArrayList')
+ ArrayList = clr.load_cli_class(self.mscorlib, 'System.Collections', 'ArrayList')
obj = ArrayList(42)
assert obj.Capacity == 42
def test_None_as_null(self):
import clr
- ArrayList = clr.load_cli_class('System.Collections', 'ArrayList')
- Hashtable = clr.load_cli_class('System.Collections', 'Hashtable')
+ ArrayList = clr.load_cli_class(self.mscorlib, 'System.Collections', 'ArrayList')
+ Hashtable = clr.load_cli_class(self.mscorlib, 'System.Collections', 'Hashtable')
x = ArrayList()
x.Add(None)
assert x[0] is None
@@ -128,7 +131,7 @@
def test_pass_opaque_arguments(self):
import clr
- ArrayList = clr.load_cli_class('System.Collections', 'ArrayList')
+ ArrayList = clr.load_cli_class(self.mscorlib, 'System.Collections', 'ArrayList')
class Foo:
pass
obj = Foo()
@@ -139,7 +142,7 @@
def test_string_wrapping(self):
import clr
- ArrayList = clr.load_cli_class('System.Collections', 'ArrayList')
+ ArrayList = clr.load_cli_class(self.mscorlib, 'System.Collections', 'ArrayList')
x = ArrayList()
x.Add("bar")
s = x[0]
@@ -148,21 +151,21 @@
def test_static_property(self):
import clr
import os
- Environment = clr.load_cli_class('System', 'Environment')
+ Environment = clr.load_cli_class(self.mscorlib, 'System', 'Environment')
assert Environment.CurrentDirectory == os.getcwd()
Environment.CurrentDirectory == '/'
assert Environment.CurrentDirectory == os.getcwd()
def test_GetEnumerator(self):
import clr
- ArrayList = clr.load_cli_class('System.Collections', 'ArrayList')
+ ArrayList = clr.load_cli_class(self.mscorlib, 'System.Collections', 'ArrayList')
x = ArrayList()
enum = x.GetEnumerator()
assert enum.MoveNext() is False
def test_iteration_arrayList(self):
import clr
- ArrayList = clr.load_cli_class('System.Collections', 'ArrayList')
+ ArrayList = clr.load_cli_class(self.mscorlib, 'System.Collections', 'ArrayList')
x = ArrayList()
x.Add(1)
x.Add(2)
@@ -175,7 +178,7 @@
def test_iteration_stack(self):
import clr
- Stack = clr.load_cli_class('System.Collections', 'Stack')
+ Stack = clr.load_cli_class(self.mscorlib, 'System.Collections', 'Stack')
obj = Stack()
obj.Push(1)
obj.Push(54)
@@ -187,7 +190,7 @@
def test_load_generic_class(self):
import clr
- ListInt = clr.load_cli_class("System.Collections.Generic", "List`1[System.Int32]")
+ ListInt = clr.load_cli_class(self.mscorlib, "System.Collections.Generic", "List`1[System.Int32]")
x = ListInt()
x.Add(42)
x.Add(4)
@@ -199,13 +202,15 @@
def test_generic_class_typeerror(self):
import clr
- ListInt = clr.load_cli_class("System.Collections.Generic", "List`1[System.Int32]")
+ ListInt = clr.load_cli_class(self.mscorlib, "System.Collections.Generic", "List`1[System.Int32]")
x = ListInt()
raises(TypeError, x.Add, "test")
def test_generic_dict(self):
import clr
- genDictIntStr = clr.load_cli_class("System.Collections.Generic","Dictionary`2[System.Int32,System.String]")
+ genDictIntStr = clr.load_cli_class(self.mscorlib,
+ "System.Collections.Generic",
+ "Dictionary`2[System.Int32,System.String]")
x = genDictIntStr()
x[1] = "test"
x[2] = "rest"
Modified: pypy/branch/clr-module-improvements/pypy/module/clr/test/test_importer.py
==============================================================================
--- pypy/branch/clr-module-improvements/pypy/module/clr/test/test_importer.py (original)
+++ pypy/branch/clr-module-improvements/pypy/module/clr/test/test_importer.py Fri Jan 18 21:47:21 2008
@@ -5,23 +5,31 @@
space = gettestobjspace(usemodules=('clr', ))
cls.space = space
- def test_list_of_valid_namespaces(self):
+ def test_list_of_namespaces_and_classes(self):
import clr
- ns, gen = clr.get_assemblies_info()
+ ns, classes, generics = clr.get_assemblies_info()
assert 'System' in ns
assert 'System.Collections' in ns
assert 'System.Runtime' in ns
assert 'System.Runtime.InteropServices' in ns
+ assert 'System' not in classes
+ assert 'System.Math' in classes
+ assert 'System.Collections.ArrayList' in classes
+
+ assert 'System.Collections.Generic.List' in classes
+ assert generics['System.Collections.Generic.List'] == 'System.Collections.Generic.List`1'
+
def test_import_hook_simple(self):
+ mscorlib = 'mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'
import clr
import System.Math
assert System.Math.Abs(-5) == 5
assert System.Math.Pow(2, 5) == 2**5
- Math = clr.load_cli_class('System', 'Math')
+ Math = clr.load_cli_class(mscorlib, 'System', 'Math')
assert Math is System.Math
import System
@@ -34,7 +42,7 @@
assert sum == 3+44
import System.Collections.ArrayList
- ArrayList = clr.load_cli_class('System.Collections', 'ArrayList')
+ ArrayList = clr.load_cli_class(mscorlib, 'System.Collections', 'ArrayList')
assert ArrayList is System.Collections.ArrayList
def test_ImportError(self):
@@ -55,3 +63,13 @@
def test_generic_class_import(self):
import System.Collections.Generic.List
+ def test_import_from(self):
+ from System.Collections import ArrayList
+
+ def test_AddReferenceByPartialName(self):
+ import clr
+ def fn():
+ import System.Xml.XmlWriter
+ raises(ImportError, fn)
+ clr.AddReferenceByPartialName('System.Xml')
+ fn() # does not raise
More information about the Pypy-commit
mailing list