[pypy-svn] r37186 - in pypy/dist/pypy/annotation: . test

arigo at codespeak.net arigo at codespeak.net
Tue Jan 23 13:42:44 CET 2007


Author: arigo
Date: Tue Jan 23 13:42:41 2007
New Revision: 37186

Modified:
   pypy/dist/pypy/annotation/test/test_annrpython.py
   pypy/dist/pypy/annotation/unaryop.py
Log:
Fix the HarmlesslyBlocked getattr, with test.


Modified: pypy/dist/pypy/annotation/test/test_annrpython.py
==============================================================================
--- pypy/dist/pypy/annotation/test/test_annrpython.py	(original)
+++ pypy/dist/pypy/annotation/test/test_annrpython.py	Tue Jan 23 13:42:41 2007
@@ -2423,6 +2423,28 @@
                 from pypy.annotation.classdef import NoSuchSlotError
                 py.test.raises(NoSuchSlotError, a.build_types, fun, [int])
 
+    def test_slots_enforce_attrs(self):
+        class Superbase(object):
+            __slots__ = 'x'
+        class Base(Superbase):
+            pass
+        class A(Base):
+            pass
+        class B(Base):
+            pass
+        def fun(s):
+            if s is None:   # known not to be None in this test
+                o = B()
+                o.x = 12
+            elif len(s) > 5:
+                o = A()
+            else:
+                o = Base()
+            return o.x
+        a = self.RPythonAnnotator()
+        s = a.build_types(fun, [str])
+        assert s == annmodel.s_ImpossibleValue   # but not blocked blocks
+
     def test_pbc_enforce_attrs(self):
         class F(object):
             _attrs_ = ['foo',]

Modified: pypy/dist/pypy/annotation/unaryop.py
==============================================================================
--- pypy/dist/pypy/annotation/unaryop.py	(original)
+++ pypy/dist/pypy/annotation/unaryop.py	Tue Jan 23 13:42:41 2007
@@ -525,10 +525,17 @@
             if isinstance(s_result, SomePBC):
                 s_result = ins.classdef.lookup_filter(s_result, attr)
             elif isinstance(s_result, SomeImpossibleValue):
-                ins.classdef.check_missing_attribute_update(attr)
-                if ins.classdef.classdesc.allslots is not None:
-                    if attr in ins.classdef.classdesc.allslots:
-                        raise HarmlesslyBlocked("getattr on a slot")
+                if ins.classdef.check_missing_attribute_update(attr):
+                    attrdef = ins.classdef.find_attribute(attr)
+                    attrdef.read_locations[position] = True
+                    s_result = attrdef.getvalue()
+                # blocking is harmless if the attribute is explicitly listed
+                # in the class or a parent class.
+                if isinstance(s_result, SomeImpossibleValue):
+                    for basedef in ins.classdef.getmro():
+                        if basedef.classdesc.allslots is not None:
+                            if attr in basedef.classdesc.allslots:
+                                raise HarmlesslyBlocked("getattr on a slot")
             return s_result
         return SomeObject()
     getattr.can_only_throw = []



More information about the Pypy-commit mailing list