Skip to content

Commit 24b214c

Browse files
committed
fix: preserve NaN through socket parse fallback instead of coercing to null
Swap bare NaN for a sentinel string before JSON.parse and revive it back to a real NaN so Python-side float(nan) round-trips to the frontend.
1 parent 86a1289 commit 24b214c

2 files changed

Lines changed: 11 additions & 5 deletions

File tree

packages/reflex-base/src/reflex_base/.templates/web/utils/state.js

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -437,19 +437,22 @@ const resolveSocket = (socket) => {
437437

438438
// Python's json.dumps emits bare Infinity/-Infinity/NaN tokens (invalid JSON).
439439
// Rewrite them outside string literals so JSON.parse accepts the payload.
440-
// 1e999 / -1e999 overflow to ±Infinity; NaN has no JSON literal so it becomes null.
440+
// 1e999 / -1e999 overflow to ±Infinity; NaN has no JSON literal, so it is
441+
// swapped for a sentinel string and revived back to NaN after parsing.
441442
// The alternation matches whole string literals first (passed through unchanged),
442443
// guaranteeing bare-token matches only land in numeric positions.
443-
const NON_FINITE_FLOAT_RE = /"(?:[^"\\]|\\.)*"|-?Infinity|NaN/g;
444+
const NAN_SENTINEL = "__reflex_nan__";
445+
const NON_FINITE_FLOAT_RE = /"(?:[^"\\]|\\.)*"|-?\bInfinity\b|\bNaN\b/g;
444446
const NON_FINITE_REPLACEMENTS = {
445447
Infinity: "1e999",
446448
"-Infinity": "-1e999",
447-
NaN: "null",
449+
NaN: `"${NAN_SENTINEL}"`,
448450
};
449451
const rewriteBareNonFiniteFloats = (str) =>
450452
str.replace(NON_FINITE_FLOAT_RE, (match) =>
451453
match[0] === '"' ? match : NON_FINITE_REPLACEMENTS[match],
452454
);
455+
const reviveNonFiniteFloats = (_k, v) => (v === NAN_SENTINEL ? NaN : v);
453456

454457
/**
455458
* Queue events to be processed and trigger processing of queue.
@@ -559,7 +562,10 @@ export const connect = async (
559562
return JSON.parse(str);
560563
} catch (e) {
561564
try {
562-
return JSON.parse(rewriteBareNonFiniteFloats(str));
565+
return JSON.parse(
566+
rewriteBareNonFiniteFloats(str),
567+
reviveNonFiniteFloats,
568+
);
563569
} catch (e2) {
564570
return false;
565571
}

tests/integration/test_computed_vars.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,7 @@ async def test_computed_vars(
232232

233233
special_floats = driver.find_element(By.ID, "special_floats")
234234
assert special_floats
235-
assert special_floats.text == "42.9, , Infinity, -Infinity"
235+
assert special_floats.text == "42.9, NaN, Infinity, -Infinity"
236236

237237
increment = driver.find_element(By.ID, "increment")
238238
assert increment.is_enabled()

0 commit comments

Comments
 (0)