From ebfa636b50cf939ae5c2ee12fcd39a3a3fa4c036 Mon Sep 17 00:00:00 2001 From: Kodi Arfer Date: Sun, 26 Feb 2017 10:18:20 -0800 Subject: [PATCH] Fix #1237: iterator-handling bug in `partition` Also, `partition` with n < 0 now raises an error. --- NEWS | 1 + hy/core/language.hy | 4 +++- tests/native_tests/core.hy | 14 +++++++++++--- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/NEWS b/NEWS index 7456e5b..f9cfc4c 100644 --- a/NEWS +++ b/NEWS @@ -13,6 +13,7 @@ Changes from 0.12.1 [ Bug Fixes ] * Shadowed comparison operators now use `and` instead of `&` for chained comparisons + * partition no longer prematurely exhausts input iterators Changes from 0.12.0 diff --git a/hy/core/language.hy b/hy/core/language.hy index ef80379..baf8d5d 100644 --- a/hy/core/language.hy +++ b/hy/core/language.hy @@ -371,7 +371,9 @@ more to skip elements, or less for a sliding window with overlap." (setv step (or step n) - slices (genexpr (itertools.islice coll start None step) [start (range n)])) + coll-clones (tee coll n) + slices (genexpr (islice (get coll-clones start) start None step) + [start (range n)])) (if (is fillvalue -sentinel) (apply zip slices) (apply zip-longest slices {"fillvalue" fillvalue}))) diff --git a/tests/native_tests/core.hy b/tests/native_tests/core.hy index 52fbb1e..7859700 100644 --- a/tests/native_tests/core.hy +++ b/tests/native_tests/core.hy @@ -455,9 +455,11 @@ ;; length 1 is valid (assert-equal (list (partition ten 1)) [(, 0) (, 1) (, 2) (, 3) (, 4) (, 5) (, 6) (, 7) (, 8) (, 9)]) - ;; tuples of length < 1 don't crash + ;; length 0 returns an empty sequence (assert-equal (list (partition ten 0)) []) - (assert-equal (list (partition ten -1)) []) + ;; negative length raises ValueError + (try (do (partition ten -1) (assert False)) + (except [ValueError])) ;; keep remainder with a fillvalue (assert-equal (list (partition ten 3 :fillvalue "x")) [(, 0 1 2) (, 3 4 5) (, 6 7 8) (, 9 "x" "x")]) @@ -466,7 +468,13 @@ [(, 0 1) (, 3 4) (, 6 7)]) ;; overlap with step < n (assert-equal (list (partition (range 5) 2 1)) - [(, 0 1) (, 1 2) (, 2 3) (, 3 4)])) + [(, 0 1) (, 1 2) (, 2 3) (, 3 4)]) + ;; tee the input as necessary + ;; https://github.com/hylang/hy/issues/1237 + (assert-equal (list (take 4 (partition (cycle [1 2 3]) 3))) + [(, 1 2 3) (, 1 2 3) (, 1 2 3) (, 1 2 3)]) + (assert-equal (list (partition (iter (range 10)))) + [(, 0 1) (, 2 3) (, 4 5) (, 6 7) (, 8 9)])) (defn test-pos [] "NATIVE: testing the pos? function"