bpo-36607: Eliminate RuntimeError raised by asyncio.all_tasks() (GH-1… · python/cpython@83abd96

GitHub

GitHub CopilotWrite better code with AI | MCP RegistryIntegrate external tools | ActionsAutomate any workflow | CodespacesInstant dev environments | IssuesPlan and track work | Code ReviewManage code changes | Code QualityEnforce quality at merge | Why GitHub | Marketplace | View all features | Enterprises | Small and medium teams | Startups | View all use cases | View all industries | View all solutions | AI | Software Development | DevOps | Security | View all topics | Customer stories | Events & webinars | Ebooks & reports | Business insights | Trust center | Partners | View all resources

Original file line numberDiff line numberDiff line change@@ -42,9 +42,22 @@ def all_tasks(loop=None):

4242"""Return a set of all tasks for the loop."""

4343ifloopisNone:

4444loop=events.get_running_loop()

45-# NB: set(_all_tasks) is required to protect

46-# from https://bugs.python.org/issue34970 bug

47-return {tfortinlist(_all_tasks)

45+# Looping over a WeakSet (_all_tasks) isn't safe as it can be updated from another

46+# thread while we do so. Therefore we cast it to list prior to filtering. The list

47+# cast itself requires iteration, so we repeat it several times ignoring

48+# RuntimeErrors (which are not very likely to occur). See issues 34970 and 36607 for

49+# details.

50+i=0

51+whileTrue:

52+try:

53+tasks=list(_all_tasks)

54+exceptRuntimeError:

55+i+=1

56+ifi>=1000:

57+raise

58+else:

59+break

60+return {tfortintasks

4861iffutures._get_loop(t) isloopandnott.done()}

49625063@@ -54,9 +67,22 @@ def _all_tasks_compat(loop=None):

5467# method.

5568ifloopisNone:

5669loop=events.get_event_loop()

57-# NB: set(_all_tasks) is required to protect

58-# from https://bugs.python.org/issue34970 bug

59-return {tfortinlist(_all_tasks) iffutures._get_loop(t) isloop}

70+# Looping over a WeakSet (_all_tasks) isn't safe as it can be updated from another

71+# thread while we do so. Therefore we cast it to list prior to filtering. The list

72+# cast itself requires iteration, so we repeat it several times ignoring

73+# RuntimeErrors (which are not very likely to occur). See issues 34970 and 36607 for

74+# details.

75+i=0

76+whileTrue:

77+try:

78+tasks=list(_all_tasks)

79+exceptRuntimeError:

80+i+=1

81+ifi>=1000:

82+raise

83+else:

84+break

85+return {tfortintasksiffutures._get_loop(t) isloop}

608661876288def_set_task_name(task, name):