Repository: pulumi/pulumi
Issue: [sdk/python] RuntimeError: Set changed size during iteration

A user reported hitting this failure in the Pulumi Python SDK:

```
error: Program failed with an unhandled exception:
    Traceback (most recent call last):
      File "/usr/local/bin/pulumi-language-python-exec", line 179, in <module>
        loop.run_until_complete(coro)
      File "/usr/lib/python3.9/asyncio/base_events.py", line 642, in run_until_complete
        return future.result()
      File "/usr/local/lib/python3.9/dist-packages/pulumi/runtime/stack.py", line 126, in run_in_stack
        await run_pulumi_func(lambda: Stack(func))
      File "/usr/local/lib/python3.9/dist-packages/pulumi/runtime/stack.py", line 51, in run_pulumi_func
        await wait_for_rpcs()
      File "/usr/local/lib/python3.9/dist-packages/pulumi/runtime/stack.py", line 73, in wait_for_rpcs
        await RPC_MANAGER.rpcs.pop()
      File "/usr/local/lib/python3.9/dist-packages/pulumi/runtime/rpc_manager.py", line 68, in rpc_wrapper
        result = await rpc
      File "/usr/local/lib/python3.9/dist-packages/pulumi/output.py", line 99, in is_value_known
        return await is_known and not contains_unknowns(await future)
      File "/usr/local/lib/python3.9/dist-packages/pulumi/output.py", line 99, in is_value_known
        return await is_known and not contains_unknowns(await future)
      File "/usr/local/lib/python3.9/dist-packages/pulumi/output.py", line 99, in is_value_known
        return await is_known and not contains_unknowns(await future)
      [Previous line repeated 34 more times]
      File "/usr/local/lib/python3.9/dist-packages/pulumi/runtime/resource.py", line 514, in do_register
        resolver = await prepare_resource(res, ty, custom, remote, props, opts, typ)
      File "/usr/local/lib/python3.9/dist-packages/pulumi/runtime/resource.py", line 109, in prepare_resource
        explicit_urn_dependencies = await _resolve_depends_on_urns(
      File "/usr/local/lib/python3.9/dist-packages/pulumi/runtime/resource.py", line 852, in _resolve_depends_on_urns
        return await _expand_dependencies(all_deps, from_resource)
      File "/usr/local/lib/python3.9/dist-packages/pulumi/runtime/resource.py", line 823, in _expand_dependencies
        await _add_dependency(urns, d, from_resource)
      File "/usr/local/lib/python3.9/dist-packages/pulumi/runtime/resource.py", line 809, in _add_dependency
        urn = await res.urn.future()
      File "/usr/local/lib/python3.9/dist-packages/pulumi/runtime/rpc_manager.py", line 68, in rpc_wrapper
        result = await rpc
      File "/usr/local/lib/python3.9/dist-packages/pulumi/output.py", line 99, in is_value_known
        return await is_known and not contains_unknowns(await future)
      File "/usr/local/lib/python3.9/dist-packages/pulumi/output.py", line 99, in is_value_known
        return await is_known and not contains_unknowns(await future)
      File "/usr/local/lib/python3.9/dist-packages/pulumi/output.py", line 124, in get_value
        val = await self._future
      File "/usr/local/lib/python3.9/dist-packages/pulumi/output.py", line 99, in is_value_known
        return await is_known and not contains_unknowns(await future)
      File "/usr/local/lib/python3.9/dist-packages/pulumi/output.py", line 99, in is_value_known
        return await is_known and not contains_unknowns(await future)
      File "/usr/local/lib/python3.9/dist-packages/pulumi/output.py", line 99, in is_value_known
        return await is_known and not contains_unknowns(await future)
      [Previous line repeated 3 more times]
      File "/usr/local/lib/python3.9/dist-packages/pulumi/runtime/resource.py", line 514, in do_register
        resolver = await prepare_resource(res, ty, custom, remote, props, opts, typ)
      File "/usr/local/lib/python3.9/dist-packages/pulumi/runtime/resource.py", line 109, in prepare_resource
        explicit_urn_dependencies = await _resolve_depends_on_urns(
      File "/usr/local/lib/python3.9/dist-packages/pulumi/runtime/resource.py", line 852, in _resolve_depends_on_urns
        return await _expand_dependencies(all_deps, from_resource)
      File "/usr/local/lib/python3.9/dist-packages/pulumi/runtime/resource.py", line 823, in _expand_dependencies
        await _add_dependency(urns, d, from_resource)
      File "/usr/local/lib/python3.9/dist-packages/pulumi/runtime/resource.py", line 804, in _add_dependency
        await _add_dependency(deps, child, from_resource)
      File "/usr/local/lib/python3.9/dist-packages/pulumi/runtime/resource.py", line 803, in _add_dependency
        for child in res._childResources:
    RuntimeError: Set changed size during iteration
```

Changed files:
sdk/python/lib/pulumi/runtime/resource.py

diff --git a/sdk/python/lib/pulumi/runtime/resource.py b/sdk/python/lib/pulumi/runtime/resource.py
index b2025eb26..a0e334e25 100644
--- a/sdk/python/lib/pulumi/runtime/resource.py
+++ b/sdk/python/lib/pulumi/runtime/resource.py
@@ -800,7 +800,12 @@ async def _add_dependency(
     from .. import ComponentResource  # pylint: disable=import-outside-toplevel
 
     if isinstance(res, ComponentResource) and not res._remote:
-        for child in res._childResources:
+        # Copy the set before iterating so that any concurrent child additions during
+        # the dependency computation (which is async, so can be interleaved with other
+        # operations including child resource construction which adds children to this
+        # resource) do not trigger modification during iteration errors.
+        child_resources = res._childResources.copy()
+        for child in child_resources:
             await _add_dependency(deps, child, from_resource)
         return