Source

pypy / pypy / objspace / std / tupleobject.py

Daniel Roberts 0077cf5 


Nicholas Riley d6d030a 
Daniel Roberts 0077cf5 
Carl Friedrich B… 8ff436a 
Armin Rigo 50f5c28 
Benjamin Peterso… ef7a313 
Maciej Fijalkows… b5a2e0b 
Maciej Fijalkows… 12f4497 
Armin Rigo c85db2c 
Armin Rigo 6a00154 
Maciej Fijalkows… a19a489 


Armin Rigo b0c70fd 
Armin Rigo 3ed133d 
Armin Rigo b0c70fd 
Armin Rigo 5f96cb1 








Armin Rigo b0c70fd 
Armin Rigo 6a00154 
Hakan Ardo 4c85cbc 
Daniel Roberts 0077cf5 
Nicholas Riley d6d030a 
Maciej Fijalkows… b5a2e0b 
Armin Rigo 6a00154 






Nicholas Riley d6d030a 
Carl Friedrich B… bcb9cb8 
Samuele Pedroni ca4b87c 

Armin Rigo 5f96cb1 





Armin Rigo 6a00154 




Carl Friedrich B… d81e3f3 
Armin Rigo 6a00154 
Samuele Pedroni ca4b87c 
Armin Rigo caf29a9 

Armin Rigo 6a00154 
Armin Rigo caf29a9 





Armin Rigo 6a00154 






Nicholas Riley d6d030a 
Armin Rigo 6a00154 




Lukas Diekmann 7c21b36 
Armin Rigo 6a00154 
Armin Rigo 50f5c28 


Lukas Diekmann 7c21b36 
Armin Rigo 50f5c28 
Armin Rigo 022ef50 





Armin Rigo 6a00154 

Maciej Fijalkows… b5a2e0b 
Armin Rigo 6a00154 



Lukas Diekmann 3b8838b 
Armin Rigo 6a00154 
Samuele Pedroni 1f86ec3 

Guido Wesdorp f74fa3d 
Samuele Pedroni 1f86ec3 


Anders Hammarqui… 36e3bae 
Anders Hammarqui… d3bdd29 
Anders Hammarqui… 36e3bae 
Armin Rigo 6a00154 
Lukas Diekmann 3b8838b 
Armin Rigo 6a00154 
Samuele Pedroni ca4b87c 
Samuele Pedroni 1f86ec3 
Armin Rigo 6a00154 
Samuele Pedroni ca4b87c 
Samuele Pedroni 1f86ec3 
Armin Rigo 6a00154 
Maciej Fijalkows… a19a489 


Maciej Fijalkows… f189a84 

Maciej Fijalkows… a19a489 

Armin Rigo 6a00154 


Maciej Fijalkows… a19a489 


Armin Rigo 6a00154 
Maciej Fijalkows… a19a489 
Michael Hudson-D… d3cbebb 

Carl Friedrich B… ae47a8c 
Armin Rigo 6a00154 


Armin Rigo c85db2c 















Armin Rigo 6a00154 
Armin Rigo c85db2c 



Armin Rigo 6a00154 
Maciej Fijalkows… b5a2e0b 








Samuele Pedroni 056d774 
Armin Rigo 6a00154 
Alex Gaynor c1bb870 

Maciej Fijalkows… 12f4497 
Maciej Fijalkows… f189a84 
Maciej Fijalkows… a19a489 
Alex Gaynor c1bb870 
Armin Rigo 7262da8 


Alex Gaynor c1bb870 

Alex Gaynor 3431a63 
Armin Rigo 7262da8 



Alex Gaynor c1bb870 
Armin Rigo 6a00154 
Samuele Pedroni 453f8aa 
Lukas Diekmann 3b8838b 
Samuele Pedroni 453f8aa 
Benjamin Peterso… ef7a313 








Carl Friedrich B… 81222f3 
Benjamin Peterso… ef7a313 







from pypy.interpreter.error import OperationError
from pypy.objspace.std.model import registerimplementation, W_Object
from pypy.objspace.std.register_all import register_all
from pypy.objspace.std.inttype import wrapint
from pypy.objspace.std.multimethod import FailedToImplement
from pypy.rlib.rarithmetic import intmask
from pypy.objspace.std.sliceobject import W_SliceObject, normalize_simple_slice
from pypy.objspace.std import slicetype
from pypy.rlib.debug import make_sure_not_resized
from pypy.rlib import jit
from pypy.tool.sourcetools import func_with_new_name

# Tuples of known length up to UNROLL_TUPLE_LIMIT have unrolled certain methods
UNROLL_TUPLE_LIMIT = 10

class W_AbstractTupleObject(W_Object):
    __slots__ = ()

    def tolist(self):
        "Returns the items, as a fixed-size list."
        raise NotImplementedError

    def getitems_copy(self):
        "Returns a copy of the items, as a resizable list."
        raise NotImplementedError


class W_TupleObject(W_AbstractTupleObject):
    from pypy.objspace.std.tupletype import tuple_typedef as typedef
    _immutable_fields_ = ['wrappeditems[*]']

    def __init__(w_self, wrappeditems):
        make_sure_not_resized(wrappeditems)
        w_self.wrappeditems = wrappeditems   # a list of wrapped values

    def __repr__(w_self):
        """ representation for debugging purposes """
        reprlist = [repr(w_item) for w_item in w_self.wrappeditems]
        return "%s(%s)" % (w_self.__class__.__name__, ', '.join(reprlist))

    def unwrap(w_tuple, space):
        items = [space.unwrap(w_item) for w_item in w_tuple.wrappeditems]
        return tuple(items)

    def tolist(self):
        return self.wrappeditems

    def getitems_copy(self):
        return self.wrappeditems[:]   # returns a resizable list

registerimplementation(W_TupleObject)


def len__Tuple(space, w_tuple):
    result = len(w_tuple.wrappeditems)
    return wrapint(space, result)

def getitem__Tuple_ANY(space, w_tuple, w_index):
    # getindex_w should get a second argument space.w_IndexError,
    # but that doesn't exist the first time this is called.
    try:
        w_IndexError = space.w_IndexError
    except AttributeError:
        w_IndexError = None
    index = space.getindex_w(w_index, w_IndexError, "tuple index")
    try:
        return w_tuple.wrappeditems[index]
    except IndexError:
        raise OperationError(space.w_IndexError,
                             space.wrap("tuple index out of range"))

def getitem__Tuple_Slice(space, w_tuple, w_slice):
    items = w_tuple.wrappeditems
    length = len(items)
    start, stop, step, slicelength = w_slice.indices4(space, length)
    assert slicelength >= 0
    subitems = [None] * slicelength
    for i in range(slicelength):
        subitems[i] = items[start]
        start += step
    return space.newtuple(subitems)

def getslice__Tuple_ANY_ANY(space, w_tuple, w_start, w_stop):
    length = len(w_tuple.wrappeditems)
    start, stop = normalize_simple_slice(space, length, w_start, w_stop)
    return space.newtuple(w_tuple.wrappeditems[start:stop])

def contains__Tuple_ANY(space, w_tuple, w_obj):
    for w_item in w_tuple.wrappeditems:
        if space.eq_w(w_item, w_obj):
            return space.w_True
    return space.w_False

def iter__Tuple(space, w_tuple):
    from pypy.objspace.std import iterobject
    return iterobject.W_FastTupleIterObject(w_tuple, w_tuple.wrappeditems)

def add__Tuple_Tuple(space, w_tuple1, w_tuple2):
    items1 = w_tuple1.wrappeditems
    items2 = w_tuple2.wrappeditems
    return space.newtuple(items1 + items2)

def mul_tuple_times(space, w_tuple, 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
    if times == 1 and space.type(w_tuple) == space.w_tuple:
        return w_tuple
    items = w_tuple.wrappeditems
    return space.newtuple(items * times)

def mul__Tuple_ANY(space, w_tuple, w_times):
    return mul_tuple_times(space, w_tuple, w_times)

def mul__ANY_Tuple(space, w_times, w_tuple):
    return mul_tuple_times(space, w_tuple, w_times)

def tuple_unroll_condition(space, w_tuple1, w_tuple2):
    lgt1 = len(w_tuple1.wrappeditems)
    lgt2 = len(w_tuple2.wrappeditems)
    return ((jit.isconstant(lgt1) and lgt1 <= UNROLL_TUPLE_LIMIT) or
            (jit.isconstant(lgt2) and lgt2 <= UNROLL_TUPLE_LIMIT))

@jit.look_inside_iff(tuple_unroll_condition)
def eq__Tuple_Tuple(space, w_tuple1, w_tuple2):
    items1 = w_tuple1.wrappeditems
    items2 = w_tuple2.wrappeditems
    lgt1 = len(items1)
    lgt2 = len(items2)
    if lgt1 != lgt2:
        return space.w_False
    for i in range(lgt1):
        item1 = items1[i]
        item2 = items2[i]
        if not space.eq_w(item1, item2):
            return space.w_False
    return space.w_True

def _make_tuple_comparison(name):
    import operator
    op = getattr(operator, name)
    #
    @jit.look_inside_iff(tuple_unroll_condition)
    def compare_tuples(space, w_tuple1, w_tuple2):
        items1 = w_tuple1.wrappeditems
        items2 = w_tuple2.wrappeditems
        ncmp = min(len(items1), len(items2))
        # Search for the first index where items are different
        for p in range(ncmp):
            if not space.eq_w(items1[p], items2[p]):
                return getattr(space, name)(items1[p], items2[p])
        # No more items to compare -- compare sizes
        return space.newbool(op(len(items1), len(items2)))
    return func_with_new_name(compare_tuples, name + '__Tuple_Tuple')

lt__Tuple_Tuple = _make_tuple_comparison('lt')
le__Tuple_Tuple = _make_tuple_comparison('le')
gt__Tuple_Tuple = _make_tuple_comparison('gt')
ge__Tuple_Tuple = _make_tuple_comparison('ge')

def repr__Tuple(space, w_tuple):
    items = w_tuple.wrappeditems
    # XXX this is quite innefficient, still better than calling
    #     it via applevel
    if len(items) == 1:
        return space.wrap("(" + space.str_w(space.repr(items[0])) + ",)")
    return space.wrap("(" +
                 (", ".join([space.str_w(space.repr(item)) for item in items]))
                      + ")")

def hash__Tuple(space, w_tuple):
    return space.wrap(hash_tuple(space, w_tuple.wrappeditems))

@jit.look_inside_iff(lambda space, wrappeditems:
                     jit.isconstant(len(wrappeditems)) and
                     len(wrappeditems) < UNROLL_TUPLE_LIMIT)
def hash_tuple(space, wrappeditems):
    # this is the CPython 2.4 algorithm (changed from 2.3)
    mult = 1000003
    x = 0x345678
    z = len(wrappeditems)
    for w_item in wrappeditems:
        y = space.hash_w(w_item)
        x = (x ^ y) * mult
        z -= 1
        mult += 82520 + z + z
    x += 97531
    return intmask(x)

def getnewargs__Tuple(space, w_tuple):
    return space.newtuple([space.newtuple(w_tuple.wrappeditems)])

def tuple_count__Tuple_ANY(space, w_tuple, w_obj):
    count = 0
    for w_item in w_tuple.wrappeditems:
        if space.eq_w(w_item, w_obj):
            count += 1
    return space.wrap(count)

def tuple_index__Tuple_ANY_ANY_ANY(space, w_tuple, w_obj, w_start, w_stop):
    length = len(w_tuple.wrappeditems)
    start, stop = slicetype.unwrap_start_stop(space, length, w_start, w_stop)
    for i in range(start, min(stop, length)):
        w_item = w_tuple.wrappeditems[i]
        if space.eq_w(w_item, w_obj):
            return space.wrap(i)
    raise OperationError(space.w_ValueError,
                         space.wrap("tuple.index(x): x not in tuple"))

from pypy.objspace.std import tupletype
register_all(vars(), tupletype)
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.