Author: Armin Rigo <[email protected]>
Branch:
Changeset: r74896:3fe17318bbdb
Date: 2014-12-12 14:22 +0000
http://bitbucket.org/pypy/pypy/changeset/3fe17318bbdb/
Log: (cfbolz, arigo)
Fix for prebuilt r_ordereddicts.
diff --git a/rpython/annotator/bookkeeper.py b/rpython/annotator/bookkeeper.py
--- a/rpython/annotator/bookkeeper.py
+++ b/rpython/annotator/bookkeeper.py
@@ -19,7 +19,7 @@
from rpython.annotator import description
from rpython.annotator.signature import annotationoftype
from rpython.annotator.argument import simple_args
-from rpython.rlib.objectmodel import r_dict, Symbolic
+from rpython.rlib.objectmodel import r_dict, r_ordereddict, Symbolic
from rpython.tool.algo.unionfind import UnionFind
from rpython.rtyper import extregistry
@@ -260,21 +260,23 @@
result.listdef.generalize(self.immutablevalue(e))
result.const_box = key
return result
- elif tp is dict or tp is r_dict or tp is SomeOrderedDict.knowntype:
- if tp is SomeOrderedDict.knowntype:
- cls = SomeOrderedDict
- else:
- cls = SomeDict
+ elif (tp is dict or tp is r_dict or
+ tp is SomeOrderedDict.knowntype or tp is r_ordereddict):
key = Constant(x)
try:
return self.immutable_cache[key]
except KeyError:
+ if tp is SomeOrderedDict.knowntype or tp is r_ordereddict:
+ cls = SomeOrderedDict
+ else:
+ cls = SomeDict
+ is_r_dict = issubclass(tp, r_dict)
result = cls(DictDef(self,
s_ImpossibleValue,
s_ImpossibleValue,
- is_r_dict = tp is r_dict))
+ is_r_dict = is_r_dict))
self.immutable_cache[key] = result
- if tp is r_dict:
+ if is_r_dict:
s_eqfn = self.immutablevalue(x.key_eq)
s_hashfn = self.immutablevalue(x.key_hash)
result.dictdef.dictkey.update_rdict_annotations(s_eqfn,
diff --git a/rpython/rtyper/lltypesystem/rordereddict.py
b/rpython/rtyper/lltypesystem/rordereddict.py
--- a/rpython/rtyper/lltypesystem/rordereddict.py
+++ b/rpython/rtyper/lltypesystem/rordereddict.py
@@ -217,7 +217,7 @@
#dictobj = getattr(dictobj, '__self__', dictobj)
if dictobj is None:
return lltype.nullptr(self.DICT)
- if not isinstance(dictobj, (dict, objectmodel.r_dict)):
+ if not isinstance(dictobj, (dict, objectmodel.r_ordereddict)):
raise TypeError("expected a dict: %r" % (dictobj,))
try:
key = Constant(dictobj)
@@ -231,7 +231,8 @@
if r_key.lowleveltype == llmemory.Address:
raise TypeError("No prebuilt dicts of address keys")
r_value = self.value_repr
- if isinstance(dictobj, objectmodel.r_dict):
+ if isinstance(dictobj, objectmodel.r_ordereddict):
+
if self.r_rdict_eqfn.lowleveltype != lltype.Void:
l_fn = self.r_rdict_eqfn.convert_const(dictobj.key_eq)
l_dict.fnkeyeq = l_fn
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
@@ -878,6 +878,81 @@
res = self.interpret(func, [])
assert lltype.typeOf(res.item0) == lltype.typeOf(res.item1)
+ def test_r_dict(self):
+ class FooError(Exception):
+ pass
+ def myeq(n, m):
+ return n == m
+ def myhash(n):
+ if n < 0:
+ raise FooError
+ return -n
+ def f(n):
+ d = self.new_r_dict(myeq, myhash)
+ for i in range(10):
+ d[i] = i*i
+ try:
+ value1 = d[n]
+ except FooError:
+ value1 = 99
+ try:
+ value2 = n in d
+ except FooError:
+ value2 = 99
+ try:
+ value3 = d[-n]
+ except FooError:
+ value3 = 99
+ try:
+ value4 = (-n) in d
+ except FooError:
+ value4 = 99
+ return (value1 * 1000000 +
+ value2 * 10000 +
+ value3 * 100 +
+ value4)
+ res = self.interpret(f, [5])
+ assert res == 25019999
+
+ def test_r_dict_popitem_hash(self):
+ def deq(n, m):
+ return n == m
+ def dhash(n):
+ return ~n
+ def func():
+ d = self.new_r_dict(deq, dhash)
+ d[5] = 2
+ d[6] = 3
+ k1, v1 = d.popitem()
+ assert len(d) == 1
+ k2, v2 = d.popitem()
+ try:
+ d.popitem()
+ except KeyError:
+ pass
+ else:
+ assert 0, "should have raised KeyError"
+ assert len(d) == 0
+ return k1*1000 + v1*100 + k2*10 + v2
+
+ res = self.interpret(func, [])
+ assert res in [5263, 6352]
+
+ def test_prebuilt_r_dict(self):
+ def deq(n, m):
+ return (n & 3) == (m & 3)
+ def dhash(n):
+ return n & 3
+ d = self.new_r_dict(deq, dhash)
+ d[0x123] = "abcd"
+ d[0x231] = "efgh"
+ def func():
+ return d[0x348973] + d[0x12981]
+
+ res = self.interpret(func, [])
+ res = self.ll_to_string(res)
+ assert res == "abcdefgh"
+
class TestRDict(BaseTestRDict):
@staticmethod
@@ -888,6 +963,10 @@
def newdict2():
return {}
+ @staticmethod
+ def new_r_dict(myeq, myhash):
+ return r_dict(myeq, myhash)
+
def test_two_dicts_with_different_value_types(self):
def func(i):
d1 = {}
@@ -1043,66 +1122,6 @@
assert lltype.typeOf(res.item1) == lltype.typeOf(res.item2)
assert lltype.typeOf(res.item1) == lltype.typeOf(res.item3)
- def test_r_dict(self):
- class FooError(Exception):
- pass
- def myeq(n, m):
- return n == m
- def myhash(n):
- if n < 0:
- raise FooError
- return -n
- def f(n):
- d = r_dict(myeq, myhash)
- for i in range(10):
- d[i] = i*i
- try:
- value1 = d[n]
- except FooError:
- value1 = 99
- try:
- value2 = n in d
- except FooError:
- value2 = 99
- try:
- value3 = d[-n]
- except FooError:
- value3 = 99
- try:
- value4 = (-n) in d
- except FooError:
- value4 = 99
- return (value1 * 1000000 +
- value2 * 10000 +
- value3 * 100 +
- value4)
- res = self.interpret(f, [5])
- assert res == 25019999
-
- def test_dict_popitem_hash(self):
- def deq(n, m):
- return n == m
- def dhash(n):
- return ~n
- def func():
- d = r_dict(deq, dhash)
- d[5] = 2
- d[6] = 3
- k1, v1 = d.popitem()
- assert len(d) == 1
- k2, v2 = d.popitem()
- try:
- d.popitem()
- except KeyError:
- pass
- else:
- assert 0, "should have raised KeyError"
- assert len(d) == 0
- return k1*1000 + v1*100 + k2*10 + v2
-
- res = self.interpret(func, [])
- assert res in [5263, 6352]
-
def test_nonnull_hint(self):
def eq(a, b):
return a == b
diff --git a/rpython/rtyper/test/test_rordereddict.py
b/rpython/rtyper/test/test_rordereddict.py
--- a/rpython/rtyper/test/test_rordereddict.py
+++ b/rpython/rtyper/test/test_rordereddict.py
@@ -268,6 +268,10 @@
def newdict2():
return OrderedDict()
+ @staticmethod
+ def new_r_dict(myeq, myhash):
+ return objectmodel.r_ordereddict(myeq, myhash)
+
def test_two_dicts_with_different_value_types(self):
def func(i):
d1 = OrderedDict()
@@ -283,64 +287,3 @@
def test_memoryerror_should_not_insert(self):
py.test.skip("I don't want to edit this file on two branches")
-
-
- def test_r_dict(self):
- class FooError(Exception):
- pass
- def myeq(n, m):
- return n == m
- def myhash(n):
- if n < 0:
- raise FooError
- return -n
- def f(n):
- d = objectmodel.r_ordereddict(myeq, myhash)
- for i in range(10):
- d[i] = i*i
- try:
- value1 = d[n]
- except FooError:
- value1 = 99
- try:
- value2 = n in d
- except FooError:
- value2 = 99
- try:
- value3 = d[-n]
- except FooError:
- value3 = 99
- try:
- value4 = (-n) in d
- except FooError:
- value4 = 99
- return (value1 * 1000000 +
- value2 * 10000 +
- value3 * 100 +
- value4)
- res = self.interpret(f, [5])
- assert res == 25019999
-
- def test_dict_popitem_hash(self):
- def deq(n, m):
- return n == m
- def dhash(n):
- return ~n
- def func():
- d = objectmodel.r_ordereddict(deq, dhash)
- d[5] = 2
- d[6] = 3
- k1, v1 = d.popitem()
- assert len(d) == 1
- k2, v2 = d.popitem()
- try:
- d.popitem()
- except KeyError:
- pass
- else:
- assert 0, "should have raised KeyError"
- assert len(d) == 0
- return k1*1000 + v1*100 + k2*10 + v2
-
- res = self.interpret(func, [])
- assert res in [5263, 6352]
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit