Skip to content

Commit 1ac8f02

Browse files
authored
add , and _ operations (#4950)
* add `,` and `_` operations * add tests
1 parent c472990 commit 1ac8f02

File tree

3 files changed

+117
-19
lines changed

3 files changed

+117
-19
lines changed

reflex/vars/number.py

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -546,45 +546,45 @@ def __format__(self, format_spec: str) -> str:
546546
Raises:
547547
VarValueError: If the format specifier is not supported.
548548
"""
549+
from .sequence import (
550+
get_decimal_string_operation,
551+
get_decimal_string_separator_operation,
552+
)
553+
554+
separator = ""
555+
556+
if format_spec and format_spec[:1] == ",":
557+
separator = ","
558+
format_spec = format_spec[1:]
559+
elif format_spec and format_spec[:1] == "_":
560+
separator = "_"
561+
format_spec = format_spec[1:]
562+
549563
if (
550564
format_spec
551565
and format_spec[-1] == "f"
552566
and format_spec[0] == "."
553567
and format_spec[1:-1].isdigit()
554568
):
555569
how_many_decimals = int(format_spec[1:-1])
570+
return f"{get_decimal_string_operation(self, Var.create(how_many_decimals), Var.create(separator))}"
571+
572+
if not format_spec and separator:
556573
return (
557-
f"{get_decimal_string_operation(self, Var.create(how_many_decimals))}"
574+
f"{get_decimal_string_separator_operation(self, Var.create(separator))}"
558575
)
559576

560577
if format_spec:
561578
raise VarValueError(
562579
(
563-
"Unknown format code '{}' for object of type 'NumberVar'. It is only supported to use '.f' for float numbers."
580+
"Unknown format code '{}' for object of type 'NumberVar'. It is only supported to use ',', '_', and '.f' for float numbers."
564581
"If possible, use computed variables instead: https://reflex.dev/docs/vars/computed-vars/"
565582
).format(format_spec)
566583
)
567584

568585
return super().__format__(format_spec)
569586

570587

571-
@var_operation
572-
def get_decimal_string_operation(value: NumberVar, decimals: NumberVar):
573-
"""Get the decimal string of the number.
574-
575-
Args:
576-
value: The number.
577-
decimals: The number of decimals.
578-
579-
Returns:
580-
The decimal string of the number.
581-
"""
582-
return var_operation_return(
583-
js_expression=f"({value}.toFixed({decimals}))",
584-
var_type=str,
585-
)
586-
587-
588588
def binary_number_operation(
589589
func: Callable[[NumberVar, NumberVar], str],
590590
) -> Callable[[number_types, number_types], NumberVar]:

reflex/vars/sequence.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1202,6 +1202,43 @@ def string_replace_operation(
12021202
)
12031203

12041204

1205+
@var_operation
1206+
def get_decimal_string_separator_operation(value: NumberVar, separator: StringVar):
1207+
"""Get the decimal string separator.
1208+
1209+
Args:
1210+
value: The number.
1211+
separator: The separator.
1212+
1213+
Returns:
1214+
The decimal string separator.
1215+
"""
1216+
return var_operation_return(
1217+
js_expression=f"({value}.toLocaleString('en-US').replaceAll(',', {separator}))",
1218+
var_type=str,
1219+
)
1220+
1221+
1222+
@var_operation
1223+
def get_decimal_string_operation(
1224+
value: NumberVar, decimals: NumberVar, separator: StringVar
1225+
):
1226+
"""Get the decimal string of the number.
1227+
1228+
Args:
1229+
value: The number.
1230+
decimals: The number of decimals.
1231+
separator: The separator.
1232+
1233+
Returns:
1234+
The decimal string of the number.
1235+
"""
1236+
return var_operation_return(
1237+
js_expression=f"({value}.toLocaleString('en-US', ((decimals) => ({{minimumFractionDigits: decimals, maximumFractionDigits: decimals}}))({decimals})).replaceAll(',', {separator}))",
1238+
var_type=str,
1239+
)
1240+
1241+
12051242
# Compile regex for finding reflex var tags.
12061243
_decode_var_pattern_re = (
12071244
rf"{constants.REFLEX_VAR_OPENING_TAG}(.*?){constants.REFLEX_VAR_CLOSING_TAG}"

tests/integration/test_var_operations.py

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -665,6 +665,54 @@ def index():
665665
rx.foreach(VarOperationState.optional_dict_value, rx.text.span),
666666
id="optional_dict_value",
667667
),
668+
rx.box(
669+
rx.text.span(f"{rx.Var.create(13212312312.1231231)}"),
670+
id="float_format",
671+
),
672+
rx.box(
673+
rx.text.span(f"{rx.Var.create(13212312312.1231231):.0f}"),
674+
id="float_format_0f",
675+
),
676+
rx.box(
677+
rx.text.span(f"{rx.Var.create(13212312312.1231231):.1f}"),
678+
id="float_format_1f",
679+
),
680+
rx.box(
681+
rx.text.span(f"{rx.Var.create(13212312312.1231231):.2f}"),
682+
id="float_format_2f",
683+
),
684+
rx.box(
685+
rx.text.span(f"{rx.Var.create(13212312312.1231231):,}"),
686+
id="float_format_comma",
687+
),
688+
rx.box(
689+
rx.text.span(f"{rx.Var.create(13212312312.1231231):_}"),
690+
id="float_format_underscore",
691+
),
692+
rx.box(
693+
rx.text.span(f"{rx.Var.create(13212312312.1231231):,.0f}"),
694+
id="float_format_comma_0f",
695+
),
696+
rx.box(
697+
rx.text.span(f"{rx.Var.create(13212312312.1231231):,.1f}"),
698+
id="float_format_comma_1f",
699+
),
700+
rx.box(
701+
rx.text.span(f"{rx.Var.create(13212312312.1231231):,.2f}"),
702+
id="float_format_comma_2f",
703+
),
704+
rx.box(
705+
rx.text.span(f"{rx.Var.create(13212312312.1231231):_.0f}"),
706+
id="float_format_underscore_0f",
707+
),
708+
rx.box(
709+
rx.text.span(f"{rx.Var.create(13212312312.1231231):_.1f}"),
710+
id="float_format_underscore_1f",
711+
),
712+
rx.box(
713+
rx.text.span(f"{rx.Var.create(13212312312.1231231):_.2f}"),
714+
id="float_format_underscore_2f",
715+
),
668716
)
669717

670718

@@ -875,6 +923,19 @@ def test_var_operations(driver, var_operations: AppHarness):
875923
("str_in_foreach", "a b c d e f"),
876924
("str_var_in_foreach", "f i r s t"),
877925
("typed_dict_in_foreach", "Hello Alice33Hello Bob28"),
926+
# fstring operations
927+
("float_format", "13212312312.123123"),
928+
("float_format_0f", "13212312312"),
929+
("float_format_1f", "13212312312.1"),
930+
("float_format_2f", "13212312312.12"),
931+
("float_format_comma", "13,212,312,312.123"),
932+
("float_format_underscore", "13_212_312_312.123"),
933+
("float_format_comma_0f", "13,212,312,312"),
934+
("float_format_comma_1f", "13,212,312,312.1"),
935+
("float_format_comma_2f", "13,212,312,312.12"),
936+
("float_format_underscore_0f", "13_212_312_312"),
937+
("float_format_underscore_1f", "13_212_312_312.1"),
938+
("float_format_underscore_2f", "13_212_312_312.12"),
878939
]
879940

880941
for tag, expected in tests:

0 commit comments

Comments
 (0)