Treat None as an empty string in optional StringVar operations
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
- Bug fix (non-breaking change which fixes an issue)
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?
Problem
A str | None state var holding None crashed the page for every string operation that compiles to a native string method:
class S(rx.State):
m: str | None = None
rx.foreach(S.m.split(" "), rx.text) # TypeError: Cannot read properties of null (reading 'split')
split with a separator, strip / lstrip / rstrip, lower, upper, title, capitalize, contains, startswith, endswith, replace and * all threw, and the whole page fell into the error boundary. length, indexing, slicing and split() already read None as "" through the code point helpers, so the behaviour depended on which operation was used.
Fix
This takes option 1 from #7873 (treat None as "" everywhere), which is the rule #7800 already set for optional lists and sets.
StringVar gets the same _or_empty() view ArrayVar has: when the var type allows None, the operation reads (x ?? ""), typed without None. A string that cannot be None compiles exactly as before, with no guard. The operations that go through a null-safe helper (pyStrLength, pyStrAt, pyStrSlice, pyStrChars) are left unguarded.
Not changed: + / f-string concatenation and the comparison operators, which do not throw on null.
Tests
tests/units/reflex_base/vars/test_sequence.py: the exact compiled JS of every guarded operation for an optional and a required string, the result types, and the helper-backed operations that stay unguarded.tests/integration/tests_playwright/test_var_operations.py: the existing app renders the operations on an optional string holdingNoneand on one holding a value. Without the fix the page does not render at all (TypeError: Cannot read properties of nullin the browser).
Ran locally: tests/units (one unrelated browser-launch test in reflex_bench cannot start Chromium in my sandbox), the two string Playwright modules, ruff check, ruff format, and pyright on the changed files.
closes #7873
https://claude.ai/code/session_01LwJUCTCgM7D4Vj6H4dRWss
Generated by Claude Code