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

antocuni at codespeak.net antocuni at codespeak.net
Thu Jan 25 18:23:55 CET 2007


Author: antocuni
Date: Thu Jan 25 18:23:54 2007
New Revision: 37349

Modified:
   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:
Initial support for dispatching to overloaded methods.



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	Thu Jan 25 18:23:54 2007
@@ -25,7 +25,7 @@
     def __raise_TypeError(self, thing):
         raise TypeError, 'unbound method %s() must be called with %s ' \
               'instance as first argument (got %s instead)' % \
-              (self.im_name, self.im_class.__cliname__, thing)
+              (self.im_name, self.im_class.__cliclass__, thing)
 
     def __call__(self, *args):
         if len(args) == 0:
@@ -36,7 +36,7 @@
         return im_self.__cliobj__.call_method(self.im_name, args, 1) # ignore the first arg
 
     def __repr__(self):
-        return '<unbound CLI method %s.%s>' % (self.im_class.__cliname__, self.im_name)
+        return '<unbound CLI method %s.%s>' % (self.im_class.__cliclass__, self.im_name)
 
 
 class BoundMethod(object):
@@ -50,7 +50,7 @@
         return self.im_self.__cliobj__.call_method(self.im_name, args)
 
     def __repr__(self):
-        return '<bound CLI method %s.%s of %s>' % (self.im_self.__class__.__cliname__, self.im_name, self.im_self)
+        return '<bound CLI method %s.%s of %s>' % (self.im_self.__class__.__cliclass__, self.im_name, self.im_self)
 
 
 class CliClassWrapper(object):
@@ -58,12 +58,13 @@
 
     def __init__(self):
         import _dotnet
-        self.__cliobj__ = _dotnet._CliObject_internal(self.__cliname__)
+        self.__cliobj__ = _dotnet._CliObject_internal(self.__cliclass__)
 
 
 class ArrayList(CliClassWrapper):
-    __cliname__ = 'System.Collections.ArrayList'
+    __cliclass__ = 'System.Collections.ArrayList'
 
     Add = MethodWrapper('Add')
     get_Item = MethodWrapper('get_Item')
     __getitem__ = get_Item
+    IndexOf = MethodWrapper('IndexOf')

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	Thu Jan 25 18:23:54 2007
@@ -8,6 +8,7 @@
 
 System = CLR.System
 TargetInvocationException = NativeException(CLR.System.Reflection.TargetInvocationException)
+AmbiguousMatchException = NativeException(CLR.System.Reflection.AmbiguousMatchException)
 
 import sys
 
@@ -16,10 +17,18 @@
         self.space = space
         self.b_obj = b_obj
 
-    def call_method(self, name, w_args, startfrom=0):
+    def get_method(self, name, b_paramtypes):
         b_type = self.b_obj.GetType()
-        b_meth = b_type.GetMethod(name) # TODO: overloading!
-        b_args = self.rewrap_args(w_args, startfrom)
+        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))
@@ -33,10 +42,15 @@
 
     def rewrap_args(self, w_args, startfrom):
         args = self.space.unpackiterable(w_args)
-        b_res = new_array(System.Object, len(args)-startfrom)
+        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)):
-            b_res[i-startfrom] = self.py2cli(args[i])
-        return b_res
+            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

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	Thu Jan 25 18:23:54 2007
@@ -48,3 +48,11 @@
         import _dotnet
         raises(TypeError, _dotnet.ArrayList.Add)
         raises(TypeError, _dotnet.ArrayList.Add, 0)
+
+    def test_overload(self):
+        import _dotnet
+        obj = _dotnet.ArrayList()
+        for i in range(10):
+            obj.Add(i)
+        assert obj.IndexOf(7) == 7
+        assert obj.IndexOf(7, 0, 5) == -1



More information about the Pypy-commit mailing list