This can be generalized to the problem of finding the origin of an arbitrary exception.
Use the traceback
module to inspect the stacktrace of your exception object.
Here is a previous answer on a similar subject.
Some example code:
g1 = genOne(6, 3) # The inputs are arbitrary numbers
try:
while True:
next(g1)
except:
exc_type, exc_value, exc_traceback = sys.exc_info()
print(traceback.extract_tb(exc_traceback)[-1])
Shell output:
> ./test.py
genOne: 0
genTwo: 0
genOne: 1
genTwo: 1
genOne: 2
genTwo: 2
genOne: 3
genTwo: 3
genOne: 4
('./test.py', 12, 'genOne', 'next(g2)')
Note that the [-1]
in the extract_tb()
call explicitly checks only the first lower level of the stacktrace. With the print you can see which element of that output you'd need to check (genOne
-> item index #2 in that list). In your particular example you'd probably want to check if the lowest level generator string genTwo
exists in any of the elements of the traceback.extract_tb(exc_traceback)
array.
Those hardcoded checks relying on internal code details are been frowned upon, especially since in your particular example you do not have control over their implementation.