[pypy-svn] r17055 - in pypy/dist/pypy: annotation translator/test

arigo at codespeak.net arigo at codespeak.net
Mon Aug 29 20:08:08 CEST 2005


Author: arigo
Date: Mon Aug 29 20:08:06 2005
New Revision: 17055

Modified:
   pypy/dist/pypy/annotation/bookkeeper.py
   pypy/dist/pypy/annotation/classdef.py
   pypy/dist/pypy/translator/test/test_annrpython.py
Log:
Yet another case of annotator problem (here creating an infinite recursion
with immutablevalue()), discovered by trying to annotate the thunk objspace.
See the new test.



Modified: pypy/dist/pypy/annotation/bookkeeper.py
==============================================================================
--- pypy/dist/pypy/annotation/bookkeeper.py	(original)
+++ pypy/dist/pypy/annotation/bookkeeper.py	Mon Aug 29 20:08:06 2005
@@ -253,7 +253,8 @@
             cdef = ClassDef(cls, self)
             self.userclasses[cls] = cdef
             self.userclasseslist.append(cdef)
-            return self.userclasses[cls]
+            cdef.setup()
+            return cdef
 
     def getlistdef(self, **flags):
         """Get the ListDef associated with the current position."""

Modified: pypy/dist/pypy/annotation/classdef.py
==============================================================================
--- pypy/dist/pypy/annotation/classdef.py	(original)
+++ pypy/dist/pypy/annotation/classdef.py	Mon Aug 29 20:08:06 2005
@@ -158,8 +158,22 @@
         if self.basedef:
             self.basedef.subdefs[cls] = self
 
+        # pass some data to the setup() method, which must be called
+        # after the __init__()
+        self.sources_from_the_class = mixeddict, sources
+
+        # forced attributes
+        if cls in FORCE_ATTRIBUTES_INTO_CLASSES:
+            for name, s_value in FORCE_ATTRIBUTES_INTO_CLASSES[cls].items():
+                self.generalize_attr(name, s_value)
+                self.find_attribute(name).readonly = False
+
+    def setup(self):
         # collect the (supposed constant) class attributes
-        for name, value in mixeddict.items():
+        cls = self.cls
+        d, sources = self.sources_from_the_class
+        del self.sources_from_the_class   # setup() shouldn't be called twice
+        for name, value in d.items():
             # ignore some special attributes
             if name.startswith('_') and not isinstance(value, FunctionType):
                 continue
@@ -168,12 +182,6 @@
                     value.class_ = cls # remember that this is really a method
             self.add_source_for_attribute(name, sources.get(name, cls), self)
 
-        # forced attributes
-        if cls in FORCE_ATTRIBUTES_INTO_CLASSES:
-            for name, s_value in FORCE_ATTRIBUTES_INTO_CLASSES[cls].items():
-                self.generalize_attr(name, s_value)
-                self.find_attribute(name).readonly = False
-
     def add_source_for_attribute(self, attr, source, clsdef=None):
         """Adds information about a constant source for an attribute.
         """

Modified: pypy/dist/pypy/translator/test/test_annrpython.py
==============================================================================
--- pypy/dist/pypy/translator/test/test_annrpython.py	(original)
+++ pypy/dist/pypy/translator/test/test_annrpython.py	Mon Aug 29 20:08:06 2005
@@ -1508,6 +1508,22 @@
         s = a.build_types(f, [])
         assert s == a.bookkeeper.immutablevalue(123)
 
+    def test_class_attribute_is_an_instance_of_itself(self):
+        class Base:
+            hello = None
+        class A(Base):
+            pass
+        A.hello = globalA = A()
+        def f():
+            return (Base().hello, globalA)
+        a = self.RPythonAnnotator()
+        s = a.build_types(f, [])
+        assert isinstance(s, annmodel.SomeTuple)
+        assert isinstance(s.items[0], annmodel.SomeInstance)
+        assert s.items[0].classdef.cls is A
+        assert s.items[0].can_be_None
+        assert s.items[1] == a.bookkeeper.immutablevalue(A.hello)
+
 def g(n):
     return [0,1,2,n]
 



More information about the Pypy-commit mailing list