Skip to content

Commit 5fb749e

Browse files
committed
refactor: rename to pop_views_until, based on feedback from @ndonkoHenri
Rename pop_until_with_result() to pop_views_until(), on_view_pop_result to on_views_pop_until, and ViewPopResultEvent to ViewsPopUntilEvent. Requested by @FeodorFitsner in the PR review.
1 parent 72b9e75 commit 5fb749e

File tree

4 files changed

+60
-62
lines changed

4 files changed

+60
-62
lines changed

sdk/python/examples/apps/routing_navigation/pop_until_with_result.py renamed to sdk/python/examples/apps/routing_navigation/pop_views_until.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -81,9 +81,7 @@ def route_change():
8181
ft.Button(
8282
"Finish and go Home",
8383
on_click=lambda _: asyncio.create_task(
84-
page.pop_until_with_result(
85-
"/", result="Flow completed!"
86-
)
84+
page.pop_views_until("/", result="Flow completed!")
8785
),
8886
),
8987
],
@@ -92,7 +90,7 @@ def route_change():
9290

9391
page.update()
9492

95-
def on_pop_result(e: ft.ViewPopResultEvent):
93+
def on_pop_result(e: ft.ViewsPopUntilEvent):
9694
result_text.value = f"Result: {e.result}"
9795
page.show_dialog(ft.SnackBar(ft.Text(f"Result: {e.result}")))
9896
page.update()
@@ -105,7 +103,7 @@ async def view_pop(e: ft.ViewPopEvent):
105103

106104
page.on_route_change = route_change
107105
page.on_view_pop = view_pop
108-
page.on_view_pop_result = on_pop_result
106+
page.on_views_pop_until = on_pop_result
109107

110108
route_change()
111109

sdk/python/packages/flet/src/flet/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -409,7 +409,7 @@
409409
PlatformBrightnessChangeEvent,
410410
RouteChangeEvent,
411411
ViewPopEvent,
412-
ViewPopResultEvent,
412+
ViewsPopUntilEvent,
413413
)
414414
from flet.controls.painting import (
415415
Paint,
@@ -1073,7 +1073,7 @@
10731073
"VerticalDivider",
10741074
"View",
10751075
"ViewPopEvent",
1076-
"ViewPopResultEvent",
1076+
"ViewsPopUntilEvent",
10771077
"VisualDensity",
10781078
"Wakelock",
10791079
"WebBrowserName",

sdk/python/packages/flet/src/flet/controls/page.py

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -215,10 +215,10 @@ class ViewPopEvent(Event["Page"]):
215215

216216

217217
@dataclass
218-
class ViewPopResultEvent(Event["Page"]):
218+
class ViewsPopUntilEvent(Event["Page"]):
219219
"""
220-
Event payload delivered when [`Page.pop_until_with_result`]\
221-
[flet.Page.pop_until_with_result] completes navigation.
220+
Event payload delivered when [`Page.pop_views_until`]\
221+
[flet.Page.pop_views_until] completes navigation.
222222
223223
Carries the result value back to the destination view, analogous to
224224
Flutter's `Navigator.popUntilWithResult`.
@@ -232,7 +232,7 @@ class ViewPopResultEvent(Event["Page"]):
232232
result: Any = None
233233
"""
234234
The result value passed from the caller of
235-
[`pop_until_with_result`][flet.Page.pop_until_with_result].
235+
[`pop_views_until`][flet.Page.pop_views_until].
236236
"""
237237

238238
view: Optional[View] = None
@@ -532,9 +532,9 @@ class Page(BasePage):
532532
Called when the user clicks automatic "Back" button in [`AppBar`][flet.] control.
533533
"""
534534

535-
on_view_pop_result: Optional[EventHandler[ViewPopResultEvent]] = None
535+
on_views_pop_until: Optional[EventHandler[ViewsPopUntilEvent]] = None
536536
"""
537-
Called when [`pop_until_with_result`][flet.Page.pop_until_with_result] reaches
537+
Called when [`pop_views_until`][flet.Page.pop_views_until] reaches
538538
the destination view.
539539
540540
The event carries the result value passed by the caller.
@@ -741,7 +741,7 @@ def before_event(self, e: ControlEvent):
741741
self.__last_route = e.route
742742
self.query()
743743

744-
elif isinstance(e, ViewPopEvent | ViewPopResultEvent):
744+
elif isinstance(e, ViewPopEvent | ViewsPopUntilEvent):
745745
for v in unwrap_component(self.views):
746746
v = unwrap_component(v)
747747
if v.route == e.route:
@@ -931,11 +931,11 @@ async def view_pop(e):
931931
arguments={"route": new_route},
932932
)
933933

934-
async def pop_until_with_result(self, route: str, result: Any = None) -> None:
934+
async def pop_views_until(self, route: str, result: Any = None) -> None:
935935
"""
936936
Pops views from the navigation stack until a view with the given
937937
`route` is found, then delivers `result` via the
938-
[`on_view_pop_result`][flet.Page.on_view_pop_result] event.
938+
[`on_views_pop_until`][flet.Page.on_views_pop_until] event.
939939
940940
This is the Flet equivalent of Flutter's `Navigator.popUntilWithResult`.
941941
@@ -945,22 +945,22 @@ async def pop_until_with_result(self, route: str, result: Any = None) -> None:
945945
946946
947947
def main(page: ft.Page):
948-
def on_pop_result(e: ft.ViewPopResultEvent):
948+
def on_pop_result(e: ft.ViewsPopUntilEvent):
949949
page.show_dialog(ft.SnackBar(ft.Text(f"Result: {e.result}")))
950950
951-
page.on_view_pop_result = on_pop_result
951+
page.on_views_pop_until = on_pop_result
952952
953953
# ... later, from a deeply nested view:
954954
async def go_back(ev):
955-
await page.pop_until_with_result("/", result="Done!")
955+
await page.pop_views_until("/", result="Done!")
956956
```
957957
958958
Args:
959959
route: Target route to navigate back to. Must match the `route`
960960
of an existing [`View`][flet.View] in
961961
[`page.views`][flet.Page.views].
962962
result: Optional value delivered to
963-
[`on_view_pop_result`][flet.Page.on_view_pop_result] on the
963+
[`on_views_pop_until`][flet.Page.on_views_pop_until] on the
964964
destination view.
965965
966966
Raises:
@@ -986,17 +986,17 @@ async def go_back(ev):
986986
# Update browser URL
987987
await self.push_route(route)
988988

989-
# Fire on_view_pop_result for the destination view
990-
if self.on_view_pop_result:
989+
# Fire on_views_pop_until for the destination view
990+
if self.on_views_pop_until:
991991
target_view = unwrap_component(views[target_idx])
992-
e = ViewPopResultEvent(
993-
name="view_pop_result",
992+
e = ViewsPopUntilEvent(
993+
name="views_pop_until",
994994
control=self,
995995
route=route,
996996
result=result,
997997
view=target_view,
998998
)
999-
await self._trigger_event("view_pop_result", event_data=None, e=e)
999+
await self._trigger_event("views_pop_until", event_data=None, e=e)
10001000

10011001
self.update()
10021002

sdk/python/packages/flet/tests/test_pop_until_with_result.py renamed to sdk/python/packages/flet/tests/test_pop_views_until.py

Lines changed: 37 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
import flet as ft
77
from flet.controls.control_event import get_event_field_type
8-
from flet.controls.page import Page, ViewPopResultEvent
8+
from flet.controls.page import Page, ViewsPopUntilEvent
99
from flet.messaging.connection import Connection
1010
from flet.messaging.session import Session
1111
from flet.pubsub.pubsub_hub import PubSubHub
@@ -17,64 +17,64 @@ def _make_page() -> Page:
1717
return Page(sess=Session(conn))
1818

1919

20-
def test_view_pop_result_event_creation():
20+
def test_views_pop_until_event_creation():
2121
page = _make_page()
22-
evt = ViewPopResultEvent(
23-
name="view_pop_result",
22+
evt = ViewsPopUntilEvent(
23+
name="views_pop_until",
2424
control=page,
2525
route="/",
2626
result="test_result",
2727
)
2828
assert evt.route == "/"
2929
assert evt.result == "test_result"
3030
assert evt.view is None
31-
assert evt.name == "view_pop_result"
31+
assert evt.name == "views_pop_until"
3232

3333

34-
def test_view_pop_result_event_default_result():
34+
def test_views_pop_until_event_default_result():
3535
page = _make_page()
36-
evt = ViewPopResultEvent(
37-
name="view_pop_result",
36+
evt = ViewsPopUntilEvent(
37+
name="views_pop_until",
3838
control=page,
3939
route="/home",
4040
)
4141
assert evt.result is None
4242

4343

44-
def test_get_event_field_type_on_view_pop_result():
44+
def test_get_event_field_type_on_views_pop_until():
4545
page = _make_page()
46-
event_type = get_event_field_type(page, "on_view_pop_result")
47-
assert event_type == ViewPopResultEvent
46+
event_type = get_event_field_type(page, "on_views_pop_until")
47+
assert event_type == ViewsPopUntilEvent
4848

4949

50-
def test_view_pop_result_event_importable_from_flet():
51-
assert hasattr(ft, "ViewPopResultEvent")
52-
assert ft.ViewPopResultEvent is ViewPopResultEvent
50+
def test_views_pop_until_event_importable_from_flet():
51+
assert hasattr(ft, "ViewsPopUntilEvent")
52+
assert ft.ViewsPopUntilEvent is ViewsPopUntilEvent
5353

5454

55-
def test_page_has_on_view_pop_result_attribute():
55+
def test_page_has_on_views_pop_until_attribute():
5656
page = _make_page()
57-
assert hasattr(page, "on_view_pop_result")
58-
assert page.on_view_pop_result is None
57+
assert hasattr(page, "on_views_pop_until")
58+
assert page.on_views_pop_until is None
5959

6060

61-
def test_page_has_pop_until_with_result_method():
61+
def test_page_has_pop_views_until_method():
6262
page = _make_page()
63-
assert hasattr(page, "pop_until_with_result")
64-
assert inspect.iscoroutinefunction(page.pop_until_with_result)
63+
assert hasattr(page, "pop_views_until")
64+
assert inspect.iscoroutinefunction(page.pop_views_until)
6565

6666

6767
@pytest.mark.asyncio
68-
async def test_pop_until_with_result_raises_on_missing_route():
68+
async def test_pop_views_until_raises_on_missing_route():
6969
page = _make_page()
7070
page.views = [ft.View(route="/")]
7171

7272
with pytest.raises(ValueError, match="No view found with route '/nonexistent'"):
73-
await page.pop_until_with_result("/nonexistent")
73+
await page.pop_views_until("/nonexistent")
7474

7575

7676
@pytest.mark.asyncio
77-
async def test_pop_until_with_result_removes_views_above_target():
77+
async def test_pop_views_until_removes_views_above_target():
7878
page = _make_page()
7979
page.views = [
8080
ft.View(route="/"),
@@ -87,14 +87,14 @@ async def test_pop_until_with_result_removes_views_above_target():
8787
patch.object(page, "_invoke_method", new_callable=AsyncMock),
8888
patch.object(page, "update"),
8989
):
90-
await page.pop_until_with_result("/", result="done")
90+
await page.pop_views_until("/", result="done")
9191

9292
assert len(page.views) == 1
9393
assert page.views[0].route == "/"
9494

9595

9696
@pytest.mark.asyncio
97-
async def test_pop_until_with_result_removes_to_middle_view():
97+
async def test_pop_views_until_removes_to_middle_view():
9898
page = _make_page()
9999
page.views = [
100100
ft.View(route="/"),
@@ -106,15 +106,15 @@ async def test_pop_until_with_result_removes_to_middle_view():
106106
patch.object(page, "_invoke_method", new_callable=AsyncMock),
107107
patch.object(page, "update"),
108108
):
109-
await page.pop_until_with_result("/step1", result="partial")
109+
await page.pop_views_until("/step1", result="partial")
110110

111111
assert len(page.views) == 2
112112
assert page.views[0].route == "/"
113113
assert page.views[1].route == "/step1"
114114

115115

116116
@pytest.mark.asyncio
117-
async def test_pop_until_with_result_no_op_when_target_is_top():
117+
async def test_pop_views_until_no_op_when_target_is_top():
118118
page = _make_page()
119119
page.views = [
120120
ft.View(route="/"),
@@ -125,51 +125,51 @@ async def test_pop_until_with_result_no_op_when_target_is_top():
125125
patch.object(page, "_invoke_method", new_callable=AsyncMock),
126126
patch.object(page, "update"),
127127
):
128-
await page.pop_until_with_result("/current", result="same")
128+
await page.pop_views_until("/current", result="same")
129129

130130
assert len(page.views) == 2
131131
assert page.views[-1].route == "/current"
132132

133133

134134
@pytest.mark.asyncio
135-
async def test_pop_until_with_result_fires_only_view_pop_result():
135+
async def test_pop_views_until_fires_only_views_pop_until():
136136
page = _make_page()
137137
page.views = [
138138
ft.View(route="/"),
139139
ft.View(route="/step1"),
140140
ft.View(route="/step2"),
141141
]
142142

143-
page.on_view_pop_result = lambda e: None
143+
page.on_views_pop_until = lambda e: None
144144

145145
with (
146146
patch.object(page, "_invoke_method", new_callable=AsyncMock),
147147
patch.object(page, "update"),
148148
patch.object(page, "_trigger_event", new_callable=AsyncMock) as mock_trigger,
149149
):
150-
await page.pop_until_with_result("/", result="finished")
150+
await page.pop_views_until("/", result="finished")
151151

152152
trigger_calls = [call.args[0] for call in mock_trigger.call_args_list]
153-
# on_view_pop should NOT be fired — pop_until_with_result handles removal
153+
# on_view_pop should NOT be fired — pop_views_until handles removal
154154
assert "view_pop" not in trigger_calls
155-
# on_view_pop_result SHOULD be fired for the destination view
156-
assert "view_pop_result" in trigger_calls
155+
# on_views_pop_until SHOULD be fired for the destination view
156+
assert "views_pop_until" in trigger_calls
157157

158158

159159
@pytest.mark.asyncio
160-
async def test_pop_until_with_result_no_event_when_no_handler():
160+
async def test_pop_views_until_no_event_when_no_handler():
161161
page = _make_page()
162162
page.views = [
163163
ft.View(route="/"),
164164
ft.View(route="/step1"),
165165
]
166166

167-
# No on_view_pop_result handler set
167+
# No on_views_pop_until handler set
168168
with (
169169
patch.object(page, "_invoke_method", new_callable=AsyncMock),
170170
patch.object(page, "update"),
171171
patch.object(page, "_trigger_event", new_callable=AsyncMock) as mock_trigger,
172172
):
173-
await page.pop_until_with_result("/", result="done")
173+
await page.pop_views_until("/", result="done")
174174

175175
assert mock_trigger.call_count == 0

0 commit comments

Comments
 (0)