def gen():
    try:
        yield 1
    except ValueError as e:
        print("got ValueError from upstream!", repr(e.args))
    yield "str1"
    raise TypeError

def gen2():
    print((yield from gen()))

g = gen2()
print(next(g))
print(g.throw(ValueError))
try:
    print(next(g))
except TypeError:
    print("got TypeError from downstream!")

# passing None as second argument to throw
g = gen2()
print(next(g))
print(g.throw(ValueError, None))
try:
    print(next(g))
except TypeError:
    print("got TypeError from downstream!")

# passing an exception instance as second argument to throw
g = gen2()
print(next(g))
print(g.throw(ValueError, ValueError(123)))
try:
    print(next(g))
except TypeError:
    print("got TypeError from downstream!")

def gen():
    try:
        yield 1
    except ValueError as e:
        print("got ValueError from upstream!", repr(e.args))
    yield "str1"
    raise TypeError

def gen2():
    print((yield from gen()))

g = gen2()
print(next(g))
print(g.throw(ValueError))
try:
    print(next(g))
except TypeError:
    print("got TypeError from downstream!")

# passing None as second argument to throw
g = gen2()
print(next(g))
print(g.throw(ValueError, None))
try:
    print(next(g))
except TypeError:
    print("got TypeError from downstream!")

# passing an exception instance as second argument to throw
g = gen2()
print(next(g))
print(g.throw(ValueError, ValueError(123)))
try:
    print(next(g))
except TypeError:
    print("got TypeError from downstream!")

# thrown value is caught and then generator returns normally
def gen():
    try:
        yield 123
    except ValueError:
        print('ValueError')
    # return normally after catching thrown exception
def gen2():
    yield from gen()
    yield 789
g = gen2()
print(next(g))
print(g.throw(ValueError))

Add test for throw into yield-from with normal return.
tests/basics: Add test for throw into yield-from with normal return.

This test was found by missing coverage of a branch in py/nativeglue.c.

  def gen():
      try:
          yield 1
      except ValueError as e:
          print("got ValueError from upstream!", repr(e.args))
      yield "str1"
      raise TypeError
  
  def gen2():
      print((yield from gen()))
  
  g = gen2()
  print(next(g))
  print(g.throw(ValueError))
  try:
      print(next(g))
  except TypeError:
      print("got TypeError from downstream!")
  
  # passing None as second argument to throw
  g = gen2()
  print(next(g))
  print(g.throw(ValueError, None))
  try:
      print(next(g))
  except TypeError:
      print("got TypeError from downstream!")
  
  # passing an exception instance as second argument to throw
  g = gen2()
  print(next(g))
  print(g.throw(ValueError, ValueError(123)))
  try:
      print(next(g))
  except TypeError:
      print("got TypeError from downstream!")
  
+ # thrown value is caught and then generator returns normally
+ def gen():
+     try:
+         yield 123
+     except ValueError:
+         print('ValueError')
+     # return normally after catching thrown exception
+ def gen2():
+     yield from gen()
+     yield 789
+ g = gen2()
+ print(next(g))
+ print(g.throw(ValueError))
+ 
Add test for throw into yield-from with normal return.
## Code Before:
def gen():
    try:
        yield 1
    except ValueError as e:
        print("got ValueError from upstream!", repr(e.args))
    yield "str1"
    raise TypeError

def gen2():
    print((yield from gen()))

g = gen2()
print(next(g))
print(g.throw(ValueError))
try:
    print(next(g))
except TypeError:
    print("got TypeError from downstream!")

# passing None as second argument to throw
g = gen2()
print(next(g))
print(g.throw(ValueError, None))
try:
    print(next(g))
except TypeError:
    print("got TypeError from downstream!")

# passing an exception instance as second argument to throw
g = gen2()
print(next(g))
print(g.throw(ValueError, ValueError(123)))
try:
    print(next(g))
except TypeError:
    print("got TypeError from downstream!")

## Instruction:
Add test for throw into yield-from with normal return.
## Code After:
def gen():
    try:
        yield 1
    except ValueError as e:
        print("got ValueError from upstream!", repr(e.args))
    yield "str1"
    raise TypeError

def gen2():
    print((yield from gen()))

g = gen2()
print(next(g))
print(g.throw(ValueError))
try:
    print(next(g))
except TypeError:
    print("got TypeError from downstream!")

# passing None as second argument to throw
g = gen2()
print(next(g))
print(g.throw(ValueError, None))
try:
    print(next(g))
except TypeError:
    print("got TypeError from downstream!")

# passing an exception instance as second argument to throw
g = gen2()
print(next(g))
print(g.throw(ValueError, ValueError(123)))
try:
    print(next(g))
except TypeError:
    print("got TypeError from downstream!")

# thrown value is caught and then generator returns normally
def gen():
    try:
        yield 123
    except ValueError:
        print('ValueError')
    # return normally after catching thrown exception
def gen2():
    yield from gen()
    yield 789
g = gen2()
print(next(g))
print(g.throw(ValueError))
