Skip to content

Commit

Permalink
add special handling for infinity and nan (#3943)
Browse files Browse the repository at this point in the history
* add special handling for infinity and nan

* use custom exception

* add test for inf and nan
  • Loading branch information
adhami3310 authored and masenf committed Sep 20, 2024
1 parent 45f5326 commit 6ae6698
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 2 deletions.
4 changes: 4 additions & 0 deletions reflex/utils/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,3 +107,7 @@ class EventHandlerShadowsBuiltInStateMethod(ReflexError, NameError):

class GeneratedCodeHasNoFunctionDefs(ReflexError):
"""Raised when refactored code generated with flexgen has no functions defined."""


class PrimitiveUnserializableToJSON(ReflexError, ValueError):
"""Raised when a primitive type is unserializable to JSON. Usually with NaN and Infinity."""
19 changes: 17 additions & 2 deletions reflex/vars/number.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import dataclasses
import json
import math
import sys
from typing import (
TYPE_CHECKING,
Expand All @@ -18,7 +19,7 @@
)

from reflex.constants.base import Dirs
from reflex.utils.exceptions import VarTypeError
from reflex.utils.exceptions import PrimitiveUnserializableToJSON, VarTypeError
from reflex.utils.imports import ImportDict, ImportVar

from .base import (
Expand Down Expand Up @@ -1040,7 +1041,14 @@ def json(self) -> str:
Returns:
The JSON representation of the var.
Raises:
PrimitiveUnserializableToJSON: If the var is unserializable to JSON.
"""
if math.isinf(self._var_value) or math.isnan(self._var_value):
raise PrimitiveUnserializableToJSON(
f"No valid JSON representation for {self}"
)
return json.dumps(self._var_value)

def __hash__(self) -> int:
Expand All @@ -1062,8 +1070,15 @@ def create(cls, value: float | int, _var_data: VarData | None = None):
Returns:
The number var.
"""
if math.isinf(value):
js_expr = "Infinity" if value > 0 else "-Infinity"
elif math.isnan(value):
js_expr = "NaN"
else:
js_expr = str(value)

return cls(
_js_expr=str(value),
_js_expr=js_expr,
_var_type=type(value),
_var_data=_var_data,
_var_value=value,
Expand Down
17 changes: 17 additions & 0 deletions tests/test_var.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from reflex.base import Base
from reflex.constants.base import REFLEX_VAR_CLOSING_TAG, REFLEX_VAR_OPENING_TAG
from reflex.state import BaseState
from reflex.utils.exceptions import PrimitiveUnserializableToJSON
from reflex.utils.imports import ImportVar
from reflex.vars import VarData
from reflex.vars.base import (
Expand Down Expand Up @@ -974,6 +975,22 @@ def test_index_operation():
assert str(array_var[0].to(NumberVar) + 9) == "([1, 2, 3, 4, 5].at(0) + 9)"


@pytest.mark.parametrize(
"var, expected_js",
[
(Var.create(float("inf")), "Infinity"),
(Var.create(-float("inf")), "-Infinity"),
(Var.create(float("nan")), "NaN"),
],
)
def test_inf_and_nan(var, expected_js):
assert str(var) == expected_js
assert isinstance(var, NumberVar)
assert isinstance(var, LiteralVar)
with pytest.raises(PrimitiveUnserializableToJSON):
var.json()


def test_array_operations():
array_var = LiteralArrayVar.create([1, 2, 3, 4, 5])

Expand Down

0 comments on commit 6ae6698

Please sign in to comment.