import asyncio
import sys

async def worker_task(delay, task_id):
    """A task that calls another function before hitting an await."""
    print(f"Task {task_id}: Starting work.")
    
    # Simulate a call to a deep helper function
    helper_result = deep_helper(task_id)
    
    await asyncio.sleep(delay) # The task yields control here
    
    # Simulate a bug only if helper_result is 1
    if helper_result == 1 and delay > 0.5:
        raise ValueError(f"Task {task_id} failed after wait.")
        
    print(f"Task {task_id}: Finished work.")
    return helper_result

def deep_helper(task_id):
    """A synchronous helper that would be lost in older tracebacks."""
    # In Python 3.13, a traceback from the ValueError would often only show 
    # the failure within worker_task, losing the context of where the error 
    # condition (helper_result == 1) originated.
    # In Python 3.14, the enhanced introspection attempts to preserve the full context.
    return task_id % 3

async def main():
    print(f"Running Asyncio Debug Example on {sys.version.split()[0]}")
    tasks = [
        worker_task(0.2, 1),
        worker_task(1.0, 2), # This task should fail (2 % 3 is not 1, but the point is the stack trace)
        worker_task(0.5, 3), 
    ]
    
    # Use asyncio.gather to run tasks concurrently
    results = await asyncio.gather(*tasks, return_exceptions=True)
    
    # The actual difference in 3.14 is the *output* of the error (verbose stack trace)
    for result in results:
        if isinstance(result, Exception):
            print(f"\n--- Exception Caught ---")
            print(result)
        else:
            print(f"Result: {result}")
            
# asyncio.run(main())
