[Twisted-Python] cursors

Kevin Turner acapnotic at twistedmatrix.com
Sat Nov 24 01:01:12 EST 2001


Someone, either Glyph or Tommi, mentioned that they wanted cursors a
while back.  "What's that," I asked; then thought "hm.  I could do
that."  But I didn't.  Only, now I did.  I think.

-- 
The moon is waxing gibbous, 58.9% illuminated, 8.2 days old.
-------------- next part --------------
# -*- Python -*-
# Kevin Turner <acapnotic at foobox.net>, November 23, 2001
# This code is in the Public Domain.

from UserList import UserList
import types

class CursoredList(UserList):
    _cursorlist = None

    def __init__(self, seq=None):
        UserList.__init__(self, seq)

    def setCursor(self):
        if self._cursorlist is None:
            self._cursorlist = []

        self._cursorlist[:] = range(len(self.data))
        self._cursorLen = len(self.data)

    def cursor(self, key):
        if self._cursorlist is None:
            return self.__getitem__(key)

        if isinstance(key, types.SliceType):
            start, stop, step = key.start, key.stop, key.step
            if not step:
                step = 1
            if start is None:
                start = 0
            elif start < 0:
                start = self._cursorLen + start

            if (stop is None) or (stop > self._cursorLen):
                stop = self._cursorLen
            elif stop < 0:
                start = self._cursorLen + stop

            result = []
            for i in xrange(start, stop, step):
                result.append(self.cursor(i))
            return result

        else:
            key = int(key)
            if key < 0:
                key = self._cursorLen + key
            assert(0 <= key < self._cursorLen)

            new_key = self._cursorlist.index(key)

            return self.__getitem__(new_key)

    def __setitem__(self, key, value):
        if (self._cursorlist is not None) \
           and isinstance(key, types.SliceType):

            self._cursorlist[key.start:key.stop] = [None] * len(value)

        if isinstance(key, types.SliceType):
            self.data[key.start:key.stop] = value
        else:
            self.data[key] = value

    def __getitem__(self, key):
        if isinstance(key, types.SliceType):
            return self.data[key.start:key.stop]
        else:
            return self.data[key]

    def __delitem__(self, key):
        if not isinstance(key, types.SliceType):
            key = slice(key, key+1)

        self.__setitem__(key, [])

    def __getslice__(self, start, stop):
        return self.__getitem__(slice(start, stop))

    def __setslice__(self, start, stop, value):
        return self.__setitem__(slice(start, stop), value)

    def __delslice__(self, start, stop):
        return self.__delitem__(slice(start, stop))

    def __iadd__(self, other):
        self.extend(other)
        return self

    def __imul__(self, multiplier):
        if self._cursorlist is not None:
            self._cursorlist.extend(([None] * len(self.data))
                                    * (multiplier-1))
        self.data[:] = self.data * multiplier

    def append(self, item):
        self[len(self):len(self)] = [item]

    def insert(self, i, item):
        self[i:i] = [item]

    def pop(self, i=-1):
        value = self[i]
        del self[i]
        return value

    def remove(self, item):
        i = self.index(item)
        del self[i]

    def reverse(self):
        self.data.reverse()
        if self._cursorlist is not None:
            self._cursorlist.reverse()

    def sort(self, cmpfunc=None):
        if self._cursorlist is not None:
            zipped = map(None, self.data, self._cursorlist)
            if cmpfunc:
                # The supplied cmpfunc won't be expecting the zipped list.
                cmpfunc_ = lambda x, y, c=cmpfunc: c(x[0], y[0])
                zipped.sort(cmpfunc_)
            else:
                zipped.sort()
            for i in range(len(zipped)):
                self.data[i], self._cursorlist[i] = zipped[i]
        else:
            self.data.sort()

    def extend(self, other):
        self[len(self):len(self)] = other


More information about the Twisted-Python mailing list