# HG changeset patch # User Paul Boddie # Date 1480629986 -3600 # Node ID 79c82d827bbe2cefa22606bfb682810ee8802731 # Parent 77890dd7214eeda3868eeaab4f5cea4e830f4b90 Fixed the xrange implementation, removing incorrect NO_END interpretation, adding start and end validation, adding string representations. Moved range from the iterable module to the span module. Added a test of ranges. diff -r 77890dd7214e -r 79c82d827bbe lib/__builtins__/__init__.py --- a/lib/__builtins__/__init__.py Thu Dec 01 21:23:11 2016 +0100 +++ b/lib/__builtins__/__init__.py Thu Dec 01 23:06:26 2016 +0100 @@ -75,7 +75,7 @@ from __builtins__.file import file from __builtins__.float import float from __builtins__.int import int -from __builtins__.span import xrange, slice +from __builtins__.span import range, slice, xrange from __builtins__.iterator import itemiterator from __builtins__.list import list from __builtins__.long import long @@ -92,7 +92,7 @@ from __builtins__.comparable import cmp, hash from __builtins__.identity import callable, help, id, isinstance, issubclass, repr from __builtins__.io import open, raw_input, print_, sysfile -from __builtins__.iterable import all, any, enumerate, filter, iter, len, map, max, min, range, reduce, reversed, sorted, sum, zip +from __builtins__.iterable import all, any, enumerate, filter, iter, len, map, max, min, reduce, reversed, sorted, sum, zip from __builtins__.namespace import dir, globals, locals, vars from __builtins__.numeric import abs, divmod, pow, round diff -r 77890dd7214e -r 79c82d827bbe lib/__builtins__/iterable.py --- a/lib/__builtins__/iterable.py Thu Dec 01 21:23:11 2016 +0100 +++ b/lib/__builtins__/iterable.py Thu Dec 01 23:06:26 2016 +0100 @@ -3,7 +3,7 @@ """ Iteration-related functions. -Copyright (C) 2015 Paul Boddie +Copyright (C) 2015, 2016 Paul Boddie This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -19,8 +19,6 @@ this program. If not, see . """ -from __builtins__.span import xrange - def all(iterable): pass def any(iterable): pass def enumerate(iterable): pass @@ -59,12 +57,6 @@ lowest = arg return lowest -def range(start_or_end, end=None, step=1): - - "Implementation of range." - - return list(xrange(start_or_end, end, step)) - def reduce(function, sequence, initial=None): pass def reversed(sequence): pass def sorted(iterable, cmp=None, key=None, reverse=False): pass diff -r 77890dd7214e -r 79c82d827bbe lib/__builtins__/span.py --- a/lib/__builtins__/span.py Thu Dec 01 21:23:11 2016 +0100 +++ b/lib/__builtins__/span.py Thu Dec 01 23:06:26 2016 +0100 @@ -3,7 +3,7 @@ """ Span-related objects. -Copyright (C) 2015 Paul Boddie +Copyright (C) 2015, 2016 Paul Boddie This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -19,7 +19,9 @@ this program. If not, see . """ -class xrange(object): +from __builtins__.sequence import _max, _min + +class xrange: "Implementation of xrange." @@ -37,8 +39,32 @@ self.end = end self.step = step + + # Constrain the end according to the start and step. + + if step > 0: + self.end = _max(self.start, self.end) + elif step < 0: + self.end = _min(self.start, self.end) + else: + raise ValueError(self.step) + self.current = self.start - self.limited = self.end is not xrange.NO_END + + def __str__(self): + + "Return a string representation." + + b = buffer([self.__name__, "(", self.start, ", ", self.end, ", ", self.step, ")"]) + return str(b) + + __repr__ = __str__ + + def __len__(self): + + "Return the length of the range." + + return (self.end - self.start) / self.step def __iter__(self): @@ -50,9 +76,8 @@ "Return the next item or raise a StopIteration exception." - if self.limited: - if self.step < 0 and self.current <= self.end or self.step > 0 and self.current >= self.end: - raise StopIteration() + if self.step < 0 and self.current <= self.end or self.step > 0 and self.current >= self.end: + raise StopIteration() current = self.current self.current += self.step @@ -68,4 +93,10 @@ get_using(xrange.__init__, self)(start_or_end, end, step) +def range(start_or_end, end=None, step=1): + + "Implementation of range." + + return list(xrange(start_or_end, end, step)) + # vim: tabstop=4 expandtab shiftwidth=4 diff -r 77890dd7214e -r 79c82d827bbe tests/range.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/range.py Thu Dec 01 23:06:26 2016 +0100 @@ -0,0 +1,18 @@ +l = range(0, 10) +print l # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] +print len(l) # 10 + +x = xrange(0, -10, -2) +print x # __builtins__.span.xrange(0, -10, -2) +print len(x) # 5 + +for i in x: + print i # 0 + # -2 + # -4 + # -6 + # -8 + +x = xrange(0, -10, 2) +print x # __builtins__.span.xrange(0, 0, 2) +print len(x) # 0