Skip to content

Commit 953f336

Browse files
adhami3310masenfAlek99Manas1820cool-storm
committed
fully migrate vars into new system (#3743)
* fully migrate vars into new system * i hate rufffff (no i don't) * fix silly pright issues (except colormode and state) * remove all instances of Var.create * create immutable callable var and get rid of more base vars * implement hash for all functions * get reflex-web to compile * get it to compile reflex-web successfully * fix tests * fix pyi * use override from typing_extension * put plotly inside of a catch * dicts are unusable sadly * fix silly mistake * overload equals to special case immutable var * improve test_cond * solve more CI issues, down to 94 failures * down to 20 errors * down to 13 errors * pass all testcases * fix pyright issues * reorder things * use get origin more * use fixed_type logic * various optimizations * go back to passing test cases * use less boilerplate * remove unnecessary print message * remove weird comment * add test for html issue * add type ignore * fix another silly issue * override get all var data for var operations call * make integration tests pass * fix immutable call var * better logic for finding parent class * use even better logic for finding state wrt computedvar * only choose the ones that are defined in the same module * small dict to large dict * [REF-3591] Remove chakra-related files from immutable vars PR (#3821) * Add comments to html metadata component (#3731) * fix: add verification for path /404 (#3723) Co-authored-by: coolstorm <[email protected]> * Use the new state name when setting `is_hydrated` to false (#3738) * Use `._is_mutable()` to account for parent state proxy (#3739) When a parent state proxy is set, also allow child StateProxy._self_mutable to override the parent's `_is_mutable()`. * bump to 0.5.9 (#3746) * add message when installing requirements.txt is needed for chosen template during init (#3750) * #3752 bugfix add domain for XAxis (#3764) * fix appharness app_source typing (#3777) * fix import clash between connectionToaster and hooks.useState (#3749) * use different registry when in china, fixes #3700 (#3702) * do not reload compilation if using local app in AppHarness (#3790) * do not reload if using local app * Update reflex/testing.py Co-authored-by: Masen Furer <[email protected]> --------- Co-authored-by: Masen Furer <[email protected]> * Bump memory on relevant actions (#3781) Co-authored-by: Alek Petuskey <[email protected]> * [REF-3334] Validate Toast Props (#3793) * [REF-3536][REF-3537][REF-3541] Move chakra components into its repo(reflex-chakra) (#3798) * fix get_uuid_string_var (#3795) * minor State cleanup (#3768) * Fix code wrap in markdown (#3755) --------- Co-authored-by: Alek Petuskey <[email protected]> Co-authored-by: Manas Gupta <[email protected]> Co-authored-by: coolstorm <[email protected]> Co-authored-by: Thomas Brandého <[email protected]> Co-authored-by: Shubhankar Dimri <[email protected]> Co-authored-by: benedikt-bartscher <[email protected]> Co-authored-by: Khaleel Al-Adhami <[email protected]> Co-authored-by: Alek Petuskey <[email protected]> Co-authored-by: Elijah Ahianyo <[email protected]> * pyproject.toml: bump to 0.6.0a1 * pyproject.toml: depend on reflex-chakra>=0.6.0a New Var system support in reflex-chakra 0.6.0a1 * poetry.lock: relock dependencies * integration: bump listening timeout to 1200 seconds * integration: bump listening timeout to 1800 seconds * Use cached_var_no_lock to avoid ImmutableVar deadlocks (#3835) * Use cached_var_no_lock to avoid ImmutableVar deadlocks ImmutableVar subclasses will always return the same value for a _var_name or _get_all_var_data so there is no need to use a per-class lock to protect a cached attribute on an instance, and doing so actually is observed to cause deadlocks when a particular _cached_var_name creates new LiteralVar instances and attempts to serialize them. * remove unused module global --------- Co-authored-by: Masen Furer <[email protected]> Co-authored-by: Alek Petuskey <[email protected]> Co-authored-by: Manas Gupta <[email protected]> Co-authored-by: coolstorm <[email protected]> Co-authored-by: Thomas Brandého <[email protected]> Co-authored-by: Shubhankar Dimri <[email protected]> Co-authored-by: benedikt-bartscher <[email protected]> Co-authored-by: Alek Petuskey <[email protected]> Co-authored-by: Elijah Ahianyo <[email protected]>
1 parent 503163b commit 953f336

File tree

189 files changed

+11534
-14807
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

189 files changed

+11534
-14807
lines changed

integration/test_form_submit.py

+2
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,8 @@ async def get_form_data():
272272

273273
form_data = format.collect_form_dict_names(form_data)
274274

275+
print(form_data)
276+
275277
assert form_data["name_input"] == "foo"
276278
assert form_data["pin_input"] == pin_values
277279
assert form_data["number_input"] == "-3"

integration/test_tailwind.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ def test_tailwind_app(tailwind_app: AppHarness, tailwind_disabled: bool):
109109
assert len(paragraphs) == 3
110110
for p in paragraphs:
111111
assert tailwind_app.poll_for_content(p, exp_not_equal="") == PARAGRAPH_TEXT
112-
assert p.value_of_css_property("font-family") == "monospace"
112+
assert p.value_of_css_property("font-family") == '"monospace"'
113113
if tailwind_disabled:
114114
# expect default color, not "text-red-500" from tailwind utility class
115115
assert p.value_of_css_property("color") not in TEXT_RED_500_COLOR

integration/test_var_operations.py

+13-10
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ def VarOperations():
1717
import reflex_chakra as rc
1818

1919
import reflex as rx
20+
from reflex.ivars.base import LiteralVar
21+
from reflex.ivars.sequence import ArrayVar
2022

2123
class VarOperationState(rx.State):
2224
int_var1: int = 10
@@ -31,8 +33,8 @@ class VarOperationState(rx.State):
3133
str_var2: str = "second"
3234
str_var3: str = "ThIrD"
3335
str_var4: str = "a long string"
34-
dict1: Dict = {1: 2}
35-
dict2: Dict = {3: 4}
36+
dict1: Dict[int, int] = {1: 2}
37+
dict2: Dict[int, int] = {3: 4}
3638
html_str: str = "<div>hello</div>"
3739

3840
app = rx.App(state=rx.State)
@@ -549,29 +551,29 @@ def index():
549551
"second",
550552
query=[VarOperationState.str_var2],
551553
),
552-
rx.text(rx.Var.range(2, 5).join(","), id="list_join_range1"),
553-
rx.text(rx.Var.range(2, 10, 2).join(","), id="list_join_range2"),
554-
rx.text(rx.Var.range(5, 0, -1).join(","), id="list_join_range3"),
555-
rx.text(rx.Var.range(0, 3).join(","), id="list_join_range4"),
554+
rx.text(ArrayVar.range(2, 5).join(","), id="list_join_range1"),
555+
rx.text(ArrayVar.range(2, 10, 2).join(","), id="list_join_range2"),
556+
rx.text(ArrayVar.range(5, 0, -1).join(","), id="list_join_range3"),
557+
rx.text(ArrayVar.range(0, 3).join(","), id="list_join_range4"),
556558
rx.box(
557559
rx.foreach(
558-
rx.Var.range(0, 2),
560+
ArrayVar.range(0, 2),
559561
lambda x: rx.text(VarOperationState.list1[x], as_="p"),
560562
),
561563
id="foreach_list_arg",
562564
),
563565
rx.box(
564566
rx.foreach(
565-
rx.Var.range(0, 2),
567+
ArrayVar.range(0, 2),
566568
lambda x, ix: rx.text(VarOperationState.list1[ix], as_="p"),
567569
),
568570
id="foreach_list_ix",
569571
),
570572
rx.box(
571573
rx.foreach(
572-
rx.Var.create_safe(list(range(0, 3))).to(List[int]),
574+
LiteralVar.create(list(range(0, 3))).to(ArrayVar, List[int]),
573575
lambda x: rx.foreach(
574-
rx.Var.range(x),
576+
ArrayVar.range(x),
575577
lambda y: rx.text(VarOperationState.list1[y], as_="p"),
576578
),
577579
),
@@ -785,6 +787,7 @@ def test_var_operations(driver, var_operations: AppHarness):
785787
]
786788

787789
for tag, expected in tests:
790+
print(tag)
788791
assert driver.find_element(By.ID, tag).text == expected
789792

790793
# Highlight component with var query (does not plumb ID)

poetry.lock

+9-9
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.poetry]
22
name = "reflex"
3-
version = "0.5.9"
3+
version = "0.6.0a1"
44
description = "Web apps in pure Python."
55
license = "Apache-2.0"
66
authors = [
@@ -61,7 +61,7 @@ httpx = ">=0.25.1,<1.0"
6161
twine = ">=4.0.0,<6.0"
6262
tomlkit = ">=0.12.4,<1.0"
6363
lazy_loader = ">=0.4"
64-
reflex-chakra = ">=0.1.1a1,<0.6"
64+
reflex-chakra = ">=0.6.0a"
6565

6666
[tool.poetry.group.dev.dependencies]
6767
pytest = ">=7.1.2,<8.0"

reflex/__init__.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -324,7 +324,7 @@
324324
"style": ["Style", "toggle_color_mode"],
325325
"utils.imports": ["ImportVar"],
326326
"utils.serializers": ["serializer"],
327-
"vars": ["cached_var", "Var"],
327+
"vars": ["Var"],
328328
}
329329

330330
_SUBMODULES: set[str] = {
@@ -338,6 +338,7 @@
338338
"testing",
339339
"utils",
340340
"vars",
341+
"ivars",
341342
"config",
342343
"compiler",
343344
}

reflex/__init__.pyi

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ from . import compiler as compiler
1212
from . import components as components
1313
from . import config as config
1414
from . import event as event
15+
from . import ivars as ivars
1516
from . import model as model
1617
from . import style as style
1718
from . import testing as testing
@@ -189,7 +190,6 @@ from .style import toggle_color_mode as toggle_color_mode
189190
from .utils.imports import ImportVar as ImportVar
190191
from .utils.serializers import serializer as serializer
191192
from .vars import Var as Var
192-
from .vars import cached_var as cached_var
193193

194194
del compat
195195
RADIX_THEMES_MAPPING: dict

reflex/app.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -465,7 +465,7 @@ def _generate_component(component: Component | ComponentCallable) -> Component:
465465
raise
466466
except TypeError as e:
467467
message = str(e)
468-
if "BaseVar" in message or "ComputedVar" in message:
468+
if "Var" in message:
469469
raise VarOperationTypeError(
470470
"You may be trying to use an invalid Python function on a state var. "
471471
"When referencing a var inside your render code, only limited var operations are supported. "
@@ -1128,6 +1128,7 @@ def _process_background(
11281128
Task if the event was backgroundable, otherwise None
11291129
"""
11301130
substate, handler = state._get_event_handler(event)
1131+
11311132
if not handler.is_background:
11321133
return None
11331134

reflex/base.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -110,14 +110,15 @@ def add_field(cls, var: Any, default_value: Any):
110110
var: The variable to add a pydantic field for.
111111
default_value: The default value of the field
112112
"""
113+
var_name = var._var_name.split(".")[-1]
113114
new_field = ModelField.infer(
114-
name=var._var_name,
115+
name=var_name,
115116
value=default_value,
116117
annotation=var._var_type,
117118
class_validators=None,
118119
config=cls.__config__, # type: ignore
119120
)
120-
cls.__fields__.update({var._var_name: new_field})
121+
cls.__fields__.update({var_name: new_field})
121122

122123
def get_value(self, key: str) -> Any:
123124
"""Get the value of a field.

reflex/compiler/compiler.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
StatefulComponent,
1919
)
2020
from reflex.config import get_config
21+
from reflex.ivars.base import ImmutableVar
2122
from reflex.state import BaseState
2223
from reflex.style import SYSTEM_COLOR_MODE
2324
from reflex.utils.exec import is_prod_mode
@@ -81,7 +82,7 @@ def _compile_contexts(state: Optional[Type[BaseState]], theme: Component | None)
8182
The compiled context file.
8283
"""
8384
appearance = getattr(theme, "appearance", None)
84-
if appearance is None or Var.create_safe(appearance)._var_name == "inherit":
85+
if appearance is None or str(ImmutableVar.create_safe(appearance)) == "inherit":
8586
appearance = SYSTEM_COLOR_MODE
8687

8788
last_compiled_time = str(datetime.now())

reflex/components/base/app_wrap.py

+2-4
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
from reflex.components.base.fragment import Fragment
44
from reflex.components.component import Component
5-
from reflex.vars import Var
5+
from reflex.ivars.base import ImmutableVar
66

77

88
class AppWrap(Fragment):
@@ -15,6 +15,4 @@ def create(cls) -> Component:
1515
Returns:
1616
A new AppWrap component containing {children}.
1717
"""
18-
return super().create(
19-
Var.create("{children}", _var_is_local=False, _var_is_string=False)
20-
)
18+
return super().create(ImmutableVar.create("children"))

reflex/components/base/app_wrap.pyi

+16-26
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ from typing import Any, Callable, Dict, Optional, Union, overload
88
from reflex.components.base.fragment import Fragment
99
from reflex.event import EventHandler, EventSpec
1010
from reflex.style import Style
11-
from reflex.vars import BaseVar, Var
11+
from reflex.vars import Var
1212

1313
class AppWrap(Fragment):
1414
@overload
@@ -22,50 +22,40 @@ class AppWrap(Fragment):
2222
class_name: Optional[Any] = None,
2323
autofocus: Optional[bool] = None,
2424
custom_attrs: Optional[Dict[str, Union[Var, str]]] = None,
25-
on_blur: Optional[
26-
Union[EventHandler, EventSpec, list, Callable, BaseVar]
27-
] = None,
28-
on_click: Optional[
29-
Union[EventHandler, EventSpec, list, Callable, BaseVar]
30-
] = None,
25+
on_blur: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
26+
on_click: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
3127
on_context_menu: Optional[
32-
Union[EventHandler, EventSpec, list, Callable, BaseVar]
28+
Union[EventHandler, EventSpec, list, Callable, Var]
3329
] = None,
3430
on_double_click: Optional[
35-
Union[EventHandler, EventSpec, list, Callable, BaseVar]
36-
] = None,
37-
on_focus: Optional[
38-
Union[EventHandler, EventSpec, list, Callable, BaseVar]
39-
] = None,
40-
on_mount: Optional[
41-
Union[EventHandler, EventSpec, list, Callable, BaseVar]
31+
Union[EventHandler, EventSpec, list, Callable, Var]
4232
] = None,
33+
on_focus: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
34+
on_mount: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
4335
on_mouse_down: Optional[
44-
Union[EventHandler, EventSpec, list, Callable, BaseVar]
36+
Union[EventHandler, EventSpec, list, Callable, Var]
4537
] = None,
4638
on_mouse_enter: Optional[
47-
Union[EventHandler, EventSpec, list, Callable, BaseVar]
39+
Union[EventHandler, EventSpec, list, Callable, Var]
4840
] = None,
4941
on_mouse_leave: Optional[
50-
Union[EventHandler, EventSpec, list, Callable, BaseVar]
42+
Union[EventHandler, EventSpec, list, Callable, Var]
5143
] = None,
5244
on_mouse_move: Optional[
53-
Union[EventHandler, EventSpec, list, Callable, BaseVar]
45+
Union[EventHandler, EventSpec, list, Callable, Var]
5446
] = None,
5547
on_mouse_out: Optional[
56-
Union[EventHandler, EventSpec, list, Callable, BaseVar]
48+
Union[EventHandler, EventSpec, list, Callable, Var]
5749
] = None,
5850
on_mouse_over: Optional[
59-
Union[EventHandler, EventSpec, list, Callable, BaseVar]
51+
Union[EventHandler, EventSpec, list, Callable, Var]
6052
] = None,
6153
on_mouse_up: Optional[
62-
Union[EventHandler, EventSpec, list, Callable, BaseVar]
63-
] = None,
64-
on_scroll: Optional[
65-
Union[EventHandler, EventSpec, list, Callable, BaseVar]
54+
Union[EventHandler, EventSpec, list, Callable, Var]
6655
] = None,
56+
on_scroll: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
6757
on_unmount: Optional[
68-
Union[EventHandler, EventSpec, list, Callable, BaseVar]
58+
Union[EventHandler, EventSpec, list, Callable, Var]
6959
] = None,
7060
**props,
7161
) -> "AppWrap":

reflex/components/base/bare.py

+7-2
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,14 @@
77
from reflex.components.component import Component
88
from reflex.components.tags import Tag
99
from reflex.components.tags.tagless import Tagless
10+
from reflex.ivars.base import ImmutableVar
1011
from reflex.vars import Var
1112

1213

1314
class Bare(Component):
1415
"""A component with no tag."""
1516

16-
contents: Var[str]
17+
contents: Var[Any]
1718

1819
@classmethod
1920
def create(cls, contents: Any) -> Component:
@@ -25,13 +26,17 @@ def create(cls, contents: Any) -> Component:
2526
Returns:
2627
The component.
2728
"""
28-
if isinstance(contents, Var) and contents._var_data:
29+
if isinstance(contents, ImmutableVar):
30+
return cls(contents=contents)
31+
if isinstance(contents, Var) and contents._get_all_var_data():
2932
contents = contents.to(str)
3033
else:
3134
contents = str(contents) if contents is not None else ""
3235
return cls(contents=contents) # type: ignore
3336

3437
def _render(self) -> Tag:
38+
if isinstance(self.contents, ImmutableVar):
39+
return Tagless(contents=f"{{{str(self.contents)}}}")
3540
return Tagless(contents=str(self.contents))
3641

3742
def _get_vars(self, include_children: bool = False) -> Iterator[Var]:

0 commit comments

Comments
 (0)