[pypy-commit] pypy default: merge heads
bivab
noreply at buildbot.pypy.org
Sun May 19 11:11:47 CEST 2013
Author: David Schneider <david.schneider at picle.org>
Branch:
Changeset: r64308:2708b1ed0639
Date: 2013-05-19 11:10 +0200
http://bitbucket.org/pypy/pypy/changeset/2708b1ed0639/
Log: merge heads
diff too long, truncating to 2000 out of 2290 lines
diff --git a/pypy/doc/coding-guide.rst b/pypy/doc/coding-guide.rst
--- a/pypy/doc/coding-guide.rst
+++ b/pypy/doc/coding-guide.rst
@@ -339,8 +339,9 @@
+ methods and other class attributes do not change after startup
+ single inheritance is fully supported
-+ simple mixins work too, but the mixed in class needs a ``_mixin_ = True``
- class attribute
++ simple mixins somewhat work too, but the mixed in class needs a
+ ``_mixin_ = True`` class attribute. isinstance checks against the
+ mixin type will fail when translated.
+ classes are first-class objects too
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/goal/targetpypystandalone.py b/pypy/goal/targetpypystandalone.py
--- a/pypy/goal/targetpypystandalone.py
+++ b/pypy/goal/targetpypystandalone.py
@@ -10,6 +10,8 @@
from rpython.config.config import ConflictConfigError
from pypy.tool.option import make_objspace
from pypy.conftest import pypydir
+from rpython.rlib import rthread
+from pypy.module.thread import os_thread
thisdir = py.path.local(__file__).dirpath()
@@ -120,6 +122,15 @@
source = rffi.charp2str(ll_source)
return _pypy_execute_source(source)
+ @entrypoint('main', [], c_name='pypy_init_threads')
+ def pypy_init_threads():
+ os_thread.setup_threads(space)
+ rffi.aroundstate.before()
+
+ @entrypoint('main', [], c_name='pypy_thread_attach')
+ def pypy_thread_attach():
+ rthread.gc_thread_start()
+
w_globals = space.newdict()
space.setitem(w_globals, space.wrap('__builtins__'),
space.builtin_modules['__builtin__'])
@@ -137,6 +148,8 @@
return 0
return entry_point, {'pypy_execute_source': pypy_execute_source,
+ 'pypy_init_threads': pypy_init_threads,
+ 'pypy_thread_attach': pypy_thread_attach,
'pypy_setup_home': pypy_setup_home}
def call_finish(space):
diff --git a/pypy/interpreter/astcompiler/codegen.py b/pypy/interpreter/astcompiler/codegen.py
--- a/pypy/interpreter/astcompiler/codegen.py
+++ b/pypy/interpreter/astcompiler/codegen.py
@@ -853,9 +853,10 @@
self.emit_jump(ops.JUMP_IF_FALSE_OR_POP, cleanup, True)
if i < (ops_count - 1):
comp.comparators[i].walkabout(self)
- comp.comparators[-1].walkabout(self)
- last_kind = compare_operations(comp.ops[-1])
- self.emit_op_arg(ops.COMPARE_OP, last_kind)
+ last_op, last_comparator = comp.ops[-1], comp.comparators[-1]
+ if not self._optimize_comparator(last_op, last_comparator):
+ last_comparator.walkabout(self)
+ self.emit_op_arg(ops.COMPARE_OP, compare_operations(last_op))
if ops_count > 1:
end = self.new_block()
self.emit_jump(ops.JUMP_FORWARD, end)
@@ -864,6 +865,37 @@
self.emit_op(ops.POP_TOP)
self.use_next_block(end)
+ def _optimize_comparator(self, op, node):
+ """Fold lists/sets of constants in the context of "in"/"not in".
+
+ lists are folded into tuples, sets into frozensets, otherwise
+ returns False
+ """
+ if op in (ast.In, ast.NotIn):
+ is_list = isinstance(node, ast.List)
+ if is_list or isinstance(node, ast.Set):
+ w_const = self._tuple_of_consts(node.elts)
+ if w_const is not None:
+ if not is_list:
+ from pypy.objspace.std.setobject import (
+ W_FrozensetObject)
+ w_const = W_FrozensetObject(self.space, w_const)
+ self.load_const(w_const)
+ return True
+ return False
+
+ def _tuple_of_consts(self, elts):
+ """Return a tuple of consts from elts if possible, or None"""
+ count = len(elts) if elts is not None else 0
+ consts_w = [None] * count
+ for i in range(count):
+ w_value = elts[i].as_constant()
+ if w_value is None:
+ # Not all constants
+ return None
+ consts_w[i] = w_value
+ return self.space.newtuple(consts_w)
+
def visit_IfExp(self, ifexp):
self.update_position(ifexp.lineno)
end = self.new_block()
diff --git a/pypy/interpreter/astcompiler/test/test_compiler.py b/pypy/interpreter/astcompiler/test/test_compiler.py
--- a/pypy/interpreter/astcompiler/test/test_compiler.py
+++ b/pypy/interpreter/astcompiler/test/test_compiler.py
@@ -973,3 +973,30 @@
counts = self.count_instructions(source3)
assert counts[ops.BUILD_LIST] == 1
assert ops.BUILD_LIST_FROM_ARG not in counts
+
+ def test_folding_of_list_constants(self):
+ for source in (
+ # in/not in constants with BUILD_LIST should be folded to a tuple:
+ 'a in [1,2,3]',
+ 'a not in ["a","b","c"]',
+ 'a in [None, 1, None]',
+ 'a not in [(1, 2), 3, 4]',
+ ):
+ source = 'def f(): %s' % source
+ counts = self.count_instructions(source)
+ assert ops.BUILD_LIST not in counts
+ assert ops.LOAD_CONST in counts
+
+ def test_folding_of_set_constants(self):
+ for source in (
+ # in/not in constants with BUILD_SET should be folded to a frozenset:
+ 'a in {1,2,3}',
+ 'a not in {"a","b","c"}',
+ 'a in {None, 1, None}',
+ 'a not in {(1, 2), 3, 4}',
+ 'a in {1, 2, 3, 3, 2, 1}',
+ ):
+ source = 'def f(): %s' % source
+ counts = self.count_instructions(source)
+ assert ops.BUILD_SET not in counts
+ assert ops.LOAD_CONST in counts
diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py
--- a/pypy/interpreter/baseobjspace.py
+++ b/pypy/interpreter/baseobjspace.py
@@ -242,6 +242,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_compiler.py b/pypy/interpreter/test/test_compiler.py
--- a/pypy/interpreter/test/test_compiler.py
+++ b/pypy/interpreter/test/test_compiler.py
@@ -936,6 +936,21 @@
output = s.getvalue()
assert "LOAD_GLOBAL" not in output
+ def test_folding_of_list_constants(self):
+ source = 'a in [1, 2, 3]'
+ co = compile(source, '', 'exec')
+ i = co.co_consts.index((1, 2, 3))
+ assert i > -1
+ assert isinstance(co.co_consts[i], tuple)
+
+ def test_folding_of_set_constants(self):
+ source = 'a in {1, 2, 3}'
+ co = compile(source, '', 'exec')
+ i = co.co_consts.index(set([1, 2, 3]))
+ assert i > -1
+ assert isinstance(co.co_consts[i], frozenset)
+
+
class AppTestCallMethod(object):
spaceconfig = {'objspace.opcodes.CALL_METHOD': True}
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,24 +1,25 @@
-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.baseobjspace import W_Root
from pypy.interpreter.error import OperationError, operationerrfmt
+from pypy.interpreter.gateway import (
+ WrappedDefault, applevel, interp2app, unwrap_spec)
+from pypy.interpreter.mixedmodule import MixedModule
from pypy.interpreter.signature import Signature
+from pypy.objspace.std.stdtypedef import StdTypeDef
-from rpython.rlib.objectmodel import r_dict, specialize, newlist_hint
+from rpython.rlib import jit, rerased
from rpython.rlib.debug import mark_dict_non_null
-from rpython.tool.sourcetools import func_with_new_name
+from rpython.rlib.objectmodel import newlist_hint, r_dict, specialize
+from rpython.tool.sourcetools import func_renamer, 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)
def _never_equal_to_string(space, w_lookup_type):
- """ Handles the case of a non string key lookup.
+ """Handles the case of a non string key lookup.
Types that have a sane hash/eq function should allow us to return True
directly to signal that the key is not in the dict in any case.
XXX The types should provide such a flag. """
@@ -32,7 +33,7 @@
@specialize.call_location()
def w_dict_unrolling_heuristic(w_dct):
- """ In which cases iterating over dict items can be unrolled.
+ """In which cases iterating over dict items can be unrolled.
Note that w_dct is an instance of W_DictMultiObject, not necesarilly
an actual dict
"""
@@ -40,13 +41,24 @@
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):
-
+ instance=False, strdict=False,
+ kwargs=False):
if space.config.objspace.std.withcelldict and module:
from pypy.objspace.std.celldict import ModuleDictStrategy
assert w_type is None
@@ -56,11 +68,9 @@
elif space.config.objspace.std.withmapdict and instance:
from pypy.objspace.std.mapdict import MapDictStrategy
strategy = space.fromcache(MapDictStrategy)
-
elif instance or strdict or module:
assert w_type is None
strategy = space.fromcache(StringDictStrategy)
-
elif kwargs:
assert w_type is None
from pypy.objspace.std.kwargsdict import EmptyKwargsDictStrategy
@@ -81,7 +91,7 @@
self.dstorage = storage
def __repr__(w_self):
- """ representation for debugging purposes """
+ """representation for debugging purposes"""
return "%s(%s)" % (w_self.__class__.__name__, w_self.strategy)
def unwrap(w_dict, space):
@@ -94,12 +104,10 @@
def missing_method(w_dict, space, w_key):
if not space.is_w(space.type(w_dict), space.w_dict):
- w_missing = space.lookup(w_dict, "__missing__")
- if w_missing is None:
- return None
- return space.get_and_call_function(w_missing, w_dict, w_key)
- else:
- return None
+ w_missing = space.lookup(w_dict, '__missing__')
+ if w_missing is not None:
+ return space.get_and_call_function(w_missing, w_dict, w_key)
+ return None
def initialize_content(w_self, list_pairs_w):
for w_k, w_v in list_pairs_w:
@@ -108,6 +116,228 @@
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 True:
+ 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()
+
+ @unwrap_spec(w_default=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)
+ return w_value if w_value is not None else w_default
+
+ @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])
+
+ @unwrap_spec(w_default=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 \
@@ -128,8 +358,87 @@
_add_indirections()
+
+app = 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__ = interp2app(W_DictMultiObject.descr_new),
+ fromkeys = interp2app(W_DictMultiObject.descr_fromkeys,
+ as_classmethod=True),
+ __hash__ = None,
+ __repr__ = interp2app(W_DictMultiObject.descr_repr),
+ __init__ = interp2app(W_DictMultiObject.descr_init),
+
+ __eq__ = interp2app(W_DictMultiObject.descr_eq),
+ __ne__ = interp2app(W_DictMultiObject.descr_ne),
+ __lt__ = interp2app(W_DictMultiObject.descr_lt),
+ __le__ = interp2app(W_DictMultiObject.descr_le),
+ __gt__ = interp2app(W_DictMultiObject.descr_gt),
+ __ge__ = interp2app(W_DictMultiObject.descr_ge),
+
+ __len__ = interp2app(W_DictMultiObject.descr_len),
+ __iter__ = interp2app(W_DictMultiObject.descr_iter),
+ __contains__ = interp2app(W_DictMultiObject.descr_contains),
+
+ __getitem__ = interp2app(W_DictMultiObject.descr_getitem),
+ __setitem__ = interp2app(W_DictMultiObject.descr_setitem),
+ __delitem__ = interp2app(W_DictMultiObject.descr_delitem),
+
+ __reversed__ = interp2app(W_DictMultiObject.descr_reversed),
+ copy = interp2app(W_DictMultiObject.descr_copy),
+ items = interp2app(W_DictMultiObject.descr_items),
+ keys = interp2app(W_DictMultiObject.descr_keys),
+ values = interp2app(W_DictMultiObject.descr_values),
+ iteritems = interp2app(W_DictMultiObject.descr_iteritems),
+ iterkeys = interp2app(W_DictMultiObject.descr_iterkeys),
+ itervalues = interp2app(W_DictMultiObject.descr_itervalues),
+ viewkeys = interp2app(W_DictMultiObject.descr_viewkeys),
+ viewitems = interp2app(W_DictMultiObject.descr_viewitems),
+ viewvalues = interp2app(W_DictMultiObject.descr_viewvalues),
+ has_key = interp2app(W_DictMultiObject.descr_has_key),
+ clear = interp2app(W_DictMultiObject.descr_clear),
+ get = interp2app(W_DictMultiObject.descr_get),
+ pop = interp2app(W_DictMultiObject.descr_pop),
+ popitem = interp2app(W_DictMultiObject.descr_popitem),
+ setdefault = interp2app(W_DictMultiObject.descr_setdefault),
+ update = interp2app(W_DictMultiObject.descr_update),
+ )
+
+
class DictStrategy(object):
-
def __init__(self, space):
self.space = space
@@ -139,7 +448,7 @@
def w_keys(self, w_dict):
iterator = self.iterkeys(w_dict)
result = newlist_hint(self.length(w_dict))
- while 1:
+ while True:
w_key = iterator.next_key()
if w_key is not None:
result.append(w_key)
@@ -149,7 +458,7 @@
def values(self, w_dict):
iterator = self.itervalues(w_dict)
result = newlist_hint(self.length(w_dict))
- while 1:
+ while True:
w_value = iterator.next_value()
if w_value is not None:
result.append(w_value)
@@ -159,7 +468,7 @@
def items(self, w_dict):
iterator = self.iteritems(w_dict)
result = newlist_hint(self.length(w_dict))
- while 1:
+ while True:
w_key, w_value = iterator.next_item()
if w_key is not None:
result.append(self.space.newtuple([w_key, w_value]))
@@ -171,7 +480,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)
@@ -195,14 +503,14 @@
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)
def get_empty_storage(self):
- return self.erase(None)
+ return self.erase(None)
def switch_to_correct_strategy(self, w_dict, w_key):
withidentitydict = self.space.config.objspace.std.withidentitydict
@@ -301,21 +609,24 @@
def getiteritems(self, w_dict):
return iter([(None, None)])
+
# Iterator Implementation base classes
def _new_next(TP):
- if TP == 'key' or TP == 'value':
+ if TP in ('key', 'value'):
EMPTY = None
else:
EMPTY = None, None
-
+
def next(self):
if self.dictimplementation is None:
return EMPTY
+ space = self.space
if self.len != self.dictimplementation.length():
self.len = -1 # Make this error state sticky
- raise OperationError(self.space.w_RuntimeError,
- self.space.wrap("dictionary changed size during iteration"))
+ msg = "dictionary changed size during iteration"
+ raise OperationError(space.w_RuntimeError, space.wrap(msg))
+
# look for the next entry
if self.pos < self.len:
result = getattr(self, 'next_' + TP + '_entry')()
@@ -333,8 +644,8 @@
w_value = self.dictimplementation.getitem(w_key)
if w_value is None:
self.len = -1 # Make this error state sticky
- raise OperationError(self.space.w_RuntimeError,
- self.space.wrap("dictionary changed during iteration"))
+ msg = "dictionary changed during iteration"
+ raise OperationError(space.w_RuntimeError, space.wrap(msg))
return (w_key, w_value)
# no more entries
self.dictimplementation = None
@@ -372,7 +683,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)
@@ -424,11 +735,6 @@
create_iterator_classes(EmptyDictStrategy)
-registerimplementation(W_DictMultiObject)
-
-# DictImplementation lattice
-# XXX fix me
-
# concrete subclasses of the above
@@ -472,7 +778,8 @@
def setdefault(self, w_dict, w_key, w_default):
if self.is_correct_type(w_key):
- return self.unerase(w_dict.dstorage).setdefault(self.unwrap(w_key), w_default)
+ return self.unerase(w_dict.dstorage).setdefault(self.unwrap(w_key),
+ w_default)
else:
self.switch_to_object_strategy(w_dict)
return w_dict.setdefault(w_key, w_default)
@@ -512,7 +819,7 @@
space = self.space
dict_w = self.unerase(w_dict.dstorage)
return [space.newtuple([self.wrap(key), w_value])
- for (key, w_value) in dict_w.iteritems()]
+ for (key, w_value) in dict_w.iteritems()]
def popitem(self, w_dict):
key, value = self.unerase(w_dict.dstorage).popitem()
@@ -543,7 +850,6 @@
class ObjectDictStrategy(AbstractTypedStrategy, DictStrategy):
-
erase, unerase = rerased.new_erasing_pair("object")
erase = staticmethod(erase)
unerase = staticmethod(unerase)
@@ -558,9 +864,9 @@
return True
def get_empty_storage(self):
- new_dict = r_dict(self.space.eq_w, self.space.hash_w,
- force_non_null=True)
- return self.erase(new_dict)
+ new_dict = r_dict(self.space.eq_w, self.space.hash_w,
+ force_non_null=True)
+ return self.erase(new_dict)
def _never_equal_to(self, w_lookup_type):
return False
@@ -576,8 +882,8 @@
create_iterator_classes(ObjectDictStrategy)
+
class StringDictStrategy(AbstractTypedStrategy, DictStrategy):
-
erase, unerase = rerased.new_erasing_pair("string")
erase = staticmethod(erase)
unerase = staticmethod(unerase)
@@ -642,7 +948,6 @@
class UnicodeDictStrategy(AbstractTypedStrategy, DictStrategy):
-
erase, unerase = rerased.new_erasing_pair("unicode")
erase = staticmethod(erase)
unerase = staticmethod(unerase)
@@ -744,9 +1049,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:
@@ -764,7 +1066,7 @@
w_dict_unrolling_heuristic(w_data))
def update1_dict_dict(space, w_dict, w_data):
iterator = w_data.iteritems()
- while 1:
+ while True:
w_key, w_value = iterator.next_item()
if w_key is None:
break
@@ -788,6 +1090,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,
@@ -798,72 +1103,19 @@
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)
-
-dict_has_key__DictMulti_ANY = contains__DictMulti_ANY
-
-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()
- while 1:
+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 True:
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 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
- if w_smallest_diff_a_key is None or space.is_true(space.lt(w_key, w_smallest_diff_a_key)):
+ 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
@@ -874,105 +1126,11 @@
w_smallest_diff_a_key = w_key
return w_smallest_diff_a_key, w_its_value
-def lt__DictMulti_DictMulti(space, w_left, w_right):
- # Different sizes, no problem
- if w_left.length() < w_right.length():
- return space.w_True
- if w_left.length() > w_right.length():
- return space.w_False
-
- # Same size
- w_leftdiff, w_leftval = characterize(space, w_left, w_right)
- if w_leftdiff is None:
- return space.w_False
- w_rightdiff, w_rightval = characterize(space, w_right, w_left)
- 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
-
-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 space.newlist(w_self.items())
-
-def dict_keys__DictMulti(space, w_self):
- return w_self.w_keys()
-
-def dict_values__DictMulti(space, w_self):
- return space.newlist(w_self.values())
-
-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_viewitems__DictMulti(space, w_self):
- return W_DictViewItemsObject(space, w_self)
-
-def dict_viewkeys__DictMulti(space, w_self):
- return W_DictViewKeysObject(space, w_self)
-
-def dict_viewvalues__DictMulti(space, w_self):
- return W_DictViewValuesObject(space, w_self)
-
-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])
-
# ____________________________________________________________
# 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
@@ -981,139 +1139,265 @@
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.type(self)
+
+ 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_DictMultiIterKeysObject):
+ w_clone = space.allocate_instance(W_DictMultiIterKeysObject,
+ w_typeobj)
+ elif isinstance(self, W_DictMultiIterValuesObject):
+ w_clone = space.allocate_instance(W_DictMultiIterValuesObject,
+ w_typeobj)
+ elif isinstance(self, W_DictMultiIterItemsObject):
+ w_clone = space.allocate_instance(W_DictMultiIterItemsObject,
+ 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)
+ w_ret = space.newtuple([new_inst, space.newtuple([w_res])])
+ 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__ = interp2app(W_DictMultiIterItemsObject.descr_iter),
+ next = interp2app(W_DictMultiIterItemsObject.descr_next),
+ __length_hint__ = interp2app(W_BaseDictMultiIterObject.descr_length_hint),
+ __reduce__ = interp2app(W_BaseDictMultiIterObject.descr_reduce),
+ )
-def iter__DictMultiIterKeysObject(space, w_dictiter):
- return w_dictiter
+W_DictMultiIterKeysObject.typedef = StdTypeDef(
+ "dict_iterkeys",
+ __iter__ = interp2app(W_DictMultiIterKeysObject.descr_iter),
+ next = interp2app(W_DictMultiIterKeysObject.descr_next),
+ __length_hint__ = interp2app(W_BaseDictMultiIterObject.descr_length_hint),
+ __reduce__ = interp2app(W_BaseDictMultiIterObject.descr_reduce),
+ )
-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__ = interp2app(W_DictMultiIterValuesObject.descr_iter),
+ next = interp2app(W_DictMultiIterValuesObject.descr_next),
+ __length_hint__ = interp2app(W_BaseDictMultiIterObject.descr_length_hint),
+ __reduce__ = interp2app(W_BaseDictMultiIterObject.descr_reduce),
+ )
-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)))
-class W_DictViewItemsObject(W_DictViewObject):
- from pypy.objspace.std.dicttype import dict_items_typedef as typedef
-registerimplementation(W_DictViewItemsObject)
+ def descr_len(self, space):
+ return space.len(self.w_dict)
+
+def _all_contained_in(space, w_dictview, w_other):
+ w_iter = space.iter(w_dictview)
+ for w_item in space.iteriterable(w_iter):
+ if not space.is_true(space.contains(w_other, w_item)):
+ return space.w_False
+ return space.w_True
+
+def _is_set_like(w_other):
+ from pypy.objspace.std.setobject import W_BaseSetObject
+ return (isinstance(w_other, W_BaseSetObject) or
+ isinstance(w_other, W_DictViewKeysObject) or
+ isinstance(w_other, W_DictViewItemsObject))
+
+class SetLikeDictView(object):
+ _mixin_ = True
+
+ def descr_eq(self, space, w_other):
+ if not _is_set_like(w_other):
+ return space.w_NotImplemented
+ if space.len_w(self) == space.len_w(w_other):
+ return _all_contained_in(space, self, w_other)
+ return space.w_False
+
+ def descr_ne(self, space, w_other):
+ if not _is_set_like(w_other):
+ return space.w_NotImplemented
+ return space.not_(space.eq(self, w_other))
+
+ def descr_lt(self, space, w_other):
+ if not _is_set_like(w_other):
+ return space.w_NotImplemented
+ if space.len_w(self) < space.len_w(w_other):
+ return _all_contained_in(space, self, w_other)
+ return space.w_False
+
+ def descr_le(self, space, w_other):
+ if not _is_set_like(w_other):
+ return space.w_NotImplemented
+ if space.len_w(self) <= space.len_w(w_other):
+ return _all_contained_in(space, self, w_other)
+ return space.w_False
+
+ def descr_gt(self, space, w_other):
+ if not _is_set_like(w_other):
+ return space.w_NotImplemented
+ if space.len_w(self) > space.len_w(w_other):
+ return _all_contained_in(space, w_other, self)
+ return space.w_False
+
+ def descr_ge(self, space, w_other):
+ if not _is_set_like(w_other):
+ return space.w_NotImplemented
+ if space.len_w(self) >= space.len_w(w_other):
+ return _all_contained_in(space, w_other, self)
+ return space.w_False
+
+ def _as_set_op(name, methname):
+ @func_renamer('descr_' + name)
+ def op(self, space, w_other):
+ w_set = space.call_function(space.w_set, self)
+ space.call_method(w_set, methname, w_other)
+ return w_set
+ @func_renamer('descr_r' + name)
+ def rop(self, space, w_other):
+ w_set = space.call_function(space.w_set, w_other)
+ space.call_method(w_set, methname, self)
+ return w_set
+ return op, rop
+
+ descr_sub, descr_rsub = _as_set_op('sub', 'difference_update')
+ descr_and, descr_rand = _as_set_op('and', 'intersection_update')
+ descr_or, descr_ror = _as_set_op('or', 'update')
+ descr_xor, descr_rxor = _as_set_op('xor', 'symmetric_difference_update')
+
+class W_DictViewItemsObject(W_DictViewObject, SetLikeDictView):
+ def descr_iter(self, space):
+ return W_DictMultiIterItemsObject(space, self.w_dict.iteritems())
+
+class W_DictViewKeysObject(W_DictViewObject, SetLikeDictView):
+ 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__ = interp2app(W_DictViewItemsObject.descr_repr),
+ __len__ = interp2app(W_DictViewItemsObject.descr_len),
+ __iter__ = interp2app(W_DictViewItemsObject.descr_iter),
-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)
+ __eq__ = interp2app(W_DictViewItemsObject.descr_eq),
+ __ne__ = interp2app(W_DictViewItemsObject.descr_ne),
+ __lt__ = interp2app(W_DictViewItemsObject.descr_lt),
+ __le__ = interp2app(W_DictViewItemsObject.descr_le),
+ __gt__ = interp2app(W_DictViewItemsObject.descr_gt),
+ __ge__ = interp2app(W_DictViewItemsObject.descr_ge),
-def all_contained_in(space, w_dictview, w_otherview):
- w_iter = space.iter(w_dictview)
+ __sub__ = interp2app(W_DictViewItemsObject.descr_sub),
+ __rsub__ = interp2app(W_DictViewItemsObject.descr_rsub),
+ __and__ = interp2app(W_DictViewItemsObject.descr_and),
+ __rand__ = interp2app(W_DictViewItemsObject.descr_rand),
+ __or__ = interp2app(W_DictViewItemsObject.descr_or),
+ __ror__ = interp2app(W_DictViewItemsObject.descr_ror),
+ __xor__ = interp2app(W_DictViewItemsObject.descr_xor),
+ __rxor__ = interp2app(W_DictViewItemsObject.descr_rxor),
+ )
- 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
+W_DictViewKeysObject.typedef = StdTypeDef(
+ "dict_keys",
+ __repr__ = interp2app(W_DictViewKeysObject.descr_repr),
+ __len__ = interp2app(W_DictViewKeysObject.descr_len),
+ __iter__ = interp2app(W_DictViewKeysObject.descr_iter),
- return space.w_True
+ __eq__ = interp2app(W_DictViewKeysObject.descr_eq),
+ __ne__ = interp2app(W_DictViewKeysObject.descr_ne),
+ __lt__ = interp2app(W_DictViewKeysObject.descr_lt),
+ __le__ = interp2app(W_DictViewKeysObject.descr_le),
+ __gt__ = interp2app(W_DictViewKeysObject.descr_gt),
+ __ge__ = interp2app(W_DictViewKeysObject.descr_ge),
-def eq__DictViewKeys_DictViewKeys(space, w_dictview, w_otherview):
- if space.eq_w(space.len(w_dictview), space.len(w_otherview)):
- return all_contained_in(space, w_dictview, w_otherview)
- return space.w_False
-eq__DictViewKeys_settypedef = eq__DictViewKeys_DictViewKeys
-eq__DictViewKeys_frozensettypedef = eq__DictViewKeys_DictViewKeys
+ __sub__ = interp2app(W_DictViewKeysObject.descr_sub),
+ __rsub__ = interp2app(W_DictViewKeysObject.descr_rsub),
+ __and__ = interp2app(W_DictViewKeysObject.descr_and),
+ __rand__ = interp2app(W_DictViewKeysObject.descr_rand),
+ __or__ = interp2app(W_DictViewKeysObject.descr_or),
+ __ror__ = interp2app(W_DictViewKeysObject.descr_ror),
+ __xor__ = interp2app(W_DictViewKeysObject.descr_xor),
+ __rxor__ = interp2app(W_DictViewKeysObject.descr_rxor),
+ )
-eq__DictViewKeys_DictViewItems = eq__DictViewKeys_DictViewKeys
-eq__DictViewItems_DictViewItems = eq__DictViewKeys_DictViewKeys
-eq__DictViewItems_settypedef = eq__DictViewItems_DictViewItems
-eq__DictViewItems_frozensettypedef = eq__DictViewItems_DictViewItems
-
-def repr__DictViewKeys(space, w_dictview):
- w_seq = space.call_function(space.w_list, w_dictview)
- w_repr = space.repr(w_seq)
- return space.wrap("%s(%s)" % (space.type(w_dictview).getname(space),
- space.str_w(w_repr)))
-repr__DictViewItems = repr__DictViewKeys
-repr__DictViewValues = repr__DictViewKeys
-
-def and__DictViewKeys_DictViewKeys(space, w_dictview, w_otherview):
- w_set = space.call_function(space.w_set, w_dictview)
- space.call_method(w_set, "intersection_update", w_otherview)
- return w_set
-and__DictViewKeys_settypedef = and__DictViewKeys_DictViewKeys
-and__DictViewItems_DictViewItems = and__DictViewKeys_DictViewKeys
-and__DictViewItems_settypedef = and__DictViewKeys_DictViewKeys
-
-def or__DictViewKeys_DictViewKeys(space, w_dictview, w_otherview):
- w_set = space.call_function(space.w_set, w_dictview)
- space.call_method(w_set, "update", w_otherview)
- return w_set
-or__DictViewKeys_settypedef = or__DictViewKeys_DictViewKeys
-or__DictViewItems_DictViewItems = or__DictViewKeys_DictViewKeys
-or__DictViewItems_settypedef = or__DictViewKeys_DictViewKeys
-
-def xor__DictViewKeys_DictViewKeys(space, w_dictview, w_otherview):
- w_set = space.call_function(space.w_set, w_dictview)
- space.call_method(w_set, "symmetric_difference_update", w_otherview)
- return w_set
-xor__DictViewKeys_settypedef = xor__DictViewKeys_DictViewKeys
-xor__DictViewItems_DictViewItems = xor__DictViewKeys_DictViewKeys
-xor__DictViewItems_settypedef = xor__DictViewKeys_DictViewKeys
-
-# ____________________________________________________________
-
-from pypy.objspace.std import dicttype
-register_all(vars(), dicttype)
+W_DictViewValuesObject.typedef = StdTypeDef(
+ "dict_values",
+ __repr__ = interp2app(W_DictViewValuesObject.descr_repr),
+ __len__ = interp2app(W_DictViewValuesObject.descr_len),
+ __iter__ = interp2app(W_DictViewValuesObject.descr_iter),
+ )
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,221 +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() -> list of D's (key, value) pairs, as"
- ' 2-tuples')
-dict_keys = SMM('keys', 1,
- doc="D.keys() -> list of D's keys")
-dict_values = SMM('values', 1,
- doc="D.values() -> list of D's values")
-dict_has_key = SMM('has_key', 2,
- doc='D.has_key(k) -> True if D has a key k, else False')
-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_viewkeys = SMM('viewkeys', 1,
- doc="D.viewkeys() -> a set-like object providing a view on D's keys")
-dict_viewitems = SMM('viewitems', 1,
- doc="D.viewitems() -> a set-like object providing a view on D's items")
-dict_viewvalues = SMM('viewvalues', 1,
- doc="D.viewvalues() -> an object providing a view on D's values")
-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 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")
-
-
-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 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(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
-
-dict_keys_typedef = StdTypeDef(
- "dict_keys",
- )
-
-dict_items_typedef = StdTypeDef(
- "dict_items",
- )
-
-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
@@ -309,15 +309,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.
@@ -329,7 +332,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.basestringtype import basestring_typedef
from pypy.objspace.std.stringtype import str_typedef
from pypy.objspace.std.bytearraytype import bytearray_typedef
@@ -81,6 +80,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)
@@ -92,10 +92,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: [],
@@ -108,9 +104,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: [],
}
@@ -333,9 +326,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
@@ -253,10 +253,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
@@ -2,8 +2,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):
@@ -409,6 +408,24 @@
assert {'a': 1 } < { 'b': 1}
assert {'a': 1, 'x': 2 } < { 'b': 1, 'x': 2}
+ 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})
@@ -604,6 +621,9 @@
assert d.values() == []
assert d.keys() == []
+ def test_cmp_with_noncmp(self):
+ assert not {} > object()
+
class AppTest_DictMultiObject(AppTest_DictObject):
def test_emptydict_unhashable(self):
@@ -676,6 +696,7 @@
assert d.viewkeys() == e.viewkeys()
del e["a"]
assert d.viewkeys() != e.viewkeys()
+ assert not d.viewkeys() == 42
def test_dict_items(self):
d = {1: 10, "a": "ABC"}
@@ -700,6 +721,7 @@
assert d.viewitems() == e.viewitems()
e["a"] = "def"
assert d.viewitems() != e.viewitems()
+ assert not d.viewitems() == 42
def test_dict_mixed_keys_items(self):
d = {(1, 1): 11, (2, 2): 22}
@@ -712,6 +734,7 @@
values = d.viewvalues()
assert set(values) == set([10, "ABC"])
assert len(values) == 2
+ assert not values == 42
def test_dict_repr(self):
d = {1: 10, "a": "ABC"}
@@ -754,6 +777,13 @@
assert d1.viewkeys() ^ set(d2.viewkeys()) == set('ac')
assert d1.viewkeys() ^ set(d3.viewkeys()) == set('abde')
+ assert d1.viewkeys() - d1.viewkeys() == set()
+ assert d1.viewkeys() - d2.viewkeys() == set('a')
+ assert d1.viewkeys() - d3.viewkeys() == set('ab')
+ assert d1.viewkeys() - set(d1.viewkeys()) == set()
+ assert d1.viewkeys() - set(d2.viewkeys()) == set('a')
+ assert d1.viewkeys() - set(d3.viewkeys()) == set('ab')
+
def test_items_set_operations(self):
d1 = {'a': 1, 'b': 2}
d2 = {'a': 2, 'b': 2}
@@ -782,6 +812,113 @@
assert (d1.viewitems() ^ d3.viewitems() ==
set([('a', 1), ('b', 2), ('d', 4), ('e', 5)]))
+ assert d1.viewitems() - d1.viewitems() == set()
+ assert d1.viewitems() - d2.viewitems() == set([('a', 1)])
+ assert d1.viewitems() - d3.viewitems() == set([('a', 1), ('b', 2)])
+
+ def test_keys_set_operations_any_type(self):
+ d = {1: u'a', 2: u'b', 3: u'c'}
+ assert d.viewkeys() & set([1]) == set([1])
+ assert d.viewkeys() & {1: u'foo'} == set([1])
+ assert d.viewkeys() & [1, 2] == set([1, 2])
+ #
+ assert set([1]) & d.viewkeys() == set([1])
+ assert {1: u'foo'} & d.viewkeys() == set([1])
+ assert [1, 2] & d.viewkeys() == set([1, 2])
+ #
+ assert d.viewkeys() - set([1]) == set([2, 3])
+ assert set([1, 4]) - d.viewkeys() == set([4])
+ #
+ assert d.viewkeys() == set([1, 2, 3])
+ # XXX: The following 4 commented out are CPython 2.7 bugs
+ #assert set([1, 2, 3]) == d.viewkeys()
+ assert d.viewkeys() == frozenset(set([1, 2, 3]))
+ #assert frozenset(set([1, 2, 3])) == d.viewkeys()
+ assert not d.viewkeys() != set([1, 2, 3])
+ #assert not set([1, 2, 3]) != d.viewkeys()
+ assert not d.viewkeys() != frozenset(set([1, 2, 3]))
+ #assert not frozenset(set([1, 2, 3])) != d.viewkeys()
+
+ def test_items_set_operations_any_type(self):
+ d = {1: u'a', 2: u'b', 3: u'c'}
+ assert d.viewitems() & set([(1, u'a')]) == set([(1, u'a')])
+ assert d.viewitems() & {(1, u'a'): u'foo'} == set([(1, u'a')])
+ assert d.viewitems() & [(1, u'a'), (2, u'b')] == set([(1, u'a'), (2, u'b')])
+ #
+ assert set([(1, u'a')]) & d.viewitems() == set([(1, u'a')])
+ assert {(1, u'a'): u'foo'} & d.viewitems() == set([(1, u'a')])
+ assert [(1, u'a'), (2, u'b')] & d.viewitems() == set([(1, u'a'), (2, u'b')])
+ #
+ assert d.viewitems() - set([(1, u'a')]) == set([(2, u'b'), (3, u'c')])
+ assert set([(1, u'a'), 4]) - d.viewitems() == set([4])
+ #
+ assert d.viewitems() == set([(1, u'a'), (2, u'b'), (3, u'c')])
+ # XXX: The following 4 commented out are CPython 2.7 bugs
+ #assert set([(1, u'a'), (2, u'b'), (3, u'c')]) == d.viewitems()
+ assert d.viewitems() == frozenset(set([(1, u'a'), (2, u'b'), (3, u'c')]))
+ #assert frozenset(set([(1, u'a'), (2, u'b'), (3, u'c')])) == d.viewitems()
+ assert not d.viewitems() != set([(1, u'a'), (2, u'b'), (3, u'c')])
+ #assert not set([(1, u'a'), (2, u'b'), (3, u'c')]) != d.viewitems()
+ assert not d.viewitems() != frozenset(set([(1, u'a'), (2, u'b'), (3, u'c')]))
+ #assert not frozenset(set([(1, u'a'), (2, u'b'), (3, u'c')])) != d.viewitems()
+
+ def test_dictviewset_unhashable_values(self):
+ class C:
+ def __eq__(self, other):
+ return True
+ d = {1: C()}
+ assert d.viewitems() <= d.viewitems()
+
+ def test_compare_keys_and_items(self):
+ d1 = {1: 2}
+ d2 = {(1, 2): 'foo'}
+ assert d1.viewitems() == d2.viewkeys()
+
+ def test_keys_items_contained(self):
+ def helper(fn):
+ empty = fn(dict())
+ empty2 = fn(dict())
+ smaller = fn({1:1, 2:2})
+ larger = fn({1:1, 2:2, 3:3})
+ larger2 = fn({1:1, 2:2, 3:3})
+ larger3 = fn({4:1, 2:2, 3:3})
+
+ assert smaller < larger
+ assert smaller <= larger
+ assert larger > smaller
+ assert larger >= smaller
+
+ assert not smaller >= larger
+ assert not smaller > larger
+ assert not larger <= smaller
+ assert not larger < smaller
+
+ assert not smaller < larger3
+ assert not smaller <= larger3
+ assert not larger3 > smaller
+ assert not larger3 >= smaller
+
+ # Inequality strictness
+ assert larger2 >= larger
+ assert larger2 <= larger
+ assert not larger2 > larger
+ assert not larger2 < larger
+
+ assert larger == larger2
+ assert smaller != larger
+
+ # There is an optimization on the zero-element case.
+ assert empty == empty2
+ assert not empty != empty2
+ assert not empty == smaller
+ assert empty != smaller
+
+ # With the same size, an elementwise compare happens
+ assert larger != larger3
+ assert not larger == larger3
+
+ helper(lambda x: x.viewkeys())
+ helper(lambda x: x.viewitems())
class AppTestStrategies(object):
def setup_class(cls):
@@ -971,10 +1108,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:
diff --git a/rpython/memory/gc/env.py b/rpython/memory/gc/env.py
--- a/rpython/memory/gc/env.py
+++ b/rpython/memory/gc/env.py
@@ -1,9 +1,10 @@
"""
Utilities to get environ variables and platform-specific memory-related values.
"""
-import os, sys
+import os, sys, platform
from rpython.rlib.rarithmetic import r_uint
from rpython.rlib.debug import debug_print, debug_start, debug_stop
+from rpython.rlib.rstring import assert_str0
from rpython.rtyper.lltypesystem import lltype, rffi
from rpython.rtyper.lltypesystem.lloperation import llop
@@ -130,7 +131,22 @@
# ---------- Linux2 ----------
-def get_L2cache_linux2(filename="/proc/cpuinfo"):
+def get_L2cache_linux2():
+ arch = platform.machine()
+ if arch.endswith('86') or arch == 'x86_64':
+ return get_L2cache_linux2_cpuinfo()
+ if arch in ('alpha', 'ppc', 'ppc64'):
+ return get_L2cache_linux2_cpuinfo(label='L2 cache')
+ if arch == 'ia64':
+ return get_L2cache_linux2_ia64()
+ if arch in ('parisc', 'parisc64'):
+ return get_L2cache_linux2_cpuinfo(label='D-cache')
+ if arch in ('sparc', 'sparc64'):
+ return get_L2cache_linux2_sparc()
+ return -1
+
+
+def get_L2cache_linux2_cpuinfo(filename="/proc/cpuinfo", label='cache size'):
debug_start("gc-hardware")
L2cache = sys.maxint
try:
@@ -149,12 +165,8 @@
else:
data = ''.join(data)
linepos = 0
- # Currently on ARM-linux we won't find any information about caches in
More information about the pypy-commit
mailing list