[pypy-svn] r30189 - in pypy/dist/pypy/translator/cli: . test

antocuni at codespeak.net antocuni at codespeak.net
Wed Jul 19 00:32:03 CEST 2006


Author: antocuni
Date: Wed Jul 19 00:31:57 2006
New Revision: 30189

Modified:
   pypy/dist/pypy/translator/cli/class_.py
   pypy/dist/pypy/translator/cli/test/test_class.py
Log:
Mark classes as abstract when they don't override abstract methods
defined in superclasses.



Modified: pypy/dist/pypy/translator/cli/class_.py
==============================================================================
--- pypy/dist/pypy/translator/cli/class_.py	(original)
+++ pypy/dist/pypy/translator/cli/class_.py	Wed Jul 19 00:31:57 2006
@@ -41,9 +41,24 @@
             return self.db.class_name(base_class)
 
     def is_abstract(self):
+        # if INSTANCE has an abstract method, the class is abstract
+        method_names = set()
         for m_name, m_meth in self.INSTANCE._methods.iteritems():
             if not hasattr(m_meth, 'graph'):
                 return True
+            method_names.add(m_name)
+
+        # if superclasses have abstract methods not overriden by
+        # INSTANCE, the class is abstract
+        abstract_method_names = set()
+        cls = self.INSTANCE._superclass
+        while cls is not None:
+            abstract_method_names.update(cls._methods.keys())
+            cls = cls._superclass
+        not_overriden = abstract_method_names.difference(method_names)
+        if not_overriden:
+            return True
+        
         return False
 
     def render(self, ilasm):        

Modified: pypy/dist/pypy/translator/cli/test/test_class.py
==============================================================================
--- pypy/dist/pypy/translator/cli/test/test_class.py	(original)
+++ pypy/dist/pypy/translator/cli/test/test_class.py	Wed Jul 19 00:31:57 2006
@@ -21,6 +21,23 @@
             return call(a, x) + call(b, x)
         assert self.interpret(fn, [0]) == 3
 
+    def test_abstract_method2(self):
+        class Root:
+            pass
+        class Class1(Root):
+            pass
+        class Derived(Class1):
+            x = 1
+        class Class2(Root):
+            x = 2
+        def get_x(obj):
+            return obj.x
+        def fn():
+            a = Derived()
+            b = Class2()
+            return get_x(a) + get_x(b)
+        assert self.interpret(fn, []) == 3
+
     def test_same_name(self):
         class A:
             def __init__(self, x):



More information about the Pypy-commit mailing list