[pypy-svn] r17432 - in pypy/dist/pypy: annotation rpython/test
arigo at codespeak.net
arigo at codespeak.net
Fri Sep 9 21:00:39 CEST 2005
Author: arigo
Date: Fri Sep 9 21:00:36 2005
New Revision: 17432
Modified:
pypy/dist/pypy/annotation/builtin.py
pypy/dist/pypy/annotation/dictdef.py
pypy/dist/pypy/annotation/listdef.py
pypy/dist/pypy/rpython/test/test_objectmodel.py
Log:
Annotating r_dicts.
Modified: pypy/dist/pypy/annotation/builtin.py
==============================================================================
--- pypy/dist/pypy/annotation/builtin.py (original)
+++ pypy/dist/pypy/annotation/builtin.py Fri Sep 9 21:00:36 2005
@@ -9,7 +9,7 @@
from pypy.annotation.model import SomeList, SomeString, SomeTuple, SomeSlice
from pypy.annotation.model import SomeUnicodeCodePoint, SomeAddress
from pypy.annotation.model import SomeFloat, unionof
-from pypy.annotation.model import SomePBC, SomeInstance
+from pypy.annotation.model import SomePBC, SomeInstance, SomeDict
from pypy.annotation.model import annotation_to_lltype
from pypy.annotation.model import add_knowntypedata
from pypy.annotation.bookkeeper import getbookkeeper
@@ -236,6 +236,10 @@
def robjmodel_we_are_translated():
return immutablevalue(True)
+def robjmodel_r_dict(s_eqfn, s_hashfn):
+ dictdef = getbookkeeper().getdictdef()
+ dictdef.dictkey.update_rdict_annotations(s_eqfn, s_hashfn)
+ return SomeDict(dictdef)
##def rarith_ovfcheck(s_obj):
## if isinstance(s_obj, SomeInteger) and s_obj.unsigned:
@@ -275,6 +279,7 @@
BUILTIN_ANALYZERS[pypy.rpython.objectmodel.instantiate] = robjmodel_instantiate
BUILTIN_ANALYZERS[pypy.rpython.objectmodel.we_are_translated] = (
robjmodel_we_are_translated)
+BUILTIN_ANALYZERS[pypy.rpython.objectmodel.r_dict] = robjmodel_r_dict
BUILTIN_ANALYZERS[Exception.__init__.im_func] = exception_init
BUILTIN_ANALYZERS[OSError.__init__.im_func] = exception_init
Modified: pypy/dist/pypy/annotation/dictdef.py
==============================================================================
--- pypy/dist/pypy/annotation/dictdef.py (original)
+++ pypy/dist/pypy/annotation/dictdef.py Fri Sep 9 21:00:36 2005
@@ -1,12 +1,52 @@
from pypy.annotation.model import SomeObject, SomeImpossibleValue
+from pypy.annotation.model import SomeInteger, SomeBool, unionof
from pypy.annotation.listdef import ListItem
class DictKey(ListItem):
+ custom_eq_hash = False
+
def patch(self):
for dictdef in self.itemof:
dictdef.dictkey = self
+ def merge(self, other):
+ if self is not other:
+ assert self.custom_eq_hash == other.custom_eq_hash, (
+ "mixing plain dictionaries with r_dict()")
+ ListItem.merge(self, other)
+ if self.custom_eq_hash:
+ self.update_rdict_annotations(other.s_rdict_eqfn,
+ other.s_rdict_hashfn)
+
+ def generalize(self, s_other_value):
+ updated = ListItem.generalize(self, s_other_value)
+ if updated and self.custom_eq_hash:
+ self.emulate_rdict_calls()
+ return updated
+
+ def update_rdict_annotations(self, s_eqfn, s_hashfn):
+ if not self.custom_eq_hash:
+ self.custom_eq_hash = True
+ else:
+ s_eqfn = unionof(s_eqfn, self.s_rdict_eqfn)
+ s_hashfn = unionof(s_hashfn, self.s_rdict_hashfn)
+ self.s_rdict_eqfn = s_eqfn
+ self.s_rdict_hashfn = s_hashfn
+ self.emulate_rdict_calls()
+
+ def emulate_rdict_calls(self):
+ s_key = self.s_value
+ s1 = self.bookkeeper.emulate_pbc_call(self.s_rdict_eqfn, [s_key, s_key])
+ assert SomeBool().contains(s1), (
+ "the custom eq function of an r_dict must return a boolean"
+ " (got %r)" % (s1,))
+ s2 = self.bookkeeper.emulate_pbc_call(self.s_rdict_hashfn, [s_key])
+ assert SomeInteger().contains(s2), (
+ "the custom hash function of an r_dict must return an integer"
+ " (got %r)" % (s2,))
+
+
class DictValue(ListItem):
def patch(self):
for dictdef in self.itemof:
Modified: pypy/dist/pypy/annotation/listdef.py
==============================================================================
--- pypy/dist/pypy/annotation/listdef.py (original)
+++ pypy/dist/pypy/annotation/listdef.py Fri Sep 9 21:00:36 2005
@@ -49,11 +49,13 @@
s_new_value = unionof(self.s_value, s_other_value)
if isdegenerated(s_new_value):
self.bookkeeper.ondegenerated(self, s_new_value)
- if s_new_value != self.s_value:
+ updated = s_new_value != self.s_value
+ if updated:
self.s_value = s_new_value
# reflow from all reading points
for position_key in self.read_locations:
self.bookkeeper.annotator.reflowfromposition(position_key)
+ return updated
class ListDef:
Modified: pypy/dist/pypy/rpython/test/test_objectmodel.py
==============================================================================
--- pypy/dist/pypy/rpython/test/test_objectmodel.py (original)
+++ pypy/dist/pypy/rpython/test/test_objectmodel.py Fri Sep 9 21:00:36 2005
@@ -1,5 +1,5 @@
-import py
from pypy.rpython.objectmodel import *
+from pypy.translator.translator import Translator
from pypy.rpython.test.test_llinterp import interpret
@@ -11,15 +11,23 @@
res = interpret(fn, [])
assert res is True
+
+def strange_key_eq(key1, key2):
+ return key1[0] == key2[0] # only the 1st character is relevant
+def strange_key_hash(key):
+ return ord(key[0])
+
def test_r_dict():
- def key_eq(key1, key2):
- return key1[0] == key2[0] # only the 1st character is relevant
- def key_hash(key):
- return ord(key[0])
- d = r_dict(key_eq, key_hash)
+ # NB. this test function is also annotated/rtyped by the next tests
+ d = r_dict(strange_key_eq, strange_key_hash)
d['hello'] = 42
assert d['hi there'] == 42
- py.test.raises(KeyError, 'd["dumb"]')
+ try:
+ d["dumb"]
+ except KeyError:
+ pass
+ else:
+ assert False, "should have raised"
assert len(d) == 1
assert 'oops' not in d
assert list(d) == ['hello']
@@ -37,3 +45,20 @@
assert list(d.iteritems()) == [('hello', 42)]
d.clear()
assert d.keys() == []
+ return True # for the tests below
+
+def test_annotate_r_dict():
+ t = Translator(test_r_dict)
+ a = t.annotate([])
+ #t.view()
+ assert strange_key_eq in t.flowgraphs
+ assert strange_key_hash in t.flowgraphs
+ graph = t.flowgraphs[strange_key_eq]
+ assert a.binding(graph.getargs()[0]).knowntype == str
+ assert a.binding(graph.getargs()[1]).knowntype == str
+ graph = t.flowgraphs[strange_key_hash]
+ assert a.binding(graph.getargs()[0]).knowntype == str
+
+def INPROGRESS_test_rtype_r_dict():
+ res = interpret(test_r_dict, [])
+ assert res is True
More information about the Pypy-commit
mailing list