Skip to content

Fast renderer: an effect may change its parent element's kwargs - #66

Closed
maartenbreddels wants to merge 1 commit into
masterfrom
fix/fast-effect-mutates-kwargs
Closed

maartenbreddels wants to merge 1 commit into
masterfrom
fix/fast-effect-mutates-kwargs

Conversation

@maartenbreddels

Copy link
Copy Markdown
Contributor

Part of the audit of REACTON_FAST=1 against the default renderer. This is one small PR per finding; this one is A2.

Problem

Effects of child components run while the fast reconciler walks the kwargs of their parent widget element. If such an effect changes those kwargs (for example parent_el.kwargs.update(box_style=...)), the fast renderer crashes with RuntimeError: dictionary changed size during iteration. The default renderer walks a copy of the kwargs (kwargs = el.kwargs.copy() at the start of _RenderContext._reconsolidate), so it does not crash.

Fix

The fast renderer now walks a shallow copy too. The same copy is used for the "unchanged element" check, so that check compares against what was actually reconciled.

Tests

  • test_child_effect_changes_parent_element_kwargs covers the create path and the update path.
  • On master it fails with REACTON_FAST=1 and passes with =0. With this PR it passes in both modes.
  • Full suite: 210 passed (default), 211 passed (fast).

🤖 Generated with Claude Code

Effects of child components run while the reconciler walks the kwargs of
their parent widget element. When such an effect changed those kwargs
(like adding a key), the fast renderer crashed with "dictionary changed
size during iteration". The default renderer walks a copy of the kwargs,
so it never had this problem; the fast renderer now does the same.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@maartenbreddels

Copy link
Copy Markdown
Contributor Author

Closing this. Changing an element's kwargs after it was rendered (here: from a child's effect, while the parent element is being reconciled) is not something reacton should support. Elements are immutable once rendered.

  • The default renderer does not crash, but it also ignores the change for that render, because it walks a copy of the kwargs.
  • So making the fast renderer tolerate it too would only hide a bug in user code. A crash at least tells the user something is wrong.
  • Legitimate uses change kwargs only while an element is being built, before it is rendered: reacton's own use_event, and solara's ConfirmationDialog. Those do not hit this.

We will note in benchmarks/README.md that changing kwargs after render is unsupported and may raise in fast mode. A clearer error for both renderers (for example read-only kwargs after render) could be a separate PR later.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant