[pypy-svn] r17514 - in pypy/dist/pypy: annotation rpython rpython/test

pedronis at codespeak.net pedronis at codespeak.net
Tue Sep 13 00:06:01 CEST 2005


Author: pedronis
Date: Tue Sep 13 00:05:58 2005
New Revision: 17514

Modified:
   pypy/dist/pypy/annotation/dictdef.py
   pypy/dist/pypy/rpython/rclass.py
   pypy/dist/pypy/rpython/test/test_rdict.py
Log:
enable using instances as dict key using identity



Modified: pypy/dist/pypy/annotation/dictdef.py
==============================================================================
--- pypy/dist/pypy/annotation/dictdef.py	(original)
+++ pypy/dist/pypy/annotation/dictdef.py	Tue Sep 13 00:05:58 2005
@@ -1,11 +1,16 @@
 from pypy.annotation.model import SomeObject, SomeImpossibleValue
 from pypy.annotation.model import SomeInteger, SomeBool, unionof
+from pypy.annotation.model import SomeInstance
 from pypy.annotation.listdef import ListItem
 
 
 class DictKey(ListItem):
     custom_eq_hash = False
 
+    def __init__(self, bookkeeper, s_value):
+        ListItem.__init__(self, bookkeeper, s_value)
+        self.enable_hashing()
+
     def patch(self):
         for dictdef in self.itemof:
             dictdef.dictkey = self
@@ -20,8 +25,14 @@
                                               other.s_rdict_hashfn,
                                               other=other)
 
+    def enable_hashing(self):
+        if isinstance(self.s_value, SomeInstance):
+            self.bookkeeper.needs_hash_support[self.s_value.classdef.cls] = 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

Modified: pypy/dist/pypy/rpython/rclass.py
==============================================================================
--- pypy/dist/pypy/rpython/rclass.py	(original)
+++ pypy/dist/pypy/rpython/rclass.py	Tue Sep 13 00:05:58 2005
@@ -472,7 +472,22 @@
             return result
 
     def get_ll_eq_function(self):
-        return None
+        return ll_inst_eq
+
+    def get_ll_hash_function(self):
+        if self.classdef is None:
+            return None
+        if self.rtyper.needs_hash_support( self.classdef.cls):
+            try:
+                return self._ll_hash_function
+            except AttributeError:
+                INSPTR = self.lowleveltype
+                def _ll_hash_function(ins):
+                    return ll_inst_hash(cast_pointer(INSPTR, ins))
+                self._ll_hash_function = _ll_hash_function
+                return _ll_hash_function
+        else:
+            return self.rbase.get_ll_hash_function()
 
     def initialize_prebuilt_instance(self, value, classdef, result):
         if self.classdef is not None:
@@ -671,6 +686,7 @@
         v = rpair.rtype_eq(hop)
         return hop.genop("bool_not", [v], resulttype=Bool)
 
+
 def ll_both_none(ins1, ins2):
     return not ins1 and not ins2
 
@@ -722,6 +738,9 @@
        cached = ins.hash_cache = id(ins)
     return cached
 
+def ll_inst_eq(ins1, ins2):
+    return ins1 == ins2
+
 def ll_inst_type(obj):
     if obj:
         return obj.typeptr

Modified: pypy/dist/pypy/rpython/test/test_rdict.py
==============================================================================
--- pypy/dist/pypy/rpython/test/test_rdict.py	(original)
+++ pypy/dist/pypy/rpython/test/test_rdict.py	Tue Sep 13 00:05:58 2005
@@ -382,3 +382,16 @@
             print 'current dict length:', referencelength
         assert l_dict.num_items == referencelength
     complete_check()
+
+def test_id_instances_keys():
+    class A:
+        pass
+    def f():
+        a = A()
+        b = A()
+        d = {}
+        d[a] = 1
+        d[b] = 7
+        return len(d) + d[a] + d[b]
+    res = interpret(f, [])
+    assert res == 10



More information about the Pypy-commit mailing list