Author: Alex Gaynor <alex.gay...@gmail.com>
Branch: 
Changeset: r65329:9e66586a4360
Date: 2013-07-11 17:13 +1000
http://bitbucket.org/pypy/pypy/changeset/9e66586a4360/

Log:    Allow using types as a part of a hash key.

diff --git a/rpython/rtyper/lltypesystem/rclass.py 
b/rpython/rtyper/lltypesystem/rclass.py
--- a/rpython/rtyper/lltypesystem/rclass.py
+++ b/rpython/rtyper/lltypesystem/rclass.py
@@ -69,6 +69,7 @@
                             ('subclassrange_max', Signed),
                             ('rtti', Ptr(RuntimeTypeInfo)),
                             ('name', Ptr(Array(Char))),
+                            ('hash', Signed),
                             ('instantiate', Ptr(FuncType([], OBJECTPTR))),
                             hints = {'immutable': True}))
 # non-gc case
@@ -185,6 +186,7 @@
         """Initialize the 'self' portion of the 'vtable' belonging to the
         given subclass."""
         if self.classdef is None:
+            vtable.hash = hash(rsubcls)
             # initialize the 'subclassrange_*' and 'name' fields
             if rsubcls.classdef is not None:
                 #vtable.parenttypeptr = rsubcls.rbase.getvtable()
diff --git a/rpython/rtyper/lltypesystem/rpbc.py 
b/rpython/rtyper/lltypesystem/rpbc.py
--- a/rpython/rtyper/lltypesystem/rpbc.py
+++ b/rpython/rtyper/lltypesystem/rpbc.py
@@ -401,6 +401,20 @@
     def getlowleveltype(self):
         return rclass.CLASSTYPE
 
+    def get_ll_hash_function(self):
+        return ll_cls_hash
+
+    get_ll_fasthash_function = get_ll_hash_function
+
+    def get_ll_eq_function(self):
+        return None
+
+
+def ll_cls_hash(cls):
+    if not cls:
+        return 0
+    else:
+        return cls.hash
 
 # ____________________________________________________________
 
diff --git a/rpython/rtyper/test/test_rdict.py 
b/rpython/rtyper/test/test_rdict.py
--- a/rpython/rtyper/test/test_rdict.py
+++ b/rpython/rtyper/test/test_rdict.py
@@ -519,6 +519,32 @@
         res = self.interpret(f, [0])
         assert res == 4
 
+    def test_prebuilt_cls_dict(self):
+        class A(object):
+            pass
+
+        class B(A):
+            pass
+
+        d = {(A, 3): 3, (B, 0): 4}
+
+        def f(i):
+            if i:
+                cls = A
+            else:
+                cls = B
+            try:
+                return d[cls, i]
+            except KeyError:
+                return -99
+
+        res = self.interpret(f, [0])
+        assert res == 4
+        res = self.interpret(f, [3])
+        assert res == 3
+        res = self.interpret(f, [10])
+        assert res == -99
+
     def test_access_in_try(self):
         def f(d):
             try:
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to