Skip to content

ENG-9859 fix(state): preserve source function __dict__ and kwdefaults in _copy…#6725

Open
FarhanAliRaza wants to merge 4 commits into
reflex-dev:mainfrom
FarhanAliRaza:farhan/eng-9859-basestate_copy_fn-should-preserve-the-source-functions
Open

ENG-9859 fix(state): preserve source function __dict__ and kwdefaults in _copy…#6725
FarhanAliRaza wants to merge 4 commits into
reflex-dev:mainfrom
FarhanAliRaza:farhan/eng-9859-basestate_copy_fn-should-preserve-the-source-functions

Conversation

@FarhanAliRaza

Copy link
Copy Markdown
Contributor

…_fn (ENG-9859)

When the State metaclass pulls a computed-var getter or event handler in from a mixin, _copy_fn rebuilds the function via FunctionType, which drops the function's dict. Previously it hand-copied only the background-task and event-actions markers back on, silently losing any other attribute a framework or downstream user set on the getter/handler.

Copy the full dict onto the copy, which subsumes the per-marker copies and lets arbitrary markers (e.g. Reflex Enterprise's _auth tag) survive mixin inheritance. Also carry kwdefaults, which FunctionType likewise drops — without it a mixin handler with a keyword-only default raised TypeError when called through the subclass.

All Submissions:

  • Have you followed the guidelines stated in CONTRIBUTING.md file?
  • Have you checked to ensure there aren't any other open Pull Requests for the desired changed?

Type of change

Please delete options that are not relevant.

  • New feature (non-breaking change which adds functionality)

New Feature Submission:

  • Does your submission pass the tests?
  • Have you linted your code locally prior to submission?

Changes To Core Features:

  • Have you added an explanation of what your changes do and why you'd like us to include them?
  • Have you written new tests for your core changes, as applicable?
  • Have you successfully ran tests with your changes locally?

…_fn (ENG-9859)

When the State metaclass pulls a computed-var getter or event handler in
from a mixin, _copy_fn rebuilds the function via FunctionType, which drops
the function's __dict__. Previously it hand-copied only the background-task
and event-actions markers back on, silently losing any other attribute a
framework or downstream user set on the getter/handler.

Copy the full __dict__ onto the copy, which subsumes the per-marker copies
and lets arbitrary markers (e.g. Reflex Enterprise's _auth tag) survive
mixin inheritance. Also carry __kwdefaults__, which FunctionType likewise
drops — without it a mixin handler with a keyword-only default raised
TypeError when called through the subclass.
@FarhanAliRaza FarhanAliRaza requested a review from a team as a code owner July 9, 2026 09:05
@greptile-apps

greptile-apps Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes _copy_fn in BaseState so that functions copied from mixins retain their full __dict__ and __kwdefaults__, rather than only the handful of attributes that were previously hard-coded.

  • Replaces three separate setattr/object.__setattr__ calls with a single newfn.__dict__.update(fn.__dict__), which subsumes all prior per-marker copies and future-proofs arbitrary user-set attributes.
  • Adds newfn.__kwdefaults__ = fn.__kwdefaults__ to fix a TypeError that previously occurred when a mixin event handler declared keyword-only arguments with defaults.
  • Three new targeted tests verify __dict__ independence, __kwdefaults__ round-trip invocability, and the preserved background-task marker.

Confidence Score: 5/5

Safe to merge — the change is a narrow, well-tested fix to function copying in mixin inheritance with no impact on the broader state machinery.

The fix replaces explicit per-attribute copies with a clean __dict__.update plus __kwdefaults__ assignment. Both operations on a plain FunctionType are straightforward and carry no hidden side effects. The previous object.__setattr__ path for EVENT_ACTIONS_MARKER is fully subsumed by the new approach since function attributes live in __dict__. Three new tests directly exercise the changed code paths, including an end-to-end callable invocation of a handler with keyword-only defaults.

No files require special attention.

Important Files Changed

Filename Overview
reflex/state.py Replaces hand-copied attribute assignments in _copy_fn with __dict__.update + __kwdefaults__ copy, fixing mixin inheritance for arbitrary function attributes and keyword-only defaults.
tests/units/test_state.py Adds three new test cases covering: custom __dict__ attribute preservation, __kwdefaults__ preservation with a callable invocation check, and background-task marker preservation via mixin inheritance.
news/6725.bugfix.md New changelog entry describing the bugfix for mixin function attribute and kwdefault preservation.

Reviews (2): Last reviewed commit: "chore: shorten changelog entry" | Re-trigger Greptile

@codspeed-hq

codspeed-hq Bot commented Jul 9, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 26 untouched benchmarks
⏩ 8 skipped benchmarks1


Comparing FarhanAliRaza:farhan/eng-9859-basestate_copy_fn-should-preserve-the-source-functions (6fc747c) with main (948c619)2

Open in CodSpeed

Footnotes

  1. 8 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

  2. No successful run was found on main (3b97060) during the generation of this report, so 948c619 was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

@FarhanAliRaza FarhanAliRaza added reflex-enterprise For issues related to `reflex-enterprise` skip-changelog For doc/internal changes labels Jul 9, 2026

@masenf masenf left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good, needs a changelog entry

Comment thread tests/units/test_state.py Outdated
@FarhanAliRaza FarhanAliRaza requested a review from masenf July 10, 2026 15:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

reflex-enterprise For issues related to `reflex-enterprise` skip-changelog For doc/internal changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants