[pypy-svn] r34915 - in pypy/dist/pypy/module/_dotnet: . test

antocuni at codespeak.net antocuni at codespeak.net
Thu Nov 23 21:43:56 CET 2006


Author: antocuni
Date: Thu Nov 23 21:43:55 2006
New Revision: 34915

Added:
   pypy/dist/pypy/module/_dotnet/
   pypy/dist/pypy/module/_dotnet/__init__.py   (contents, props changed)
   pypy/dist/pypy/module/_dotnet/app_dotnet.py   (contents, props changed)
   pypy/dist/pypy/module/_dotnet/interp_dotnet.py   (contents, props changed)
   pypy/dist/pypy/module/_dotnet/test/
   pypy/dist/pypy/module/_dotnet/test/test_dotnet.py   (contents, props changed)
   pypy/dist/pypy/module/_dotnet/test/test_dotnet.pyc   (contents, props changed)
Log:
Very first implementation of .NET integration at applevel: this is
more a proof of concept than a real implementation. The idea is to
have a thin layer at interp-level doing the dispatching to the .NET
code, and implementing all the types at application level.

This should make very easy to dynamically add new .NET wrappers,
because we just need to dynamically create applevel classes.



Added: pypy/dist/pypy/module/_dotnet/__init__.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/module/_dotnet/__init__.py	Thu Nov 23 21:43:55 2006
@@ -0,0 +1,13 @@
+# Package initialisation
+from pypy.interpreter.mixedmodule import MixedModule
+
+class Module(MixedModule):
+    """CLR module"""
+
+    appleveldefs = {
+        'ArrayList': 'app_dotnet.ArrayList',
+    }
+    
+    interpleveldefs = {
+        '_CliObject_internal': 'interp_dotnet.W_CliObject',
+    }

Added: pypy/dist/pypy/module/_dotnet/app_dotnet.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/module/_dotnet/app_dotnet.py	Thu Nov 23 21:43:55 2006
@@ -0,0 +1,15 @@
+# NOT_RPYTHON
+
+class ArrayList(object):
+    __cliname__ = 'System.Collections.ArrayList'
+    ATTRS = ['Add']
+
+    def __init__(self):
+        import _dotnet
+        self.obj = _dotnet._CliObject_internal(self.__cliname__)
+
+    def Add(self, x):
+        return self.obj.call_method('Add', [x])
+
+    def get_Item(self, idx):
+        return self.obj.call_method('get_Item', [idx])

Added: pypy/dist/pypy/module/_dotnet/interp_dotnet.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/module/_dotnet/interp_dotnet.py	Thu Nov 23 21:43:55 2006
@@ -0,0 +1,66 @@
+from pypy.interpreter.baseobjspace import ObjSpace, W_Root, Wrappable
+from pypy.interpreter.error import OperationError
+from pypy.interpreter.gateway import interp2app
+from pypy.interpreter.typedef import TypeDef
+from pypy.rpython.ootypesystem import ootype
+from pypy.translator.cli.dotnet import CLR, box, unbox, NativeException, native_exc, new_array, init_array
+
+# TODO: this code is not translatable
+
+Type = CLR.System.Type
+Object = CLR.System.Object
+TargetInvocationException = NativeException(CLR.System.Reflection.TargetInvocationException)
+
+import sys
+
+class W_CliObject(Wrappable):
+    def __init__(self, space, obj):
+        self.space = space
+        self.obj = obj
+
+    def call_method(self, name, w_args):
+        t = self.obj.GetType()
+        meth = t.GetMethod(name) # TODO: overloading!
+        args = self.rewrap_args(w_args)
+        try:
+            res = meth.Invoke(self.obj, args)
+        except TargetInvocationException, e:
+            inner = native_exc(e).get_InnerException()
+            message = str(inner.get_Message())
+            # TODO: use the appropriate exception, not StandardError
+            raise OperationError(self.space.w_StandardError, self.space.wrap(message))
+        return self.cli2py(res)
+    call_method.unwrap_spec = ['self', str, W_Root]
+
+    def rewrap_args(self, w_args):
+        py_args = self.space.unpackiterable(w_args)
+        res = new_array(Object, len(py_args))
+        for i in range(len(py_args)):
+            res[i] = self.py2cli(py_args[i])
+        return res
+
+    def py2cli(self, w_obj):
+        space = self.space
+        if space.is_true(space.isinstance(w_obj, self.space.w_int)):
+            return box(space.int_w(w_obj))
+        else:
+            assert False
+
+    def cli2py(self, obj):
+        intval = unbox(obj, ootype.Signed) # TODO: support other types
+        return self.space.wrap(intval)
+
+
+def cli_object_new(space, w_subtype, typename):
+    t = Type.GetType(typename)
+    ctor = t.GetConstructor(init_array(Type))
+    obj = ctor.Invoke(init_array(Object))
+    return space.wrap(W_CliObject(space, obj))
+cli_object_new.unwrap_spec = [ObjSpace, W_Root, str]
+
+
+W_CliObject.typedef = TypeDef(
+    '_CliObject_internal',
+    __new__ = interp2app(cli_object_new),
+    call_method = interp2app(W_CliObject.call_method),
+    )

Added: pypy/dist/pypy/module/_dotnet/test/test_dotnet.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/module/_dotnet/test/test_dotnet.py	Thu Nov 23 21:43:55 2006
@@ -0,0 +1,26 @@
+from pypy.conftest import gettestobjspace
+import os
+
+class AppTestDotnet:
+    def setup_class(cls):
+        space = gettestobjspace(usemodules=('_dotnet',))
+        cls.space = space
+
+    def test_cliobject(self):
+        import _dotnet
+        obj = _dotnet._CliObject_internal('System.Collections.ArrayList')
+        max_index = obj.call_method('Add', [42])
+        assert max_index == 0
+
+    def test_ArrayList(self):
+        import _dotnet
+        obj = _dotnet.ArrayList()
+        obj.Add(42)
+        obj.Add(43)
+        total = obj.get_Item(0) + obj.get_Item(1)
+        assert total == 42+43
+
+    def test_ArrayList_error(self):
+        import _dotnet
+        obj = _dotnet.ArrayList()
+        raises(StandardError, obj.get_Item, 0)

Added: pypy/dist/pypy/module/_dotnet/test/test_dotnet.pyc
==============================================================================
Binary file. No diff available.



More information about the Pypy-commit mailing list