[pypy-svn] r33656 - in pypy/dist/pypy/rpython/ootypesystem: . test
antocuni at codespeak.net
antocuni at codespeak.net
Tue Oct 24 15:39:53 CEST 2006
Author: antocuni
Date: Tue Oct 24 15:39:52 2006
New Revision: 33656
Modified:
pypy/dist/pypy/rpython/ootypesystem/ootype.py
pypy/dist/pypy/rpython/ootypesystem/test/test_ooann.py
pypy/dist/pypy/rpython/ootypesystem/test/test_ootype.py
Log:
Support for automatic upcast when calling overloaded methods.
Modified: pypy/dist/pypy/rpython/ootypesystem/ootype.py
==============================================================================
--- pypy/dist/pypy/rpython/ootypesystem/ootype.py (original)
+++ pypy/dist/pypy/rpython/ootypesystem/ootype.py Tue Oct 24 15:39:52 2006
@@ -889,14 +889,34 @@
signatures.add(ARGS)
def _resolve_overloading(self, ARGS):
+ # this overloading resolution algorithm is quite simple:
+ # 1) if there is an exact match between ARGS and meth.ARGS, return meth
+ # 2) if there is *only one* meth such as ARGS can be converted
+ # to meth.ARGS with one or more upcasts, return meth
+ # 3) otherwise, fail
+ matches = []
for meth in self._overloadings:
- # check if one of the overloadings has the correct signature
- # TODO: this algorithm is quite naive, it doesn't handle
- # automatic conversions
METH = meth._TYPE
if METH.ARGS == ARGS:
- return meth
- raise TypeError, 'No suitable overloading found for method'
+ return meth # case 1
+ elif self._check_upcast(ARGS, METH.ARGS):
+ matches.append(meth)
+ if len(matches) == 1:
+ return matches[0]
+ elif len(matches) > 1:
+ raise TypeError, 'More than one method match, please use explicit casts'
+ else:
+ raise TypeError, 'No suitable overloading found for method'
+
+ def _check_upcast(self, ARGS1, ARGS2):
+ if len(ARGS1) != len(ARGS2):
+ return False
+ for ARG1, ARG2 in zip(ARGS1, ARGS2):
+ if not (isinstance(ARG1, Instance) and isinstance(ARG2, Instance)):
+ return False
+ if not isSubclass(ARG1, ARG2):
+ return False
+ return True
def _annotate_overloading(self, args_s):
ARGS = tuple([self._annotation_to_lltype(arg_s) for arg_s in args_s])
Modified: pypy/dist/pypy/rpython/ootypesystem/test/test_ooann.py
==============================================================================
--- pypy/dist/pypy/rpython/ootypesystem/test/test_ooann.py (original)
+++ pypy/dist/pypy/rpython/ootypesystem/test/test_ooann.py Tue Oct 24 15:39:52 2006
@@ -308,3 +308,25 @@
return a
a = RPythonAnnotator()
assert isinstance(a.build_types(f, []), annmodel.SomeFloat)
+
+def test_overload_upcast():
+ C = Instance("base", ROOT, {}, {
+ 'foo': overload(meth(Meth([], Void)),
+ meth(Meth([ROOT], String)))})
+ def f():
+ c = new(C)
+ return c.foo(c)
+ a = RPythonAnnotator()
+ assert isinstance(a.build_types(f, []), annmodel.SomeString)
+
+def test_overload_upcast_fail():
+ C = Instance("base", ROOT, {}, {})
+ C._add_methods({
+ 'foo': overload(meth(Meth([], Signed)),
+ meth(Meth([ROOT, C], String)),
+ meth(Meth([C, ROOT], String)))})
+ def f():
+ c = new(C)
+ return c.foo(c)
+ a = RPythonAnnotator()
+ py.test.raises(TypeError, a.build_types, f, [])
Modified: pypy/dist/pypy/rpython/ootypesystem/test/test_ootype.py
==============================================================================
--- pypy/dist/pypy/rpython/ootypesystem/test/test_ootype.py (original)
+++ pypy/dist/pypy/rpython/ootypesystem/test/test_ootype.py Tue Oct 24 15:39:52 2006
@@ -191,6 +191,15 @@
assert c.m(2, 3) == 8
assert c.m(2.0) == 6
+def test_overloaded_method_upcast():
+ def m(self, dummy):
+ return 42
+ C = Instance("base", ROOT, {}, {
+ 'foo': overload(meth(Meth([ROOT], String), _callable=m))})
+ c = new(C)
+ assert c.foo(c) == 42
+
+
def test_explicit_name_clash():
C = Instance("test", ROOT, {})
More information about the Pypy-commit
mailing list