[pypy-svn] r68369 - in pypy/branch/gc-hash/pypy/annotation: . test

arigo at codespeak.net arigo at codespeak.net
Tue Oct 13 13:17:53 CEST 2009


Author: arigo
Date: Tue Oct 13 13:17:53 2009
New Revision: 68369

Modified:
   pypy/branch/gc-hash/pypy/annotation/bookkeeper.py
   pypy/branch/gc-hash/pypy/annotation/dictdef.py
   pypy/branch/gc-hash/pypy/annotation/test/test_annrpython.py
   pypy/branch/gc-hash/pypy/annotation/unaryop.py
Log:
Refactoring in the annotator, mainly to make hash() not RPython any more,
but also to force compute_identity_hash() on all prebuilt dictionary keys.


Modified: pypy/branch/gc-hash/pypy/annotation/bookkeeper.py
==============================================================================
--- pypy/branch/gc-hash/pypy/annotation/bookkeeper.py	(original)
+++ pypy/branch/gc-hash/pypy/annotation/bookkeeper.py	Tue Oct 13 13:17:53 2009
@@ -169,7 +169,6 @@
         self.pending_specializations = []   # list of callbacks
         self.external_class_cache = {}      # cache of ExternalType classes
 
-        self.needs_hash_support = {}
         self.needs_generic_instantiate = {}
 
         self.stats = Stats(self)
@@ -219,12 +218,6 @@
                 self.consider_call_site_for_pbc(pbc, 'simple_call', 
                                                 args_s, s_ImpossibleValue)
             self.emulated_pbc_calls = {}
-
-            for clsdef in self.needs_hash_support.keys():
-                for clsdef2 in self.needs_hash_support:
-                    if clsdef.issubclass(clsdef2) and clsdef is not clsdef2:
-                        del self.needs_hash_support[clsdef]
-                        break
         finally:
             self.leave()
 
@@ -399,6 +392,7 @@
                         for ek, ev in items:
                             result.dictdef.generalize_key(self.immutablevalue(ek))
                             result.dictdef.generalize_value(self.immutablevalue(ev))
+                            result.dictdef.seen_prebuilt_key(ek)
                         seen_elements = len(items)
                         # if the dictionary grew during the iteration,
                         # start over again
@@ -417,6 +411,7 @@
                 for ek, ev in x.iteritems():
                     dictdef.generalize_key(self.immutablevalue(ek, False))
                     dictdef.generalize_value(self.immutablevalue(ev, False))
+                    dictdef.seen_prebuilt_key(ek)
                 result = SomeDict(dictdef)
         elif tp is weakref.ReferenceType:
             x1 = x()

Modified: pypy/branch/gc-hash/pypy/annotation/dictdef.py
==============================================================================
--- pypy/branch/gc-hash/pypy/annotation/dictdef.py	(original)
+++ pypy/branch/gc-hash/pypy/annotation/dictdef.py	Tue Oct 13 13:17:53 2009
@@ -2,6 +2,7 @@
 from pypy.annotation.model import SomeInteger, s_Bool, unionof
 from pypy.annotation.model import SomeInstance
 from pypy.annotation.listdef import ListItem
+from pypy.rlib.objectmodel import compute_identity_hash
 
 
 class DictKey(ListItem):
@@ -10,7 +11,6 @@
     def __init__(self, bookkeeper, s_value, is_r_dict=False):
         ListItem.__init__(self, bookkeeper, s_value)
         self.is_r_dict = is_r_dict
-        self.enable_hashing()
 
     def patch(self):
         for dictdef in self.itemof:
@@ -26,15 +26,8 @@
                                               other.s_rdict_hashfn,
                                               other=other)
 
-    def enable_hashing(self):
-        # r_dicts don't need the RPython hash of their keys
-        if isinstance(self.s_value, SomeInstance) and not self.is_r_dict:
-            self.bookkeeper.needs_hash_support[self.s_value.classdef] = True
-
     def generalize(self, s_other_value):
         updated = ListItem.generalize(self, s_other_value)
-        if updated:
-            self.enable_hashing()
         if updated and self.custom_eq_hash:
             self.emulate_rdict_calls()
         return updated
@@ -139,6 +132,12 @@
     def generalize_value(self, s_value):
         self.dictvalue.generalize(s_value)
 
+    def seen_prebuilt_key(self, x):
+        try:
+            compute_identity_hash(x)
+        except TypeError:
+            pass     # e.g. if x is an int
+
     def __repr__(self):
         return '<{%r: %r}>' % (self.dictkey.s_value, self.dictvalue.s_value)
 

Modified: pypy/branch/gc-hash/pypy/annotation/test/test_annrpython.py
==============================================================================
--- pypy/branch/gc-hash/pypy/annotation/test/test_annrpython.py	(original)
+++ pypy/branch/gc-hash/pypy/annotation/test/test_annrpython.py	Tue Oct 13 13:17:53 2009
@@ -3187,15 +3187,6 @@
         s = a.build_types(f, [int])
         assert s.const == 0
 
-    def test_hash(self):
-        class A(object):
-            pass
-        def f():
-            return hash(A()) + hash(None)
-        a = self.RPythonAnnotator()
-        s = a.build_types(f, [])
-        assert s.knowntype == int
-
     def test_contains_of_empty_dict(self):
         class A(object):
             def meth(self):

Modified: pypy/branch/gc-hash/pypy/annotation/unaryop.py
==============================================================================
--- pypy/branch/gc-hash/pypy/annotation/unaryop.py	(original)
+++ pypy/branch/gc-hash/pypy/annotation/unaryop.py	Tue Oct 13 13:17:53 2009
@@ -20,11 +20,12 @@
 def immutablevalue(x):
     return getbookkeeper().immutablevalue(x)
 
-UNARY_OPERATIONS = set(['len', 'is_true', 'getattr', 'setattr', 'delattr', 'hash',
+UNARY_OPERATIONS = set(['len', 'is_true', 'getattr', 'setattr', 'delattr',
                         'simple_call', 'call_args', 'str', 'repr',
                         'iter', 'next', 'invert', 'type', 'issubtype',
                         'pos', 'neg', 'nonzero', 'abs', 'hex', 'oct',
-                        'ord', 'int', 'float', 'long', 'id',
+                        'ord', 'int', 'float', 'long',
+                        'hash', 'id',    # <== not supported any more
                         'getslice', 'setslice', 'delslice',
                         'neg_ovf', 'abs_ovf', 'hint', 'unicode', 'unichr'])
 
@@ -98,7 +99,8 @@
         return obj.is_true()
 
     def hash(obj):
-        raise TypeError, "hash() is not generally supported"
+        raise TypeError, ("cannot use hash() in RPython; "
+                          "see objectmodel.compute_xxx()")
 
     def str(obj):
         getbookkeeper().count('str', obj)
@@ -121,10 +123,8 @@
         return SomeString()
 
     def id(obj):
-        raise Exception("cannot use id() in RPython; pick one of:\n"
-                        "\t\t objectmodel.compute_unique_id()\n"
-                        "\t\t hash()\n"
-                        "\t\t objectmodel.current_object_addr_as_int()")
+        raise Exception("cannot use id() in RPython; "
+                        "see objectmodel.compute_xxx()")
 
     def int(obj):
         return SomeInteger()
@@ -203,9 +203,6 @@
             return getbookkeeper().immutablevalue(bool(self.const))
         return s_Bool
 
-    def hash(flt):
-        return SomeInteger()
-
 class __extend__(SomeInteger):
 
     def invert(self):
@@ -272,11 +269,6 @@
     def getanyitem(tup):
         return unionof(*tup.items)
 
-    def hash(tup):
-        for s_item in tup.items:
-            s_item.hash()    # record that we need the hash of each item
-        return SomeInteger()
-
     def getslice(tup, s_start, s_stop):
         assert s_start.is_immutable_constant(),"tuple slicing: needs constants"
         assert s_stop.is_immutable_constant(), "tuple slicing: needs constants"
@@ -501,9 +493,6 @@
     def ord(str):
         return SomeInteger(nonneg=True)
 
-    def hash(str):
-        return SomeInteger()
-
     def method_split(str, patt): # XXX
         getbookkeeper().count("str_split", str, patt)
         return getbookkeeper().newlist(str.basestringclass())
@@ -632,10 +621,6 @@
             # create or update the attribute in clsdef
             clsdef.generalize_attr(attr, s_value)
 
-    def hash(ins):
-        getbookkeeper().needs_hash_support[ins.classdef] = True
-        return SomeInteger()
-
     def is_true_behavior(ins, s):
         if not ins.can_be_None:
             s.const = True
@@ -694,13 +679,6 @@
         else:
             return SomeObject()    # len() on a pbc? no chance
 
-    def hash(pbc):
-        if pbc.isNone():
-            # only supports hash(None) as part of hash(<SomeInstance>)
-            return SomeInteger()
-        else:
-            return SomeObject.hash(pbc)
-
 class __extend__(SomeGenericCallable):
     def call(self, args):
         bookkeeper = getbookkeeper()



More information about the Pypy-commit mailing list