Bug report
Bug description:
A single synchronous generator on the stack hides the whole async call chain above it
Repro:
import asyncio
def page_ids(total):
for i in range(total):
if i == 100:
print(asyncio.format_call_graph())
return
yield i
def collect():
return list(page_ids(250))
async def fetch():
return collect()
async def main():
print('got', len(await fetch()), 'ids')
asyncio.run(main())
Actual output:
* Task(name='Task-1', id=0x103f78b90)
+ Call stack:
| File '/Users/timofeiivankov/cpython/repro.py', line 6, in generator page_ids()
Expected:
* Task(name='Task-1', id=0x103cd4b90)
+ Call stack:
| File '/Users/timofeiivankov/cpython/repro.py', line 6, in generator page_ids()
| File '/Users/timofeiivankov/cpython/repro.py', line 11, in collect()
| File '/Users/timofeiivankov/cpython/repro.py', line 14, in async fetch()
| File '/Users/timofeiivankov/cpython/repro.py', line 17, in async main()
Proposed fix: change is_async check
From: is_async = f.f_generator is not None to is_async = isinstance(f.f_generator, types.CoroutineType)
Have a fix ready for that
CPython versions tested on:
CPython main branch
Operating systems tested on:
macOS
Linked PRs
Bug report
Bug description:
A single synchronous generator on the stack hides the whole async call chain above it
Repro:
Actual output:
Expected:
Proposed fix: change
is_asynccheckFrom:
is_async = f.f_generator is not Nonetois_async = isinstance(f.f_generator, types.CoroutineType)Have a fix ready for that
CPython versions tested on:
CPython main branch
Operating systems tested on:
macOS
Linked PRs