[pypy-commit] pypy default: merge heads
arigo
noreply at buildbot.pypy.org
Wed Jun 29 09:32:18 CEST 2011
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r45174:c19ba84541c5
Date: 2011-06-29 09:40 +0200
http://bitbucket.org/pypy/pypy/changeset/c19ba84541c5/
Log: merge heads
diff --git a/pypy/annotation/bookkeeper.py b/pypy/annotation/bookkeeper.py
--- a/pypy/annotation/bookkeeper.py
+++ b/pypy/annotation/bookkeeper.py
@@ -299,12 +299,13 @@
listdef.generalize_range_step(flags['range_step'])
return SomeList(listdef)
- def getdictdef(self, is_r_dict=False):
+ def getdictdef(self, is_r_dict=False, force_non_null=False):
"""Get the DictDef associated with the current position."""
try:
dictdef = self.dictdefs[self.position_key]
except KeyError:
- dictdef = DictDef(self, is_r_dict=is_r_dict)
+ dictdef = DictDef(self, is_r_dict=is_r_dict,
+ force_non_null=force_non_null)
self.dictdefs[self.position_key] = dictdef
return dictdef
diff --git a/pypy/annotation/builtin.py b/pypy/annotation/builtin.py
--- a/pypy/annotation/builtin.py
+++ b/pypy/annotation/builtin.py
@@ -311,8 +311,14 @@
def robjmodel_we_are_translated():
return immutablevalue(True)
-def robjmodel_r_dict(s_eqfn, s_hashfn):
- dictdef = getbookkeeper().getdictdef(is_r_dict=True)
+def robjmodel_r_dict(s_eqfn, s_hashfn, s_force_non_null=None):
+ if s_force_non_null is None:
+ force_non_null = False
+ else:
+ assert s_force_non_null.is_constant()
+ force_non_null = s_force_non_null.const
+ dictdef = getbookkeeper().getdictdef(is_r_dict=True,
+ force_non_null=force_non_null)
dictdef.dictkey.update_rdict_annotations(s_eqfn, s_hashfn)
return SomeDict(dictdef)
diff --git a/pypy/annotation/dictdef.py b/pypy/annotation/dictdef.py
--- a/pypy/annotation/dictdef.py
+++ b/pypy/annotation/dictdef.py
@@ -85,12 +85,14 @@
def __init__(self, bookkeeper, s_key = s_ImpossibleValue,
s_value = s_ImpossibleValue,
- is_r_dict = False):
+ is_r_dict = False,
+ force_non_null = False):
self.dictkey = DictKey(bookkeeper, s_key, is_r_dict)
self.dictkey.itemof[self] = True
self.dictvalue = DictValue(bookkeeper, s_value)
self.dictvalue.itemof[self] = True
self.bookkeeper = bookkeeper
+ self.force_non_null = force_non_null
def read_key(self, position_key=None):
if position_key is None:
diff --git a/pypy/module/cpyext/api.py b/pypy/module/cpyext/api.py
--- a/pypy/module/cpyext/api.py
+++ b/pypy/module/cpyext/api.py
@@ -562,7 +562,8 @@
elif callable.api_func.restype is not lltype.Void:
retval = rffi.cast(callable.api_func.restype, result)
except Exception, e:
- print 'Fatal error in cpyext, calling', callable.__name__
+ print 'Fatal error in cpyext, CPython compatibility layer, calling', callable.__name__
+ print 'Either report a bug or consider not using this particular extension'
if not we_are_translated():
import traceback
traceback.print_exc()
diff --git a/pypy/objspace/std/dictmultiobject.py b/pypy/objspace/std/dictmultiobject.py
--- a/pypy/objspace/std/dictmultiobject.py
+++ b/pypy/objspace/std/dictmultiobject.py
@@ -1,13 +1,14 @@
import py, sys
from pypy.objspace.std.model import registerimplementation, W_Object
from pypy.objspace.std.register_all import register_all
+from pypy.objspace.std.settype import set_typedef as settypedef
from pypy.interpreter import gateway
from pypy.interpreter.argument import Signature
from pypy.interpreter.error import OperationError, operationerrfmt
from pypy.module.__builtin__.__init__ import BUILTIN_TO_INDEX, OPTIMIZED_BUILTINS
from pypy.rlib.objectmodel import r_dict, we_are_translated
-from pypy.objspace.std.settype import set_typedef as settypedef
+from pypy.rlib.debug import mark_dict_non_null
def _is_str(space, w_key):
return space.is_w(space.type(w_key), space.w_str)
@@ -59,7 +60,8 @@
def initialize_as_rdict(self):
assert self.r_dict_content is None
- self.r_dict_content = r_dict(self.space.eq_w, self.space.hash_w)
+ self.r_dict_content = r_dict(self.space.eq_w, self.space.hash_w,
+ force_non_null=True)
return self.r_dict_content
@@ -308,6 +310,7 @@
def __init__(self, space):
self.space = space
self.content = {}
+ mark_dict_non_null(self.content)
def impl_setitem(self, w_key, w_value):
space = self.space
@@ -317,6 +320,7 @@
self._as_rdict().impl_fallback_setitem(w_key, w_value)
def impl_setitem_str(self, key, w_value):
+ assert key is not None
self.content[key] = w_value
def impl_setdefault(self, w_key, w_default):
@@ -342,6 +346,7 @@
return len(self.content)
def impl_getitem_str(self, key):
+ assert key is not None
return self.content.get(key, None)
def impl_getitem(self, w_key):
diff --git a/pypy/objspace/std/setobject.py b/pypy/objspace/std/setobject.py
--- a/pypy/objspace/std/setobject.py
+++ b/pypy/objspace/std/setobject.py
@@ -112,7 +112,7 @@
# some helper functions
def newset(space):
- return r_dict(space.eq_w, space.hash_w)
+ return r_dict(space.eq_w, space.hash_w, force_non_null=True)
def make_setdata_from_w_iterable(space, w_iterable=None):
"""Return a new r_dict with the content of w_iterable."""
diff --git a/pypy/rlib/debug.py b/pypy/rlib/debug.py
--- a/pypy/rlib/debug.py
+++ b/pypy/rlib/debug.py
@@ -262,6 +262,28 @@
return hop.inputarg(hop.args_r[0], arg=0)
+def mark_dict_non_null(d):
+ """ Mark dictionary as having non-null keys and values. A warning would
+ be emitted (not an error!) in case annotation disagrees.
+ """
+ assert isinstance(d, dict)
+ return d
+
+
+class DictMarkEntry(ExtRegistryEntry):
+ _about_ = mark_dict_non_null
+
+ def compute_result_annotation(self, s_dict):
+ from pypy.annotation.model import SomeDict, s_None
+
+ assert isinstance(s_dict, SomeDict)
+ s_dict.dictdef.force_non_null = True
+ return s_dict
+
+ def specialize_call(self, hop):
+ hop.exception_cannot_occur()
+ return hop.inputarg(hop.args_r[0], arg=0)
+
class IntegerCanBeNegative(Exception):
pass
diff --git a/pypy/rlib/objectmodel.py b/pypy/rlib/objectmodel.py
--- a/pypy/rlib/objectmodel.py
+++ b/pypy/rlib/objectmodel.py
@@ -448,10 +448,11 @@
The functions key_eq() and key_hash() are used by the key comparison
algorithm."""
- def __init__(self, key_eq, key_hash):
+ def __init__(self, key_eq, key_hash, force_non_null=False):
self._dict = {}
self.key_eq = key_eq
self.key_hash = key_hash
+ self.force_non_null = force_non_null
def __getitem__(self, key):
return self._dict[_r_dictkey(self, key)]
diff --git a/pypy/rlib/test/test_debug.py b/pypy/rlib/test/test_debug.py
--- a/pypy/rlib/test/test_debug.py
+++ b/pypy/rlib/test/test_debug.py
@@ -1,11 +1,12 @@
import py
-from pypy.rlib.debug import check_annotation, make_sure_not_resized
-from pypy.rlib.debug import debug_print, debug_start, debug_stop
-from pypy.rlib.debug import have_debug_prints, debug_offset, debug_flush
-from pypy.rlib.debug import check_nonneg, IntegerCanBeNegative
+from pypy.rlib.debug import (check_annotation, make_sure_not_resized,
+ debug_print, debug_start, debug_stop,
+ have_debug_prints, debug_offset, debug_flush,
+ check_nonneg, IntegerCanBeNegative,
+ mark_dict_non_null)
from pypy.rlib import debug
-from pypy.rpython.test.test_llinterp import interpret
+from pypy.rpython.test.test_llinterp import interpret, gengraph
def test_check_annotation():
class Error(Exception):
@@ -52,8 +53,17 @@
py.test.raises(ListChangeUnallowed, interpret, f, [],
list_comprehension_operations=True)
+def test_mark_dict_non_null():
+ def f():
+ d = {"ac": "bx"}
+ mark_dict_non_null(d)
+ return d
-class DebugTests:
+ t, typer, graph = gengraph(f, [])
+ assert sorted(graph.returnblock.inputargs[0].concretetype.TO.entries.TO.OF._flds.keys()) == ['key', 'value']
+
+
+class DebugTests(object):
def test_debug_print_start_stop(self):
def f(x):
diff --git a/pypy/rpython/lltypesystem/rdict.py b/pypy/rpython/lltypesystem/rdict.py
--- a/pypy/rpython/lltypesystem/rdict.py
+++ b/pypy/rpython/lltypesystem/rdict.py
@@ -9,6 +9,7 @@
from pypy.rpython import robject
from pypy.rlib import objectmodel, jit
from pypy.rpython import rmodel
+from pypy.rpython.error import TyperError
HIGHEST_BIT = intmask(1 << (LONG_BIT - 1))
MASK = intmask(HIGHEST_BIT - 1)
@@ -42,7 +43,7 @@
class DictRepr(AbstractDictRepr):
def __init__(self, rtyper, key_repr, value_repr, dictkey, dictvalue,
- custom_eq_hash=None):
+ custom_eq_hash=None, force_non_null=False):
self.rtyper = rtyper
self.DICT = lltype.GcForwardReference()
self.lowleveltype = lltype.Ptr(self.DICT)
@@ -61,6 +62,7 @@
self.dictvalue = dictvalue
self.dict_cache = {}
self._custom_eq_hash_repr = custom_eq_hash
+ self.force_non_null = force_non_null
# setup() needs to be called to finish this initialization
def _externalvsinternal(self, rtyper, item_repr):
@@ -97,6 +99,13 @@
s_value = self.dictvalue.s_value
nullkeymarker = not self.key_repr.can_ll_be_null(s_key)
nullvaluemarker = not self.value_repr.can_ll_be_null(s_value)
+ if self.force_non_null:
+ if not nullkeymarker:
+ rmodel.warning("%s can be null, but forcing non-null in dict key" % s_key)
+ nullkeymarker = True
+ if not nullvaluemarker:
+ rmodel.warning("%s can be null, but forcing non-null in dict value" % s_value)
+ nullvaluemarker = True
dummykeyobj = self.key_repr.get_ll_dummyval_obj(self.rtyper,
s_key)
dummyvalueobj = self.value_repr.get_ll_dummyval_obj(self.rtyper,
@@ -640,12 +649,15 @@
pass
-def rtype_r_dict(hop):
+def rtype_r_dict(hop, i_force_non_null=None):
r_dict = hop.r_result
if not r_dict.custom_eq_hash:
raise TyperError("r_dict() call does not return an r_dict instance")
- v_eqfn, v_hashfn = hop.inputargs(r_dict.r_rdict_eqfn,
- r_dict.r_rdict_hashfn)
+ v_eqfn = hop.inputarg(r_dict.r_rdict_eqfn, arg=0)
+ v_hashfn = hop.inputarg(r_dict.r_rdict_hashfn, arg=1)
+ if i_force_non_null is not None:
+ assert i_force_non_null == 2
+ hop.inputarg(lltype.Void, arg=2)
cDICT = hop.inputconst(lltype.Void, r_dict.DICT)
hop.exception_cannot_occur()
v_result = hop.gendirectcall(ll_newdict, cDICT)
diff --git a/pypy/rpython/ootypesystem/rdict.py b/pypy/rpython/ootypesystem/rdict.py
--- a/pypy/rpython/ootypesystem/rdict.py
+++ b/pypy/rpython/ootypesystem/rdict.py
@@ -18,7 +18,7 @@
class DictRepr(AbstractDictRepr):
def __init__(self, rtyper, key_repr, value_repr, dictkey, dictvalue,
- custom_eq_hash=None):
+ custom_eq_hash=None, force_non_null=False):
self.rtyper = rtyper
self.custom_eq_hash = custom_eq_hash is not None
diff --git a/pypy/rpython/rdict.py b/pypy/rpython/rdict.py
--- a/pypy/rpython/rdict.py
+++ b/pypy/rpython/rdict.py
@@ -15,6 +15,7 @@
dictvalue = self.dictdef.dictvalue
s_key = dictkey .s_value
s_value = dictvalue.s_value
+ force_non_null = self.dictdef.force_non_null
if (s_key.__class__ is annmodel.SomeObject and s_key.knowntype == object and
s_value.__class__ is annmodel.SomeObject and s_value.knowntype == object):
return robject.pyobj_repr
@@ -29,7 +30,8 @@
lambda: rtyper.getrepr(s_value),
dictkey,
dictvalue,
- custom_eq_hash)
+ custom_eq_hash,
+ force_non_null)
def rtyper_makekey(self):
self.dictdef.dictkey .dont_change_any_more = True
diff --git a/pypy/rpython/test/test_rdict.py b/pypy/rpython/test/test_rdict.py
--- a/pypy/rpython/test/test_rdict.py
+++ b/pypy/rpython/test/test_rdict.py
@@ -598,7 +598,6 @@
res = self.interpret(func, [])
assert res in [5263, 6352]
-
class TestLLtype(BaseTestRdict, LLRtypeMixin):
def test_dict_but_not_with_char_keys(self):
def func(i):
@@ -860,6 +859,25 @@
res = f()
assert res == 1
+ def test_nonnull_hint(self):
+ def eq(a, b):
+ return a == b
+ def rhash(a):
+ return 3
+
+ def func(i):
+ d = r_dict(eq, rhash, force_non_null=True)
+ if not i:
+ d[None] = i
+ else:
+ d[str(i)] = i
+ return "12" in d, d
+
+ llres = self.interpret(func, [12])
+ assert llres.item0 == 1
+ DICT = lltype.typeOf(llres.item1)
+ assert sorted(DICT.TO.entries.TO.OF._flds) == ['f_hash', 'key', 'value']
+
# ____________________________________________________________
More information about the pypy-commit
mailing list