Skip to content

Commit

Permalink
feature: recompute variable directory (#2383)
Browse files Browse the repository at this point in the history
* recompute variable directory

* add test for var dir recompute
  • Loading branch information
dinhlongviolin1 authored Jan 9, 2025
1 parent 115b2e8 commit 81de95e
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 11 deletions.
37 changes: 26 additions & 11 deletions taipy/gui/utils/_variable_directory.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ def __init__(self, locals_context: _LocalsContext):
self._var_dir: t.Dict[str, t.Dict] = {}
self._var_head: t.Dict[str, t.List[t.Tuple[str, str]]] = {}
self._imported_var_dir: t.Dict[str, t.List[t.Tuple[str, str, str]]] = {}
self._pre_processed_module: t.Set[str] = set()
self._processed_module: t.Set[str] = set()

def set_default(self, frame: FrameType) -> None:
self._default_module = _get_module_name_from_frame(frame)
Expand All @@ -39,7 +41,10 @@ def add_frame(self, frame: t.Optional[FrameType]) -> None:
self._imported_var_dir[t.cast(str, module_name)] = imported_var_list

def pre_process_module_import_all(self) -> None:
for imported_dir in self._imported_var_dir.values():
for base_module, imported_dir in self._imported_var_dir.items():
# Skip pre process for modules that have been processed
if base_module in self._pre_processed_module:
continue
additional_var_list: t.List[t.Tuple[str, str, str]] = []
for name, asname, module in imported_dir:
if name != "*" or asname != "*":
Expand All @@ -51,21 +56,28 @@ def pre_process_module_import_all(self) -> None:
(v, v, module) for v in self._locals_context.get_locals().keys() if not v.startswith("_")
)
imported_dir.extend(additional_var_list)
# Save the pre-processed module
self._pre_processed_module.add(base_module)

def process_imported_var(self) -> None:
self.pre_process_module_import_all()
default_imported_dir = self._imported_var_dir[t.cast(str, self._default_module)]
with self._locals_context.set_locals_context(self._default_module):
for name, asname, module in default_imported_dir:
if name == "*" and asname == "*":
continue
imported_module_name = _get_module_name_from_imported_var(
name, self._locals_context.get_locals().get(asname, None), module
)
temp_var_name = self.add_var(asname, self._default_module)
self.add_var(name, imported_module_name, temp_var_name)
default_module = t.cast(str, self._default_module)
if default_module not in self._processed_module:
default_imported_dir = self._imported_var_dir[default_module]
with self._locals_context.set_locals_context(self._default_module):
for name, asname, module in default_imported_dir:
if name == "*" and asname == "*":
continue
imported_module_name = _get_module_name_from_imported_var(
name, self._locals_context.get_locals().get(asname, None), module
)
temp_var_name = self.add_var(asname, self._default_module)
self.add_var(name, imported_module_name, temp_var_name)
self._processed_module.add(default_module)

for k, v in self._imported_var_dir.items():
if k in self._processed_module:
continue
with self._locals_context.set_locals_context(k):
for name, asname, module in v:
if name == "*" and asname == "*":
Expand All @@ -82,6 +94,7 @@ def process_imported_var(self) -> None:
self.add_var(asname, k, var_name)
else:
self.add_var(name, imported_module_name, var_asname)
self._processed_module.add(k)

def add_var(self, name: str, module: t.Optional[str], var_name: t.Optional[str] = None) -> str:
if module is None:
Expand Down Expand Up @@ -119,9 +132,11 @@ def get_var(self, name: str, module: str) -> t.Optional[str]:
_MODULE_ID = "_TPMDL_"
_RE_TPMDL_DECODE = re.compile(r"(.*?)" + _MODULE_ID + r"(\d+)$")


def _is_moduled_variable(var_name: str):
return _MODULE_ID in var_name


def _variable_encode(var_name: str, module_name: t.Optional[str]):
if module_name is None:
return var_name
Expand Down
29 changes: 29 additions & 0 deletions tests/gui/gui_specific/state_asset/page2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Copyright 2021-2025 Avaiga Private Limited
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
# an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
# specific language governing permissions and limitations under the License.

from taipy.gui import Markdown

b = 20


def get_b(state):
return state.b


def set_b(state, val):
state.b = val


md_page2 = Markdown(
"""
<|{b}|>
"""
)
36 changes: 36 additions & 0 deletions tests/gui/gui_specific/test_variable_directory.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Copyright 2021-2025 Avaiga Private Limited
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
# an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
# specific language governing permissions and limitations under the License.


from taipy.gui import Gui
from taipy.gui.utils import _LocalsContext, _VariableDirectory

from .state_asset.page1 import md_page1
from .state_asset.page2 import md_page2


def test_variable_directory_dyanmic_process(gui: Gui):
gui.run(run_server=False)
with gui.get_flask_app().app_context():
locals_context = _LocalsContext()
variable_directory = _VariableDirectory(locals_context)
page1_module = str(md_page1._get_module_name())
page2_module = str(md_page2._get_module_name())
locals_context.add(page1_module, md_page1._get_locals())
variable_directory.set_default(md_page1._get_frame()) # type: ignore
variable_directory.process_imported_var()
assert page1_module in variable_directory._pre_processed_module
assert page1_module in variable_directory._processed_module
locals_context.add(page2_module, md_page2._get_locals())
variable_directory.add_frame(md_page2._get_frame())
variable_directory.process_imported_var()
assert page2_module in variable_directory._pre_processed_module
assert page2_module in variable_directory._processed_module

0 comments on commit 81de95e

Please sign in to comment.