1def gen():
2    try:
3        yield 1
4    except ValueError as e:
5        print("got ValueError from upstream!", repr(e.args))
6    yield "str1"
7    raise TypeError
8
9def gen2():
10    print((yield from gen()))
11
12g = gen2()
13print(next(g))
14print(g.throw(ValueError))
15try:
16    print(next(g))
17except TypeError:
18    print("got TypeError from downstream!")
19
20# passing None as second argument to throw
21g = gen2()
22print(next(g))
23print(g.throw(ValueError, None))
24try:
25    print(next(g))
26except TypeError:
27    print("got TypeError from downstream!")
28
29# passing an exception instance as second argument to throw
30g = gen2()
31print(next(g))
32print(g.throw(ValueError, ValueError(123)))
33try:
34    print(next(g))
35except TypeError:
36    print("got TypeError from downstream!")
37
38# thrown value is caught and then generator returns normally
39def gen():
40    try:
41        yield 123
42    except ValueError:
43        print('ValueError')
44    # return normally after catching thrown exception
45def gen2():
46    yield from gen()
47    yield 789
48g = gen2()
49print(next(g))
50print(g.throw(ValueError))
51