Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fully migrate vars into new system #3743

Merged
merged 48 commits into from
Aug 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
de1fbdb
fully migrate vars into new system
adhami3310 Aug 5, 2024
1eecd1f
i hate rufffff (no i don't)
adhami3310 Aug 5, 2024
450610a
fix silly pright issues (except colormode and state)
adhami3310 Aug 5, 2024
da95d0f
remove all instances of Var.create
adhami3310 Aug 5, 2024
c397cb2
create immutable callable var and get rid of more base vars
adhami3310 Aug 5, 2024
81cd679
implement hash for all functions
adhami3310 Aug 6, 2024
ea33c39
get reflex-web to compile
adhami3310 Aug 9, 2024
982e4c1
get it to compile reflex-web successfully
adhami3310 Aug 9, 2024
f6938cf
fix tests
adhami3310 Aug 12, 2024
0ae8831
fix pyi
adhami3310 Aug 12, 2024
4349d69
use override from typing_extension
adhami3310 Aug 12, 2024
854d729
put plotly inside of a catch
adhami3310 Aug 12, 2024
e0c4e97
dicts are unusable sadly
adhami3310 Aug 12, 2024
5bfc0c0
fix silly mistake
adhami3310 Aug 12, 2024
0fd4237
overload equals to special case immutable var
adhami3310 Aug 12, 2024
2c26dad
improve test_cond
adhami3310 Aug 12, 2024
2f49ce0
solve more CI issues, down to 94 failures
adhami3310 Aug 13, 2024
82a3498
down to 20 errors
adhami3310 Aug 14, 2024
39bc0c0
down to 13 errors
adhami3310 Aug 14, 2024
d516b3b
pass all testcases
adhami3310 Aug 14, 2024
e92218d
fix pyright issues
adhami3310 Aug 14, 2024
1d45f70
reorder things
adhami3310 Aug 14, 2024
777e8bc
use get origin more
adhami3310 Aug 14, 2024
75ef773
use fixed_type logic
adhami3310 Aug 15, 2024
8de75b7
various optimizations
adhami3310 Aug 15, 2024
1603e06
go back to passing test cases
adhami3310 Aug 15, 2024
9e1a35f
use less boilerplate
adhami3310 Aug 15, 2024
ab63e57
remove unnecessary print message
adhami3310 Aug 15, 2024
5a8ca04
remove weird comment
adhami3310 Aug 15, 2024
9deda27
add test for html issue
adhami3310 Aug 15, 2024
0ad21fe
add type ignore
adhami3310 Aug 15, 2024
4978b20
fix another silly issue
adhami3310 Aug 15, 2024
3d7ea37
override get all var data for var operations call
adhami3310 Aug 16, 2024
69f0d1d
make integration tests pass
adhami3310 Aug 16, 2024
85c1590
fix immutable call var
adhami3310 Aug 17, 2024
dd13dba
better logic for finding parent class
adhami3310 Aug 17, 2024
397683a
use even better logic for finding state wrt computedvar
adhami3310 Aug 17, 2024
bf1d052
only choose the ones that are defined in the same module
adhami3310 Aug 19, 2024
9fb4b67
small dict to large dict
adhami3310 Aug 19, 2024
26002a8
[REF-3591] Remove chakra-related files from immutable vars PR (#3821)
masenf Aug 22, 2024
02def8c
Merge branch 'main' into immutable-vars
masenf Aug 22, 2024
7d7f788
pyproject.toml: bump to 0.6.0a1
masenf Aug 23, 2024
8b51244
pyproject.toml: depend on reflex-chakra>=0.6.0a
masenf Aug 23, 2024
f09d2e2
Merge remote-tracking branch 'origin/main' into immutable-vars
masenf Aug 23, 2024
56f278d
poetry.lock: relock dependencies
masenf Aug 23, 2024
86563b6
integration: bump listening timeout to 1200 seconds
masenf Aug 23, 2024
a94eedf
integration: bump listening timeout to 1800 seconds
masenf Aug 23, 2024
650aa1b
Use cached_var_no_lock to avoid ImmutableVar deadlocks (#3835)
masenf Aug 26, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions integration/test_form_submit.py
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,8 @@ async def get_form_data():

form_data = format.collect_form_dict_names(form_data)

print(form_data)

assert form_data["name_input"] == "foo"
assert form_data["pin_input"] == pin_values
assert form_data["number_input"] == "-3"
Expand Down
2 changes: 1 addition & 1 deletion integration/test_tailwind.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ def test_tailwind_app(tailwind_app: AppHarness, tailwind_disabled: bool):
assert len(paragraphs) == 3
for p in paragraphs:
assert tailwind_app.poll_for_content(p, exp_not_equal="") == PARAGRAPH_TEXT
assert p.value_of_css_property("font-family") == "monospace"
assert p.value_of_css_property("font-family") == '"monospace"'
if tailwind_disabled:
# expect default color, not "text-red-500" from tailwind utility class
assert p.value_of_css_property("color") not in TEXT_RED_500_COLOR
Expand Down
23 changes: 13 additions & 10 deletions integration/test_var_operations.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ def VarOperations():
import reflex_chakra as rc

import reflex as rx
from reflex.ivars.base import LiteralVar
from reflex.ivars.sequence import ArrayVar

class VarOperationState(rx.State):
int_var1: int = 10
Expand All @@ -31,8 +33,8 @@ class VarOperationState(rx.State):
str_var2: str = "second"
str_var3: str = "ThIrD"
str_var4: str = "a long string"
dict1: Dict = {1: 2}
dict2: Dict = {3: 4}
dict1: Dict[int, int] = {1: 2}
dict2: Dict[int, int] = {3: 4}
html_str: str = "<div>hello</div>"

app = rx.App(state=rx.State)
Expand Down Expand Up @@ -549,29 +551,29 @@ def index():
"second",
query=[VarOperationState.str_var2],
),
rx.text(rx.Var.range(2, 5).join(","), id="list_join_range1"),
rx.text(rx.Var.range(2, 10, 2).join(","), id="list_join_range2"),
rx.text(rx.Var.range(5, 0, -1).join(","), id="list_join_range3"),
rx.text(rx.Var.range(0, 3).join(","), id="list_join_range4"),
rx.text(ArrayVar.range(2, 5).join(","), id="list_join_range1"),
rx.text(ArrayVar.range(2, 10, 2).join(","), id="list_join_range2"),
rx.text(ArrayVar.range(5, 0, -1).join(","), id="list_join_range3"),
rx.text(ArrayVar.range(0, 3).join(","), id="list_join_range4"),
rx.box(
rx.foreach(
rx.Var.range(0, 2),
ArrayVar.range(0, 2),
lambda x: rx.text(VarOperationState.list1[x], as_="p"),
),
id="foreach_list_arg",
),
rx.box(
rx.foreach(
rx.Var.range(0, 2),
ArrayVar.range(0, 2),
lambda x, ix: rx.text(VarOperationState.list1[ix], as_="p"),
),
id="foreach_list_ix",
),
rx.box(
rx.foreach(
rx.Var.create_safe(list(range(0, 3))).to(List[int]),
LiteralVar.create(list(range(0, 3))).to(ArrayVar, List[int]),
lambda x: rx.foreach(
rx.Var.range(x),
ArrayVar.range(x),
lambda y: rx.text(VarOperationState.list1[y], as_="p"),
),
),
Expand Down Expand Up @@ -785,6 +787,7 @@ def test_var_operations(driver, var_operations: AppHarness):
]

for tag, expected in tests:
print(tag)
assert driver.find_element(By.ID, tag).text == expected

# Highlight component with var query (does not plumb ID)
Expand Down
18 changes: 9 additions & 9 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "reflex"
version = "0.5.9"
version = "0.6.0a1"
description = "Web apps in pure Python."
license = "Apache-2.0"
authors = [
Expand Down Expand Up @@ -61,7 +61,7 @@ httpx = ">=0.25.1,<1.0"
twine = ">=4.0.0,<6.0"
tomlkit = ">=0.12.4,<1.0"
lazy_loader = ">=0.4"
reflex-chakra = ">=0.1.1a1,<0.6"
reflex-chakra = ">=0.6.0a"

[tool.poetry.group.dev.dependencies]
pytest = ">=7.1.2,<8.0"
Expand Down
3 changes: 2 additions & 1 deletion reflex/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,7 @@
"style": ["Style", "toggle_color_mode"],
"utils.imports": ["ImportVar"],
"utils.serializers": ["serializer"],
"vars": ["cached_var", "Var"],
"vars": ["Var"],
}

_SUBMODULES: set[str] = {
Expand All @@ -338,6 +338,7 @@
"testing",
"utils",
"vars",
"ivars",
"config",
"compiler",
}
Expand Down
2 changes: 1 addition & 1 deletion reflex/__init__.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ from . import compiler as compiler
from . import components as components
from . import config as config
from . import event as event
from . import ivars as ivars
from . import model as model
from . import style as style
from . import testing as testing
Expand Down Expand Up @@ -189,7 +190,6 @@ from .style import toggle_color_mode as toggle_color_mode
from .utils.imports import ImportVar as ImportVar
from .utils.serializers import serializer as serializer
from .vars import Var as Var
from .vars import cached_var as cached_var

del compat
RADIX_THEMES_MAPPING: dict
Expand Down
8 changes: 5 additions & 3 deletions reflex/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -442,7 +442,7 @@ def _generate_component(component: Component | ComponentCallable) -> Component:
raise
except TypeError as e:
message = str(e)
if "BaseVar" in message or "ComputedVar" in message:
if "Var" in message:
raise VarOperationTypeError(
"You may be trying to use an invalid Python function on a state var. "
"When referencing a var inside your render code, only limited var operations are supported. "
Expand Down Expand Up @@ -527,9 +527,10 @@ def add_page(
self._enable_state()
else:
for var in component._get_vars(include_children=True):
if not var._var_data:
var_data = var._get_all_var_data()
if not var_data:
continue
if not var._var_data.state:
if not var_data.state:
continue
self._enable_state()
break
Expand Down Expand Up @@ -1113,6 +1114,7 @@ def _process_background(
Task if the event was backgroundable, otherwise None
"""
substate, handler = state._get_event_handler(event)

if not handler.is_background:
return None

Expand Down
5 changes: 3 additions & 2 deletions reflex/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,14 +110,15 @@ def add_field(cls, var: Any, default_value: Any):
var: The variable to add a pydantic field for.
default_value: The default value of the field
"""
var_name = var._var_name.split(".")[-1]
new_field = ModelField.infer(
name=var._var_name,
name=var_name,
value=default_value,
annotation=var._var_type,
class_validators=None,
config=cls.__config__, # type: ignore
)
cls.__fields__.update({var._var_name: new_field})
cls.__fields__.update({var_name: new_field})

def get_value(self, key: str) -> Any:
"""Get the value of a field.
Expand Down
3 changes: 2 additions & 1 deletion reflex/compiler/compiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
StatefulComponent,
)
from reflex.config import get_config
from reflex.ivars.base import ImmutableVar
from reflex.state import BaseState
from reflex.style import SYSTEM_COLOR_MODE
from reflex.utils.exec import is_prod_mode
Expand Down Expand Up @@ -80,7 +81,7 @@ def _compile_contexts(state: Optional[Type[BaseState]], theme: Component | None)
The compiled context file.
"""
appearance = getattr(theme, "appearance", None)
if appearance is None or Var.create_safe(appearance)._var_name == "inherit":
if appearance is None or str(ImmutableVar.create_safe(appearance)) == "inherit":
appearance = SYSTEM_COLOR_MODE

last_compiled_time = str(datetime.now())
Expand Down
6 changes: 2 additions & 4 deletions reflex/components/base/app_wrap.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from reflex.components.base.fragment import Fragment
from reflex.components.component import Component
from reflex.vars import Var
from reflex.ivars.base import ImmutableVar


class AppWrap(Fragment):
Expand All @@ -15,6 +15,4 @@ def create(cls) -> Component:
Returns:
A new AppWrap component containing {children}.
"""
return super().create(
Var.create("{children}", _var_is_local=False, _var_is_string=False)
)
return super().create(ImmutableVar.create("children"))
42 changes: 16 additions & 26 deletions reflex/components/base/app_wrap.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ from typing import Any, Callable, Dict, Optional, Union, overload
from reflex.components.base.fragment import Fragment
from reflex.event import EventHandler, EventSpec
from reflex.style import Style
from reflex.vars import BaseVar, Var
from reflex.vars import Var

class AppWrap(Fragment):
@overload
Expand All @@ -22,50 +22,40 @@ class AppWrap(Fragment):
class_name: Optional[Any] = None,
autofocus: Optional[bool] = None,
custom_attrs: Optional[Dict[str, Union[Var, str]]] = None,
on_blur: Optional[
Union[EventHandler, EventSpec, list, Callable, BaseVar]
] = None,
on_click: Optional[
Union[EventHandler, EventSpec, list, Callable, BaseVar]
] = None,
on_blur: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
on_click: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
on_context_menu: Optional[
Union[EventHandler, EventSpec, list, Callable, BaseVar]
Union[EventHandler, EventSpec, list, Callable, Var]
] = None,
on_double_click: Optional[
Union[EventHandler, EventSpec, list, Callable, BaseVar]
] = None,
on_focus: Optional[
Union[EventHandler, EventSpec, list, Callable, BaseVar]
] = None,
on_mount: Optional[
Union[EventHandler, EventSpec, list, Callable, BaseVar]
Union[EventHandler, EventSpec, list, Callable, Var]
] = None,
on_focus: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
on_mount: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
on_mouse_down: Optional[
Union[EventHandler, EventSpec, list, Callable, BaseVar]
Union[EventHandler, EventSpec, list, Callable, Var]
] = None,
on_mouse_enter: Optional[
Union[EventHandler, EventSpec, list, Callable, BaseVar]
Union[EventHandler, EventSpec, list, Callable, Var]
] = None,
on_mouse_leave: Optional[
Union[EventHandler, EventSpec, list, Callable, BaseVar]
Union[EventHandler, EventSpec, list, Callable, Var]
] = None,
on_mouse_move: Optional[
Union[EventHandler, EventSpec, list, Callable, BaseVar]
Union[EventHandler, EventSpec, list, Callable, Var]
] = None,
on_mouse_out: Optional[
Union[EventHandler, EventSpec, list, Callable, BaseVar]
Union[EventHandler, EventSpec, list, Callable, Var]
] = None,
on_mouse_over: Optional[
Union[EventHandler, EventSpec, list, Callable, BaseVar]
Union[EventHandler, EventSpec, list, Callable, Var]
] = None,
on_mouse_up: Optional[
Union[EventHandler, EventSpec, list, Callable, BaseVar]
] = None,
on_scroll: Optional[
Union[EventHandler, EventSpec, list, Callable, BaseVar]
Union[EventHandler, EventSpec, list, Callable, Var]
] = None,
on_scroll: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
on_unmount: Optional[
Union[EventHandler, EventSpec, list, Callable, BaseVar]
Union[EventHandler, EventSpec, list, Callable, Var]
] = None,
**props,
) -> "AppWrap":
Expand Down
9 changes: 7 additions & 2 deletions reflex/components/base/bare.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,14 @@
from reflex.components.component import Component
from reflex.components.tags import Tag
from reflex.components.tags.tagless import Tagless
from reflex.ivars.base import ImmutableVar
from reflex.vars import Var


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

contents: Var[str]
contents: Var[Any]

@classmethod
def create(cls, contents: Any) -> Component:
Expand All @@ -25,13 +26,17 @@ def create(cls, contents: Any) -> Component:
Returns:
The component.
"""
if isinstance(contents, Var) and contents._var_data:
if isinstance(contents, ImmutableVar):
return cls(contents=contents)
if isinstance(contents, Var) and contents._get_all_var_data():
contents = contents.to(str)
else:
contents = str(contents) if contents is not None else ""
return cls(contents=contents) # type: ignore

def _render(self) -> Tag:
if isinstance(self.contents, ImmutableVar):
return Tagless(contents=f"{{{str(self.contents)}}}")
return Tagless(contents=str(self.contents))

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