asyncio.TaskGroup vs asyncio.gather() — when does structured concurrency actually matter?