<commit_before>from functools import reduce
import operator as op

from six import PY2
from toolz import peek

from zipline.utils.functional import foldr


if PY2:
    class range(object):
        """Lazy range object with constant time containment check.

        The arguments are the same as ``range``.
        """
        __slots__ = 'start', 'stop', 'step'

        def __init__(self, stop, *args):
            if len(args) > 2:
                raise TypeError(
                    'range takes at most 3 arguments (%d given)' % len(args)
                )

            if not args:
                self.start = 0
                self.stop = stop
                self.step = 1
            else:
                self.start = stop
                self.stop = args[0]
                try:
                    self.step = args[1]
                except IndexError:
                    self.step = 1

        def __iter__(self):
            n = self.start
            stop = self.stop
            step = self.step
            while n < stop:
                yield n
                n += step

        _ops = (
            (op.gt, op.ge),
            (op.le, op.lt),
        )

        def __contains__(self, other, _ops=_ops):
            start = self.start
            step = self.step
            cmp_start, cmp_stop = _ops[step > 0]
            return (
                cmp_start(start, other) and
                cmp_stop(other, self.stop) and
                (other - start) % step == 0
            )

        del _ops

        def __repr__(self):
            return '%s(%s, %s%s)' % (
                type(self).__name__,
                self.start,
                self.stop,
                (', ' + str(self.step)) if self.step != 1 else '',
            )

        def __hash__(self):
            return hash((type(self), self.start, self.stop, self.step))

        def __eq__(self, other):
            return reduce(
                getattr(self, attr) == getattr(other, attr)
                for attr in self.__slots__
            )
else:
    range = range


def from_tuple(tup):
    """Convert a tuple into a range with error handling.

    Parameters
    ----------
    tup : tuple (len 2 or 3)
        The tuple to turn into a range.

    Returns
    -------
    range : range
        The range from the tuple.

    Raises
    ------
    ValueError
        Raised when the tuple length is not 2 or 3.
    """
    if len(tup) not in (2, 3):
        raise ValueError(<commit_msg>TST: add tests for range.__eq__<commit_after>import operator as op

from six import PY2
from toolz import peek

from zipline.utils.functional import foldr


if PY2:
    class range(object):
        """Lazy range object with constant time containment check.

        The arguments are the same as ``range``.
        """
        __slots__ = 'start', 'stop', 'step'

        def __init__(self, stop, *args):
            if len(args) > 2:
                raise TypeError(
                    'range takes at most 3 arguments (%d given)' % len(args)
                )

            if not args:
                self.start = 0
                self.stop = stop
                self.step = 1
            else:
                self.start = stop
                self.stop = args[0]
                try:
                    self.step = args[1]
                except IndexError:
                    self.step = 1

        def __iter__(self):
            n = self.start
            stop = self.stop
            step = self.step
            while n < stop:
                yield n
                n += step

        _ops = (
            (op.gt, op.ge),
            (op.le, op.lt),
        )

        def __contains__(self, other, _ops=_ops):
            start = self.start
            step = self.step
            cmp_start, cmp_stop = _ops[step > 0]
            return (
                cmp_start(start, other) and
                cmp_stop(other, self.stop) and
                (other - start) % step == 0
            )

        del _ops

        def __repr__(self):
            return '%s(%s, %s%s)' % (
                type(self).__name__,
                self.start,
                self.stop,
                (', ' + str(self.step)) if self.step != 1 else '',
            )

        def __hash__(self):
            return hash((type(self), self.start, self.stop, self.step))

        def __eq__(self, other):
            """
            Examples
            --------
            >>> range(1) == range(1)
            True
            >>> range(0, 5, 2) == range(0, 5, 2)
            True
            >>> range(5, 0, -2) == range(5, 0, -2)
            True

            >>> range(1) == range(2)
            False
            >>> range(0, 5, 2) == range(0, 5, 3)
            False
            """
            return all(
                getattr(self, attr) == getattr(other, attr)
                for attr in self.__slots__
            )
else:
    range = range


def from_tuple(tup):
    """Convert a tuple into a range with error handling.

    Parameters
    ----------
    tup : tuple (len 2 or 3)
        The tuple to turn into a range.

    Returns
    -------
    range : range
        The range from the tuple.

    Raises
    ------
    ValueError
        Raised when the tuple length is not 2 or 3.
    """
    if len(tup) not in (2, 3):
        raise ValueError(
{'fraction_non_alphanumeric': 0.10633526443655392, 'fraction_numerical': 0.010839095496168941, 'mean_word_length': 1.1425140112089671, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 22, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1168220', 'n_tokens_mistral': 1577, 'n_tokens_neox': 1450, 'n_words': 459}