[pypy-commit] pypy dict-strategies: split string strategy into an abstract mixin and a concrete instantiation
cfbolz
noreply at buildbot.pypy.org
Wed May 25 18:05:21 CEST 2011
Author: Carl Friedrich Bolz <cfbolz at gmx.de>
Branch: dict-strategies
Changeset: r44472:b9b197fbbede
Date: 2011-05-25 18:10 +0200
http://bitbucket.org/pypy/pypy/changeset/b9b197fbbede/
Log: split string strategy into an abstract mixin and a concrete
instantiation
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
@@ -328,33 +328,46 @@
# concrete subclasses of the above
-class StringDictStrategy(DictStrategy):
+class AbstractUnwrappedStrategy(object):
+ _mixin_ = True
- erase, unerase = rerased.new_erasing_pair("string")
- erase = staticmethod(erase)
- unerase = staticmethod(unerase)
+ @staticmethod
+ def erase(storage):
+ raise NotImplementedError("abstract base class")
- def __init__(self, space):
- self.space = space
+ @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):
- return self.erase({})
+ raise NotImplementedError("abstract base class")
def setitem(self, w_dict, w_key, w_value):
space = self.space
- if space.is_w(space.type(w_key), space.w_str):
- self.setitem_str(w_dict, self.space.str_w(w_key), w_value)
+ 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.unerase(w_dict.dstorage)[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 space.is_w(space.type(w_key), space.w_str):
- return self.unerase(w_dict.dstorage).setdefault(space.str_w(w_key), w_default)
+ if self.is_correct_type(w_key):
+ return self.unerase(w_dict.dstorage).setdefault(space.unwrap(w_key), w_default)
else:
self.switch_to_object_strategy(w_dict)
return w_dict.setdefault(w_key, w_default)
@@ -362,8 +375,8 @@
def delitem(self, w_dict, w_key):
space = self.space
w_key_type = space.type(w_key)
- if space.is_w(w_key_type, space.w_str):
- del self.unerase(w_dict.dstorage)[space.str_w(w_key)]
+ if self.is_correct_type(w_key):
+ del self.unerase(w_dict.dstorage)[self.unwrap(w_key)]
return
elif _is_sane_hash(space, w_key_type):
raise KeyError
@@ -375,29 +388,21 @@
return len(self.unerase(w_dict.dstorage))
def getitem_str(self, w_dict, key):
- return self.unerase(w_dict.dstorage).get(key, None)
+ return None
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 --
- w_lookup_type = space.type(w_key)
- if space.is_w(w_lookup_type, space.w_str):
- return self.getitem_str(w_dict, space.str_w(w_key))
- elif _is_sane_hash(space, w_lookup_type):
+
+ if self.is_correct_type(w_key):
+ return self.unerase(w_dict.dstorage).get(self.unwrap(w_key), None)
+ elif _is_sane_hash(space, space.type(w_key)):
return None
else:
self.switch_to_object_strategy(w_dict)
return w_dict.getitem(w_key)
- def iter(self, w_dict):
- return StrIteratorImplementation(self.space, w_dict)
-
def keys(self, w_dict):
- space = self.space
- return [space.wrap(key) for key in self.unerase(w_dict.dstorage).iterkeys()]
+ 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()
@@ -405,12 +410,12 @@
def items(self, w_dict):
space = self.space
dict_w = self.unerase(w_dict.dstorage)
- return [space.newtuple([space.wrap(key), w_value])
+ 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.space.wrap(key), value)
+ return (self.wrap(key), value)
def clear(self, w_dict):
self.unerase(w_dict.dstorage).clear()
@@ -420,10 +425,57 @@
strategy = self.space.fromcache(ObjectDictStrategy)
d_new = strategy.unerase(strategy.get_empty_storage())
for key, value in d.iteritems():
- d_new[self.space.wrap(key)] = value
+ d_new[self.wrap(key)] = value
w_dict.strategy = strategy
w_dict.dstorage = strategy.erase(d_new)
+class StringDictStrategy(AbstractUnwrappedStrategy, DictStrategy):
+
+ erase, unerase = rerased.new_erasing_pair("string")
+ erase = staticmethod(erase)
+ unerase = staticmethod(unerase)
+
+ def __init__(self, space):
+ self.space = space
+
+ 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):
+ return self.erase({})
+
+ def setitem_str(self, w_dict, key, w_value):
+ 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 --
+
+ if self.is_correct_type(w_key):
+ return self.unerase(w_dict.dstorage).get(self.unwrap(w_key), None)
+ elif _is_sane_hash(space, space.type(w_key)):
+ return None
+ else:
+ self.switch_to_object_strategy(w_dict)
+ return w_dict.getitem(w_key)
+
+ def getitem_str(self, w_dict, key):
+ return self.unerase(w_dict.dstorage).get(key, None)
+
+ def iter(self, w_dict):
+ return StrIteratorImplementation(self.space, w_dict)
+
+
class StrIteratorImplementation(IteratorImplementation):
def __init__(self, space, dictimplementation):
IteratorImplementation.__init__(self, space, dictimplementation)
More information about the pypy-commit
mailing list