[pypy-commit] pypy kill-single-impl-multimethods: Refactor the world :) Killed a bunch of multimethods in dict objects.
alex_gaynor
noreply at buildbot.pypy.org
Sun Aug 7 00:50:55 CEST 2011
Author: Alex Gaynor <alex.gaynor at gmail.com>
Branch: kill-single-impl-multimethods
Changeset: r46337:216a263e6a0b
Date: 2011-08-06 15:34 -0700
http://bitbucket.org/pypy/pypy/changeset/216a263e6a0b/
Log: Refactor the world :) Killed a bunch of multimethods in dict
objects.
diff --git a/pypy/interpreter/typedef.py b/pypy/interpreter/typedef.py
--- a/pypy/interpreter/typedef.py
+++ b/pypy/interpreter/typedef.py
@@ -28,14 +28,14 @@
# xxx used by faking
self.fakedcpytype = None
self.add_entries(**rawdict)
-
+
def add_entries(self, **rawdict):
# xxx fix the names of the methods to match what app-level expects
for key, value in rawdict.items():
if isinstance(value, (interp2app, GetSetProperty)):
value.name = key
self.rawdict.update(rawdict)
-
+
def _freeze_(self):
# hint for the annotator: track individual constant instances of TypeDef
return True
@@ -187,7 +187,7 @@
def add(Proto):
for key, value in Proto.__dict__.items():
- if (not key.startswith('__') and not key.startswith('_mixin_')
+ if (not key.startswith('__') and not key.startswith('_mixin_')
or key == '__del__'):
if hasattr(value, "func_name"):
value = func_with_new_name(value, value.func_name)
@@ -274,10 +274,10 @@
class Proto(object):
def getdict(self, space):
return self.w__dict__
-
+
def setdict(self, space, w_dict):
self.w__dict__ = check_new_dictionary(space, w_dict)
-
+
def user_setup(self, space, w_subtype):
self.w__dict__ = space.newdict(
instance=True, classofinstance=w_subtype)
@@ -299,8 +299,8 @@
if not space.is_true(space.isinstance(w_dict, space.w_dict)):
raise OperationError(space.w_TypeError,
space.wrap("setting dictionary to a non-dict"))
- from pypy.objspace.std import dictmultiobject
- assert isinstance(w_dict, dictmultiobject.W_DictMultiObject)
+ from pypy.objspace.std import dicttype
+ assert isinstance(w_dict, dicttype.W_DictMultiObject)
return w_dict
check_new_dictionary._dont_inline_ = True
@@ -342,7 +342,7 @@
return %(name)s(%(args)s, %(extra)s)
"""
miniglobals[cls_name] = cls
-
+
name = func.__name__
extra = ', '.join(extraargs)
from pypy.interpreter import pycode
@@ -462,7 +462,7 @@
space, '__delattr__',
self.reqcls, Arguments(space, [w_obj,
space.wrap(self.name)]))
-
+
def descr_get_objclass(space, property):
return property.objclass_getter(space)
@@ -480,7 +480,7 @@
return space.w_None
else:
return w_value
-
+
return GetSetProperty(fget, cls=cls, doc=doc)
GetSetProperty.typedef = TypeDef(
@@ -502,7 +502,7 @@
self.index = index
self.name = name
self.w_cls = w_cls
-
+
def typecheck(self, space, w_obj):
if not space.is_true(space.isinstance(w_obj, self.w_cls)):
raise operationerrfmt(space.w_TypeError,
@@ -511,7 +511,7 @@
self.name,
self.w_cls.name,
space.type(w_obj).getname(space))
-
+
def descr_member_get(self, space, w_obj, w_w_cls=None):
"""member.__get__(obj[, type]) -> value
Read the slot 'member' of the given 'obj'."""
@@ -524,13 +524,13 @@
raise OperationError(space.w_AttributeError,
space.wrap(self.name)) # XXX better message
return w_result
-
+
def descr_member_set(self, space, w_obj, w_value):
"""member.__set__(obj, value)
Write into the slot 'member' of the given 'obj'."""
self.typecheck(space, w_obj)
w_obj.setslotvalue(self.index, w_value)
-
+
def descr_member_del(self, space, w_obj):
"""member.__delete__(obj)
Delete the value of the slot 'member' from the given 'obj'."""
diff --git a/pypy/objspace/std/celldict.py b/pypy/objspace/std/celldict.py
--- a/pypy/objspace/std/celldict.py
+++ b/pypy/objspace/std/celldict.py
@@ -3,9 +3,8 @@
optimization is not helping at all, but in conjunction with the JIT it can
speed up global lookups a lot."""
-from pypy.objspace.std.dictmultiobject import IteratorImplementation
-from pypy.objspace.std.dictmultiobject import DictStrategy, _never_equal_to_string
-from pypy.objspace.std.dictmultiobject import ObjectDictStrategy
+from pypy.objspace.std.dicttype import (IteratorImplementation, DictStrategy,
+ _never_equal_to_string, ObjectDictStrategy)
from pypy.rlib import jit, rerased
class ModuleCell(object):
diff --git a/pypy/objspace/std/dictmultiobject.py b/pypy/objspace/std/dictmultiobject.py
deleted file mode 100644
--- a/pypy/objspace/std/dictmultiobject.py
+++ /dev/null
@@ -1,867 +0,0 @@
-import py, sys
-from pypy.objspace.std.model import registerimplementation, W_Object
-from pypy.objspace.std.register_all import register_all
-from pypy.objspace.std.settype import set_typedef as settypedef
-from pypy.interpreter import gateway
-from pypy.interpreter.argument import Signature
-from pypy.interpreter.error import OperationError, operationerrfmt
-
-from pypy.rlib.objectmodel import r_dict, we_are_translated, specialize
-from pypy.rlib.debug import mark_dict_non_null
-
-from pypy.rlib import rerased
-
-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.
- 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. """
-
- # XXX there are many more types
- return (space.is_w(w_lookup_type, space.w_NoneType) or
- space.is_w(w_lookup_type, space.w_int) or
- space.is_w(w_lookup_type, space.w_bool) or
- space.is_w(w_lookup_type, space.w_float)
- )
-
-class W_DictMultiObject(W_Object):
- from pypy.objspace.std.dicttype import dict_typedef as typedef
-
- @staticmethod
- def allocate_and_init_instance(space, w_type=None, module=False,
- instance=False, classofinstance=None,
- strdict=False):
-
- if space.config.objspace.std.withcelldict and module:
- from pypy.objspace.std.celldict import ModuleDictStrategy
- assert w_type is None
- strategy = space.fromcache(ModuleDictStrategy)
-
- elif instance or strdict or module:
- assert w_type is None
- strategy = space.fromcache(StringDictStrategy)
-
- else:
- strategy = space.fromcache(EmptyDictStrategy)
-
- if w_type is None:
- w_type = space.w_dict
- storage = strategy.get_empty_storage()
- w_self = space.allocate_instance(W_DictMultiObject, w_type)
- W_DictMultiObject.__init__(w_self, space, strategy, storage)
- return w_self
-
- def __init__(self, space, strategy, storage):
- self.space = space
- self.strategy = strategy
- self.dstorage = storage
-
- def __repr__(w_self):
- """ representation for debugging purposes """
- return "%s(%s)" % (w_self.__class__.__name__, w_self.strategy)
-
- def unwrap(w_dict, space):
- result = {}
- items = w_dict.items()
- for w_pair in items:
- key, val = space.unwrap(w_pair)
- result[key] = val
- return result
-
- 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
-
- def initialize_content(w_self, list_pairs_w):
- for w_k, w_v in list_pairs_w:
- w_self.setitem(w_k, w_v)
-
-def _add_indirections():
- dict_methods = "setitem setitem_str getitem \
- getitem_str delitem length \
- clear keys values \
- items iter setdefault \
- popitem".split()
-
- def make_method(method):
- def f(self, *args):
- return getattr(self.strategy, method)(self, *args)
- f.func_name = method
- return f
-
- for method in dict_methods:
- setattr(W_DictMultiObject, method, make_method(method))
-
-_add_indirections()
-
-class DictStrategy(object):
-
- def __init__(self, space):
- self.space = space
-
- def get_empty_storage(self):
- raise NotImplementedError
-
- def keys(self, w_dict):
- iterator = self.iter(w_dict)
- result = []
- while 1:
- w_key, w_value = iterator.next()
- if w_key is not None:
- result.append(w_key)
- else:
- return result
-
- def values(self, w_dict):
- iterator = self.iter(w_dict)
- result = []
- while 1:
- w_key, w_value = iterator.next()
- if w_value is not None:
- result.append(w_value)
- else:
- return result
-
- def items(self, w_dict):
- iterator = self.iter(w_dict)
- result = []
- while 1:
- w_key, w_value = iterator.next()
- if w_key is not None:
- result.append(self.space.newtuple([w_key, w_value]))
- else:
- return result
-
- def clear(self, w_dict):
- strategy = self.space.fromcache(EmptyDictStrategy)
- storage = strategy.get_empty_storage()
- w_dict.strategy = strategy
- w_dict.dstorage = storage
-
-
-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)
-
- def switch_to_correct_strategy(self, w_dict, w_key):
- withidentitydict = self.space.config.objspace.std.withidentitydict
- if type(w_key) is self.space.StringObjectCls:
- self.switch_to_string_strategy(w_dict)
- return
- w_type = self.space.type(w_key)
- if self.space.is_w(w_type, self.space.w_int):
- self.switch_to_int_strategy(w_dict)
- elif withidentitydict and w_type.compares_by_identity():
- self.switch_to_identity_strategy(w_dict)
- else:
- self.switch_to_object_strategy(w_dict)
-
- def switch_to_string_strategy(self, w_dict):
- strategy = self.space.fromcache(StringDictStrategy)
- storage = strategy.get_empty_storage()
- w_dict.strategy = strategy
- w_dict.dstorage = storage
-
- def switch_to_int_strategy(self, w_dict):
- strategy = self.space.fromcache(IntDictStrategy)
- storage = strategy.get_empty_storage()
- w_dict.strategy = strategy
- w_dict.dstorage = storage
-
- def switch_to_identity_strategy(self, w_dict):
- from pypy.objspace.std.identitydict import IdentityDictStrategy
- strategy = self.space.fromcache(IdentityDictStrategy)
- storage = strategy.get_empty_storage()
- w_dict.strategy = strategy
- w_dict.dstorage = storage
-
- def switch_to_object_strategy(self, w_dict):
- strategy = self.space.fromcache(ObjectDictStrategy)
- storage = strategy.get_empty_storage()
- w_dict.strategy = strategy
- w_dict.dstorage = storage
-
- def getitem(self, w_dict, w_key):
- #return w_value or None
- # in case the key is unhashable, try to hash it
- self.space.hash(w_key)
- # return None anyway
- return None
-
- def getitem_str(self, w_dict, key):
- #return w_value or None
- return None
-
- def setdefault(self, w_dict, w_key, w_default):
- # here the dict is always empty
- self.switch_to_correct_strategy(w_dict, w_key)
- w_dict.setitem(w_key, w_default)
- return w_default
-
- def setitem(self, w_dict, w_key, w_value):
- self.switch_to_correct_strategy(w_dict, w_key)
- w_dict.setitem(w_key, w_value)
-
- def setitem_str(self, w_dict, key, w_value):
- self.switch_to_string_strategy(w_dict)
- w_dict.setitem_str(key, w_value)
-
- def delitem(self, w_dict, w_key):
- # in case the key is unhashable, try to hash it
- self.space.hash(w_key)
- raise KeyError
-
- def length(self, w_dict):
- return 0
-
- def iter(self, w_dict):
- return EmptyIteratorImplementation(self.space, w_dict)
-
- def clear(self, w_dict):
- return
-
- def popitem(self, w_dict):
- raise KeyError
-
-registerimplementation(W_DictMultiObject)
-
-# DictImplementation lattice
-# XXX fix me
-
-# Iterator Implementation base classes
-
-class IteratorImplementation(object):
- def __init__(self, space, implementation):
- self.space = space
- self.dictimplementation = implementation
- self.len = implementation.length()
- self.pos = 0
-
- def next(self):
- if self.dictimplementation is None:
- return None, None
- 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"))
- # look for the next entry
- if self.pos < self.len:
- result = self.next_entry()
- self.pos += 1
- return result
- # no more entries
- self.dictimplementation = None
- return None, None
-
- def next_entry(self):
- """ Purely abstract method
- """
- raise NotImplementedError
-
- def length(self):
- if self.dictimplementation is not None:
- return self.len - self.pos
- return 0
-
-class EmptyIteratorImplementation(IteratorImplementation):
- def next(self):
- return (None, None)
-
-
-
-# concrete subclasses of the above
-
-class AbstractTypedStrategy(object):
- _mixin_ = True
-
- @staticmethod
- def erase(storage):
- raise NotImplementedError("abstract base class")
-
- @staticmethod
- def unerase(obj):
- raise NotImplementedError("abstract base class")
-
- def wrap(self, unwrapped):
- raise NotImplementedError
-
- def unwrap(self, wrapped):
- raise NotImplementedError
-
- def is_correct_type(self, w_obj):
- raise NotImplementedError("abstract base class")
-
- def get_empty_storage(self):
- raise NotImplementedError("abstract base class")
-
- def _never_equal_to(self, w_lookup_type):
- raise NotImplementedError("abstract base class")
-
- def setitem(self, w_dict, w_key, w_value):
- space = self.space
- if self.is_correct_type(w_key):
- self.unerase(w_dict.dstorage)[self.unwrap(w_key)] = w_value
- return
- else:
- self.switch_to_object_strategy(w_dict)
- w_dict.setitem(w_key, w_value)
-
- def setitem_str(self, w_dict, key, w_value):
- self.switch_to_object_strategy(w_dict)
- w_dict.setitem(self.space.wrap(key), w_value)
-
- def setdefault(self, w_dict, w_key, w_default):
- space = self.space
- if self.is_correct_type(w_key):
- 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)
-
- def delitem(self, w_dict, w_key):
- space = self.space
- w_key_type = space.type(w_key)
- if self.is_correct_type(w_key):
- del self.unerase(w_dict.dstorage)[self.unwrap(w_key)]
- return
- else:
- self.switch_to_object_strategy(w_dict)
- return w_dict.delitem(w_key)
-
- def length(self, w_dict):
- return len(self.unerase(w_dict.dstorage))
-
- def getitem_str(self, w_dict, key):
- return self.getitem(w_dict, self.space.wrap(key))
-
- def getitem(self, w_dict, w_key):
- space = self.space
- if self.is_correct_type(w_key):
- return self.unerase(w_dict.dstorage).get(self.unwrap(w_key), None)
- elif self._never_equal_to(space.type(w_key)):
- return None
- else:
- self.switch_to_object_strategy(w_dict)
- return w_dict.getitem(w_key)
-
- def keys(self, w_dict):
- return [self.wrap(key) for key in self.unerase(w_dict.dstorage).iterkeys()]
-
- def values(self, w_dict):
- return self.unerase(w_dict.dstorage).values()
-
- def items(self, w_dict):
- 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()]
-
- def popitem(self, w_dict):
- key, value = self.unerase(w_dict.dstorage).popitem()
- return (self.wrap(key), value)
-
- def clear(self, w_dict):
- self.unerase(w_dict.dstorage).clear()
-
- def switch_to_object_strategy(self, w_dict):
- d = self.unerase(w_dict.dstorage)
- strategy = self.space.fromcache(ObjectDictStrategy)
- d_new = strategy.unerase(strategy.get_empty_storage())
- for key, value in d.iteritems():
- d_new[self.wrap(key)] = value
- w_dict.strategy = strategy
- w_dict.dstorage = strategy.erase(d_new)
-
-class ObjectDictStrategy(AbstractTypedStrategy, DictStrategy):
-
- erase, unerase = rerased.new_erasing_pair("object")
- erase = staticmethod(erase)
- unerase = staticmethod(unerase)
-
- def wrap(self, unwrapped):
- return unwrapped
-
- def unwrap(self, wrapped):
- return wrapped
-
- def is_correct_type(self, w_obj):
- 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)
-
- def _never_equal_to(self, w_lookup_type):
- return False
-
- def iter(self, w_dict):
- return ObjectIteratorImplementation(self.space, self, w_dict)
-
- def keys(self, w_dict):
- return self.unerase(w_dict.dstorage).keys()
-
-
-class StringDictStrategy(AbstractTypedStrategy, DictStrategy):
-
- erase, unerase = rerased.new_erasing_pair("string")
- erase = staticmethod(erase)
- unerase = staticmethod(unerase)
-
- def wrap(self, unwrapped):
- return self.space.wrap(unwrapped)
-
- def unwrap(self, wrapped):
- return self.space.str_w(wrapped)
-
- def is_correct_type(self, w_obj):
- space = self.space
- return space.is_w(space.type(w_obj), space.w_str)
-
- def get_empty_storage(self):
- res = {}
- mark_dict_non_null(res)
- return self.erase(res)
-
- def _never_equal_to(self, w_lookup_type):
- return _never_equal_to_string(self.space, w_lookup_type)
-
- def setitem_str(self, w_dict, key, w_value):
- assert key is not None
- self.unerase(w_dict.dstorage)[key] = w_value
-
- def getitem(self, w_dict, w_key):
- space = self.space
- # -- This is called extremely often. Hack for performance --
- if type(w_key) is space.StringObjectCls:
- return self.getitem_str(w_dict, w_key.unwrap(space))
- # -- End of performance hack --
- return AbstractTypedStrategy.getitem(self, w_dict, w_key)
-
- def getitem_str(self, w_dict, key):
- assert key is not None
- return self.unerase(w_dict.dstorage).get(key, None)
-
- def iter(self, w_dict):
- return StrIteratorImplementation(self.space, self, w_dict)
-
-
-class _WrappedIteratorMixin(object):
- _mixin_ = True
-
- def __init__(self, space, strategy, dictimplementation):
- IteratorImplementation.__init__(self, space, dictimplementation)
- self.iterator = strategy.unerase(dictimplementation.dstorage).iteritems()
-
- def next_entry(self):
- # note that this 'for' loop only runs once, at most
- for key, w_value in self.iterator:
- return self.space.wrap(key), w_value
- else:
- return None, None
-
-class _UnwrappedIteratorMixin:
- _mixin_ = True
-
- def __init__(self, space, strategy, dictimplementation):
- IteratorImplementation.__init__(self, space, dictimplementation)
- self.iterator = strategy.unerase(dictimplementation.dstorage).iteritems()
-
- def next_entry(self):
- # note that this 'for' loop only runs once, at most
- for w_key, w_value in self.iterator:
- return w_key, w_value
- else:
- return None, None
-
-
-class StrIteratorImplementation(_WrappedIteratorMixin, IteratorImplementation):
- pass
-
-class IntDictStrategy(AbstractTypedStrategy, DictStrategy):
- erase, unerase = rerased.new_erasing_pair("int")
- erase = staticmethod(erase)
- unerase = staticmethod(unerase)
-
- def wrap(self, unwrapped):
- return self.space.wrap(unwrapped)
-
- def unwrap(self, wrapped):
- return self.space.int_w(wrapped)
-
- def get_empty_storage(self):
- return self.erase({})
-
- def is_correct_type(self, w_obj):
- space = self.space
- return space.is_w(space.type(w_obj), space.w_int)
-
- def _never_equal_to(self, w_lookup_type):
- space = self.space
- # XXX there are many more types
- return (space.is_w(w_lookup_type, space.w_NoneType) or
- space.is_w(w_lookup_type, space.w_str) or
- space.is_w(w_lookup_type, space.w_unicode)
- )
-
- def iter(self, w_dict):
- return IntIteratorImplementation(self.space, self, w_dict)
-
-class IntIteratorImplementation(_WrappedIteratorMixin, IteratorImplementation):
- pass
-
-class ObjectIteratorImplementation(_UnwrappedIteratorMixin, IteratorImplementation):
- pass
-
-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:
- # no 'keys' method, so we assume it is a sequence of pairs
- for w_pair in space.listview(w_data):
- pair = space.fixedview(w_pair)
- if len(pair) != 2:
- raise OperationError(space.w_ValueError,
- space.wrap("sequence of pairs expected"))
- w_key, w_value = pair
- w_dict.setitem(w_key, w_value)
- else:
- if isinstance(w_data, W_DictMultiObject): # optimization case only
- update1_dict_dict(space, w_dict, w_data)
- else:
- # general case -- "for k in o.keys(): dict.__setitem__(d, k, o[k])"
- w_keys = space.call_method(w_data, "keys")
- for w_key in space.listview(w_keys):
- w_value = space.getitem(w_data, w_key)
- w_dict.setitem(w_key, w_value)
-
-def update1_dict_dict(space, w_dict, w_data):
- iterator = w_data.iter()
- while 1:
- w_key, w_value = iterator.next()
- if w_key is None:
- break
- w_dict.setitem(w_key, w_value)
-
-def init_or_update(space, w_dict, __args__, funcname):
- w_src, w_kwds = __args__.parse_obj(
- None, funcname,
- init_signature, # signature
- init_defaults) # default argument
- if w_src is not None:
- update1(space, w_dict, w_src)
- 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_DictMultiIterObject(space, w_dict.iter(), KEYSITER)
-
-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.iter()
- while 1:
- w_key, w_val = iteratorimplementation.next()
- 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.iter()
- while 1:
- w_key, w_val = iteratorimplementation.next()
- 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)):
- 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
-
-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 space.newlist(w_self.keys())
-
-def dict_values__DictMulti(space, w_self):
- return space.newlist(w_self.values())
-
-def dict_iteritems__DictMulti(space, w_self):
- return W_DictMultiIterObject(space, w_self.iter(), ITEMSITER)
-
-def dict_iterkeys__DictMulti(space, w_self):
- return W_DictMultiIterObject(space, w_self.iter(), KEYSITER)
-
-def dict_itervalues__DictMulti(space, w_self):
- return W_DictMultiIterObject(space, w_self.iter(), VALUESITER)
-
-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
-
-
-KEYSITER = 0
-ITEMSITER = 1
-VALUESITER = 2
-
-class W_DictMultiIterObject(W_Object):
- from pypy.objspace.std.dicttype import dictiter_typedef as typedef
-
- _immutable_fields_ = ["iteratorimplementation", "itertype"]
-
- def __init__(w_self, space, iteratorimplementation, itertype):
- w_self.space = space
- w_self.iteratorimplementation = iteratorimplementation
- w_self.itertype = itertype
-
-registerimplementation(W_DictMultiIterObject)
-
-def iter__DictMultiIterObject(space, w_dictiter):
- return w_dictiter
-
-def next__DictMultiIterObject(space, w_dictiter):
- iteratorimplementation = w_dictiter.iteratorimplementation
- w_key, w_value = iteratorimplementation.next()
- if w_key is not None:
- itertype = w_dictiter.itertype
- if itertype == KEYSITER:
- return w_key
- elif itertype == VALUESITER:
- return w_value
- elif itertype == ITEMSITER:
- return space.newtuple([w_key, w_value])
- else:
- assert 0, "should be unreachable"
- raise OperationError(space.w_StopIteration, space.w_None)
-
-# ____________________________________________________________
-# Views
-
-class W_DictViewObject(W_Object):
- 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)
-
-class W_DictViewItemsObject(W_DictViewObject):
- from pypy.objspace.std.dicttype import dict_items_typedef as typedef
-registerimplementation(W_DictViewItemsObject)
-
-class W_DictViewValuesObject(W_DictViewObject):
- from pypy.objspace.std.dicttype import dict_values_typedef as typedef
-registerimplementation(W_DictViewValuesObject)
-
-def len__DictViewKeys(space, w_dictview):
- return space.len(w_dictview.w_dict)
-len__DictViewItems = len__DictViewValues = len__DictViewKeys
-
-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)
-
-def all_contained_in(space, w_dictview, w_otherview):
- w_iter = space.iter(w_dictview)
- assert isinstance(w_iter, W_DictMultiIterObject)
-
- 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 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_DictViewItems = eq__DictViewKeys_DictViewKeys
-eq__DictViewItems_DictViewItems = eq__DictViewKeys_DictViewKeys
-eq__DictViewItems_settypedef = 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)
diff --git a/pypy/objspace/std/dictproxyobject.py b/pypy/objspace/std/dictproxyobject.py
--- a/pypy/objspace/std/dictproxyobject.py
+++ b/pypy/objspace/std/dictproxyobject.py
@@ -1,7 +1,6 @@
from pypy.objspace.std.model import registerimplementation, W_Object
from pypy.objspace.std.register_all import register_all
-from pypy.objspace.std.dictmultiobject import W_DictMultiObject, IteratorImplementation
-from pypy.objspace.std.dictmultiobject import DictStrategy
+from pypy.objspace.std.dicttype import W_DictMultiObject, IteratorImplementation, DictStrategy
from pypy.objspace.std.typeobject import unwrap_cell
from pypy.interpreter.error import OperationError
diff --git a/pypy/objspace/std/dicttype.py b/pypy/objspace/std/dicttype.py
--- a/pypy/objspace/std/dicttype.py
+++ b/pypy/objspace/std/dicttype.py
@@ -1,63 +1,693 @@
-from pypy.interpreter.error import OperationError
+import sys
+
+from pypy.interpreter import gateway
+from pypy.interpreter.argument import Signature
+from pypy.interpreter.baseobjspace import Wrappable
+from pypy.interpreter.error import OperationError, operationerrfmt
from pypy.interpreter.mixedmodule import MixedModule
-from pypy.interpreter import gateway
+from pypy.objspace.std.model import registerimplementation
+from pypy.objspace.std.register_all import register_all
+from pypy.objspace.std.settype import set_typedef as settypedef
from pypy.objspace.std.stdtypedef import StdTypeDef, SMM
-from pypy.objspace.std.register_all import register_all
+from pypy.rlib import rerased
+from pypy.rlib.debug import mark_dict_non_null
+from pypy.rlib.objectmodel import r_dict, we_are_translated, specialize
-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'))
+def _never_equal_to_string(space, w_lookup_type):
+ """ 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. """
-register_all(vars(), globals())
+ # XXX there are many more types
+ return (space.is_w(w_lookup_type, space.w_NoneType) or
+ space.is_w(w_lookup_type, space.w_int) or
+ space.is_w(w_lookup_type, space.w_bool) or
+ space.is_w(w_lookup_type, space.w_float)
+ )
+
+class W_DictMultiObject(Wrappable):
+ @staticmethod
+ def allocate_and_init_instance(space, w_type=None, module=False,
+ instance=False, classofinstance=None,
+ strdict=False):
+
+ if space.config.objspace.std.withcelldict and module:
+ from pypy.objspace.std.celldict import ModuleDictStrategy
+ assert w_type is None
+ strategy = space.fromcache(ModuleDictStrategy)
+
+ elif instance or strdict or module:
+ assert w_type is None
+ strategy = space.fromcache(StringDictStrategy)
+
+ else:
+ strategy = space.fromcache(EmptyDictStrategy)
+
+ if w_type is None:
+ w_type = space.w_dict
+ storage = strategy.get_empty_storage()
+ w_self = space.allocate_instance(W_DictMultiObject, w_type)
+ W_DictMultiObject.__init__(w_self, space, strategy, storage)
+ return w_self
+
+ def __init__(self, space, strategy, storage):
+ self.space = space
+ self.strategy = strategy
+ self.dstorage = storage
+
+ def __repr__(w_self):
+ """ representation for debugging purposes """
+ return "%s(%s)" % (w_self.__class__.__name__, w_self.strategy)
+
+ def unwrap(w_dict, space):
+ result = {}
+ items = w_dict.items()
+ for w_pair in items:
+ key, val = space.unwrap(w_pair)
+ result[key] = val
+ return result
+
+ 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
+
+ def initialize_content(w_self, list_pairs_w):
+ for w_k, w_v in list_pairs_w:
+ w_self.setitem(w_k, w_v)
+
+ def descr__new__(space, w_subtype, __args__):
+ return W_DictMultiObject.allocate_and_init_instance(space, w_subtype)
+
+ def descr__reversed__(self, space):
+ raise OperationError(space.w_TypeError, space.wrap('argument to reversed() must be a sequence'))
+
+ 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 space.newlist(self.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_DictMultiIterObject(space, self.iter(), ITEMSITER)
+
+ def descr_iterkeys(self, space):
+ """D.iterkeys() -> an iterator over the keys of D"""
+ return W_DictMultiIterObject(space, self.iter(), KEYSITER)
+
+ def descr_itervalues(self, space):
+ """D.itervalues() -> an iterator over the values of D"""
+ return W_DictMultiIterObject(space, self.iter(), VALUESITER)
+
+ 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_update(self, space, __args__):
+ """D.update(E, **F) -> None. Update D from E and F: for k in E: D[k] = E[k]
+ (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 descr_setdefault(self, space, w_key, w_value):
+ """D.setdefault(k[,d]) -> D.get(k,d), also set D[k]=d if k not in D"""
+ return self.setdefault(w_key, w_value)
+
+ def descr_popitem(self, space):
+ """D.popitem() -> (k, v), remove and return some (key, value) pair as a
+ 2-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])
+
+ def descr_pop(self, space, w_key, w_default=gateway.NoneNotWrapped):
+ """D.pop(k[,d]) -> v, remove specified key and return the corresponding value
+ If key is not found, d is returned if given, otherwise KeyError is raised"""
+ w_item = self.getitem(w_key)
+ if w_item is None:
+ if w_default is not None:
+ return w_default
+ else:
+ space.raise_key_error(w_key)
+ else:
+ self.delitem(w_key)
+ return w_item
+
+ def descr_clear(self):
+ """D.clear() -> None. Remove all items from D."""
+ self.clear()
+
+ def descr_get(self, space, w_key, w_default=None):
+ """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 None:
+ return w_default
+ return w_value
+
+ 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_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 _add_indirections():
+ dict_methods = "setitem setitem_str getitem \
+ getitem_str delitem length \
+ clear keys values \
+ items iter setdefault \
+ popitem".split()
+
+ def make_method(method):
+ def f(self, *args):
+ return getattr(self.strategy, method)(self, *args)
+ f.func_name = method
+ return f
+
+ for method in dict_methods:
+ setattr(W_DictMultiObject, method, make_method(method))
+
+_add_indirections()
+
+
+KEYSITER = 0
+ITEMSITER = 1
+VALUESITER = 2
+
+class W_DictMultiIterObject(Wrappable):
+ _immutable_fields_ = ["iteratorimplementation", "itertype"]
+
+ def __init__(w_self, space, iteratorimplementation, itertype):
+ w_self.space = space
+ w_self.iteratorimplementation = iteratorimplementation
+ w_self.itertype = itertype
+
+ 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.
+ """
+ raise OperationError(
+ space.w_TypeError,
+ space.wrap("can't pickle dictionary-keyiterator objects"))
+
+ 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)
+
+ # 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
+
+
+class W_DictViewObject(Wrappable):
+ def __init__(w_self, space, w_dict):
+ w_self.w_dict = w_dict
+
+class W_DictViewKeysObject(W_DictViewObject):
+ pass
+class W_DictViewItemsObject(W_DictViewObject):
+ pass
+class W_DictViewValuesObject(W_DictViewObject):
+ pass
+
+
+
+class DictStrategy(object):
+ def __init__(self, space):
+ self.space = space
+
+ def get_empty_storage(self):
+ raise NotImplementedError
+
+ def keys(self, w_dict):
+ iterator = self.iter(w_dict)
+ result = []
+ while 1:
+ w_key, w_value = iterator.next()
+ if w_key is not None:
+ result.append(w_key)
+ else:
+ return result
+
+ def values(self, w_dict):
+ iterator = self.iter(w_dict)
+ result = []
+ while 1:
+ w_key, w_value = iterator.next()
+ if w_value is not None:
+ result.append(w_value)
+ else:
+ return result
+
+ def items(self, w_dict):
+ iterator = self.iter(w_dict)
+ result = []
+ while 1:
+ w_key, w_value = iterator.next()
+ if w_key is not None:
+ result.append(self.space.newtuple([w_key, w_value]))
+ else:
+ return result
+
+ def clear(self, w_dict):
+ strategy = self.space.fromcache(EmptyDictStrategy)
+ storage = strategy.get_empty_storage()
+ w_dict.strategy = strategy
+ w_dict.dstorage = storage
+
+class IteratorImplementation(object):
+ def __init__(self, space, implementation):
+ self.space = space
+ self.dictimplementation = implementation
+ self.len = implementation.length()
+ self.pos = 0
+
+ def next(self):
+ if self.dictimplementation is None:
+ return None, None
+ 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"))
+ # look for the next entry
+ if self.pos < self.len:
+ result = self.next_entry()
+ self.pos += 1
+ return result
+ # no more entries
+ self.dictimplementation = None
+ return None, None
+
+ def next_entry(self):
+ """ Purely abstract method
+ """
+ raise NotImplementedError
+
+ def length(self):
+ if self.dictimplementation is not None:
+ return self.len - self.pos
+ return 0
+
+class _UnwrappedIteratorMixin(object):
+ _mixin_ = True
+
+ def __init__(self, space, strategy, dictimplementation):
+ IteratorImplementation.__init__(self, space, dictimplementation)
+ self.iterator = strategy.unerase(dictimplementation.dstorage).iteritems()
+
+ def next_entry(self):
+ # note that this 'for' loop only runs once, at most
+ for w_key, w_value in self.iterator:
+ return w_key, w_value
+ else:
+ return None, None
+
+class _WrappedIteratorMixin(object):
+ _mixin_ = True
+
+ def __init__(self, space, strategy, dictimplementation):
+ IteratorImplementation.__init__(self, space, dictimplementation)
+ self.iterator = strategy.unerase(dictimplementation.dstorage).iteritems()
+
+ def next_entry(self):
+ # note that this 'for' loop only runs once, at most
+ for key, w_value in self.iterator:
+ return self.space.wrap(key), w_value
+ else:
+ 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)
+
+ def switch_to_correct_strategy(self, w_dict, w_key):
+ withidentitydict = self.space.config.objspace.std.withidentitydict
+ if type(w_key) is self.space.StringObjectCls:
+ self.switch_to_string_strategy(w_dict)
+ return
+ w_type = self.space.type(w_key)
+ if self.space.is_w(w_type, self.space.w_int):
+ self.switch_to_int_strategy(w_dict)
+ elif withidentitydict and w_type.compares_by_identity():
+ self.switch_to_identity_strategy(w_dict)
+ else:
+ self.switch_to_object_strategy(w_dict)
+
+ def switch_to_string_strategy(self, w_dict):
+ strategy = self.space.fromcache(StringDictStrategy)
+ storage = strategy.get_empty_storage()
+ w_dict.strategy = strategy
+ w_dict.dstorage = storage
+
+ def switch_to_int_strategy(self, w_dict):
+ strategy = self.space.fromcache(IntDictStrategy)
+ storage = strategy.get_empty_storage()
+ w_dict.strategy = strategy
+ w_dict.dstorage = storage
+
+ def switch_to_identity_strategy(self, w_dict):
+ from pypy.objspace.std.identitydict import IdentityDictStrategy
+ strategy = self.space.fromcache(IdentityDictStrategy)
+ storage = strategy.get_empty_storage()
+ w_dict.strategy = strategy
+ w_dict.dstorage = storage
+
+ def switch_to_object_strategy(self, w_dict):
+ strategy = self.space.fromcache(ObjectDictStrategy)
+ storage = strategy.get_empty_storage()
+ w_dict.strategy = strategy
+ w_dict.dstorage = storage
+
+ def getitem(self, w_dict, w_key):
+ #return w_value or None
+ # in case the key is unhashable, try to hash it
+ self.space.hash(w_key)
+ # return None anyway
+ return None
+
+ def getitem_str(self, w_dict, key):
+ #return w_value or None
+ return None
+
+ def setdefault(self, w_dict, w_key, w_default):
+ # here the dict is always empty
+ self.switch_to_correct_strategy(w_dict, w_key)
+ w_dict.setitem(w_key, w_default)
+ return w_default
+
+ def setitem(self, w_dict, w_key, w_value):
+ self.switch_to_correct_strategy(w_dict, w_key)
+ w_dict.setitem(w_key, w_value)
+
+ def setitem_str(self, w_dict, key, w_value):
+ self.switch_to_string_strategy(w_dict)
+ w_dict.setitem_str(key, w_value)
+
+ def delitem(self, w_dict, w_key):
+ # in case the key is unhashable, try to hash it
+ self.space.hash(w_key)
+ raise KeyError
+
+ def length(self, w_dict):
+ return 0
+
+ def iter(self, w_dict):
+ return EmptyIteratorImplementation(self.space, w_dict)
+
+ def clear(self, w_dict):
+ return
+
+ def popitem(self, w_dict):
+ raise KeyError
+
+class EmptyIteratorImplementation(IteratorImplementation):
+ def next(self):
+ return (None, None)
+
+
+class AbstractTypedStrategy(object):
+ _mixin_ = True
+
+ @staticmethod
+ def erase(storage):
+ raise NotImplementedError("abstract base class")
+
+ @staticmethod
+ def unerase(obj):
+ raise NotImplementedError("abstract base class")
+
+ def wrap(self, unwrapped):
+ raise NotImplementedError
+
+ def unwrap(self, wrapped):
+ raise NotImplementedError
+
+ def is_correct_type(self, w_obj):
+ raise NotImplementedError("abstract base class")
+
+ def get_empty_storage(self):
+ raise NotImplementedError("abstract base class")
+
+ def _never_equal_to(self, w_lookup_type):
+ raise NotImplementedError("abstract base class")
+
+ def setitem(self, w_dict, w_key, w_value):
+ space = self.space
+ if self.is_correct_type(w_key):
+ self.unerase(w_dict.dstorage)[self.unwrap(w_key)] = w_value
+ return
+ else:
+ self.switch_to_object_strategy(w_dict)
+ w_dict.setitem(w_key, w_value)
+
+ def setitem_str(self, w_dict, key, w_value):
+ self.switch_to_object_strategy(w_dict)
+ w_dict.setitem(self.space.wrap(key), w_value)
+
+ def setdefault(self, w_dict, w_key, w_default):
+ space = self.space
+ if self.is_correct_type(w_key):
+ 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)
+
+ def delitem(self, w_dict, w_key):
+ space = self.space
+ w_key_type = space.type(w_key)
+ if self.is_correct_type(w_key):
+ del self.unerase(w_dict.dstorage)[self.unwrap(w_key)]
+ return
+ else:
+ self.switch_to_object_strategy(w_dict)
+ return w_dict.delitem(w_key)
+
+ def length(self, w_dict):
+ return len(self.unerase(w_dict.dstorage))
+
+ def getitem_str(self, w_dict, key):
+ return self.getitem(w_dict, self.space.wrap(key))
+
+ def getitem(self, w_dict, w_key):
+ space = self.space
+ if self.is_correct_type(w_key):
+ return self.unerase(w_dict.dstorage).get(self.unwrap(w_key), None)
+ elif self._never_equal_to(space.type(w_key)):
+ return None
+ else:
+ self.switch_to_object_strategy(w_dict)
+ return w_dict.getitem(w_key)
+
+ def keys(self, w_dict):
+ return [self.wrap(key) for key in self.unerase(w_dict.dstorage).iterkeys()]
+
+ def values(self, w_dict):
+ return self.unerase(w_dict.dstorage).values()
+
+ def items(self, w_dict):
+ 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()]
+
+ def popitem(self, w_dict):
+ key, value = self.unerase(w_dict.dstorage).popitem()
+ return (self.wrap(key), value)
+
+ def clear(self, w_dict):
+ self.unerase(w_dict.dstorage).clear()
+
+ def switch_to_object_strategy(self, w_dict):
+ d = self.unerase(w_dict.dstorage)
+ strategy = self.space.fromcache(ObjectDictStrategy)
+ d_new = strategy.unerase(strategy.get_empty_storage())
+ for key, value in d.iteritems():
+ d_new[self.wrap(key)] = value
+ w_dict.strategy = strategy
+ w_dict.dstorage = strategy.erase(d_new)
+
+class ObjectDictStrategy(AbstractTypedStrategy, DictStrategy):
+
+ erase, unerase = rerased.new_erasing_pair("object")
+ erase = staticmethod(erase)
+ unerase = staticmethod(unerase)
+
+ def wrap(self, unwrapped):
+ return unwrapped
+
+ def unwrap(self, wrapped):
+ return wrapped
+
+ def is_correct_type(self, w_obj):
+ 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)
+
+ def _never_equal_to(self, w_lookup_type):
+ return False
+
+ def iter(self, w_dict):
+ return ObjectIteratorImplementation(self.space, self, w_dict)
+
+ def keys(self, w_dict):
+ return self.unerase(w_dict.dstorage).keys()
+
+class ObjectIteratorImplementation(_UnwrappedIteratorMixin, IteratorImplementation):
+ pass
+
+
+class StringDictStrategy(AbstractTypedStrategy, DictStrategy):
+
+ erase, unerase = rerased.new_erasing_pair("string")
+ erase = staticmethod(erase)
+ unerase = staticmethod(unerase)
+
+ def wrap(self, unwrapped):
+ return self.space.wrap(unwrapped)
+
+ def unwrap(self, wrapped):
+ return self.space.str_w(wrapped)
+
+ def is_correct_type(self, w_obj):
+ space = self.space
+ return space.is_w(space.type(w_obj), space.w_str)
+
+ def get_empty_storage(self):
+ res = {}
+ mark_dict_non_null(res)
+ return self.erase(res)
+
+ def _never_equal_to(self, w_lookup_type):
+ return _never_equal_to_string(self.space, w_lookup_type)
+
+ def setitem_str(self, w_dict, key, w_value):
+ assert key is not None
+ self.unerase(w_dict.dstorage)[key] = w_value
+
+ def getitem(self, w_dict, w_key):
+ space = self.space
+ # -- This is called extremely often. Hack for performance --
+ if type(w_key) is space.StringObjectCls:
+ return self.getitem_str(w_dict, w_key.unwrap(space))
+ # -- End of performance hack --
+ return AbstractTypedStrategy.getitem(self, w_dict, w_key)
+
+ def getitem_str(self, w_dict, key):
+ assert key is not None
+ return self.unerase(w_dict.dstorage).get(key, None)
+
+ def iter(self, w_dict):
+ return StrIteratorImplementation(self.space, self, w_dict)
+
+class StrIteratorImplementation(_WrappedIteratorMixin, IteratorImplementation):
+ pass
+
+class IntDictStrategy(AbstractTypedStrategy, DictStrategy):
+ erase, unerase = rerased.new_erasing_pair("int")
+ erase = staticmethod(erase)
+ unerase = staticmethod(unerase)
+
+ def wrap(self, unwrapped):
+ return self.space.wrap(unwrapped)
+
+ def unwrap(self, wrapped):
+ return self.space.int_w(wrapped)
+
+ def get_empty_storage(self):
+ return self.erase({})
+
+ def is_correct_type(self, w_obj):
+ space = self.space
+ return space.is_w(space.type(w_obj), space.w_int)
+
+ def _never_equal_to(self, w_lookup_type):
+ space = self.space
+ # XXX there are many more types
+ return (space.is_w(w_lookup_type, space.w_NoneType) or
+ space.is_w(w_lookup_type, space.w_str) or
+ space.is_w(w_lookup_type, space.w_unicode)
+ )
+
+ def iter(self, w_dict):
+ return IntIteratorImplementation(self.space, self, w_dict)
+
+class IntIteratorImplementation(_WrappedIteratorMixin, IteratorImplementation):
+ pass
+
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):
@@ -107,14 +737,236 @@
# ____________________________________________________________
-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
+### MULTIMETHOD STUFF
+
+init_signature = Signature(['seq_or_map'], None, 'kwargs')
+init_defaults = [None]
+
+def init__DictMulti(space, w_dict, __args__):
+ init_or_update(space, w_dict, __args__, 'dict')
+
+def update1(space, w_dict, w_data):
+ if space.findattr(w_data, space.wrap("keys")) is None:
+ # no 'keys' method, so we assume it is a sequence of pairs
+ for w_pair in space.listview(w_data):
+ pair = space.fixedview(w_pair)
+ if len(pair) != 2:
+ raise OperationError(space.w_ValueError,
+ space.wrap("sequence of pairs expected"))
+ w_key, w_value = pair
+ w_dict.setitem(w_key, w_value)
+ else:
+ if isinstance(w_data, W_DictMultiObject): # optimization case only
+ update1_dict_dict(space, w_dict, w_data)
+ else:
+ # general case -- "for k in o.keys(): dict.__setitem__(d, k, o[k])"
+ w_keys = space.call_method(w_data, "keys")
+ for w_key in space.listview(w_keys):
+ w_value = space.getitem(w_data, w_key)
+ w_dict.setitem(w_key, w_value)
+
+def update1_dict_dict(space, w_dict, w_data):
+ iterator = w_data.iter()
+ while 1:
+ w_key, w_value = iterator.next()
+ if w_key is None:
+ break
+ w_dict.setitem(w_key, w_value)
+
+def init_or_update(space, w_dict, __args__, funcname):
+ w_src, w_kwds = __args__.parse_obj(
+ None, funcname,
+ init_signature, # signature
+ init_defaults) # default argument
+ if w_src is not None:
+ update1(space, w_dict, w_src)
+ if space.is_true(w_kwds):
+ update1(space, w_dict, w_kwds)
+
+
+def setitem__DictMulti_ANY_ANY(space, w_dict, w_newkey, w_newvalue):
+ w_dict.setitem(w_newkey, w_newvalue)
+
+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 delitem__DictMulti_ANY(space, w_dict, w_key):
+ try:
+ w_dict.delitem(w_key)
+ except KeyError:
+ space.raise_key_error(w_key)
+
+
+def contains__DictMulti_ANY(space, w_dict, w_key):
+ return space.newbool(w_dict.getitem(w_key) is not None)
+
+def len__DictMulti(space, w_dict):
+ return space.wrap(w_dict.length())
+
+def iter__DictMulti(space, w_dict):
+ return W_DictMultiIterObject(space, w_dict.iter(), KEYSITER)
+
+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.iter()
+ while 1:
+ w_key, w_val = iteratorimplementation.next()
+ 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.iter()
+ while 1:
+ w_key, w_val = iteratorimplementation.next()
+ 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)):
+ 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
+
+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 iter__DictMultiIterObject(space, w_dictiter):
+ return w_dictiter
+
+def next__DictMultiIterObject(space, w_dictiter):
+ iteratorimplementation = w_dictiter.iteratorimplementation
+ w_key, w_value = iteratorimplementation.next()
+ if w_key is not None:
+ itertype = w_dictiter.itertype
+ if itertype == KEYSITER:
+ return w_key
+ elif itertype == VALUESITER:
+ return w_value
+ elif itertype == ITEMSITER:
+ return space.newtuple([w_key, w_value])
+ else:
+ assert 0, "should be unreachable"
+ raise OperationError(space.w_StopIteration, space.w_None)
+
+def len__DictViewKeys(space, w_dictview):
+ return space.len(w_dictview.w_dict)
+len__DictViewItems = len__DictViewValues = len__DictViewKeys
+
+def iter__DictViewItems(space, w_dictview):
+ return w_dictview.w_dict.descr_iteritems(space)
+
+def iter__DictViewKeys(space, w_dictview):
+ return w_dictview.w_dict.descr_iterkeys(space)
+
+def iter__DictViewValues(space, w_dictview):
+ return w_dictview.w_dict.descr_itervalues(space)
+
+def all_contained_in(space, w_dictview, w_otherview):
+ w_iter = space.iter(w_dictview)
+ assert isinstance(w_iter, W_DictMultiIterObject)
+
+ 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 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_DictViewItems = eq__DictViewKeys_DictViewKeys
+eq__DictViewItems_DictViewItems = eq__DictViewKeys_DictViewKeys
+eq__DictViewItems_settypedef = 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
# ____________________________________________________________
-dict_typedef = StdTypeDef("dict",
+W_DictMultiObject.typedef = StdTypeDef("dict",
__doc__ = '''dict() -> new empty dictionary.
dict(mapping) -> new dictionary initialized from a mapping object\'s
(key, value) pairs.
@@ -124,85 +976,60 @@
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__),
+ __new__ = gateway.interp2app(W_DictMultiObject.descr__new__.im_func),
+ fromkeys = gateway.interp2app(descr_fromkeys, as_classmethod=True),
+
__hash__ = None,
__repr__ = gateway.interp2app(descr_repr),
- fromkeys = gateway.interp2app(descr_fromkeys, as_classmethod=True),
- )
-dict_typedef.registermethods(globals())
+ __reversed__ = gateway.interp2app(W_DictMultiObject.descr__reversed__),
+
+ 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),
+
+ viewitems = gateway.interp2app(W_DictMultiObject.descr_viewitems),
+ viewkeys = gateway.interp2app(W_DictMultiObject.descr_viewkeys),
+ viewvalues = gateway.interp2app(W_DictMultiObject.descr_viewvalues),
+
+ update = gateway.interp2app(W_DictMultiObject.descr_update),
+ setdefault = gateway.interp2app(W_DictMultiObject.descr_setdefault),
+ popitem = gateway.interp2app(W_DictMultiObject.descr_popitem),
+ pop = gateway.interp2app(W_DictMultiObject.descr_pop),
+ clear = gateway.interp2app(W_DictMultiObject.descr_clear),
+
+ get = gateway.interp2app(W_DictMultiObject.descr_get),
+ has_key = gateway.interp2app(W_DictMultiObject.descr_has_key),
+ copy = gateway.interp2app(W_DictMultiObject.descr_copy),
+)
+
+
# ____________________________________________________________
-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",
- __reduce__ = gateway.interp2app(descr_dictiter__reduce__),
- )
+W_DictMultiIterObject.typedef = StdTypeDef("dictionaryiterator",
+ __reduce__ = gateway.interp2app(W_DictMultiIterObject.descr__reduce__),
+)
# ____________________________________________________________
# Dict views
-dict_keys_typedef = StdTypeDef(
+W_DictViewKeysObject.typedef = StdTypeDef(
"dict_keys",
- )
+)
-dict_items_typedef = StdTypeDef(
+W_DictViewItemsObject.typedef = StdTypeDef(
"dict_items",
- )
+)
-dict_values_typedef = StdTypeDef(
+W_DictViewValuesObject.typedef = StdTypeDef(
"dict_values",
- )
+)
+
+
+registerimplementation(W_DictMultiObject)
+registerimplementation(W_DictMultiIterObject)
+register_all(vars(), sys.modules[__name__])
\ No newline at end of file
diff --git a/pypy/objspace/std/frame.py b/pypy/objspace/std/frame.py
--- a/pypy/objspace/std/frame.py
+++ b/pypy/objspace/std/frame.py
@@ -9,7 +9,6 @@
from pypy.module.__builtin__ import Module
from pypy.objspace.std import intobject, smallintobject
from pypy.objspace.std.multimethod import FailedToImplement
-from pypy.objspace.std.dictmultiobject import W_DictMultiObject
from pypy.objspace.std.listobject import W_ListObject
diff --git a/pypy/objspace/std/identitydict.py b/pypy/objspace/std/identitydict.py
--- a/pypy/objspace/std/identitydict.py
+++ b/pypy/objspace/std/identitydict.py
@@ -3,10 +3,8 @@
from pypy.rlib import rerased
from pypy.rlib.debug import mark_dict_non_null
-from pypy.objspace.std.dictmultiobject import (AbstractTypedStrategy,
- DictStrategy,
- IteratorImplementation,
- _UnwrappedIteratorMixin)
+from pypy.objspace.std.dicttype import (AbstractTypedStrategy, DictStrategy,
+ IteratorImplementation, _UnwrappedIteratorMixin)
# this strategy is selected by EmptyDictStrategy.switch_to_correct_strategy
diff --git a/pypy/objspace/std/mapdict.py b/pypy/objspace/std/mapdict.py
--- a/pypy/objspace/std/mapdict.py
+++ b/pypy/objspace/std/mapdict.py
@@ -1,14 +1,12 @@
import weakref
-from pypy.rlib import jit, objectmodel, debug
-from pypy.rlib.rarithmetic import intmask, r_uint
-from pypy.rlib import rerased
from pypy.interpreter.baseobjspace import W_Root
-from pypy.objspace.std.dictmultiobject import W_DictMultiObject, DictStrategy, ObjectDictStrategy
-from pypy.objspace.std.dictmultiobject import IteratorImplementation
-from pypy.objspace.std.dictmultiobject import _never_equal_to_string
+from pypy.objspace.std.dicttype import (W_DictMultiObject, DictStrategy,
+ ObjectDictStrategy, IteratorImplementation, _never_equal_to_string)
from pypy.objspace.std.objectobject import W_ObjectObject
from pypy.objspace.std.typeobject import TypeCell
+from pypy.rlib import jit, objectmodel, debug, rerased
+from pypy.rlib.rarithmetic import intmask, r_uint
# ____________________________________________________________
# attribute shapes
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
@@ -23,7 +23,7 @@
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.dicttype import W_DictMultiObject
from pypy.objspace.std.stringobject import W_StringObject
from pypy.objspace.std.ropeobject import W_RopeObject
from pypy.objspace.std.typeobject import W_TypeObject
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
@@ -37,7 +37,7 @@
"""NOT_RPYTHON: inititialization only"""
self.config = config
# All the Python types that we want to provide in this StdObjSpace
- from pypy.objspace.std.bytearraytype import W_BytearrayObject
+ from pypy.objspace.std import bytearraytype, dicttype
class result:
from pypy.objspace.std.objecttype import object_typedef
@@ -49,10 +49,10 @@
from pypy.objspace.std.frozensettype import frozenset_typedef
from pypy.objspace.std.tupletype import tuple_typedef
from pypy.objspace.std.listtype import list_typedef
- from pypy.objspace.std.dicttype import dict_typedef
+ dict_typedef = dicttype.W_DictMultiObject.typedef
from pypy.objspace.std.basestringtype import basestring_typedef
from pypy.objspace.std.stringtype import str_typedef
- bytearray_typedef = W_BytearrayObject.typedef
+ bytearray_typedef = bytearraytype.W_BytearrayObject.typedef
from pypy.objspace.std.typetype import type_typedef
from pypy.objspace.std.slicetype import slice_typedef
from pypy.objspace.std.longtype import long_typedef
@@ -76,7 +76,6 @@
from pypy.objspace.std import tupleobject
from pypy.objspace.std import smalltupleobject
from pypy.objspace.std import listobject
- from pypy.objspace.std import dictmultiobject
from pypy.objspace.std import stringobject
from pypy.objspace.std import ropeobject
from pypy.objspace.std import ropeunicodeobject
@@ -107,10 +106,10 @@
floatobject.W_FloatObject: [],
tupleobject.W_TupleObject: [],
listobject.W_ListObject: [],
- dictmultiobject.W_DictMultiObject: [],
- dictmultiobject.W_DictMultiIterObject: [],
+ dicttype.W_DictMultiObject: [],
+ dicttype.W_DictMultiIterObject: [],
stringobject.W_StringObject: [],
- W_BytearrayObject: [],
+ bytearraytype.W_BytearrayObject: [],
typeobject.W_TypeObject: [],
sliceobject.W_SliceObject: [],
longobject.W_LongObject: [],
@@ -125,16 +124,16 @@
iterobject.W_FastTupleIterObject: [],
iterobject.W_ReverseSeqIterObject: [],
unicodeobject.W_UnicodeObject: [],
- dictmultiobject.W_DictViewKeysObject: [],
- dictmultiobject.W_DictViewItemsObject: [],
- dictmultiobject.W_DictViewValuesObject: [],
+ dicttype.W_DictViewKeysObject: [],
+ dicttype.W_DictViewItemsObject: [],
+ dicttype.W_DictViewValuesObject: [],
pycode.PyCode: [],
special.Ellipsis: [],
}
self.imported_but_not_registered = {
- dictmultiobject.W_DictMultiObject: True, # XXXXXX
- dictmultiobject.W_DictMultiIterObject: True,
+ dicttype.W_DictMultiObject: True, # XXXXXX
+ dicttype.W_DictMultiIterObject: True,
listobject.W_ListObject: True,
stringobject.W_StringObject: True,
tupleobject.W_TupleObject: True,
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
@@ -18,7 +18,7 @@
# Object imports
from pypy.objspace.std.boolobject import W_BoolObject
from pypy.objspace.std.complexobject import W_ComplexObject
-from pypy.objspace.std.dictmultiobject import W_DictMultiObject
+from pypy.objspace.std.dicttype import W_DictMultiObject
from pypy.objspace.std.floatobject import W_FloatObject
from pypy.objspace.std.intobject import W_IntObject
from pypy.objspace.std.listobject import W_ListObject
diff --git a/pypy/objspace/std/proxyobject.py b/pypy/objspace/std/proxyobject.py
--- a/pypy/objspace/std/proxyobject.py
+++ b/pypy/objspace/std/proxyobject.py
@@ -19,20 +19,20 @@
def __init__(self, space, w_type, w_controller):
self.w_type = w_type
self.w_controller = w_controller
-
+
def descr_call_mismatch(self, space, name, reqcls, args):
args_w = args.arguments_w[:]
args_w[0] = space.wrap(name)
args = args.replace_arguments(args_w)
return space.call_args(self.w_controller, args)
-
+
def getclass(self, space):
return self.w_type
-
+
def setclass(self, space, w_subtype):
raise OperationError(space.w_TypeError,
space.wrap("You cannot override __class__ for transparent proxies"))
-
+
def getdictvalue(self, space, attr):
try:
return space.call_function(self.w_controller, space.wrap('__getattribute__'),
@@ -41,7 +41,7 @@
if not e.match(space, space.w_AttributeError):
raise
return None
-
+
def setdictvalue(self, space, attr, w_value):
try:
space.call_function(self.w_controller, space.wrap('__setattr__'),
@@ -51,7 +51,7 @@
if not e.match(space, space.w_AttributeError):
raise
return False
-
+
def deldictvalue(self, space, attr):
try:
space.call_function(self.w_controller, space.wrap('__delattr__'),
@@ -61,14 +61,14 @@
if not e.match(space, space.w_AttributeError):
raise
return False
-
+
def getdict(self, space):
return self.getdictvalue(space, '__dict__')
-
+
def setdict(self, space, w_dict):
if not self.setdictvalue(space, '__dict__', w_dict):
baseobjspace.W_Root.setdict(self, space, w_dict)
-
+
W_Transparent.__name__ = name
return W_Transparent
@@ -101,8 +101,8 @@
from pypy.objspace.std.listtype import list_typedef as typedef
class W_TransparentDict(W_TransparentObject):
- from pypy.objspace.std.dictmultiobject import W_DictMultiObject as original
- from pypy.objspace.std.dicttype import dict_typedef as typedef
+ from pypy.objspace.std.dicttype import W_DictMultiObject as original
+ typedef = original.typedef
registerimplementation(W_TransparentList)
registerimplementation(W_TransparentDict)
diff --git a/pypy/objspace/std/test/test_celldict.py b/pypy/objspace/std/test/test_celldict.py
--- a/pypy/objspace/std/test/test_celldict.py
+++ b/pypy/objspace/std/test/test_celldict.py
@@ -1,6 +1,6 @@
import py
from pypy.conftest import gettestobjspace, option
-from pypy.objspace.std.dictmultiobject import W_DictMultiObject
+from pypy.objspace.std.dicttype import W_DictMultiObject
from pypy.objspace.std.celldict import ModuleCell, ModuleDictStrategy
from pypy.objspace.std.test.test_dictmultiobject import FakeSpace
from pypy.interpreter import gateway
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
@@ -1,9 +1,9 @@
import py
import sys
from pypy.interpreter.error import OperationError
-from pypy.objspace.std.dictmultiobject import \
- W_DictMultiObject, setitem__DictMulti_ANY_ANY, getitem__DictMulti_ANY, \
- StringDictStrategy, ObjectDictStrategy
+from pypy.objspace.std.dicttype import (W_DictMultiObject,
+ setitem__DictMulti_ANY_ANY, getitem__DictMulti_ANY, StringDictStrategy,
+ ObjectDictStrategy)
from pypy.objspace.std.celldict import ModuleDictStrategy
from pypy.conftest import gettestobjspace
diff --git a/pypy/objspace/std/typeobject.py b/pypy/objspace/std/typeobject.py
--- a/pypy/objspace/std/typeobject.py
+++ b/pypy/objspace/std/typeobject.py
@@ -77,7 +77,7 @@
for i in range(len(self.lookup_where)):
self.lookup_where[i] = None_None
-# possible values of compares_by_identity_status
+# possible values of compares_by_identity_status
UNKNOWN = 0
COMPARES_BY_IDENTITY = 1
OVERRIDES_EQ_CMP_OR_HASH = 2
@@ -355,7 +355,7 @@
if w_value is not None:
return w_value
return None
-
+
@unroll_safe
def _lookup(w_self, key):
space = w_self.space
@@ -463,7 +463,7 @@
def getdict(w_self, space): # returning a dict-proxy!
from pypy.objspace.std.dictproxyobject import DictProxyStrategy
- from pypy.objspace.std.dictmultiobject import W_DictMultiObject
+ from pypy.objspace.std.dicttype import W_DictMultiObject
if w_self.lazyloaders:
w_self._freeze_() # force un-lazification
strategy = space.fromcache(DictProxyStrategy)
More information about the pypy-commit
mailing list