[pypy-svn] r11953 - pypy/dist/pypy/annotation

arigo at codespeak.net arigo at codespeak.net
Thu May 5 02:09:06 CEST 2005


Author: arigo
Date: Thu May  5 02:09:05 2005
New Revision: 11953

Modified:
   pypy/dist/pypy/annotation/classdef.py
   pypy/dist/pypy/annotation/unaryop.py
Log:
Annotation fun:
    sometimes, new methods can show up on classes, added
    e.g. by W_TypeObject._freeze_() -- the multimethod
    implementations.  Check that in the ClassDef...

This is really a special case for PyPy's pattern of adding
a bunch of new methods at a time.  It would break things if
we added e.g. a method that overrides another existing method.



Modified: pypy/dist/pypy/annotation/classdef.py
==============================================================================
--- pypy/dist/pypy/annotation/classdef.py	(original)
+++ pypy/dist/pypy/annotation/classdef.py	Thu May  5 02:09:05 2005
@@ -178,6 +178,8 @@
             self._generalize_attr(attr, s_value)
 
     def about_attribute(self, name):
+        """This is the interface for the code generators to ask about
+           the annotation given to a attribute."""
         for cdef in self.getmro():
             if name in cdef.attrs:
                 s_result = cdef.attrs[name].s_value
@@ -187,7 +189,7 @@
                     return None
         return None
 
-    def matching(self, pbc, name=None):
+    def matching(self, pbc, name):
         d = {}
         uplookup = None
         upfunc = None
@@ -210,13 +212,38 @@
         if uplookup is not None:
             d[upfunc] = uplookup
         elif meth:
-            if name is None:
-                name = '???'
-            self.bookkeeper.warning("demoting method %s to base class %s" % (name,self))
+            if not self.check_missing_attribute_update(name):
+                self.bookkeeper.warning("demoting method %s to base class %s" % (name,self))
         if d:
             return SomePBC(d)
         else:
             return SomeImpossibleValue()
 
+    def check_missing_attribute_update(self, name):
+        # haaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaack
+        # sometimes, new methods can show up on classes, added
+        # e.g. by W_TypeObject._freeze_() -- the multimethod
+        # implementations.  Check that here...
+        found = False
+        parents = list(self.getmro())
+        parents.reverse()
+        for base in parents:
+            if base.check_attr_here(name):
+                found = True
+        return found
+
+    def check_attr_here(self, name):
+        if name in self.cls.__dict__:
+            # oups! new attribute showed up
+            value = self.cls.__dict__[name]
+            self.add_source_for_attribute(name, value, self)
+            # maybe it also showed up in some subclass?
+            for subdef in self.getallsubdefs():
+                if subdef is not self:
+                    subdef.check_attr_here(name)
+            return True
+        else:
+            return False
+
 def isclassdef(x):
     return isinstance(x, ClassDef)

Modified: pypy/dist/pypy/annotation/unaryop.py
==============================================================================
--- pypy/dist/pypy/annotation/unaryop.py	(original)
+++ pypy/dist/pypy/annotation/unaryop.py	Thu May  5 02:09:05 2005
@@ -291,6 +291,8 @@
             # XXX do it more nicely
             if isinstance(s_result, SomePBC):
                 s_result = ins.classdef.matching(s_result, attr)
+            elif isinstance(s_result, SomeImpossibleValue):
+                ins.classdef.check_missing_attribute_update(attr)
             return s_result
         return SomeObject()
 



More information about the Pypy-commit mailing list