Skip to content

Inconsistent behavior for duplicate inputs to asyncio.as_completed versus asyncio.gather() #107619

@Alc-Was-Taken

Description

@Alc-Was-Taken

Bug report

Checklist

  • I am confident this is a bug in CPython, not a bug in a third-party project
  • I have searched the CPython issue tracker, and am confident this bug has not been reported before

A clear and concise description of the bug

The provided code displays varying behavior. The asserts below illustrate the disparity between the current and expected outcomes. While the assert using asyncio.gather functions correctly as intended, the one utilizing asyncio.as_completed shows inconsistency between the first and second call.

If the behavior is considered to be correct as intended, it would be helpful to have a brief explanation, possibly in the functools.cache documentation, clarifying the reasons behind this decision.

import asyncio
from functools import cache

@cache
async def foo():
  await asyncio.sleep(1)
  return 1

async def main():
  # assert await asyncio.gather(foo(), foo(), foo()) == [1, 1, 1], 'The result is as expected, if this line is uncommented'

  # When the above statement is uncommented, the following assert passes for [1], but the expected result is [1, 1, 1]
  assert [await result for result in asyncio.as_completed([foo(), foo(), foo()])] == [1]

  info = foo.cache_info()
  assert info.hits == 2 and info.misses == 1, 'The result is as expected, but the outcome of the previous statement is inconsistent'

  # RuntimeError: cannot reuse already awaited coroutine
  # The expected result is [1, 1, 1] or [1] if the behavior above is justified
  assert [await result for result in asyncio.as_completed([foo(), foo(), foo()])] == [1, 1, 1]

asyncio.run(main())

Your environment

  • CPython versions tested on: Output from sys.version = 3.11.4
  • Operating system and architecture: Output from sys.platform = darwin and platform.architecture() = 64bit

Linked PRs

Metadata

Metadata

Assignees

Labels

Projects

Status

Done

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions