@@ -1227,19 +1227,30 @@ async def async_fn(arg1, arg2, *, task_status=trio.TASK_STATUS_IGNORED):
12271227 raise RuntimeError ("Nursery is closed to new arrivals" )
12281228 try :
12291229 self ._pending_starts += 1
1230- # `strict_exception_groups=False` prevents the implementation-detail
1231- # nursery from inheriting `strict_exception_groups=True` from the
1232- # `run` option, which would cause it to wrap a pre-started()
1233- # exception in an extra ExceptionGroup. See #2611.
1234- async with open_nursery (strict_exception_groups = False ) as old_nursery :
1235- task_status : _TaskStatus [Any ] = _TaskStatus (old_nursery , self )
1236- thunk = functools .partial (async_fn , task_status = task_status )
1237- task = GLOBAL_RUN_CONTEXT .runner .spawn_impl (
1238- thunk , args , old_nursery , name
1239- )
1240- task ._eventual_parent_nursery = self
1241- # Wait for either TaskStatus.started or an exception to
1242- # cancel this nursery:
1230+ # wrap internal nursery in try-except to unroll any exceptiongroups
1231+ # to avoid wrapping pre-started() exceptions in an extra ExceptionGroup.
1232+ # See #2611.
1233+ try :
1234+ # set strict_exception_groups = True to make sure we always unwrap
1235+ # *this* nursery's exceptiongroup
1236+ async with open_nursery (strict_exception_groups = True ) as old_nursery :
1237+ task_status : _TaskStatus [Any ] = _TaskStatus (old_nursery , self )
1238+ thunk = functools .partial (async_fn , task_status = task_status )
1239+ task = GLOBAL_RUN_CONTEXT .runner .spawn_impl (
1240+ thunk , args , old_nursery , name
1241+ )
1242+ task ._eventual_parent_nursery = self
1243+ # Wait for either TaskStatus.started or an exception to
1244+ # cancel this nursery:
1245+ except BaseExceptionGroup as exc :
1246+ if len (exc .exceptions ) == 1 :
1247+ raise exc .exceptions [0 ] from None
1248+ raise TrioInternalError (
1249+ "Internal nursery should not have multiple tasks. This can be "
1250+ 'caused by the user managing to access the "old" nursery in '
1251+ "`task_status` and spawning tasks in it."
1252+ ) from exc
1253+
12431254 # If we get here, then the child either got reparented or exited
12441255 # normally. The complicated logic is all in TaskStatus.started().
12451256 # (Any exceptions propagate directly out of the above.)
0 commit comments