[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