Repository navigation
Conversation
[Medium impact] The PR appears safe to merge; the previous loading failure is fixed and no new actionable issues were found. SummaryRestores
No new actionable issues were found. The previous private-annotation finding is fixed. Reviews (5) · Last reviewed commit: "fix: resolve only the annotations that d..." · Reviewed by Greptile |
Merging this PR will not alter performance
|
Move the check from get_var_for_field into the state metaclass. resolve_annotations gets a keyword-only strict flag. With strict set, an annotation that names an undefined symbol re-raises the NameError, unless it is a ClassVar. BaseStateMeta sets strict only for the state's own namespace. Plain bases and components stay lenient. Field never sees an unresolved ForwardRef now, so the Optional unwrap in get_var_for_field, the BaseState._get_type_hints probe and the is_dataframe getattr patch are removed. Each annotation is evaluated on its own, so the error names the symbol of that var. Nested refs (the Python 3.14 form without the __future__ import) and backend vars raise too, as in 0.9.12.
Strict resolution ran on every annotation before _annotated_fields skipped the names that are not fields. A private attribute or a descriptor annotated with a symbol imported only under TYPE_CHECKING then raised NameError, and the state class failed to load. _annotated_fields now resolves each annotation after the private, descriptor and inherited-var checks, through a per-annotation _resolve_annotation helper. resolve_annotations uses the same helper and is lenient again, without the strict flag.
There was a problem hiding this comment.
1 issue found across 3 files (changes from recent commits).
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="packages/reflex-base/src/reflex_base/utils/types.py">
<violation number="1" location="packages/reflex-base/src/reflex_base/utils/types.py:1502">
P2: Qualified ClassVar annotations are not exempt from the new strict NameError path. `typing.ClassVar[MissingItem]` remains an unresolved forward reference whose text does not start with `ClassVar`, so state class creation raises instead of skipping this non-field; recognize qualified ClassVar forward references before re-raising.</violation>
</file>
Tip: Review your code locally with the cubic CLI to iterate faster.
View guided diff | Re-trigger cubic
| return _eval_type(value, base_globals, None, type_params=()) | ||
| return _eval_type(value, base_globals, None) | ||
| except NameError: | ||
| if strict and not is_classvar(value): |
There was a problem hiding this comment.
P2: Qualified ClassVar annotations are not exempt from the new strict NameError path. typing.ClassVar[MissingItem] remains an unresolved forward reference whose text does not start with ClassVar, so state class creation raises instead of skipping this non-field; recognize qualified ClassVar forward references before re-raising.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At packages/reflex-base/src/reflex_base/utils/types.py, line 1502:
<comment>Qualified ClassVar annotations are not exempt from the new strict NameError path. `typing.ClassVar[MissingItem]` remains an unresolved forward reference whose text does not start with `ClassVar`, so state class creation raises instead of skipping this non-field; recognize qualified ClassVar forward references before re-raising.</comment>
<file context>
@@ -1475,11 +1475,37 @@ def typehint_issubclass(
+ return _eval_type(value, base_globals, None, type_params=())
+ return _eval_type(value, base_globals, None)
+ except NameError:
+ if strict and not is_classvar(value):
+ raise
+ return value
</file context>
Closes #7488.
With
from __future__ import annotations, an undefined name in a state var annotation (for exampleitems: list[Item] = []whereItemis not defined) raisedTypeError: Unsupported type ForwardRef('list[Item]') for guess_typedeep inside var typing. 0.9.12 raisedNameError: name 'Item' is not defined, which names the missing symbol.This restores the
NameError, including for a var declared without a default (items: list[Item]), where the annotation is widened to Optional.is_dataframeinreflex_base/utils/types.pynow also tolerates an unresolvedForwardRef, which has no__name__. Added tests intests/units/test_state.pyandtests/units/utils/test_utils.pythat fail without the change.An independent review environment ran the full unit suite in chunks, not in one uninterrupted run (12,699 passed), on Python 3.11 to 3.13; I did not run it myself. I did not run lint or the full CI matrix locally; CI will.
News fragment included.
All Submissions:
Type of change