[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