summaryrefslogtreecommitdiff
path: root/Lib/test/test_collections.py
diff options
context:
space:
mode:
authorRaymond Hettinger <python@rcn.com>2015-05-09 01:07:23 -0400
committerRaymond Hettinger <python@rcn.com>2015-05-09 01:07:23 -0400
commitcd9193e561e7a6b99cde783822cb5ca082776632 (patch)
treefc645c00b105772837cf35f8651bff71a2d5243d /Lib/test/test_collections.py
parent9db297f70169d519464f8e5b5d6173e8a1b785d4 (diff)
downloadcpython-cd9193e561e7a6b99cde783822cb5ca082776632.tar.gz
Issue #24018: Add a collections.Generator abstract base class.
Diffstat (limited to 'Lib/test/test_collections.py')
-rw-r--r--Lib/test/test_collections.py73
1 files changed, 72 insertions, 1 deletions
diff --git a/Lib/test/test_collections.py b/Lib/test/test_collections.py
index 958fb62824..5b2e81fd0c 100644
--- a/Lib/test/test_collections.py
+++ b/Lib/test/test_collections.py
@@ -14,7 +14,7 @@ import sys
from collections import UserDict
from collections import ChainMap
from collections import deque
-from collections.abc import Hashable, Iterable, Iterator
+from collections.abc import Hashable, Iterable, Iterator, Generator
from collections.abc import Sized, Container, Callable
from collections.abc import Set, MutableSet
from collections.abc import Mapping, MutableMapping, KeysView, ItemsView
@@ -522,6 +522,77 @@ class TestOneTrickPonyABCs(ABCTestCase):
return
self.assertNotIsInstance(NextOnly(), Iterator)
+ def test_Generator(self):
+ class NonGen1:
+ def __iter__(self): return self
+ def __next__(self): return None
+ def close(self): pass
+ def throw(self, typ, val=None, tb=None): pass
+
+ class NonGen2:
+ def __iter__(self): return self
+ def __next__(self): return None
+ def close(self): pass
+ def send(self, value): return value
+
+ class NonGen3:
+ def close(self): pass
+ def send(self, value): return value
+ def throw(self, typ, val=None, tb=None): pass
+
+ non_samples = [
+ None, 42, 3.14, 1j, b"", "", (), [], {}, set(),
+ iter(()), iter([]), NonGen1(), NonGen2(), NonGen3()]
+ for x in non_samples:
+ self.assertNotIsInstance(x, Generator)
+ self.assertFalse(issubclass(type(x), Generator), repr(type(x)))
+
+ class Gen:
+ def __iter__(self): return self
+ def __next__(self): return None
+ def close(self): pass
+ def send(self, value): return value
+ def throw(self, typ, val=None, tb=None): pass
+
+ class MinimalGen(Generator):
+ def send(self, value):
+ return value
+ def throw(self, typ, val=None, tb=None):
+ super().throw(typ, val, tb)
+
+ def gen():
+ yield 1
+
+ samples = [gen(), (lambda: (yield))(), Gen(), MinimalGen()]
+ for x in samples:
+ self.assertIsInstance(x, Iterator)
+ self.assertIsInstance(x, Generator)
+ self.assertTrue(issubclass(type(x), Generator), repr(type(x)))
+ self.validate_abstract_methods(Generator, 'send', 'throw')
+
+ # mixin tests
+ mgen = MinimalGen()
+ self.assertIs(mgen, iter(mgen))
+ self.assertIs(mgen.send(None), next(mgen))
+ self.assertEqual(2, mgen.send(2))
+ self.assertIsNone(mgen.close())
+ self.assertRaises(ValueError, mgen.throw, ValueError)
+ self.assertRaisesRegex(ValueError, "^huhu$",
+ mgen.throw, ValueError, ValueError("huhu"))
+ self.assertRaises(StopIteration, mgen.throw, StopIteration())
+
+ class FailOnClose(Generator):
+ def send(self, value): return value
+ def throw(self, *args): raise ValueError
+
+ self.assertRaises(ValueError, FailOnClose().close)
+
+ class IgnoreGeneratorExit(Generator):
+ def send(self, value): return value
+ def throw(self, *args): pass
+
+ self.assertRaises(RuntimeError, IgnoreGeneratorExit().close)
+
def test_Sized(self):
non_samples = [None, 42, 3.14, 1j,
(lambda: (yield))(),