From afed5bf5e9434daa9d029473e06349320a580e65 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Piotr=20Ma=C5=9Blanka?= <piotr.maslanka@henrietta.com.pl>
Date: Sat, 25 Apr 2020 15:29:26 +0200
Subject: [PATCH] even, odd and count will now accept iterables, 2.7.12

---
 CHANGELOG.md                          |  2 +-
 satella/__init__.py                   |  2 +-
 satella/coding/sequences/iterators.py | 15 +++++++++------
 tests/test_coding/test_sequences.py   |  7 ++++++-
 4 files changed, 17 insertions(+), 9 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index f6a2d137..90edbe54 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,6 @@
 # v2.7.12
 
-* _TBA_
+* bugfix release: `even`, `odd` and `count` will now accept Iterables
 
 # v2.7.11
 
diff --git a/satella/__init__.py b/satella/__init__.py
index fa63300a..c2da2f54 100644
--- a/satella/__init__.py
+++ b/satella/__init__.py
@@ -1 +1 @@
-__version__ = '2.7.12_a1'
+__version__ = '2.7.12'
diff --git a/satella/coding/sequences/iterators.py b/satella/coding/sequences/iterators.py
index 3f87aedf..34e31033 100644
--- a/satella/coding/sequences/iterators.py
+++ b/satella/coding/sequences/iterators.py
@@ -3,10 +3,15 @@ import itertools
 import typing as tp
 import warnings
 
+from ..decorators import for_argument
+
 T, U = tp.TypeVar('T'), tp.TypeVar('U')
 
+IteratorOrIterable = tp.Union[tp.Iterator[T], tp.Iterable[T]]
+
 
-def even(sq: tp.Iterator[T]) -> tp.Iterator[T]:
+@for_argument(iter)
+def even(sq: IteratorOrIterable) -> tp.Iterator[T]:
     """
     Return only elements with even indices in this iterable (first element will be returned,
     as indices are counted from 0)
@@ -16,7 +21,8 @@ def even(sq: tp.Iterator[T]) -> tp.Iterator[T]:
         next(sq)
 
 
-def odd(sq: tp.Iterator[T]) -> tp.Iterator[T]:
+@for_argument(iter)
+def odd(sq: IteratorOrIterable) -> tp.Iterator[T]:
     """
     Return only elements with odd indices in this iterable.
     """
@@ -25,7 +31,7 @@ def odd(sq: tp.Iterator[T]) -> tp.Iterator[T]:
         yield next(sq)
 
 
-def count(sq: tp.Iterator, start: tp.Optional[int] = None, step: int = 1) -> tp.Iterator[int]:
+def count(sq: IteratorOrIterable, start: tp.Optional[int] = None, step: int = 1) -> tp.Iterator[int]:
     """
     Return a sequence of integers, for each entry in the sequence with provided step.
 
@@ -78,9 +84,6 @@ def is_instance(classes: tp.Union[tp.Tuple[type, ...], type]) -> tp.Callable[[ob
     return inner
 
 
-T = tp.TypeVar('T')
-
-IteratorOrIterable = tp.Union[tp.Iterator[T], tp.Iterable[T]]
 
 
 def other_sequence_no_longer_than(base_sequence: IteratorOrIterable,
diff --git a/tests/test_coding/test_sequences.py b/tests/test_coding/test_sequences.py
index 281cc994..753c0d8c 100644
--- a/tests/test_coding/test_sequences.py
+++ b/tests/test_coding/test_sequences.py
@@ -3,13 +3,18 @@ import unittest
 
 from satella.coding.sequences import choose, infinite_counter, take_n, is_instance, is_last, \
     add_next, half_product, skip_first, zip_shifted, stop_after, group_quantity, \
-    iter_dict_of_list, shift, other_sequence_no_longer_than, count
+    iter_dict_of_list, shift, other_sequence_no_longer_than, count, even, odd
 
 logger = logging.getLogger(__name__)
 
 
 class TestSequences(unittest.TestCase):
 
+    def test_even_and_odd(self):
+        a = [0, 1, 2, 3, 4, 5, 6]
+        self.assertEqual(list(even(a)), [0, 2, 4, 6])
+        self.assertEqual(list(odd(a)), [1, 3, 5])
+
     def test_count(self):
         self.assertEqual(list(count([None, None, None], 5, -2)), [5, 3, 1])
 
-- 
GitLab