Skip to content

Commit 9db15e4

Browse files
FredLL-AvaigaFred Lefévère-Laoide
andauthored
fix hold_control action support (#2400)
* fix hold_control action support resolves #2399 * lint * lint * lint * allow return without action --------- Co-authored-by: Fred Lefévère-Laoide <Fred.Lefevere-Laoide@Taipy.io>
1 parent 0541ed6 commit 9db15e4

File tree

3 files changed

+76
-16
lines changed

3 files changed

+76
-16
lines changed

taipy/gui/gui.py

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1948,10 +1948,11 @@ def _is_ui_blocked(self):
19481948
return _getscopeattr(self, Gui.__UI_BLOCK_NAME, False)
19491949

19501950
def __get_on_cancel_block_ui(self, callback: t.Optional[str]):
1951-
def _taipy_on_cancel_block_ui(guiApp, id: t.Optional[str], payload: t.Any):
1952-
if _hasscopeattr(guiApp, Gui.__UI_BLOCK_NAME):
1953-
_setscopeattr(guiApp, Gui.__UI_BLOCK_NAME, False)
1954-
guiApp.__on_action(id, {"action": callback})
1951+
def _taipy_on_cancel_block_ui(a_state: State, id: t.Optional[str], payload: t.Any):
1952+
gui_app = a_state.get_gui()
1953+
if _hasscopeattr(gui_app, Gui.__UI_BLOCK_NAME):
1954+
_setscopeattr(gui_app, Gui.__UI_BLOCK_NAME, False)
1955+
gui_app.__on_action(id, {"action": callback})
19551956

19561957
return _taipy_on_cancel_block_ui
19571958

@@ -2391,15 +2392,13 @@ def _hold_actions(
23912392
callback: t.Optional[t.Union[str, t.Callable]] = None,
23922393
message: t.Optional[str] = "Work in Progress...",
23932394
): # pragma: no cover
2394-
action_name = (
2395-
callback
2396-
if isinstance(callback, str)
2397-
else _get_lambda_id(t.cast(LambdaType, callback))
2398-
if _is_unnamed_function(callback)
2399-
else callback.__name__
2400-
if callback is not None
2401-
else None
2402-
)
2395+
if _is_unnamed_function(callback):
2396+
action_name = _get_lambda_id(t.cast(LambdaType, callback))
2397+
self._bind_var_val(action_name, callback)
2398+
else:
2399+
action_name = (
2400+
callback if isinstance(callback, str) else (callback.__name__ if callback is not None else None)
2401+
)
24032402
func = self.__get_on_cancel_block_ui(action_name)
24042403
def_action_name = func.__name__
24052404
_setscopeattr(self, def_action_name, func)
@@ -2579,7 +2578,11 @@ def __render_page(self, page_name: str) -> t.Any:
25792578
with self._set_locals_context(context):
25802579
self._call_on_page_load(nav_page)
25812580
return self._server._render(
2582-
page._rendered_jsx, page._script_paths if page._script_paths is not None else [], page._style if page._style is not None else "", page._head, context # noqa: E501
2581+
page._rendered_jsx,
2582+
page._script_paths if page._script_paths is not None else [],
2583+
page._style if page._style is not None else "",
2584+
page._head,
2585+
context, # noqa: E501
25832586
)
25842587
else:
25852588
return ("No page template", 404)

taipy/gui/utils/callable.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111

1212
import typing as t
1313
from inspect import isclass
14-
from types import LambdaType
1514

1615

1716
def _is_function(s: t.Any) -> bool:
@@ -28,4 +27,4 @@ def _function_name(s: t.Any) -> str:
2827

2928

3029
def _is_unnamed_function(s: t.Any):
31-
return isinstance(s, LambdaType) or (callable(s) and not hasattr(s, "__name__"))
30+
return (hasattr(s, "__name__") and s.__name__ == "<lambda>") or (callable(s) and not hasattr(s, "__name__"))
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
# Copyright 2021-2025 Avaiga Private Limited
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
4+
# the License. You may obtain a copy of the License at
5+
#
6+
# http://www.apache.org/licenses/LICENSE-2.0
7+
#
8+
# Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
9+
# an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
10+
# specific language governing permissions and limitations under the License.
11+
12+
from taipy.gui.utils.callable import _function_name, _is_function, _is_unnamed_function
13+
14+
15+
def my_function():
16+
pass
17+
18+
19+
class my_class:
20+
pass
21+
22+
23+
class my_callable_class:
24+
def __call__(self):
25+
pass
26+
27+
28+
def test__is_unnamed_function():
29+
assert _is_unnamed_function(my_function) is False
30+
assert _is_unnamed_function(lambda x: x) is True
31+
assert _is_unnamed_function("a") is False
32+
33+
34+
def test__is_function():
35+
assert _is_function(my_function) is True
36+
assert _is_function(lambda x: x) is True
37+
assert _is_function("a") is False
38+
39+
40+
def test__function_name():
41+
assert _function_name(my_function) == "my_function"
42+
assert _function_name(lambda x: x) == "<lambda>"
43+
assert _function_name("a") == "a"
44+
assert _function_name(1) == "1"
45+
assert _function_name(1.0) == "1.0"
46+
assert _function_name(True) == "True"
47+
assert _function_name(False) == "False"
48+
assert _function_name(None) == "None"
49+
assert _function_name([]) == "[]"
50+
assert _function_name({}) == "{}"
51+
assert _function_name(set()) == "set()"
52+
assert _function_name(tuple()) == "()" # noqa C408
53+
assert _function_name(object) == "object"
54+
assert _function_name(object()).startswith("<object ")
55+
assert _function_name(my_class) == "my_class"
56+
assert _function_name(my_class()).startswith("<tests.gui.gui_specific.test_callable.my_class ")
57+
assert _function_name(my_callable_class) == "my_callable_class"
58+
assert _function_name(my_callable_class()) == "<instance of my_callable_class>"

0 commit comments

Comments
 (0)