Author: Philip Jenvey <pjen...@underboss.org> Branch: py3k Changeset: r64289:bd92c9da8b05 Date: 2013-05-17 11:28 -0700 http://bitbucket.org/pypy/pypy/changeset/bd92c9da8b05/
Log: merge default diff --git a/pypy/doc/how-to-contribute.rst b/pypy/doc/how-to-contribute.rst --- a/pypy/doc/how-to-contribute.rst +++ b/pypy/doc/how-to-contribute.rst @@ -28,7 +28,8 @@ Layers ------ -PyPy has layers. Those layers help us keep the respective parts separated enough +PyPy has layers. Just like Ogres or onions. +Those layers help us keep the respective parts separated enough to be worked on independently and make the complexity manageable. This is, again, just a sanity requirement for such a complex project. For example writing a new optimization for the JIT usually does **not** involve touching a Python diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst --- a/pypy/doc/whatsnew-head.rst +++ b/pypy/doc/whatsnew-head.rst @@ -19,3 +19,6 @@ .. branch: numpy-subarrays Implement subarrays for numpy + +.. branch: remove-dict-smm +Remove multi-methods on dict diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -245,6 +245,11 @@ def __spacebind__(self, space): return self + def unwrap(self, space): + """NOT_RPYTHON""" + # _____ this code is here to support testing only _____ + return self + class W_InterpIterable(W_Root): def __init__(self, space, w_iterable): diff --git a/pypy/interpreter/test/test_app_main.py b/pypy/interpreter/test/test_app_main.py --- a/pypy/interpreter/test/test_app_main.py +++ b/pypy/interpreter/test/test_app_main.py @@ -1039,7 +1039,7 @@ import app_main app_main.setup_bootstrap_path('/tmp/pypy-c') # stdlib not found assert sys.executable == '' - assert sys.path == old_sys_path + [self.goal_dir] + assert sys.path == old_sys_path app_main.setup_bootstrap_path(self.fake_exe) assert sys.executable == self.fake_exe 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,19 +1,19 @@ -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.setobject import set_typedef as settypedef -from pypy.objspace.std.setobject import frozenset_typedef as frozensettypedef +from pypy.interpreter import gateway +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.error import OperationError, operationerrfmt +from pypy.interpreter.mixedmodule import MixedModule from pypy.interpreter.signature import Signature +from pypy.objspace.std.stdtypedef import StdTypeDef +from rpython.rlib import rerased, jit +from rpython.rlib.debug import mark_dict_non_null from rpython.rlib.objectmodel import r_dict, specialize, newlist_hint -from rpython.rlib.debug import mark_dict_non_null from rpython.tool.sourcetools import func_with_new_name -from rpython.rlib import rerased, jit UNROLL_CUTOFF = 5 + def _is_str(space, w_key): return space.is_w(space.type(w_key), space.w_str) @@ -40,9 +40,20 @@ w_dct.length() <= UNROLL_CUTOFF) -class W_DictMultiObject(W_Object): - from pypy.objspace.std.dicttype import dict_typedef as typedef +def negate(f): + def _negator(self, space, w_other): + # no need to use space.is_ / space.not_ + tmp = f(self, space, w_other) + if tmp is space.w_NotImplemented: + return space.w_NotImplemented + elif tmp is space.w_False: + return space.w_True + else: + return space.w_False + _negator.func_name = 'negate-%s' % f.func_name + return _negator +class W_DictMultiObject(W_Root): @staticmethod def allocate_and_init_instance(space, w_type=None, module=False, instance=False, strdict=False, kwargs=False): @@ -109,6 +120,230 @@ def setitem_str(self, key, w_value): self.strategy.setitem_str(self, key, w_value) + @staticmethod + def descr_new(space, w_dicttype, __args__): + w_obj = W_DictMultiObject.allocate_and_init_instance(space, w_dicttype) + return w_obj + + @staticmethod + def descr_fromkeys(space, w_type, w_keys, w_fill=None): + if w_fill is None: + w_fill = space.w_None + if space.is_w(w_type, space.w_dict): + w_dict = W_DictMultiObject.allocate_and_init_instance(space, w_type) + + strlist = space.listview_str(w_keys) + if strlist is not None: + for key in strlist: + w_dict.setitem_str(key, w_fill) + else: + for w_key in space.listview(w_keys): + w_dict.setitem(w_key, w_fill) + else: + w_dict = space.call_function(w_type) + for w_key in space.listview(w_keys): + space.setitem(w_dict, w_key, w_fill) + return w_dict + + def descr_init(self, space, __args__): + init_or_update(space, self, __args__, 'dict') + + def descr_repr(self, space): + ec = space.getexecutioncontext() + w_currently_in_repr = ec._py_repr + if w_currently_in_repr is None: + w_currently_in_repr = ec._py_repr = space.newdict() + return dictrepr(space, w_currently_in_repr, self) + + def descr_eq(self, space, w_other): + if space.is_w(self, w_other): + return space.w_True + if not isinstance(w_other, W_DictMultiObject): + return space.w_NotImplemented + + if self.length() != w_other.length(): + return space.w_False + iteratorimplementation = self.iteritems() + while 1: + w_key, w_val = iteratorimplementation.next_item() + if w_key is None: + break + w_rightval = w_other.getitem(w_key) + if w_rightval is None: + return space.w_False + if not space.eq_w(w_val, w_rightval): + return space.w_False + return space.w_True + + def descr_lt(self, space, w_other): + if not isinstance(w_other, W_DictMultiObject): + return space.w_NotImplemented + return self._compare_lt(space, w_other) + + def descr_gt(self, space, w_other): + if not isinstance(w_other, W_DictMultiObject): + return space.w_NotImplemented + return w_other._compare_lt(space, self) + + def _compare_lt(self, space, w_other): + # Different sizes, no problem + if self.length() < w_other.length(): + return space.w_True + if self.length() > w_other.length(): + return space.w_False + + # Same size + w_leftdiff, w_leftval = characterize(space, self, w_other) + if w_leftdiff is None: + return space.w_False + w_rightdiff, w_rightval = characterize(space, w_other, self) + if w_rightdiff is None: + # w_leftdiff is not None, w_rightdiff is None + return space.w_True + w_res = space.lt(w_leftdiff, w_rightdiff) + if (not space.is_true(w_res) and + space.eq_w(w_leftdiff, w_rightdiff) and + w_rightval is not None): + w_res = space.lt(w_leftval, w_rightval) + return w_res + + descr_ne = negate(descr_eq) + descr_le = negate(descr_gt) + descr_ge = negate(descr_lt) + + def descr_len(self, space): + return space.wrap(self.length()) + + def descr_iter(self, space): + return W_DictMultiIterKeysObject(space, self.iterkeys()) + + def descr_contains(self, space, w_key): + return space.newbool(self.getitem(w_key) is not None) + + def descr_getitem(self, space, w_key): + w_value = self.getitem(w_key) + if w_value is not None: + return w_value + + w_missing_item = self.missing_method(space, w_key) + if w_missing_item is not None: + return w_missing_item + + space.raise_key_error(w_key) + + def descr_setitem(self, space, w_newkey, w_newvalue): + self.setitem(w_newkey, w_newvalue) + + def descr_delitem(self, space, w_key): + try: + self.delitem(w_key) + except KeyError: + space.raise_key_error(w_key) + + def descr_reversed(self, space): + raise OperationError(space.w_TypeError, space.wrap('argument to reversed() must be a sequence')) + + def descr_copy(self, space): + """D.copy() -> a shallow copy of D""" + w_new = W_DictMultiObject.allocate_and_init_instance(space) + update1_dict_dict(space, w_new, self) + return w_new + + def descr_items(self, space): + """D.items() -> list of D's (key, value) pairs, as 2-tuples""" + return space.newlist(self.items()) + + def descr_keys(self, space): + """D.keys() -> list of D's keys""" + return self.w_keys() + + def descr_values(self, space): + """D.values() -> list of D's values""" + return space.newlist(self.values()) + + def descr_iteritems(self, space): + """D.iteritems() -> an iterator over the (key, value) items of D""" + return W_DictMultiIterItemsObject(space, self.iteritems()) + + def descr_iterkeys(self, space): + """D.iterkeys() -> an iterator over the keys of D""" + return W_DictMultiIterKeysObject(space, self.iterkeys()) + + def descr_itervalues(self, space): + """D.itervalues() -> an iterator over the values of D""" + return W_DictMultiIterValuesObject(space, self.itervalues()) + + def descr_viewitems(self, space): + """D.viewitems() -> a set-like object providing a view on D's items""" + return W_DictViewItemsObject(space, self) + + def descr_viewkeys(self, space): + """D.viewkeys() -> a set-like object providing a view on D's keys""" + return W_DictViewKeysObject(space, self) + + def descr_viewvalues(self, space): + """D.viewvalues() -> an object providing a view on D's values""" + return W_DictViewValuesObject(space, self) + + def descr_has_key(self, space, w_key): + """D.has_key(k) -> True if D has a key k, else False""" + return space.newbool(self.getitem(w_key) is not None) + + def descr_clear(self, space): + """D.clear() -> None. Remove all items from D.""" + self.clear() + + @gateway.unwrap_spec(w_default=gateway.WrappedDefault(None)) + def descr_get(self, space, w_key, w_default): + """D.get(k[,d]) -> D[k] if k in D, else d. d defaults to None.""" + w_value = self.getitem(w_key) + if w_value is not None: + return w_value + else: + return w_default + + @gateway.unwrap_spec(defaults_w='args_w') + def descr_pop(self, space, w_key, defaults_w): + """D.pop(k[,d]) -> v, remove specified key and return the + corresponding value\nIf key is not found, d is returned if given, + otherwise KeyError is raised + """ + len_defaults = len(defaults_w) + if len_defaults > 1: + raise operationerrfmt(space.w_TypeError, + "pop expected at most 2 arguments, got %d", + 1 + len_defaults) + w_item = self.getitem(w_key) + if w_item is None: + if len_defaults > 0: + return defaults_w[0] + else: + space.raise_key_error(w_key) + else: + self.delitem(w_key) + return w_item + + def descr_popitem(self, space): + """D.popitem() -> (k, v), remove and return some (key, value) pair as + a\n2-tuple; but raise KeyError if D is empty""" + try: + w_key, w_value = self.popitem() + except KeyError: + raise OperationError(space.w_KeyError, + space.wrap("popitem(): dictionary is empty")) + return space.newtuple([w_key, w_value]) + + @gateway.unwrap_spec(w_default=gateway.WrappedDefault(None)) + def descr_setdefault(self, space, w_key, w_default): + """D.setdefault(k[,d]) -> D.get(k,d), also set D[k]=d if k not in D""" + return self.setdefault(w_key, w_default) + + def descr_update(self, space, __args__): + """D.update(E, **F) -> None. Update D from E and F: for k in E: D[k] + = E[k]\n(if E has keys else: for (k, v) in E: D[k] = v) then: for k in + F: D[k] = F[k]""" + init_or_update(space, self, __args__, 'dict.update') + def _add_indirections(): dict_methods = "getitem getitem_str setitem setdefault \ @@ -129,8 +364,87 @@ _add_indirections() + +app = gateway.applevel(''' + def dictrepr(currently_in_repr, d): + if len(d) == 0: + return "{}" + dict_id = id(d) + if dict_id in currently_in_repr: + return '{...}' + currently_in_repr[dict_id] = 1 + try: + items = [] + # XXX for now, we cannot use iteritems() at app-level because + # we want a reasonable result instead of a RuntimeError + # even if the dict is mutated by the repr() in the loop. + for k, v in dict.items(d): + items.append(repr(k) + ": " + repr(v)) + return "{" + ', '.join(items) + "}" + finally: + try: + del currently_in_repr[dict_id] + except: + pass +''', filename=__file__) + +dictrepr = app.interphook("dictrepr") + + +W_DictMultiObject.typedef = StdTypeDef("dict", + __doc__ = '''dict() -> new empty dictionary. +dict(mapping) -> new dictionary initialized from a mapping object\'s + (key, value) pairs. +dict(seq) -> new dictionary initialized as if via: + d = {} + for k, v in seq: + d[k] = v +dict(**kwargs) -> new dictionary initialized with the name=value pairs + in the keyword argument list. For example: dict(one=1, two=2)''', + __new__ = gateway.interp2app(W_DictMultiObject.descr_new), + fromkeys = gateway.interp2app(W_DictMultiObject.descr_fromkeys, + as_classmethod=True), + __hash__ = None, + __repr__ = gateway.interp2app(W_DictMultiObject.descr_repr), + __init__ = gateway.interp2app(W_DictMultiObject.descr_init), + + __eq__ = gateway.interp2app(W_DictMultiObject.descr_eq), + __ne__ = gateway.interp2app(W_DictMultiObject.descr_ne), + __lt__ = gateway.interp2app(W_DictMultiObject.descr_lt), + __le__ = gateway.interp2app(W_DictMultiObject.descr_le), + __gt__ = gateway.interp2app(W_DictMultiObject.descr_gt), + __ge__ = gateway.interp2app(W_DictMultiObject.descr_ge), + + __len__ = gateway.interp2app(W_DictMultiObject.descr_len), + __iter__ = gateway.interp2app(W_DictMultiObject.descr_iter), + __contains__ = gateway.interp2app(W_DictMultiObject.descr_contains), + + __getitem__ = gateway.interp2app(W_DictMultiObject.descr_getitem), + __setitem__ = gateway.interp2app(W_DictMultiObject.descr_setitem), + __delitem__ = gateway.interp2app(W_DictMultiObject.descr_delitem), + + __reversed__ = gateway.interp2app(W_DictMultiObject.descr_reversed), + copy = gateway.interp2app(W_DictMultiObject.descr_copy), + items = gateway.interp2app(W_DictMultiObject.descr_items), + keys = gateway.interp2app(W_DictMultiObject.descr_keys), + values = gateway.interp2app(W_DictMultiObject.descr_values), + iteritems = gateway.interp2app(W_DictMultiObject.descr_iteritems), + iterkeys = gateway.interp2app(W_DictMultiObject.descr_iterkeys), + itervalues = gateway.interp2app(W_DictMultiObject.descr_itervalues), + viewkeys = gateway.interp2app(W_DictMultiObject.descr_viewkeys), + viewitems = gateway.interp2app(W_DictMultiObject.descr_viewitems), + viewvalues = gateway.interp2app(W_DictMultiObject.descr_viewvalues), + has_key = gateway.interp2app(W_DictMultiObject.descr_has_key), + clear = gateway.interp2app(W_DictMultiObject.descr_clear), + get = gateway.interp2app(W_DictMultiObject.descr_get), + pop = gateway.interp2app(W_DictMultiObject.descr_pop), + popitem = gateway.interp2app(W_DictMultiObject.descr_popitem), + setdefault = gateway.interp2app(W_DictMultiObject.descr_setdefault), + update = gateway.interp2app(W_DictMultiObject.descr_update), + ) + + class DictStrategy(object): - def __init__(self, space): self.space = space @@ -172,7 +486,6 @@ # it ends up taking n**2 time, because the next() calls below # will take longer and longer. But all interesting strategies # provide a better one. - space = self.space iterator = self.iteritems(w_dict) w_key, w_value = iterator.next_item() self.delitem(w_dict, w_key) @@ -196,8 +509,8 @@ def view_as_kwargs(self, w_dict): return (None, None) + class EmptyDictStrategy(DictStrategy): - erase, unerase = rerased.new_erasing_pair("empty") erase = staticmethod(erase) unerase = staticmethod(unerase) @@ -304,6 +617,7 @@ def getiteritems(self, w_dict): return iter([(None, None)]) + # Iterator Implementation base classes def _new_next(TP): @@ -311,7 +625,7 @@ EMPTY = None else: EMPTY = None, None - + def next(self): if self.dictimplementation is None: return EMPTY @@ -375,7 +689,7 @@ wrapvalue = lambda space, key : key else: wrapvalue = dictimpl.wrapvalue.im_func - + class IterClassKeys(BaseKeyIterator): def __init__(self, space, strategy, impl): self.iterator = strategy.getiterkeys(impl) @@ -427,11 +741,6 @@ create_iterator_classes(EmptyDictStrategy) -registerimplementation(W_DictMultiObject) - -# DictImplementation lattice -# XXX fix me - # concrete subclasses of the above @@ -546,7 +855,6 @@ class ObjectDictStrategy(AbstractTypedStrategy, DictStrategy): - erase, unerase = rerased.new_erasing_pair("object") erase = staticmethod(erase) unerase = staticmethod(unerase) @@ -579,8 +887,8 @@ create_iterator_classes(ObjectDictStrategy) + class StringDictStrategy(AbstractTypedStrategy, DictStrategy): - erase, unerase = rerased.new_erasing_pair("string") erase = staticmethod(erase) unerase = staticmethod(unerase) @@ -646,7 +954,6 @@ class UnicodeDictStrategy(AbstractTypedStrategy, DictStrategy): - erase, unerase = rerased.new_erasing_pair("unicode") erase = staticmethod(erase) unerase = staticmethod(unerase) @@ -748,9 +1055,6 @@ create_iterator_classes(IntDictStrategy) -init_signature = Signature(['seq_or_map'], None, 'kwargs') -init_defaults = [None] - def update1(space, w_dict, w_data): if space.findattr(w_data, space.wrap("keys")) is None: @@ -792,6 +1096,9 @@ w_dict.setitem(w_key, w_value) +init_signature = Signature(['seq_or_map'], None, 'kwargs') +init_defaults = [None] + def init_or_update(space, w_dict, __args__, funcname): w_src, w_kwds = __args__.parse_obj( None, funcname, @@ -802,131 +1109,32 @@ if space.is_true(w_kwds): update1(space, w_dict, w_kwds) -def init__DictMulti(space, w_dict, __args__): - init_or_update(space, w_dict, __args__, 'dict') - -def dict_update__DictMulti(space, w_dict, __args__): - init_or_update(space, w_dict, __args__, 'dict.update') - -def getitem__DictMulti_ANY(space, w_dict, w_key): - w_value = w_dict.getitem(w_key) - if w_value is not None: - return w_value - - w_missing_item = w_dict.missing_method(space, w_key) - if w_missing_item is not None: - return w_missing_item - - space.raise_key_error(w_key) - -def setitem__DictMulti_ANY_ANY(space, w_dict, w_newkey, w_newvalue): - w_dict.setitem(w_newkey, w_newvalue) - -def delitem__DictMulti_ANY(space, w_dict, w_key): - try: - w_dict.delitem(w_key) - except KeyError: - space.raise_key_error(w_key) - -def len__DictMulti(space, w_dict): - return space.wrap(w_dict.length()) - -def contains__DictMulti_ANY(space, w_dict, w_key): - return space.newbool(w_dict.getitem(w_key) is not None) - -def iter__DictMulti(space, w_dict): - return W_DictMultiIterKeysObject(space, w_dict.iterkeys()) - -def eq__DictMulti_DictMulti(space, w_left, w_right): - if space.is_w(w_left, w_right): - return space.w_True - - if w_left.length() != w_right.length(): - return space.w_False - iteratorimplementation = w_left.iteritems() +def characterize(space, w_a, w_b): + """ (similar to CPython) + returns the smallest key in acontent for which b's value is different or absent and this value """ + w_smallest_diff_a_key = None + w_its_value = None + iteratorimplementation = w_a.iteritems() while 1: w_key, w_val = iteratorimplementation.next_item() if w_key is None: break - w_rightval = w_right.getitem(w_key) - if w_rightval is None: - return space.w_False - if not space.eq_w(w_val, w_rightval): - return space.w_False - return space.w_True - -def dict_copy__DictMulti(space, w_self): - w_new = W_DictMultiObject.allocate_and_init_instance(space) - update1_dict_dict(space, w_new, w_self) - return w_new - - -def dict_items__DictMulti(space, w_self): - return W_DictViewItemsObject(space, w_self) - -def dict_keys__DictMulti(space, w_self): - return W_DictViewKeysObject(space, w_self) - # XXX on default this is a fast path when keys are string, do we want to - # port it to py3k? - # return w_self.w_keys() - -def dict_values__DictMulti(space, w_self): - return W_DictViewValuesObject(space, w_self) - -def dict_iteritems__DictMulti(space, w_self): - return W_DictMultiIterItemsObject(space, w_self.iteritems()) - -def dict_iterkeys__DictMulti(space, w_self): - return W_DictMultiIterKeysObject(space, w_self.iterkeys()) - -def dict_itervalues__DictMulti(space, w_self): - return W_DictMultiIterValuesObject(space, w_self.itervalues()) - -def dict_clear__DictMulti(space, w_self): - w_self.clear() - -def dict_get__DictMulti_ANY_ANY(space, w_dict, w_key, w_default): - w_value = w_dict.getitem(w_key) - if w_value is not None: - return w_value - else: - return w_default - -def dict_setdefault__DictMulti_ANY_ANY(space, w_dict, w_key, w_default): - return w_dict.setdefault(w_key, w_default) - -def dict_pop__DictMulti_ANY(space, w_dict, w_key, defaults_w): - len_defaults = len(defaults_w) - if len_defaults > 1: - raise operationerrfmt(space.w_TypeError, - "pop expected at most 2 arguments, got %d", - 1 + len_defaults) - w_item = w_dict.getitem(w_key) - if w_item is None: - if len_defaults > 0: - return defaults_w[0] - else: - space.raise_key_error(w_key) - else: - w_dict.delitem(w_key) - return w_item - -def dict_popitem__DictMulti(space, w_dict): - try: - w_key, w_value = w_dict.popitem() - except KeyError: - raise OperationError(space.w_KeyError, - space.wrap("popitem(): dictionary is empty")) - return space.newtuple([w_key, w_value]) + if w_smallest_diff_a_key is None or space.is_true(space.lt(w_key, w_smallest_diff_a_key)): + w_bvalue = w_b.getitem(w_key) + if w_bvalue is None: + w_its_value = w_val + w_smallest_diff_a_key = w_key + else: + if not space.eq_w(w_val, w_bvalue): + w_its_value = w_val + w_smallest_diff_a_key = w_key + return w_smallest_diff_a_key, w_its_value # ____________________________________________________________ # Iteration - -class W_BaseDictMultiIterObject(W_Object): - from pypy.objspace.std.dicttype import dictiter_typedef as typedef - +class W_BaseDictMultiIterObject(W_Root): _immutable_fields_ = ["iteratorimplementation"] ignore_for_isinstance_cache = True @@ -935,177 +1143,199 @@ w_self.space = space w_self.iteratorimplementation = iteratorimplementation + def descr_iter(self, space): + return self + + def descr_length_hint(self, space): + return space.wrap(self.iteratorimplementation.length()) + + def descr_reduce(self, space): + """ + This is a slightly special case of pickling. + Since iteration over a dict is a bit hairy, + we do the following: + - create a clone of the dict iterator + - run it to the original position + - collect all remaining elements into a list + At unpickling time, we just use that list + and create an iterator on it. + This is of course not the standard way. + + XXX to do: remove this __reduce__ method and do + a registration with copy_reg, instead. + """ + w_mod = space.getbuiltinmodule('_pickle_support') + mod = space.interp_w(MixedModule, w_mod) + new_inst = mod.get('dictiter_surrogate_new') + w_typeobj = space.gettypeobject(W_BaseDictMultiIterObject.typedef) + + raise OperationError( + space.w_TypeError, + space.wrap("can't pickle dictionary-keyiterator objects")) + # XXXXXX get that working again + + # we cannot call __init__ since we don't have the original dict + if isinstance(self, W_DictIter_Keys): + w_clone = space.allocate_instance(W_DictIter_Keys, w_typeobj) + elif isinstance(self, W_DictIter_Values): + w_clone = space.allocate_instance(W_DictIter_Values, w_typeobj) + elif isinstance(self, W_DictIter_Items): + w_clone = space.allocate_instance(W_DictIter_Items, w_typeobj) + else: + msg = "unsupported dictiter type '%s' during pickling" % (self,) + raise OperationError(space.w_TypeError, space.wrap(msg)) + w_clone.space = space + w_clone.content = self.content + w_clone.len = self.len + w_clone.pos = 0 + w_clone.setup_iterator() + # spool until we have the same pos + while w_clone.pos < self.pos: + w_obj = w_clone.next_entry() + w_clone.pos += 1 + stuff = [w_clone.next_entry() for i in range(w_clone.pos, w_clone.len)] + w_res = space.newlist(stuff) + tup = [ + w_res + ] + w_ret = space.newtuple([new_inst, space.newtuple(tup)]) + return w_ret + + class W_DictMultiIterKeysObject(W_BaseDictMultiIterObject): - pass + def descr_next(self, space): + iteratorimplementation = self.iteratorimplementation + w_key = iteratorimplementation.next_key() + if w_key is not None: + return w_key + raise OperationError(space.w_StopIteration, space.w_None) class W_DictMultiIterValuesObject(W_BaseDictMultiIterObject): - pass + def descr_next(self, space): + iteratorimplementation = self.iteratorimplementation + w_value = iteratorimplementation.next_value() + if w_value is not None: + return w_value + raise OperationError(space.w_StopIteration, space.w_None) class W_DictMultiIterItemsObject(W_BaseDictMultiIterObject): - pass + def descr_next(self, space): + iteratorimplementation = self.iteratorimplementation + w_key, w_value = iteratorimplementation.next_item() + if w_key is not None: + return space.newtuple([w_key, w_value]) + raise OperationError(space.w_StopIteration, space.w_None) -registerimplementation(W_DictMultiIterKeysObject) -registerimplementation(W_DictMultiIterValuesObject) -registerimplementation(W_DictMultiIterItemsObject) +W_DictMultiIterItemsObject.typedef = StdTypeDef( + "dict_iteritems", + __iter__ = gateway.interp2app(W_DictMultiIterItemsObject.descr_iter), + next = gateway.interp2app(W_DictMultiIterItemsObject.descr_next), + __length_hint__ = gateway.interp2app(W_BaseDictMultiIterObject.descr_length_hint) + ) -def iter__DictMultiIterKeysObject(space, w_dictiter): - return w_dictiter +W_DictMultiIterKeysObject.typedef = StdTypeDef( + "dict_iterkeys", + __iter__ = gateway.interp2app(W_DictMultiIterKeysObject.descr_iter), + next = gateway.interp2app(W_DictMultiIterKeysObject.descr_next), + __length_hint__ = gateway.interp2app(W_BaseDictMultiIterObject.descr_length_hint) + ) -def next__DictMultiIterKeysObject(space, w_dictiter): - iteratorimplementation = w_dictiter.iteratorimplementation - w_key = iteratorimplementation.next_key() - if w_key is not None: - return w_key - raise OperationError(space.w_StopIteration, space.w_None) +W_DictMultiIterValuesObject.typedef = StdTypeDef( + "dict_itervalues", + __iter__ = gateway.interp2app(W_DictMultiIterValuesObject.descr_iter), + next = gateway.interp2app(W_DictMultiIterValuesObject.descr_next), + __length_hint__ = gateway.interp2app(W_BaseDictMultiIterObject.descr_length_hint) + ) -def iter__DictMultiIterValuesObject(space, w_dictiter): - return w_dictiter - -def next__DictMultiIterValuesObject(space, w_dictiter): - iteratorimplementation = w_dictiter.iteratorimplementation - w_value = iteratorimplementation.next_value() - if w_value is not None: - return w_value - raise OperationError(space.w_StopIteration, space.w_None) - -def iter__DictMultiIterItemsObject(space, w_dictiter): - return w_dictiter - -def next__DictMultiIterItemsObject(space, w_dictiter): - iteratorimplementation = w_dictiter.iteratorimplementation - w_key, w_value = iteratorimplementation.next_item() - if w_key is not None: - return space.newtuple([w_key, w_value]) - raise OperationError(space.w_StopIteration, space.w_None) # ____________________________________________________________ # Views -class W_DictViewObject(W_Object): +class W_DictViewObject(W_Root): def __init__(w_self, space, w_dict): w_self.w_dict = w_dict -class W_DictViewKeysObject(W_DictViewObject): - from pypy.objspace.std.dicttype import dict_keys_typedef as typedef -registerimplementation(W_DictViewKeysObject) + def descr_repr(self, space): + w_seq = space.call_function(space.w_list, self) + w_repr = space.repr(w_seq) + return space.wrap("%s(%s)" % (space.type(self).getname(space), + space.str_w(w_repr))) + + def descr_eq(self, space, w_otherview): + if not space.eq_w(space.len(self), space.len(w_otherview)): + return space.w_False + + w_iter = space.iter(self) + while True: + try: + w_item = space.next(w_iter) + except OperationError, e: + if not e.match(space, space.w_StopIteration): + raise + break + if not space.is_true(space.contains(w_otherview, w_item)): + return space.w_False + return space.w_True + + def descr_len(self, space): + return space.len(self.w_dict) + + def descr_and(self, space, w_otherview): + w_set = space.call_function(space.w_set, self) + space.call_method(w_set, "intersection_update", w_otherview) + return w_set + + def descr_or(self, space, w_otherview): + w_set = space.call_function(space.w_set, self) + space.call_method(w_set, "update", w_otherview) + return w_set + + def descr_xor(self, space, w_otherview): + w_set = space.call_function(space.w_set, self) + space.call_method(w_set, "symmetric_difference_update", w_otherview) + return w_set class W_DictViewItemsObject(W_DictViewObject): - from pypy.objspace.std.dicttype import dict_items_typedef as typedef -registerimplementation(W_DictViewItemsObject) + def descr_iter(self, space): + return W_DictMultiIterItemsObject(space, self.w_dict.iteritems()) + +class W_DictViewKeysObject(W_DictViewObject): + def descr_iter(self, space): + return W_DictMultiIterKeysObject(space, self.w_dict.iterkeys()) class W_DictViewValuesObject(W_DictViewObject): - from pypy.objspace.std.dicttype import dict_values_typedef as typedef -registerimplementation(W_DictViewValuesObject) + def descr_iter(self, space): + return W_DictMultiIterValuesObject(space, self.w_dict.itervalues()) -def len__DictViewKeys(space, w_dictview): - return space.len(w_dictview.w_dict) -len__DictViewItems = len__DictViewValues = len__DictViewKeys +W_DictViewItemsObject.typedef = StdTypeDef( + "dict_items", + __repr__ = gateway.interp2app(W_DictViewItemsObject.descr_repr), + __eq__ = gateway.interp2app(W_DictViewItemsObject.descr_eq), + __len__ = gateway.interp2app(W_DictViewItemsObject.descr_len), + __iter__ = gateway.interp2app(W_DictViewItemsObject.descr_iter), + __and__ = gateway.interp2app(W_DictViewItemsObject.descr_and), + __or__ = gateway.interp2app(W_DictViewItemsObject.descr_or), + __xor__ = gateway.interp2app(W_DictViewItemsObject.descr_xor) + ) -def iter__DictViewKeys(space, w_dictview): - return dict_iterkeys__DictMulti(space, w_dictview.w_dict) -def iter__DictViewItems(space, w_dictview): - return dict_iteritems__DictMulti(space, w_dictview.w_dict) -def iter__DictViewValues(space, w_dictview): - return dict_itervalues__DictMulti(space, w_dictview.w_dict) +W_DictViewKeysObject.typedef = StdTypeDef( + "dict_keys", + __repr__ = gateway.interp2app(W_DictViewKeysObject.descr_repr), + __eq__ = gateway.interp2app(W_DictViewKeysObject.descr_eq), + __len__ = gateway.interp2app(W_DictViewKeysObject.descr_len), + __iter__ = gateway.interp2app(W_DictViewKeysObject.descr_iter), + __and__ = gateway.interp2app(W_DictViewKeysObject.descr_and), + __or__ = gateway.interp2app(W_DictViewKeysObject.descr_or), + __xor__ = gateway.interp2app(W_DictViewKeysObject.descr_xor) + ) -def all_contained_in(space, w_dictview, w_otherview): - w_iter = space.iter(w_dictview) - - while True: - try: - w_item = space.next(w_iter) - except OperationError, e: - if not e.match(space, space.w_StopIteration): - raise - break - if not space.is_true(space.contains(w_otherview, w_item)): - return space.w_False - - return space.w_True - -def comparison_impl(fn): - opname = fn.func_name - types = ['DictViewKeys', 'DictViewItems', 'settypedef', 'frozensettypedef'] - for lefttype in types: - for righttype in types: - fnname = '%s__%s_%s' % (opname, lefttype, righttype) - globals()[fnname] = fn - return fn - -@comparison_impl -def eq(space, w_left, w_right): - if space.eq_w(space.len(w_left), space.len(w_right)): - return all_contained_in(space, w_left, w_right) - return space.w_False - -@comparison_impl -def ne(space, w_left, w_right): - if not space.eq_w(space.len(w_left), space.len(w_right)): - return space.w_True - return space.not_(all_contained_in(space, w_left, w_right)) - -@comparison_impl -def lt(space, w_left, w_right): - if space.len_w(w_left) < space.len_w(w_right): - return all_contained_in(space, w_left, w_right) - return space.w_False - -@comparison_impl -def le(space, w_left, w_right): - if space.len_w(w_left) <= space.len_w(w_right): - return all_contained_in(space, w_left, w_right) - return space.w_False - -@comparison_impl -def gt(space, w_left, w_right): - if space.len_w(w_left) > space.len_w(w_right): - return all_contained_in(space, w_right, w_left) - return space.w_False - -@comparison_impl -def ge(space, w_left, w_right): - if space.len_w(w_left) >= space.len_w(w_right): - return all_contained_in(space, w_right, w_left) - return space.w_False - - -def repr__DictViewKeys(space, w_dictview): - typename = space.type(w_dictview).getname(space).decode('utf-8') - w_seq = space.call_function(space.w_list, w_dictview) - seq_repr = space.unicode_w(space.repr(w_seq)) - return space.wrap(u"%s(%s)" % (typename, seq_repr)) -repr__DictViewItems = repr__DictViewKeys -repr__DictViewValues = repr__DictViewKeys - - -def generate_setops(): - OPLIST = [ - ('and', 'intersection_update'), - ('or', 'update'), - ('xor', 'symmetric_difference_update'), - ('sub', 'difference_update'), - ] - - for (opname, methodname) in OPLIST: - src = py.code.Source(""" - def {opname}__DictViewKeys_ANY(space, w_dictview, w_other): - w_set = space.call_function(space.w_set, w_dictview) - space.call_method(w_set, '{methodname}', w_other) - return w_set - - def {opname}__ANY_DictViewKeys(space, w_other, w_dictview): - w_set = space.call_function(space.w_set, w_other) - space.call_method(w_set, '{methodname}', w_dictview) - return w_set - - {opname}__DictViewItems_ANY = {opname}__DictViewKeys_ANY - {opname}__ANY_DictViewItems = {opname}__ANY_DictViewKeys - """.format(opname=opname, methodname=methodname)) - exec src.compile() in globals() - -generate_setops() - -# ____________________________________________________________ - -from pypy.objspace.std import dicttype -register_all(vars(), dicttype) +W_DictViewValuesObject.typedef = StdTypeDef( + "dict_values", + __repr__ = gateway.interp2app(W_DictViewValuesObject.descr_repr), + __eq__ = gateway.interp2app(W_DictViewValuesObject.descr_eq), + __len__ = gateway.interp2app(W_DictViewValuesObject.descr_len), + __iter__ = gateway.interp2app(W_DictViewValuesObject.descr_iter), + __and__ = gateway.interp2app(W_DictViewValuesObject.descr_and), + __or__ = gateway.interp2app(W_DictViewValuesObject.descr_or), + __xor__ = gateway.interp2app(W_DictViewValuesObject.descr_xor) + ) diff --git a/pypy/objspace/std/dicttype.py b/pypy/objspace/std/dicttype.py deleted file mode 100644 --- a/pypy/objspace/std/dicttype.py +++ /dev/null @@ -1,243 +0,0 @@ -from pypy.interpreter.error import OperationError -from pypy.interpreter.mixedmodule import MixedModule -from pypy.interpreter import gateway -from pypy.objspace.std.stdtypedef import StdTypeDef, SMM -from pypy.objspace.std.register_all import register_all - -dict_copy = SMM('copy', 1, - doc='D.copy() -> a shallow copy of D') -dict_items = SMM('items', 1, - doc="D.items() -> a set-like object providing a view on D's item") -dict_keys = SMM('keys', 1, - doc="D.keys() -> a set-like object providing a view on D's keys") -dict_values = SMM('values', 1, - doc="D.values() -> an object providing a view on D's values") -dict_clear = SMM('clear', 1, - doc='D.clear() -> None. Remove all items from D.') -dict_get = SMM('get', 3, defaults=(None,), - doc='D.get(k[,d]) -> D[k] if k in D, else d. d defaults' - ' to None.') -dict_pop = SMM('pop', 2, varargs_w=True, - doc='D.pop(k[,d]) -> v, remove specified key and return' - ' the corresponding value\nIf key is not found, d is' - ' returned if given, otherwise KeyError is raised') -dict_popitem = SMM('popitem', 1, - doc='D.popitem() -> (k, v), remove and return some (key,' - ' value) pair as a\n2-tuple; but raise KeyError if D' - ' is empty') -dict_setdefault = SMM('setdefault', 3, defaults=(None,), - doc='D.setdefault(k[,d]) -> D.get(k,d), also set D[k]=d' - ' if k not in D') -dict_update = SMM('update', 1, general__args__=True, - doc='D.update(E, **F) -> None. Update D from E and F:' - ' for k in E: D[k] = E[k]\n(if E has keys else: for' - ' (k, v) in E: D[k] = v) then: for k in F: D[k] =' - ' F[k]') -dict_iteritems = SMM('iteritems', 1, - doc='D.iteritems() -> an iterator over the (key, value)' - ' items of D') -dict_iterkeys = SMM('iterkeys', 1, - doc='D.iterkeys() -> an iterator over the keys of D') -dict_itervalues = SMM('itervalues', 1, - doc='D.itervalues() -> an iterator over the values of D') -dict_reversed = SMM('__reversed__', 1) - - -def dict_reversed__ANY(space, w_dict): - raise OperationError(space.w_TypeError, space.wrap('argument to reversed() must be a sequence')) - -register_all(vars(), globals()) - -def descr_fromkeys(space, w_type, w_keys, w_fill=None): - from pypy.objspace.std.dictmultiobject import W_DictMultiObject - if w_fill is None: - w_fill = space.w_None - if space.is_w(w_type, space.w_dict): - w_dict = W_DictMultiObject.allocate_and_init_instance(space, w_type) - - strlist = space.listview_str(w_keys) - if strlist is not None: - for key in strlist: - w_dict.setitem_str(key, w_fill) - else: - for w_key in space.listview(w_keys): - w_dict.setitem(w_key, w_fill) - else: - w_dict = space.call_function(w_type) - for w_key in space.listview(w_keys): - space.setitem(w_dict, w_key, w_fill) - return w_dict - - -app = gateway.applevel(''' - def dictrepr(currently_in_repr, d): - if len(d) == 0: - return "{}" - dict_id = id(d) - if dict_id in currently_in_repr: - return '{...}' - currently_in_repr[dict_id] = 1 - try: - items = [] - # XXX for now, we cannot use items() withut list at app-level - # because we want a reasonable result instead of a RuntimeError - # even if the dict is mutated by the repr() in the loop. - for k, v in list(dict.items(d)): - items.append(repr(k) + ": " + repr(v)) - return "{" + ', '.join(items) + "}" - finally: - try: - del currently_in_repr[dict_id] - except: - pass -''', filename=__file__) - -dictrepr = app.interphook("dictrepr") - - -def descr_repr(space, w_dict): - ec = space.getexecutioncontext() - w_currently_in_repr = ec._py_repr - if w_currently_in_repr is None: - w_currently_in_repr = ec._py_repr = space.newdict() - return dictrepr(space, w_currently_in_repr, w_dict) - - -# ____________________________________________________________ - -def descr__new__(space, w_dicttype, __args__): - from pypy.objspace.std.dictmultiobject import W_DictMultiObject - w_obj = W_DictMultiObject.allocate_and_init_instance(space, w_dicttype) - return w_obj - -# ____________________________________________________________ - -dict_typedef = StdTypeDef("dict", - __doc__ = '''dict() -> new empty dictionary. -dict(mapping) -> new dictionary initialized from a mapping object\'s - (key, value) pairs. -dict(seq) -> new dictionary initialized as if via: - d = {} - for k, v in seq: - d[k] = v -dict(**kwargs) -> new dictionary initialized with the name=value pairs - in the keyword argument list. For example: dict(one=1, two=2)''', - __new__ = gateway.interp2app(descr__new__), - __hash__ = None, - __repr__ = gateway.interp2app(descr_repr), - fromkeys = gateway.interp2app(descr_fromkeys, as_classmethod=True), - ) -dict_typedef.registermethods(globals()) - -# ____________________________________________________________ - -def descr_dictiter__length_hint__(space, w_self): - from pypy.objspace.std.dictmultiobject import W_BaseDictMultiIterObject - assert isinstance(w_self, W_BaseDictMultiIterObject) - return space.wrap(w_self.iteratorimplementation.length()) - - -def descr_dictiter__reduce__(w_self, space): - """ - This is a slightly special case of pickling. - Since iteration over a dict is a bit hairy, - we do the following: - - create a clone of the dict iterator - - run it to the original position - - collect all remaining elements into a list - At unpickling time, we just use that list - and create an iterator on it. - This is of course not the standard way. - - XXX to do: remove this __reduce__ method and do - a registration with copyreg, instead. - """ - w_mod = space.getbuiltinmodule('_pickle_support') - mod = space.interp_w(MixedModule, w_mod) - new_inst = mod.get('dictiter_surrogate_new') - w_typeobj = space.gettypeobject(dictiter_typedef) - - raise OperationError( - space.w_TypeError, - space.wrap("can't pickle dictionary-keyiterator objects")) - # XXXXXX get that working again - - # we cannot call __init__ since we don't have the original dict - if isinstance(w_self, W_DictIter_Keys): - w_clone = space.allocate_instance(W_DictIter_Keys, w_typeobj) - elif isinstance(w_self, W_DictIter_Values): - w_clone = space.allocate_instance(W_DictIter_Values, w_typeobj) - elif isinstance(w_self, W_DictIter_Items): - w_clone = space.allocate_instance(W_DictIter_Items, w_typeobj) - else: - msg = "unsupported dictiter type '%s' during pickling" % (w_self, ) - raise OperationError(space.w_TypeError, space.wrap(msg)) - w_clone.space = space - w_clone.content = w_self.content - w_clone.len = w_self.len - w_clone.pos = 0 - w_clone.setup_iterator() - # spool until we have the same pos - while w_clone.pos < w_self.pos: - w_obj = w_clone.next_entry() - w_clone.pos += 1 - stuff = [w_clone.next_entry() for i in range(w_clone.pos, w_clone.len)] - w_res = space.newlist(stuff) - tup = [ - w_res - ] - w_ret = space.newtuple([new_inst, space.newtuple(tup)]) - return w_ret - -# ____________________________________________________________ - - -dictiter_typedef = StdTypeDef("dictionaryiterator", - __length_hint__ = gateway.interp2app(descr_dictiter__length_hint__), - __reduce__ = gateway.interp2app(descr_dictiter__reduce__), - ) - -# ____________________________________________________________ -# Dict views - -def descr_dictview_isdisjoin(space, w_self, w_other): - from pypy.objspace.std.dictmultiobject import W_DictViewObject - if w_self is w_other: - if space.len_w(w_self) == 0: - return space.w_True - else: - return space.w_False - - # check whether w_other is a set-like object - if (space.isinstance_w(w_other, space.w_set) or - space.isinstance_w(w_other, space.w_frozenset) or - isinstance(w_other, W_DictViewObject)): - # if w_other is set-like and it's longer, we iterate over w_self - # instead - len_self = space.len_w(w_self) - len_other = space.len_w(w_other) - if len_other > len_self: - w_self, w_other = w_other, w_self - - w_it = space.iter(w_other) - for w_item in space.iteriterable(w_it): - if space.is_true(space.contains(w_self, w_item)): - return space.w_False - return space.w_True - - -dict_keys_typedef = StdTypeDef( - "dict_keys", - isdisjoint = gateway.interp2app(descr_dictview_isdisjoin), - - ) -dict_keys_typedef.registermethods(globals()) - -dict_items_typedef = StdTypeDef( - "dict_items", - isdisjoint = gateway.interp2app(descr_dictview_isdisjoin), - ) - -dict_values_typedef = StdTypeDef( - "dict_values", - ) diff --git a/pypy/objspace/std/marshal_impl.py b/pypy/objspace/std/marshal_impl.py --- a/pypy/objspace/std/marshal_impl.py +++ b/pypy/objspace/std/marshal_impl.py @@ -12,6 +12,7 @@ from pypy.objspace.std.register_all import register_all from rpython.rlib.rarithmetic import LONG_BIT, r_longlong, r_uint, intmask from pypy.objspace.std import model +from pypy.objspace.std.dictmultiobject import W_DictMultiObject from pypy.interpreter.special import Ellipsis from pypy.interpreter.pycode import PyCode from pypy.interpreter import gateway, unicodehelper @@ -24,7 +25,6 @@ from pypy.objspace.std.floatobject import W_FloatObject from pypy.objspace.std.tupleobject import W_TupleObject from pypy.objspace.std.listobject import W_ListObject -from pypy.objspace.std.dictmultiobject import W_DictMultiObject from pypy.objspace.std.stringobject import W_StringObject from pypy.objspace.std.typeobject import W_TypeObject from pypy.objspace.std.longobject import W_LongObject, newlong @@ -279,15 +279,18 @@ return space.newlist(items_w) register(TYPE_LIST, unmarshal_List) -def marshal_w__DictMulti(space, w_dict, m): +def marshal_w_dict(space, w_dict, m): + if not isinstance(w_dict, W_DictMultiObject): + raise_exception(space, "unmarshallable object") m.start(TYPE_DICT) for w_tuple in w_dict.items(): w_key, w_value = space.fixedview(w_tuple, 2) m.put_w_obj(w_key) m.put_w_obj(w_value) m.atom(TYPE_NULL) +handled_by_any.append(('dict', marshal_w_dict)) -def unmarshal_DictMulti(space, u, tc): +def unmarshal_dict(space, u, tc): # since primitive lists are not optimized and we don't know # the dict size in advance, use the dict's setitem instead # of building a list of tuples. @@ -299,7 +302,7 @@ w_value = u.get_w_obj() space.setitem(w_dic, w_key, w_value) return w_dic -register(TYPE_DICT, unmarshal_DictMulti) +register(TYPE_DICT, unmarshal_dict) def unmarshal_NULL(self, u, tc): return None diff --git a/pypy/objspace/std/model.py b/pypy/objspace/std/model.py --- a/pypy/objspace/std/model.py +++ b/pypy/objspace/std/model.py @@ -40,7 +40,6 @@ from pypy.objspace.std.complextype import complex_typedef from pypy.objspace.std.tupletype import tuple_typedef from pypy.objspace.std.listobject import list_typedef - from pypy.objspace.std.dicttype import dict_typedef from pypy.objspace.std.stringtype import str_typedef from pypy.objspace.std.bytearraytype import bytearray_typedef from pypy.objspace.std.typeobject import type_typedef @@ -80,6 +79,7 @@ # not-multimethod based types + self.pythontypes.append(dictmultiobject.W_DictMultiObject.typedef) self.pythontypes.append(setobject.W_SetObject.typedef) self.pythontypes.append(setobject.W_FrozensetObject.typedef) @@ -91,10 +91,6 @@ floatobject.W_FloatObject: [], tupleobject.W_TupleObject: [], listobject.W_ListObject: [], - dictmultiobject.W_DictMultiObject: [], - dictmultiobject.W_DictMultiIterKeysObject: [], - dictmultiobject.W_DictMultiIterValuesObject: [], - dictmultiobject.W_DictMultiIterItemsObject: [], stringobject.W_StringObject: [], bytearrayobject.W_BytearrayObject: [], typeobject.W_TypeObject: [], @@ -107,9 +103,6 @@ iterobject.W_FastTupleIterObject: [], iterobject.W_ReverseSeqIterObject: [], unicodeobject.W_UnicodeObject: [], - dictmultiobject.W_DictViewKeysObject: [], - dictmultiobject.W_DictViewItemsObject: [], - dictmultiobject.W_DictViewValuesObject: [], pypy.interpreter.pycode.PyCode: [], pypy.interpreter.special.Ellipsis: [], } @@ -327,9 +320,6 @@ s += ' instance of %s' % self.w__class__ return '<%s>' % s - def unwrap(self, space): - raise UnwrapError('cannot unwrap %r' % self) - class UnwrapError(Exception): pass diff --git a/pypy/objspace/std/objspace.py b/pypy/objspace/std/objspace.py --- a/pypy/objspace/std/objspace.py +++ b/pypy/objspace/std/objspace.py @@ -276,10 +276,9 @@ def unwrap(self, w_obj): """NOT_RPYTHON""" - if isinstance(w_obj, model.W_Object): + # _____ this code is here to support testing only _____ + if isinstance(w_obj, W_Root): return w_obj.unwrap(self) - if isinstance(w_obj, W_Root): - return w_obj raise model.UnwrapError("cannot unwrap: %r" % w_obj) def newint(self, intval): diff --git a/pypy/objspace/std/test/test_dictmultiobject.py b/pypy/objspace/std/test/test_dictmultiobject.py --- a/pypy/objspace/std/test/test_dictmultiobject.py +++ b/pypy/objspace/std/test/test_dictmultiobject.py @@ -3,8 +3,7 @@ import py from pypy.objspace.std.dictmultiobject import (W_DictMultiObject, - setitem__DictMulti_ANY_ANY, getitem__DictMulti_ANY, StringDictStrategy, - ObjectDictStrategy) + StringDictStrategy, ObjectDictStrategy) class TestW_DictObject(object): @@ -398,6 +397,24 @@ f = getattr(operator, op) raises(TypeError, f, d1, d2) + def test_other_rich_cmp(self): + d1 = {1: 2, 3: 4} + d2 = {1: 2, 3: 4} + d3 = {1: 2, 3: 5} + d4 = {1: 2} + + assert d1 <= d2 + assert d1 <= d3 + assert not d1 <= d4 + + assert not d1 > d2 + assert not d1 > d3 + assert d1 > d4 + + assert d1 >= d2 + assert not d1 >= d3 + assert d1 >= d4 + def test_str_repr(self): assert '{}' == str({}) assert '{1: 2}' == str({1: 2}) @@ -597,6 +614,9 @@ assert isinstance(list({b'a': 1})[0], bytes) + def test_cmp_with_noncmp(self): + assert not {} > object() + class AppTest_DictMultiObject(AppTest_DictObject): def test_emptydict_unhashable(self): @@ -1127,10 +1147,10 @@ pydict = {} for i in range(N): x = randint(-N, N) - setitem__DictMulti_ANY_ANY(self.space, d, x, i) + d.descr_setitem(self.space, x, i) pydict[x] = i for key, value in pydict.iteritems(): - assert value == getitem__DictMulti_ANY(self.space, d, key) + assert value == d.descr_getitem(self.space, key) class BaseTestRDictImplementation: _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit