File: range.py

package info (click to toggle)
python-picklable-itertools 0.1.1-2
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 172 kB
  • sloc: python: 1,222; makefile: 3
file content (87 lines) | stat: -rw-r--r-- 2,757 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
import six.moves
from numbers import Integral
from .iter_dispatch import range_iterator

__all__ = ['xrange']


def _check_integral(value):
    if not isinstance(value, Integral):
        raise TypeError("'{}' object cannot be interpreted "
                        "as an integer".format(type(value).__name__))


class xrange(object):
    """A replacement for Python 3 `range()` (and Python 2 `xrange()`) that
    yields picklable iterators when iterated upon.
    """
    __slots__ = ['_start', '_stop', '_step']

    def __init__(self, *args):
        self._start = 0
        self._step = 1
        if len(args) == 0:
            raise TypeError("{} expected 1 arguments, got 0".format(
                self.__class__.__name__))
        elif len(args) == 1:
            self._stop = args[0]
            self._start = 0
        elif len(args) >= 2:
            self._start = args[0]
            self._stop = args[1]
        if len(args) == 3:
            self._step = args[2]
        if len(args) > 3:
            raise TypeError("{} expected at most 3 arguments, got {}".format(
                self.__class__.__name__, len(args)))
        _check_integral(self._start)
        _check_integral(self._stop)
        _check_integral(self._step)

    @property
    def start(self):
        return self._start

    @property
    def stop(self):
        return self._stop

    @property
    def step(self):
        return self._step

    def count(self, i):
        """rangeobject.count(value) -> integer -- return number of occurrences
        of value
        """
        if self._stop > self._start and self._step > 0:
            return int(self._start <= i < self._stop and
                       (i - self._start) % self._step == 0)
        elif self._stop < self._start and self._step < 0:
            return int(self._start >= i > self._stop and
                       (i - self._start) % self._step == 0)
        else:
            return False

    def index(self, i):
        """xrangeobject.index(value, [start, [stop]]) -> integer --
        return index of value.
        Raise ValueError if the value is not present.
        """
        if self.count(i) == 0:
            raise ValueError("{} is not in range".format(i))
        return (i - self._start) // self._step

    def __len__(self):
        return len(six.moves.xrange(self._start, self._stop, self._step))

    def __reduce__(self):
        return (self.__class__, (self.start, self.stop, self.step))

    def __iter__(self):
        return range_iterator(self)

    def __repr__(self):
        return (__name__.split('.')[0] + '.' + self.__class__.__name__ +
                (str((self.start, self.stop)) if self.step == 1 else
                 str((self.start, self.stop, self.step))))