diff options
author | Raymond Hettinger <python@rcn.com> | 2015-05-09 01:07:23 -0400 |
---|---|---|
committer | Raymond Hettinger <python@rcn.com> | 2015-05-09 01:07:23 -0400 |
commit | cd9193e561e7a6b99cde783822cb5ca082776632 (patch) | |
tree | fc645c00b105772837cf35f8651bff71a2d5243d /Lib/test/test_collections.py | |
parent | 9db297f70169d519464f8e5b5d6173e8a1b785d4 (diff) | |
download | cpython-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.py | 73 |
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))(), |