[pypy-svn] r71226 - in pypy/trunk/pypy/annotation: . test

arigo at codespeak.net arigo at codespeak.net
Sun Feb 14 15:36:50 CET 2010


Author: arigo
Date: Sun Feb 14 15:36:49 2010
New Revision: 71226

Modified:
   pypy/trunk/pypy/annotation/bookkeeper.py
   pypy/trunk/pypy/annotation/test/test_annrpython.py
Log:
__eq__ should not be called during annotation, at least
when we know that the classes differ anyway.  For cases
of hash collision that occur sometimes, notably on top
of pypy-c.


Modified: pypy/trunk/pypy/annotation/bookkeeper.py
==============================================================================
--- pypy/trunk/pypy/annotation/bookkeeper.py	(original)
+++ pypy/trunk/pypy/annotation/bookkeeper.py	Sun Feb 14 15:36:49 2010
@@ -538,7 +538,7 @@
         # this might need to expand some more.
         if x in self.descs:
             return True
-        elif x in self.seen_mutable:
+        elif (x.__class__, x) in self.seen_mutable:
             return True
         else:
             return False
@@ -564,10 +564,11 @@
             return result
 
     def see_mutable(self, x):
-        if x in self.seen_mutable:
+        key = (x.__class__, x)
+        if key in self.seen_mutable:
             return
         clsdef = self.getuniqueclassdef(x.__class__)        
-        self.seen_mutable[x] = True
+        self.seen_mutable[key] = True
         self.event('mutable', x)
         source = InstanceSource(self, x)
         for attr in source.all_instance_attributes():

Modified: pypy/trunk/pypy/annotation/test/test_annrpython.py
==============================================================================
--- pypy/trunk/pypy/annotation/test/test_annrpython.py	(original)
+++ pypy/trunk/pypy/annotation/test/test_annrpython.py	Sun Feb 14 15:36:49 2010
@@ -2445,7 +2445,33 @@
         v1, v2 = graphof(a, readout).getargs()
         assert not a.bindings[v1].is_constant()
         assert not a.bindings[v2].is_constant()
-    
+
+    def test_prebuilt_mutables_dont_use_eq(self):
+        # test that __eq__ is not called during annotation, at least
+        # when we know that the classes differ anyway
+        class Base(object):
+            def __eq__(self, other):
+                if self is other:
+                    return True
+                raise ValueError
+            def __hash__(self):
+                return 42
+        class A(Base):
+            pass
+        class B(Base):
+            pass
+        a1 = A()
+        a2 = B()
+        a1.x = 5
+        a2.x = 6
+
+        def f():
+            return a1.x + a2.x
+
+        a = self.RPythonAnnotator()
+        s = a.build_types(f, [])
+        assert s.knowntype == int
+
     def test_helper_method_annotator(self):
         def fun():
             return 21



More information about the Pypy-commit mailing list