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

antocuni at codespeak.net antocuni at codespeak.net
Fri Jan 26 11:02:11 CET 2007


Author: antocuni
Date: Fri Jan 26 11:02:11 2007
New Revision: 37372

Modified:
   pypy/dist/pypy/module/_dotnet/__init__.py
   pypy/dist/pypy/module/_dotnet/app_dotnet.py
   pypy/dist/pypy/module/_dotnet/interp_dotnet.py
   pypy/dist/pypy/module/_dotnet/test/test_dotnet.py
Log:
support for static methods



Modified: pypy/dist/pypy/module/_dotnet/__init__.py
==============================================================================
--- pypy/dist/pypy/module/_dotnet/__init__.py	(original)
+++ pypy/dist/pypy/module/_dotnet/__init__.py	Fri Jan 26 11:02:11 2007
@@ -6,8 +6,10 @@
 
     appleveldefs = {
         'ArrayList': 'app_dotnet.ArrayList',
+        'Math': 'app_dotnet.Math',
     }
     
     interpleveldefs = {
         '_CliObject_internal': 'interp_dotnet.W_CliObject',
+        'call_staticmethod': 'interp_dotnet.call_staticmethod',
     }

Modified: pypy/dist/pypy/module/_dotnet/app_dotnet.py
==============================================================================
--- pypy/dist/pypy/module/_dotnet/app_dotnet.py	(original)
+++ pypy/dist/pypy/module/_dotnet/app_dotnet.py	Fri Jan 26 11:02:11 2007
@@ -1,5 +1,20 @@
 # NOT_RPYTHON
 
+class StaticMethodWrapper(object):
+    __slots__ = ('class_name', 'meth_name',)
+
+    def __init__(self, class_name, meth_name):
+        self.class_name = class_name
+        self.meth_name = meth_name
+
+    def __call__(self, *args):
+        import _dotnet
+        return _dotnet.call_staticmethod(self.class_name, self.meth_name, args)
+
+    def __repr__(self):
+        return '<static CLI method %s.%s>' % (self.class_name, self.meth_name)
+
+
 class MethodWrapper(object):
     __slots__ = ('meth_name',)
     
@@ -15,6 +30,7 @@
     def __repr__(self):
         return '%s(%s)' % (self.__class__.__name__, repr(self.meth_name))
 
+
 class UnboundMethod(object):
     __slots__ = ('im_class', 'im_name')
     
@@ -63,8 +79,12 @@
 
 class ArrayList(CliClassWrapper):
     __cliclass__ = 'System.Collections.ArrayList'
-
     Add = MethodWrapper('Add')
     get_Item = MethodWrapper('get_Item')
     __getitem__ = get_Item
     IndexOf = MethodWrapper('IndexOf')
+
+
+class Math(CliClassWrapper):
+    __cliclass__ = 'System.Math'
+    Abs = StaticMethodWrapper(__cliclass__, 'Abs')

Modified: pypy/dist/pypy/module/_dotnet/interp_dotnet.py
==============================================================================
--- pypy/dist/pypy/module/_dotnet/interp_dotnet.py	(original)
+++ pypy/dist/pypy/module/_dotnet/interp_dotnet.py	Fri Jan 26 11:02:11 2007
@@ -10,72 +10,78 @@
 TargetInvocationException = NativeException(CLR.System.Reflection.TargetInvocationException)
 AmbiguousMatchException = NativeException(CLR.System.Reflection.AmbiguousMatchException)
 
-import sys
+def get_method(space, b_type, name, b_paramtypes):
+    try:
+        return b_type.GetMethod(name, b_paramtypes)
+    except AmbiguousMatchException:
+        msg = 'Multiple overloads for %s could match' % name
+        raise OperationError(space.w_TypeError, space.wrap(msg))
+
+
+def rewrap_args(space, w_args, startfrom):
+    args = space.unpackiterable(w_args)
+    paramlen = len(args)-startfrom
+    b_args = new_array(System.Object, paramlen)
+    b_paramtypes = new_array(System.Type, paramlen)
+    for i in range(startfrom, len(args)):
+        j = i-startfrom
+        b_obj = py2cli(space, args[i])
+        b_args[j] = b_obj
+        b_paramtypes[j] = b_obj.GetType() # XXX: potentially inefficient
+    return b_args, b_paramtypes
+
+
+def call_method(space, b_obj, b_type, name, w_args, startfrom):
+    b_args, b_paramtypes = rewrap_args(space, w_args, startfrom)
+    b_meth = get_method(space, b_type, name, b_paramtypes)
+    try:
+        # for an explanation of the box() call, see the log message for revision 35167
+        b_res = box(b_meth.Invoke(b_obj, b_args))
+    except TargetInvocationException, e:
+        b_inner = native_exc(e).get_InnerException()
+        message = str(b_inner.get_Message())
+        # TODO: use the appropriate exception, not StandardError
+        raise OperationError(space.w_StandardError, space.wrap(message))
+    return cli2py(space, b_res)
+
+def call_staticmethod(space, typename, methname, w_args):
+    b_type = System.Type.GetType(typename) # XXX: cache this!
+    return call_method(space, None, b_type, methname, w_args, 0)
+call_staticmethod.unwrap_spec = [ObjSpace, str, str, W_Root]
+
+def py2cli(space, w_obj):
+    if space.is_true(space.isinstance(w_obj, space.w_int)):
+        return box(space.int_w(w_obj))
+    if space.is_true(space.isinstance(w_obj, space.w_float)):
+        return box(space.float_w(w_obj))
+    else:
+        typename = space.type(w_obj).getname(space, '?')
+        msg = "Can't convert type %s to .NET" % typename
+        raise OperationError(space.w_TypeError, space.wrap(msg))
+
+def cli2py(space, b_obj):
+    b_type = b_obj.GetType()
+    # TODO: support other types
+    if b_type == typeof(System.Int32):
+        intval = unbox(b_obj, ootype.Signed)
+        return space.wrap(intval)
+    elif b_type == typeof(System.Double):
+        floatval = unbox(b_obj, ootype.Float)
+        return space.wrap(floatval)
+    else:
+        msg = "Can't convert object %s to Python" % str(b_obj.ToString())
+        raise OperationError(space.w_TypeError, space.wrap(msg))
+
 
 class W_CliObject(Wrappable):
     def __init__(self, space, b_obj):
         self.space = space
         self.b_obj = b_obj
 
-    def get_method(self, name, b_paramtypes):
-        b_type = self.b_obj.GetType()
-        try:
-            return b_type.GetMethod(name, b_paramtypes)
-        except AmbiguousMatchException:
-            msg = 'Multiple overloads for %s could match' % name
-            raise OperationError(self.space.w_TypeError, self.space.wrap(msg))
-
     def call_method(self, name, w_args, startfrom=0):
-        b_args, b_paramtypes = self.rewrap_args(w_args, startfrom)
-        b_meth = self.get_method(name, b_paramtypes)
-
-        try:
-            # for an explanation of the box() call, see the log message for revision 35167
-            b_res = box(b_meth.Invoke(self.b_obj, b_args))
-        except TargetInvocationException, e:
-            b_inner = native_exc(e).get_InnerException()
-            message = str(b_inner.get_Message())
-            # TODO: use the appropriate exception, not StandardError
-            raise OperationError(self.space.w_StandardError, self.space.wrap(message))
-        return self.cli2py(b_res)
+        return call_method(self.space, self.b_obj, self.b_obj.GetType(), name, w_args, startfrom)
     call_method.unwrap_spec = ['self', str, W_Root, int]
 
-    def rewrap_args(self, w_args, startfrom):
-        args = self.space.unpackiterable(w_args)
-        paramlen = len(args)-startfrom
-        b_args = new_array(System.Object, paramlen)
-        b_paramtypes = new_array(System.Type, paramlen)
-        for i in range(startfrom, len(args)):
-            j = i-startfrom
-            b_obj = self.py2cli(args[i])
-            b_args[j] = b_obj
-            b_paramtypes[j] = b_obj.GetType() # XXX: potentially inefficient
-        return b_args, b_paramtypes
-
-    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))
-        if space.is_true(space.isinstance(w_obj, self.space.w_float)):
-            return box(space.float_w(w_obj))
-        else:
-            typename = space.type(w_obj).getname(space, '?')
-            msg = "Can't convert type %s to .NET" % typename
-            raise OperationError(self.space.w_TypeError, self.space.wrap(msg))
-
-    def cli2py(self, b_obj):
-        b_type = b_obj.GetType()
-        # TODO: support other types
-        if b_type == typeof(System.Int32):
-            intval = unbox(b_obj, ootype.Signed)
-            return self.space.wrap(intval)
-        elif b_type == typeof(System.Double):
-            floatval = unbox(b_obj, ootype.Float)
-            return self.space.wrap(floatval)
-        else:
-            msg = "Can't convert object %s to Python" % str(b_obj.ToString())
-            raise OperationError(self.space.w_TypeError, self.space.wrap(msg))
-
 
 def cli_object_new(space, w_subtype, typename):
     b_type = System.Type.GetType(typename)

Modified: pypy/dist/pypy/module/_dotnet/test/test_dotnet.py
==============================================================================
--- pypy/dist/pypy/module/_dotnet/test/test_dotnet.py	(original)
+++ pypy/dist/pypy/module/_dotnet/test/test_dotnet.py	Fri Jan 26 11:02:11 2007
@@ -56,3 +56,12 @@
             obj.Add(i)
         assert obj.IndexOf(7) == 7
         assert obj.IndexOf(7, 0, 5) == -1
+
+    def test_staticmethod(self):
+        from _dotnet import Math
+        res = Math.Abs(-42)
+        assert res == 42
+        assert type(res) is int
+        res = Math.Abs(-42.0)
+        assert res == 42.0
+        assert type(res) is float



More information about the Pypy-commit mailing list