1# case where generator doesn't intercept the thrown/injected exception
2def gen():
3    yield 123
4    yield 456
5
6g = gen()
7print(next(g))
8try:
9    g.throw(KeyError)
10except KeyError:
11    print('got KeyError from downstream!')
12
13# case where a thrown exception is caught and stops the generator
14def gen():
15    try:
16        yield 1
17        yield 2
18    except:
19        pass
20g = gen()
21print(next(g))
22try:
23    g.throw(ValueError)
24except StopIteration:
25    print('got StopIteration')
26
27# generator ignores a thrown GeneratorExit (this is allowed)
28def gen():
29    try:
30        yield 123
31    except GeneratorExit as e:
32        print('GeneratorExit', repr(e.args))
33    yield 456
34
35# thrown a class
36g = gen()
37print(next(g))
38print(g.throw(GeneratorExit))
39
40# thrown an instance
41g = gen()
42print(next(g))
43print(g.throw(GeneratorExit()))
44
45# thrown an instance with None as second arg
46g = gen()
47print(next(g))
48print(g.throw(GeneratorExit(), None))
49
50# thrown a class and instance
51g = gen()
52print(next(g))
53print(g.throw(GeneratorExit, GeneratorExit(123)))
54