[pypy-commit] pypy remove-tuple-smm: hg merge remove-list-smm-2
Manuel Jacob
noreply at buildbot.pypy.org
Tue May 21 15:10:17 CEST 2013
Author: Manuel Jacob
Branch: remove-tuple-smm
Changeset: r64385:2921742865a9
Date: 2013-05-21 14:54 +0200
http://bitbucket.org/pypy/pypy/changeset/2921742865a9/
Log: hg merge remove-list-smm-2
diff --git a/pypy/objspace/std/bytearrayobject.py b/pypy/objspace/std/bytearrayobject.py
--- a/pypy/objspace/std/bytearrayobject.py
+++ b/pypy/objspace/std/bytearrayobject.py
@@ -8,7 +8,6 @@
getbytevalue, makebytearraydata_w, new_bytearray)
from pypy.objspace.std.intobject import W_IntObject
from pypy.objspace.std.inttype import wrapint
-from pypy.objspace.std.listobject import get_list_index, get_positive_index
from pypy.objspace.std.model import W_Object, registerimplementation
from pypy.objspace.std.multimethod import FailedToImplement
from pypy.objspace.std.noneobject import W_NoneObject
@@ -17,6 +16,7 @@
from pypy.objspace.std.stringobject import W_StringObject
from pypy.objspace.std.tupleobject import W_TupleObject
from pypy.objspace.std.unicodeobject import W_UnicodeObject
+from pypy.objspace.std.util import get_positive_index
from rpython.rlib.rstring import StringBuilder
@@ -587,7 +587,7 @@
_setitem_slice_helper(space, w_bytearray.data, start, step, slicelength, sequence2, empty_elem='\x00')
def delitem__Bytearray_ANY(space, w_bytearray, w_idx):
- idx = get_list_index(space, w_idx)
+ idx = space.getindex_w(w_idx, space.w_IndexError, "bytearray index")
try:
del w_bytearray.data[idx]
except IndexError:
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
@@ -5,6 +5,7 @@
from pypy.interpreter.mixedmodule import MixedModule
from pypy.interpreter.signature import Signature
from pypy.objspace.std.stdtypedef import StdTypeDef
+from pypy.objspace.std.util import negate
from rpython.rlib import jit, rerased
from rpython.rlib.debug import mark_dict_non_null
@@ -41,19 +42,6 @@
w_dct.length() <= UNROLL_CUTOFF)
-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,
diff --git a/pypy/objspace/std/listobject.py b/pypy/objspace/std/listobject.py
--- a/pypy/objspace/std/listobject.py
+++ b/pypy/objspace/std/listobject.py
@@ -1,27 +1,35 @@
-from pypy.objspace.std.model import registerimplementation, W_Object
-from pypy.objspace.std.register_all import register_all
-from pypy.objspace.std.multimethod import FailedToImplement
+import operator
+from sys import maxint
+
+from pypy.interpreter.baseobjspace import W_Root
from pypy.interpreter.error import OperationError, operationerrfmt
+from pypy.interpreter.gateway import (WrappedDefault, unwrap_spec, applevel,
+ interp2app)
from pypy.interpreter.generator import GeneratorIterator
+from pypy.interpreter.signature import Signature
+from pypy.objspace.std import slicetype
+from pypy.objspace.std.floatobject import W_FloatObject
+from pypy.objspace.std.intobject import W_IntObject
from pypy.objspace.std.inttype import wrapint
+from pypy.objspace.std.iterobject import (W_FastListIterObject,
+ W_ReverseSeqIterObject)
from pypy.objspace.std.sliceobject import W_SliceObject, normalize_simple_slice
-from pypy.objspace.std import slicetype
-from pypy.interpreter.gateway import WrappedDefault, unwrap_spec, applevel,\
- interp2app
-from pypy.interpreter import baseobjspace
-from pypy.interpreter.signature import Signature
+from pypy.objspace.std.stdtypedef import StdTypeDef
+from pypy.objspace.std.stringobject import W_StringObject
+from pypy.objspace.std.tupleobject import W_AbstractTupleObject
+from pypy.objspace.std.unicodeobject import W_UnicodeObject
+from pypy.objspace.std.util import negate, get_positive_index
+from rpython.rlib import rerased, jit, debug
+from rpython.rlib.listsort import make_timsort_class
from rpython.rlib.objectmodel import (instantiate, newlist_hint, specialize,
- resizelist_hint)
-from rpython.rlib.listsort import make_timsort_class
-from rpython.rlib import rerased, jit, debug
+ resizelist_hint)
from rpython.tool.sourcetools import func_with_new_name
-from pypy.objspace.std.stdtypedef import StdTypeDef, SMM
-from sys import maxint
+
+__all__ = ['W_ListObject', 'make_range_list', 'make_empty_list_with_size']
+
UNROLL_CUTOFF = 5
-class W_AbstractListObject(W_Object):
- __slots__ = ()
def make_range_list(space, start, step, length):
if length <= 0:
@@ -32,16 +40,19 @@
storage = strategy.erase((start, step, length))
return W_ListObject.from_storage_and_strategy(space, storage, strategy)
+
def make_empty_list(space):
strategy = space.fromcache(EmptyListStrategy)
storage = strategy.erase(None)
return W_ListObject.from_storage_and_strategy(space, storage, strategy)
+
def make_empty_list_with_size(space, hint):
strategy = SizeListStrategy(space, hint)
storage = strategy.erase(None)
return W_ListObject.from_storage_and_strategy(space, storage, strategy)
+
@jit.look_inside_iff(lambda space, list_w, sizehint:
jit.loop_unrolling_heuristic(list_w, len(list_w), UNROLL_CUTOFF))
def get_strategy_from_list_objects(space, list_w, sizehint):
@@ -52,38 +63,40 @@
# check for ints
for w_obj in list_w:
- if not is_W_IntObject(w_obj):
+ if not type(w_obj) is W_IntObject:
break
else:
return space.fromcache(IntegerListStrategy)
# check for strings
for w_obj in list_w:
- if not is_W_StringObject(w_obj):
+ if not type(w_obj) is W_StringObject:
break
else:
return space.fromcache(StringListStrategy)
# check for unicode
for w_obj in list_w:
- if not is_W_UnicodeObject(w_obj):
+ if not type(w_obj) is W_UnicodeObject:
break
else:
return space.fromcache(UnicodeListStrategy)
# check for floats
for w_obj in list_w:
- if not is_W_FloatObject(w_obj):
+ if not type(w_obj) is W_FloatObject:
break
else:
return space.fromcache(FloatListStrategy)
return space.fromcache(ObjectListStrategy)
+
def _get_printable_location(w_type):
return ('list__do_extend_from_iterable [w_type=%s]' %
w_type.getname(w_type.space))
+
_do_extend_jitdriver = jit.JitDriver(
name='list__do_extend_from_iterable',
greens=['w_type'],
@@ -108,23 +121,15 @@
i += 1
return i
-def is_W_IntObject(w_object):
- from pypy.objspace.std.intobject import W_IntObject
- return type(w_object) is W_IntObject
-def is_W_StringObject(w_object):
- from pypy.objspace.std.stringobject import W_StringObject
- return type(w_object) is W_StringObject
+def list_unroll_condition(w_list1, space, w_list2):
+ return (jit.loop_unrolling_heuristic(w_list1, w_list1.length(),
+ UNROLL_CUTOFF) or
+ jit.loop_unrolling_heuristic(w_list2, w_list2.length(),
+ UNROLL_CUTOFF))
-def is_W_UnicodeObject(w_object):
- from pypy.objspace.std.unicodeobject import W_UnicodeObject
- return type(w_object) is W_UnicodeObject
-def is_W_FloatObject(w_object):
- from pypy.objspace.std.floatobject import W_FloatObject
- return type(w_object) is W_FloatObject
-
-class W_ListObject(W_AbstractListObject):
+class W_ListObject(W_Root):
def __init__(w_self, space, wrappeditems, sizehint=-1):
assert isinstance(wrappeditems, list)
w_self.space = space
@@ -154,7 +159,8 @@
def __repr__(w_self):
""" representation for debugging purposes """
- return "%s(%s, %s)" % (w_self.__class__.__name__, w_self.strategy, w_self.lstorage._x)
+ return "%s(%s, %s)" % (w_self.__class__.__name__, w_self.strategy,
+ w_self.lstorage._x)
def unwrap(w_list, space):
# for tests only!
@@ -173,7 +179,8 @@
list_w = self.getitems()
strategy = self.space.fromcache(ObjectListStrategy)
storage = strategy.erase(list_w)
- w_objectlist = W_ListObject.from_storage_and_strategy(self.space, storage, strategy)
+ w_objectlist = W_ListObject.from_storage_and_strategy(
+ self.space, storage, strategy)
return w_objectlist
# ___________________________________________________
@@ -209,13 +216,12 @@
strategy and storage according to the other W_List"""
self.strategy.copy_into(self, other)
-
def find(self, w_item, start=0, end=maxint):
"""Find w_item in list[start:end]. If not found, raise ValueError"""
return self.strategy.find(self, w_item, start, end)
def append(self, w_item):
- 'L.append(object) -- append object to end'
+ """L.append(object) -- append object to end"""
self.strategy.append(self, w_item)
def length(self):
@@ -228,8 +234,8 @@
return self.strategy.getitem(self, index)
def getslice(self, start, stop, step, length):
- """Returns a slice of the list defined by the arguments. Arguments must be
- normalized (i.e. using normalize_simple_slice or W_Slice.indices4).
+ """Returns a slice of the list defined by the arguments. Arguments must
+ be normalized (i.e. using normalize_simple_slice or W_Slice.indices4).
May raise IndexError."""
return self.strategy.getslice(self, start, stop, step, length)
@@ -246,7 +252,7 @@
def getitems_unroll(self):
"""Returns a fixed-size list of all items after wrapping them. The JIT
- will fully unroll this function. """
+ will fully unroll this function."""
l = self.strategy.getitems_unroll(self)
debug.make_sure_not_resized(l)
return l
@@ -257,22 +263,21 @@
return self.strategy.getitems_copy(self)
def getitems_str(self):
- """ Return the items in the list as unwrapped strings. If the list does
- not use the list strategy, return None. """
+ """Return the items in the list as unwrapped strings. If the list does
+ not use the list strategy, return None."""
return self.strategy.getitems_str(self)
def getitems_unicode(self):
- """ Return the items in the list as unwrapped unicodes. If the list does
- not use the list strategy, return None. """
+ """Return the items in the list as unwrapped unicodes. If the list does
+ not use the list strategy, return None."""
return self.strategy.getitems_unicode(self)
def getitems_int(self):
- """ Return the items in the list as unwrapped ints. If the list does
- not use the list strategy, return None. """
+ """Return the items in the list as unwrapped ints. If the list does not
+ use the list strategy, return None."""
return self.strategy.getitems_int(self)
# ___________________________________________________
-
def mul(self, times):
"""Returns a copy of the list, multiplied by times.
Argument must be unwrapped."""
@@ -326,15 +331,222 @@
argument reverse. Argument must be unwrapped."""
self.strategy.sort(self, reverse)
+ # exposed to app-level
+
+ @staticmethod
+ def descr_new(space, w_listtype, __args__):
+ w_obj = space.allocate_instance(W_ListObject, w_listtype)
+ w_obj.clear(space)
+ return w_obj
+
+ def descr_init(self, space, __args__):
+ # this is on the silly side
+ w_iterable, = __args__.parse_obj(
+ None, 'list', init_signature, init_defaults)
+ self.clear(space)
+ if w_iterable is not None:
+ self.extend(w_iterable)
+
+ def descr_repr(self, space):
+ if self.length() == 0:
+ return space.wrap('[]')
+ 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 listrepr(space, w_currently_in_repr, self)
+
+ def descr_eq(self, space, w_other):
+ if not isinstance(w_other, W_ListObject):
+ return space.w_NotImplemented
+ return self._descr_eq(space, w_other)
+
+ @jit.look_inside_iff(list_unroll_condition)
+ def _descr_eq(self, space, w_other):
+ # needs to be safe against eq_w() mutating the w_lists behind our back
+ if self.length() != w_other.length():
+ return space.w_False
+
+ # XXX in theory, this can be implemented more efficiently as well.
+ # let's not care for now
+ i = 0
+ while i < self.length() and i < w_other.length():
+ if not space.eq_w(self.getitem(i), w_other.getitem(i)):
+ return space.w_False
+ i += 1
+ return space.w_True
+
+ descr_ne = negate(descr_eq)
+
+ def _make_list_comparison(name):
+ op = getattr(operator, name)
+
+ def compare_unwrappeditems(self, space, w_list2):
+ if not isinstance(w_list2, W_ListObject):
+ return space.w_NotImplemented
+ return _compare_unwrappeditems(self, space, w_list2)
+
+ @jit.look_inside_iff(list_unroll_condition)
+ def _compare_unwrappeditems(self, space, w_list2):
+ # needs to be safe against eq_w() mutating the w_lists behind our
+ # back
+ # Search for the first index where items are different
+ i = 0
+ # XXX in theory, this can be implemented more efficiently as well.
+ # let's not care for now
+ while i < self.length() and i < w_list2.length():
+ w_item1 = self.getitem(i)
+ w_item2 = w_list2.getitem(i)
+ if not space.eq_w(w_item1, w_item2):
+ return getattr(space, name)(w_item1, w_item2)
+ i += 1
+ # No more items to compare -- compare sizes
+ return space.newbool(op(self.length(), w_list2.length()))
+
+ return func_with_new_name(compare_unwrappeditems, name + '__List_List')
+
+ descr_lt = _make_list_comparison('lt')
+ descr_le = _make_list_comparison('le')
+ descr_gt = _make_list_comparison('gt')
+ descr_ge = _make_list_comparison('ge')
+
+ def descr_len(self, space):
+ result = self.length()
+ return wrapint(space, result)
+
+ def descr_iter(self, space):
+ return W_FastListIterObject(self)
+
+ def descr_contains(self, space, w_obj):
+ try:
+ self.find(w_obj)
+ return space.w_True
+ except ValueError:
+ return space.w_False
+
+ def descr_add(self, space, w_list2):
+ if not isinstance(w_list2, W_ListObject):
+ return space.w_NotImplemented
+ w_clone = self.clone()
+ w_clone.extend(w_list2)
+ return w_clone
+
+ def descr_inplace_add(self, space, w_iterable):
+ if isinstance(w_iterable, W_ListObject):
+ self.extend(w_iterable)
+ return self
+
+ try:
+ self.extend(w_iterable)
+ except OperationError, e:
+ if e.match(space, space.w_TypeError):
+ return space.w_NotImplemented
+ raise
+ return self
+
+ def descr_mul(self, space, w_times):
+ try:
+ times = space.getindex_w(w_times, space.w_OverflowError)
+ except OperationError, e:
+ if e.match(space, space.w_TypeError):
+ return space.w_NotImplemented
+ raise
+ return self.mul(times)
+
+ def descr_inplace_mul(self, space, w_times):
+ try:
+ times = space.getindex_w(w_times, space.w_OverflowError)
+ except OperationError, e:
+ if e.match(space, space.w_TypeError):
+ return space.w_NotImplemented
+ raise
+ self.inplace_mul(times)
+ return self
+
+ def descr_getitem(self, space, w_index):
+ if isinstance(w_index, W_SliceObject):
+ # XXX consider to extend rlist's functionality?
+ length = self.length()
+ start, stop, step, slicelength = w_index.indices4(space, length)
+ assert slicelength >= 0
+ if slicelength == 0:
+ return make_empty_list(space)
+ return self.getslice(start, stop, step, slicelength)
+
+ try:
+ index = space.getindex_w(w_index, space.w_IndexError, "list index")
+ return self.getitem(index)
+ except IndexError:
+ raise OperationError(space.w_IndexError,
+ space.wrap("list index out of range"))
+
+ def descr_getslice(self, space, w_start, w_stop):
+ length = self.length()
+ start, stop = normalize_simple_slice(space, length, w_start, w_stop)
+
+ slicelength = stop - start
+ if slicelength == 0:
+ return make_empty_list(space)
+ return self.getslice(start, stop, 1, stop - start)
+
+ def descr_setitem(self, space, w_index, w_any):
+ if isinstance(w_index, W_SliceObject):
+ oldsize = self.length()
+ start, stop, step, slicelength = w_index.indices4(space, oldsize)
+ if isinstance(w_any, W_ListObject):
+ self.setslice(start, step, slicelength, w_any)
+ else:
+ sequence_w = space.listview(w_any)
+ w_other = W_ListObject(space, sequence_w)
+ self.setslice(start, step, slicelength, w_other)
+ return
+
+ idx = space.getindex_w(w_index, space.w_IndexError, "list index")
+ try:
+ self.setitem(idx, w_any)
+ except IndexError:
+ raise OperationError(space.w_IndexError,
+ space.wrap("list index out of range"))
+
+ def descr_setslice(self, space, w_start, w_stop, w_iterable):
+ length = self.length()
+ start, stop = normalize_simple_slice(space, length, w_start, w_stop)
+
+ if isinstance(w_iterable, W_ListObject):
+ self.setslice(start, 1, stop - start, w_iterable)
+ else:
+ sequence_w = space.listview(w_iterable)
+ w_other = W_ListObject(space, sequence_w)
+ self.setslice(start, 1, stop - start, w_other)
+
+ def descr_delitem(self, space, w_idx):
+ if isinstance(w_idx, W_SliceObject):
+ start, stop, step, slicelength = w_idx.indices4(
+ space, self.length())
+ self.deleteslice(start, step, slicelength)
+ return
+
+ idx = space.getindex_w(w_idx, space.w_IndexError, "list index")
+ if idx < 0:
+ idx += self.length()
+ try:
+ self.pop(idx)
+ except IndexError:
+ raise OperationError(space.w_IndexError,
+ space.wrap("list index out of range"))
+
+ def descr_delslice(self, space, w_start, w_stop):
+ length = self.length()
+ start, stop = normalize_simple_slice(space, length, w_start, w_stop)
+ self.deleteslice(start, 1, stop - start)
+
def descr_reversed(self, space):
'L.__reversed__() -- return a reverse iterator over the list'
- from pypy.objspace.std.iterobject import W_ReverseSeqIterObject
return W_ReverseSeqIterObject(space, self, -1)
def descr_reverse(self, space):
'L.reverse() -- reverse *IN PLACE*'
self.reverse()
- return space.w_None
def descr_count(self, space, w_value):
'''L.count(value) -> integer -- return number of
@@ -354,7 +566,6 @@
length = self.length()
index = get_positive_index(index, length)
self.insert(index, w_value)
- return space.w_None
@unwrap_spec(index=int)
def descr_pop(self, space, index=-1):
@@ -366,7 +577,7 @@
space.wrap("pop from empty list"))
# clearly differentiate between list.pop() and list.pop(index)
if index == -1:
- return self.pop_end() # cannot raise because list is not empty
+ return self.pop_end() # cannot raise because list is not empty
if index < 0:
index += length
try:
@@ -383,9 +594,8 @@
except ValueError:
raise OperationError(space.w_ValueError,
space.wrap("list.remove(x): x not in list"))
- if i < self.length(): # otherwise list was mutated
+ if i < self.length(): # otherwise list was mutated
self.pop(i)
- return space.w_None
@unwrap_spec(w_start=WrappedDefault(0), w_stop=WrappedDefault(maxint))
def descr_index(self, space, w_value, w_start, w_stop):
@@ -424,7 +634,7 @@
sorterclass = SimpleSort
else:
self.sort(reverse)
- return space.w_None
+ return
sorter = sorterclass(self.getitems(), self.length())
sorter.space = space
@@ -474,10 +684,6 @@
raise OperationError(space.w_ValueError,
space.wrap("list modified during sort"))
- return space.w_None
-
-registerimplementation(W_ListObject)
-
class ListStrategy(object):
sizehint = -1
@@ -602,7 +808,8 @@
The storage is None. When items are added to the W_List a new RPython list
is created and the strategy and storage of the W_List are changed depending
to the added item.
- W_Lists do not switch back to EmptyListStrategy when becoming empty again."""
+ W_Lists do not switch back to EmptyListStrategy when becoming empty again.
+ """
_applevel_repr = "empty"
@@ -621,7 +828,8 @@
unerase = staticmethod(unerase)
def clone(self, w_list):
- return W_ListObject.from_storage_and_strategy(self.space, w_list.lstorage, self)
+ return W_ListObject.from_storage_and_strategy(
+ self.space, w_list.lstorage, self)
def copy_into(self, w_list, w_other):
pass
@@ -650,20 +858,21 @@
def getitems_copy(self, w_list):
return []
- getitems_fixedsize = func_with_new_name(getitems_copy, "getitems_fixedsize")
+ getitems_fixedsize = func_with_new_name(getitems_copy,
+ "getitems_fixedsize")
getitems_unroll = getitems_fixedsize
def getstorage_copy(self, w_list):
return self.erase(None)
def switch_to_correct_strategy(self, w_list, w_item):
- if is_W_IntObject(w_item):
+ if type(w_item) is W_IntObject:
strategy = self.space.fromcache(IntegerListStrategy)
- elif is_W_StringObject(w_item):
+ elif type(w_item) is W_StringObject:
strategy = self.space.fromcache(StringListStrategy)
- elif is_W_UnicodeObject(w_item):
+ elif type(w_item) is W_UnicodeObject:
strategy = self.space.fromcache(UnicodeListStrategy)
- elif is_W_FloatObject(w_item):
+ elif type(w_item) is W_FloatObject:
strategy = self.space.fromcache(FloatListStrategy)
else:
strategy = self.space.fromcache(ObjectListStrategy)
@@ -707,7 +916,6 @@
w_other.copy_into(w_list)
def _extend_from_iterable(self, w_list, w_iterable):
- from pypy.objspace.std.tupleobject import W_AbstractTupleObject
space = self.space
if isinstance(w_iterable, W_AbstractTupleObject):
w_list.__init__(space, w_iterable.getitems_copy())
@@ -742,9 +950,9 @@
def is_empty_strategy(self):
return True
+
class SizeListStrategy(EmptyListStrategy):
- """ Like empty, but when modified it'll preallocate the size to sizehint
- """
+ """Like empty, but when modified it'll preallocate the size to sizehint."""
def __init__(self, space, sizehint):
self.sizehint = sizehint
ListStrategy.__init__(self, space)
@@ -753,12 +961,13 @@
assert hint >= 0
self.sizehint = hint
+
class RangeListStrategy(ListStrategy):
"""RangeListStrategy is used when a list is created using the range method.
- The storage is a tuple containing only three integers start, step and length
- and elements are calculated based on these values.
- On any operation destroying the range (inserting, appending non-ints)
- the strategy is switched to IntegerListStrategy."""
+ The storage is a tuple containing only three integers start, step and
+ length and elements are calculated based on these values. On any operation
+ destroying the range (inserting, appending non-ints) the strategy is
+ switched to IntegerListStrategy."""
_applevel_repr = "range"
@@ -781,8 +990,9 @@
unerase = staticmethod(unerase)
def clone(self, w_list):
- storage = w_list.lstorage # lstorage is tuple, no need to clone
- w_clone = W_ListObject.from_storage_and_strategy(self.space, storage, self)
+ storage = w_list.lstorage # lstorage is tuple, no need to clone
+ w_clone = W_ListObject.from_storage_and_strategy(self.space, storage,
+ self)
return w_clone
def _resize_hint(self, w_list, hint):
@@ -794,11 +1004,13 @@
w_other.lstorage = w_list.lstorage
def find(self, w_list, w_obj, startindex, stopindex):
- if is_W_IntObject(w_obj):
+ if type(w_obj) is W_IntObject:
obj = self.unwrap(w_obj)
start, step, length = self.unerase(w_list.lstorage)
- if ((step > 0 and start <= obj <= start + (length - 1) * step and (start - obj) % step == 0) or
- (step < 0 and start + (length - 1) * step <= obj <= start and (start - obj) % step == 0)):
+ if ((step > 0 and start <= obj <= start + (length - 1) * step and
+ (start - obj) % step == 0) or
+ (step < 0 and start + (length - 1) * step <= obj <= start and
+ (start - obj) % step == 0)):
index = (obj - start) // step
else:
raise ValueError
@@ -861,16 +1073,18 @@
@jit.dont_look_inside
def getitems_fixedsize(self, w_list):
return self._getitems_range_unroll(w_list, True)
+
def getitems_unroll(self, w_list):
return self._getitems_range_unroll(w_list, True)
- _getitems_range_unroll = jit.unroll_safe(func_with_new_name(_getitems_range, "_getitems_range_unroll"))
+ _getitems_range_unroll = jit.unroll_safe(
+ func_with_new_name(_getitems_range, "_getitems_range_unroll"))
def getslice(self, w_list, start, stop, step, length):
self.switch_to_integer_strategy(w_list)
return w_list.getslice(start, stop, step, length)
def append(self, w_list, w_item):
- if is_W_IntObject(w_item):
+ if type(w_item) is W_IntObject:
self.switch_to_integer_strategy(w_list)
else:
w_list.switch_to_object_strategy()
@@ -933,6 +1147,7 @@
self.switch_to_integer_strategy(w_list)
w_list.reverse()
+
class AbstractUnwrappedStrategy(object):
_mixin_ = True
@@ -970,7 +1185,8 @@
def clone(self, w_list):
l = self.unerase(w_list.lstorage)
storage = self.erase(l[:])
- w_clone = W_ListObject.from_storage_and_strategy(self.space, storage, self)
+ w_clone = W_ListObject.from_storage_and_strategy(
+ self.space, storage, self)
return w_clone
def _resize_hint(self, w_list, hint):
@@ -1001,12 +1217,13 @@
l = self.unerase(w_list.lstorage)
try:
r = l[index]
- except IndexError: # make RPython raise the exception
+ except IndexError: # make RPython raise the exception
raise
return self.wrap(r)
@jit.look_inside_iff(lambda self, w_list:
- jit.loop_unrolling_heuristic(w_list, w_list.length(), UNROLL_CUTOFF))
+ jit.loop_unrolling_heuristic(w_list, w_list.length(),
+ UNROLL_CUTOFF))
def getitems_copy(self, w_list):
return [self.wrap(item) for item in self.unerase(w_list.lstorage)]
@@ -1015,7 +1232,8 @@
return [self.wrap(item) for item in self.unerase(w_list.lstorage)]
@jit.look_inside_iff(lambda self, w_list:
- jit.loop_unrolling_heuristic(w_list, w_list.length(), UNROLL_CUTOFF))
+ jit.loop_unrolling_heuristic(w_list, w_list.length(),
+ UNROLL_CUTOFF))
def getitems_fixedsize(self, w_list):
return self.getitems_unroll(w_list)
@@ -1030,7 +1248,8 @@
assert stop >= 0
sublist = l[start:stop]
storage = self.erase(sublist)
- return W_ListObject.from_storage_and_strategy(self.space, storage, self)
+ return W_ListObject.from_storage_and_strategy(
+ self.space, storage, self)
else:
subitems_w = [self._none_value] * length
l = self.unerase(w_list.lstorage)
@@ -1041,9 +1260,10 @@
except IndexError:
raise
storage = self.erase(subitems_w)
- return W_ListObject.from_storage_and_strategy(self.space, storage, self)
+ return W_ListObject.from_storage_and_strategy(
+ self.space, storage, self)
- def append(self, w_list, w_item):
+ def append(self, w_list, w_item):
if self.is_correct_type(w_item):
self.unerase(w_list.lstorage).append(self.unwrap(w_item))
return
@@ -1092,11 +1312,11 @@
if self is self.space.fromcache(ObjectListStrategy):
w_other = w_other._temporarily_as_objects()
- elif (not self.list_is_correct_type(w_other) and
- w_other.length() != 0):
+ elif not self.list_is_correct_type(w_other) and w_other.length() != 0:
w_list.switch_to_object_strategy()
w_other_as_object = w_other._temporarily_as_objects()
- assert w_other_as_object.strategy is self.space.fromcache(ObjectListStrategy)
+ assert (w_other_as_object.strategy is
+ self.space.fromcache(ObjectListStrategy))
w_list.setslice(start, step, slicelength, w_other_as_object)
return
@@ -1112,13 +1332,14 @@
lim = start + len2
i = newsize - 1
while i >= lim:
- items[i] = items[i-delta]
+ items[i] = items[i - delta]
i -= 1
elif delta == 0:
pass
else:
- assert start >= 0 # start<0 is only possible with slicelength==0
- del items[start:start+delta]
+ # start < 0 is only possible with slicelength == 0
+ assert start >= 0
+ del items[start:start + delta]
elif len2 != slicelength: # No resize for extended slices
raise operationerrfmt(self.space.w_ValueError, "attempt to "
"assign sequence of size %d to extended slice of size %d",
@@ -1163,7 +1384,7 @@
if step == 1:
assert start >= 0
if slicelength > 0:
- del items[start:start+slicelength]
+ del items[start:start + slicelength]
else:
n = len(items)
i = start
@@ -1172,15 +1393,15 @@
j = i + 1
i += step
while j < i:
- items[j-discard] = items[j]
+ items[j - discard] = items[j]
j += 1
j = i + 1
while j < n:
- items[j-slicelength] = items[j]
+ items[j - slicelength] = items[j]
j += 1
start = n - slicelength
- assert start >= 0 # annotator hint
+ assert start >= 0 # annotator hint
del items[start:]
def pop_end(self, w_list):
@@ -1213,6 +1434,7 @@
def reverse(self, w_list):
self.unerase(w_list.lstorage).reverse()
+
class ObjectListStrategy(AbstractUnwrappedStrategy, ListStrategy):
_none_value = None
_applevel_repr = "object"
@@ -1245,6 +1467,7 @@
def getitems(self, w_list):
return self.unerase(w_list.lstorage)
+
class IntegerListStrategy(AbstractUnwrappedStrategy, ListStrategy):
_none_value = 0
_applevel_repr = "int"
@@ -1260,7 +1483,7 @@
unerase = staticmethod(unerase)
def is_correct_type(self, w_obj):
- return is_W_IntObject(w_obj)
+ return type(w_obj) is W_IntObject
def list_is_correct_type(self, w_list):
return w_list.strategy is self.space.fromcache(IntegerListStrategy)
@@ -1275,6 +1498,7 @@
def getitems_int(self, w_list):
return self.unerase(w_list.lstorage)
+
class FloatListStrategy(AbstractUnwrappedStrategy, ListStrategy):
_none_value = 0.0
_applevel_repr = "float"
@@ -1290,7 +1514,7 @@
unerase = staticmethod(unerase)
def is_correct_type(self, w_obj):
- return is_W_FloatObject(w_obj)
+ return type(w_obj) is W_FloatObject
def list_is_correct_type(self, w_list):
return w_list.strategy is self.space.fromcache(FloatListStrategy)
@@ -1302,6 +1526,7 @@
if reverse:
l.reverse()
+
class StringListStrategy(AbstractUnwrappedStrategy, ListStrategy):
_none_value = None
_applevel_repr = "str"
@@ -1317,7 +1542,7 @@
unerase = staticmethod(unerase)
def is_correct_type(self, w_obj):
- return is_W_StringObject(w_obj)
+ return type(w_obj) is W_StringObject
def list_is_correct_type(self, w_list):
return w_list.strategy is self.space.fromcache(StringListStrategy)
@@ -1348,7 +1573,7 @@
unerase = staticmethod(unerase)
def is_correct_type(self, w_obj):
- return is_W_UnicodeObject(w_obj)
+ return type(w_obj) is W_UnicodeObject
def list_is_correct_type(self, w_list):
return w_list.strategy is self.space.fromcache(UnicodeListStrategy)
@@ -1368,196 +1593,6 @@
init_signature = Signature(['sequence'], None, None)
init_defaults = [None]
-def init__List(space, w_list, __args__):
- # this is on the silly side
- w_iterable, = __args__.parse_obj(
- None, 'list', init_signature, init_defaults)
- w_list.clear(space)
- if w_iterable is not None:
- w_list.extend(w_iterable)
-
-def len__List(space, w_list):
- result = w_list.length()
- return wrapint(space, result)
-
-def getitem__List_ANY(space, w_list, w_index):
- try:
- return w_list.getitem(get_list_index(space, w_index))
- except IndexError:
- raise OperationError(space.w_IndexError,
- space.wrap("list index out of range"))
-
-def getitem__List_Slice(space, w_list, w_slice):
- # XXX consider to extend rlist's functionality?
- length = w_list.length()
- start, stop, step, slicelength = w_slice.indices4(space, length)
- assert slicelength >= 0
- if slicelength == 0:
- return make_empty_list(space)
- return w_list.getslice(start, stop, step, slicelength)
-
-def getslice__List_ANY_ANY(space, w_list, w_start, w_stop):
- length = w_list.length()
- start, stop = normalize_simple_slice(space, length, w_start, w_stop)
-
- slicelength = stop - start
- if slicelength == 0:
- return make_empty_list(space)
- return w_list.getslice(start, stop, 1, stop - start)
-
-def setslice__List_ANY_ANY_List(space, w_list, w_start, w_stop, w_other):
- length = w_list.length()
- start, stop = normalize_simple_slice(space, length, w_start, w_stop)
- w_list.setslice(start, 1, stop-start, w_other)
-
-def setslice__List_ANY_ANY_ANY(space, w_list, w_start, w_stop, w_iterable):
- length = w_list.length()
- start, stop = normalize_simple_slice(space, length, w_start, w_stop)
- sequence_w = space.listview(w_iterable)
- w_other = W_ListObject(space, sequence_w)
- w_list.setslice(start, 1, stop-start, w_other)
-
-def delslice__List_ANY_ANY(space, w_list, w_start, w_stop):
- length = w_list.length()
- start, stop = normalize_simple_slice(space, length, w_start, w_stop)
- w_list.deleteslice(start, 1, stop-start)
-
-def contains__List_ANY(space, w_list, w_obj):
- try:
- w_list.find(w_obj)
- return space.w_True
- except ValueError:
- return space.w_False
-
-def iter__List(space, w_list):
- from pypy.objspace.std import iterobject
- return iterobject.W_FastListIterObject(w_list)
-
-def add__List_List(space, w_list1, w_list2):
- w_clone = w_list1.clone()
- w_clone.extend(w_list2)
- return w_clone
-
-def inplace_add__List_ANY(space, w_list1, w_iterable2):
- try:
- w_list1.extend(w_iterable2)
- except OperationError, e:
- if e.match(space, space.w_TypeError):
- raise FailedToImplement
- raise
- return w_list1
-
-def inplace_add__List_List(space, w_list1, w_list2):
- w_list1.extend(w_list2)
- return w_list1
-
-def mul_list_times(space, w_list, w_times):
- try:
- times = space.getindex_w(w_times, space.w_OverflowError)
- except OperationError, e:
- if e.match(space, space.w_TypeError):
- raise FailedToImplement
- raise
- return w_list.mul(times)
-
-def mul__List_ANY(space, w_list, w_times):
- return mul_list_times(space, w_list, w_times)
-
-def mul__ANY_List(space, w_times, w_list):
- return mul_list_times(space, w_list, w_times)
-
-def inplace_mul__List_ANY(space, w_list, w_times):
- try:
- times = space.getindex_w(w_times, space.w_OverflowError)
- except OperationError, e:
- if e.match(space, space.w_TypeError):
- raise FailedToImplement
- raise
- w_list.inplace_mul(times)
- return w_list
-
-def list_unroll_condition(space, w_list1, w_list2):
- return jit.loop_unrolling_heuristic(w_list1, w_list1.length(), UNROLL_CUTOFF) or \
- jit.loop_unrolling_heuristic(w_list2, w_list2.length(), UNROLL_CUTOFF)
-
- at jit.look_inside_iff(list_unroll_condition)
-def eq__List_List(space, w_list1, w_list2):
- # needs to be safe against eq_w() mutating the w_lists behind our back
- if w_list1.length() != w_list2.length():
- return space.w_False
-
- # XXX in theory, this can be implemented more efficiently as well. let's
- # not care for now
- i = 0
- while i < w_list1.length() and i < w_list2.length():
- if not space.eq_w(w_list1.getitem(i), w_list2.getitem(i)):
- return space.w_False
- i += 1
- return space.w_True
-
-def _make_list_comparison(name):
- import operator
- op = getattr(operator, name)
-
- @jit.look_inside_iff(list_unroll_condition)
- def compare_unwrappeditems(space, w_list1, w_list2):
- # needs to be safe against eq_w() mutating the w_lists behind our back
- # Search for the first index where items are different
- i = 0
- # XXX in theory, this can be implemented more efficiently as well.
- # let's not care for now
- while i < w_list1.length() and i < w_list2.length():
- w_item1 = w_list1.getitem(i)
- w_item2 = w_list2.getitem(i)
- if not space.eq_w(w_item1, w_item2):
- return getattr(space, name)(w_item1, w_item2)
- i += 1
- # No more items to compare -- compare sizes
- return space.newbool(op(w_list1.length(), w_list2.length()))
- return func_with_new_name(compare_unwrappeditems, name + '__List_List')
-
-lt__List_List = _make_list_comparison('lt')
-le__List_List = _make_list_comparison('le')
-gt__List_List = _make_list_comparison('gt')
-ge__List_List = _make_list_comparison('ge')
-
-def delitem__List_ANY(space, w_list, w_idx):
- idx = get_list_index(space, w_idx)
- if idx < 0:
- idx += w_list.length()
- try:
- w_list.pop(idx)
- except IndexError:
- raise OperationError(space.w_IndexError,
- space.wrap("list deletion index out of range"))
- return space.w_None
-
-
-def delitem__List_Slice(space, w_list, w_slice):
- start, stop, step, slicelength = w_slice.indices4(space, w_list.length())
- w_list.deleteslice(start, step, slicelength)
-
-def setitem__List_ANY_ANY(space, w_list, w_index, w_any):
- idx = get_list_index(space, w_index)
- try:
- w_list.setitem(idx, w_any)
- except IndexError:
- raise OperationError(space.w_IndexError,
- space.wrap("list index out of range"))
- return space.w_None
-
-def setitem__List_Slice_List(space, w_list, w_slice, w_other):
- oldsize = w_list.length()
- start, stop, step, slicelength = w_slice.indices4(space, oldsize)
- w_list.setslice(start, step, slicelength, w_other)
-
-def setitem__List_Slice_ANY(space, w_list, w_slice, w_iterable):
- oldsize = w_list.length()
- start, stop, step, slicelength = w_slice.indices4(space, oldsize)
- sequence_w = space.listview(w_iterable)
- w_other = W_ListObject(space, sequence_w)
- w_list.setslice(start, step, slicelength, w_other)
-
app = applevel("""
def listrepr(currently_in_repr, l):
'The app-level part of repr().'
@@ -1576,25 +1611,6 @@
listrepr = app.interphook("listrepr")
-def repr__List(space, w_list):
- if w_list.length() == 0:
- return space.wrap('[]')
- 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 listrepr(space, w_currently_in_repr, w_list)
-
-def get_positive_index(where, length):
- if where < 0:
- where += length
- if where < 0:
- where = 0
- elif where > length:
- where = length
- assert where >= 0
- return where
-
# ____________________________________________________________
# Sorting
@@ -1607,11 +1623,13 @@
StringBaseTimSort = make_timsort_class()
UnicodeBaseTimSort = make_timsort_class()
-class KeyContainer(baseobjspace.W_Root):
+
+class KeyContainer(W_Root):
def __init__(self, w_key, w_item):
self.w_key = w_key
self.w_item = w_item
+
# NOTE: all the subclasses of TimSort should inherit from a common subclass,
# so make sure that only SimpleSort inherits directly from TimSort.
# This is necessary to hide the parent method TimSort.lt() from the
@@ -1621,22 +1639,27 @@
space = self.space
return space.is_true(space.lt(a, b))
+
class IntSort(IntBaseTimSort):
def lt(self, a, b):
return a < b
+
class FloatSort(FloatBaseTimSort):
def lt(self, a, b):
return a < b
+
class StringSort(StringBaseTimSort):
def lt(self, a, b):
return a < b
+
class UnicodeSort(UnicodeBaseTimSort):
def lt(self, a, b):
return a < b
+
class CustomCompareSort(SimpleSort):
def lt(self, a, b):
space = self.space
@@ -1651,6 +1674,7 @@
raise
return result < 0
+
class CustomKeySort(SimpleSort):
def lt(self, a, b):
assert isinstance(a, KeyContainer)
@@ -1658,33 +1682,46 @@
space = self.space
return space.is_true(space.lt(a.w_key, b.w_key))
+
class CustomKeyCompareSort(CustomCompareSort):
def lt(self, a, b):
assert isinstance(a, KeyContainer)
assert isinstance(b, KeyContainer)
return CustomCompareSort.lt(self, a.w_key, b.w_key)
-# ____________________________________________________________
-
-def descr_new(space, w_listtype, __args__):
- w_obj = space.allocate_instance(W_ListObject, w_listtype)
- w_obj.clear(space)
- return w_obj
-
-# ____________________________________________________________
-
-# ____________________________________________________________
-
-def get_list_index(space, w_index):
- return space.getindex_w(w_index, space.w_IndexError, "list index")
-
-register_all(vars(), globals())
W_ListObject.typedef = StdTypeDef("list",
__doc__ = """list() -> new list
list(sequence) -> new list initialized from sequence's items""",
- __new__ = interp2app(descr_new),
+ __new__ = interp2app(W_ListObject.descr_new),
+ __init__ = interp2app(W_ListObject.descr_init),
+ __repr__ = interp2app(W_ListObject.descr_repr),
__hash__ = None,
+
+ __eq__ = interp2app(W_ListObject.descr_eq),
+ __ne__ = interp2app(W_ListObject.descr_ne),
+ __lt__ = interp2app(W_ListObject.descr_lt),
+ __le__ = interp2app(W_ListObject.descr_le),
+ __gt__ = interp2app(W_ListObject.descr_gt),
+ __ge__ = interp2app(W_ListObject.descr_ge),
+
+ __len__ = interp2app(W_ListObject.descr_len),
+ __iter__ = interp2app(W_ListObject.descr_iter),
+ __contains__ = interp2app(W_ListObject.descr_contains),
+
+ __add__ = interp2app(W_ListObject.descr_add),
+ __iadd__ = interp2app(W_ListObject.descr_inplace_add),
+ __mul__ = interp2app(W_ListObject.descr_mul),
+ __rmul__ = interp2app(W_ListObject.descr_mul),
+ __imul__ = interp2app(W_ListObject.descr_inplace_mul),
+
+ __getitem__ = interp2app(W_ListObject.descr_getitem),
+ __getslice__ = interp2app(W_ListObject.descr_getslice),
+ __setitem__ = interp2app(W_ListObject.descr_setitem),
+ __setslice__ = interp2app(W_ListObject.descr_setslice),
+ __delitem__ = interp2app(W_ListObject.descr_delitem),
+ __delslice__ = interp2app(W_ListObject.descr_delslice),
+
sort = interp2app(W_ListObject.descr_sort),
index = interp2app(W_ListObject.descr_index),
append = interp2app(W_ListObject.append),
@@ -1695,7 +1732,4 @@
extend = interp2app(W_ListObject.extend),
insert = interp2app(W_ListObject.descr_insert),
remove = interp2app(W_ListObject.descr_remove),
- )
-W_ListObject.typedef.registermethods(globals())
-
-list_typedef = W_ListObject.typedef
+)
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
@@ -297,17 +297,17 @@
return space.newtuple(items_w)
register(TYPE_TUPLE, unmarshal_Tuple)
-def marshal_w__List(space, w_list, m):
+def marshal_list(space, w_list, m):
+ if not isinstance(w_list, W_ListObject):
+ raise_exception(space, "unmarshallable object")
items = w_list.getitems()[:]
m.put_tuple_w(TYPE_LIST, items)
+handled_by_any.append(('list', marshal_list))
-def unmarshal_List(space, u, tc):
+def unmarshal_list(space, u, tc):
items_w = u.get_list_w()
return space.newlist(items_w)
-
-def finish_List(space, items_w, typecode):
- return space.newlist(items_w)
-register(TYPE_LIST, unmarshal_List)
+register(TYPE_LIST, unmarshal_list)
def marshal_w_dict(space, w_dict, m):
if not isinstance(w_dict, W_DictMultiObject):
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
@@ -39,7 +39,6 @@
from pypy.objspace.std.floattype import float_typedef
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.basestringtype import basestring_typedef
from pypy.objspace.std.stringtype import str_typedef
from pypy.objspace.std.bytearraytype import bytearray_typedef
@@ -80,6 +79,7 @@
# not-multimethod based types
+ self.pythontypes.append(listobject.W_ListObject.typedef)
self.pythontypes.append(dictmultiobject.W_DictMultiObject.typedef)
self.pythontypes.append(setobject.W_SetObject.typedef)
self.pythontypes.append(setobject.W_FrozensetObject.typedef)
@@ -91,7 +91,6 @@
intobject.W_IntObject: [],
floatobject.W_FloatObject: [],
tupleobject.W_TupleObject: [],
- listobject.W_ListObject: [],
stringobject.W_StringObject: [],
bytearrayobject.W_BytearrayObject: [],
typeobject.W_TypeObject: [],
@@ -109,11 +108,6 @@
}
self.imported_but_not_registered = {
- dictmultiobject.W_DictMultiObject: True, # XXXXXX
- dictmultiobject.W_DictMultiIterKeysObject: True,
- dictmultiobject.W_DictMultiIterValuesObject: True,
- dictmultiobject.W_DictMultiIterItemsObject: True,
- listobject.W_ListObject: True,
stringobject.W_StringObject: True,
tupleobject.W_TupleObject: True,
}
diff --git a/pypy/objspace/std/test/test_listobject.py b/pypy/objspace/std/test/test_listobject.py
--- a/pypy/objspace/std/test/test_listobject.py
+++ b/pypy/objspace/std/test/test_listobject.py
@@ -783,6 +783,8 @@
assert l == [1,2,3,4,5]
def test_iadd_subclass(self):
+ #XXX
+ skip("Maybe there is something wrong in descroperation?")
class Bar(object):
def __radd__(self, other):
return ('radd', self, other)
@@ -1306,6 +1308,12 @@
def test_use_method_for_wrong_object(self):
raises(TypeError, list.append.im_func, 1, 2)
+ def test_ne_NotImplemented(self):
+ class NonList(object):
+ pass
+ non_list = NonList()
+ assert [] != non_list
+
class AppTestForRangeLists(AppTestW_ListObject):
spaceconfig = {"objspace.std.withrangelist": True}
diff --git a/pypy/objspace/std/test/test_liststrategies.py b/pypy/objspace/std/test/test_liststrategies.py
--- a/pypy/objspace/std/test/test_liststrategies.py
+++ b/pypy/objspace/std/test/test_liststrategies.py
@@ -488,15 +488,13 @@
def test_weird_rangelist_bug(self):
l = make_range_list(self.space, 1, 1, 3)
- from pypy.objspace.std.listobject import getslice__List_ANY_ANY
# should not raise
- assert getslice__List_ANY_ANY(self.space, l, self.space.wrap(15), self.space.wrap(2222)).strategy == self.space.fromcache(EmptyListStrategy)
+ assert l.descr_getslice(self.space, self.space.wrap(15), self.space.wrap(2222)).strategy == self.space.fromcache(EmptyListStrategy)
def test_add_to_rangelist(self):
l1 = make_range_list(self.space, 1, 1, 3)
l2 = W_ListObject(self.space, [self.space.wrap(4), self.space.wrap(5)])
- from pypy.objspace.std.listobject import add__List_List
- l3 = add__List_List(self.space, l1, l2)
+ l3 = l1.descr_add(self.space, l2)
assert self.space.eq_w(l3, W_ListObject(self.space, [self.space.wrap(1), self.space.wrap(2), self.space.wrap(3), self.space.wrap(4), self.space.wrap(5)]))
def test_unicode(self):
diff --git a/pypy/objspace/std/test/test_stdobjspace.py b/pypy/objspace/std/test/test_stdobjspace.py
--- a/pypy/objspace/std/test/test_stdobjspace.py
+++ b/pypy/objspace/std/test/test_stdobjspace.py
@@ -23,19 +23,6 @@
raises(OperationError,self.space.uint_w,self.space.wrap(None))
raises(OperationError,self.space.uint_w,self.space.wrap(""))
- def test_multimethods_defined_on(self):
- from pypy.objspace.std.stdtypedef import multimethods_defined_on
- from pypy.objspace.std.listobject import W_ListObject
- res = multimethods_defined_on(W_ListObject)
- res = [(m.name, local) for (m, local) in res]
- assert ('add', False) in res
- assert ('lt', False) in res
- assert ('setitem', False) in res
- assert ('mod', False) not in res
- assert ('pop', True) not in res
- assert ('reverse', True) not in res
- assert ('popitem', True) not in res
-
def test_sliceindices(self):
space = self.space
w_obj = space.appexec([], """():
diff --git a/pypy/objspace/std/util.py b/pypy/objspace/std/util.py
new file mode 100644
--- /dev/null
+++ b/pypy/objspace/std/util.py
@@ -0,0 +1,27 @@
+def negate(f):
+ """Create a function which calls `f` and negates its result. When the
+ result is ``space.w_NotImplemented``, ``space.w_NotImplemented`` is
+ returned. This is useful for complementing e.g. the __ne__ descriptor if
+ your type already defines a __eq__ descriptor.
+ """
+ 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
+
+def get_positive_index(where, length):
+ if where < 0:
+ where += length
+ if where < 0:
+ where = 0
+ elif where > length:
+ where = length
+ assert where >= 0
+ return where
More information about the pypy-commit
mailing list