Skip to content

Commit c24192e

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 8d39810 commit c24192e

4 files changed

Lines changed: 60 additions & 62 deletions

File tree

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
@@ -533,9 +533,9 @@ class Page(BasePage):
533533
control.
534534
"""
535535

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

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

935-
async def pop_until_with_result(self, route: str, result: Any = None) -> None:
935+
async def pop_views_until(self, route: str, result: Any = None) -> None:
936936
"""
937937
Pops views from the navigation stack until a view with the given
938938
`route` is found, then delivers `result` via the
939-
[`on_view_pop_result`][flet.Page.on_view_pop_result] event.
939+
[`on_views_pop_until`][flet.Page.on_views_pop_until] event.
940940
941941
This is the Flet equivalent of Flutter's `Navigator.popUntilWithResult`.
942942
@@ -946,22 +946,22 @@ async def pop_until_with_result(self, route: str, result: Any = None) -> None:
946946
947947
948948
def main(page: ft.Page):
949-
def on_pop_result(e: ft.ViewPopResultEvent):
949+
def on_pop_result(e: ft.ViewsPopUntilEvent):
950950
page.show_dialog(ft.SnackBar(ft.Text(f"Result: {e.result}")))
951951
952-
page.on_view_pop_result = on_pop_result
952+
page.on_views_pop_until = on_pop_result
953953
954954
# ... later, from a deeply nested view:
955955
async def go_back(ev):
956-
await page.pop_until_with_result("/", result="Done!")
956+
await page.pop_views_until("/", result="Done!")
957957
```
958958
959959
Args:
960960
route: Target route to navigate back to. Must match the `route`
961961
of an existing [`View`][flet.View] in
962962
[`page.views`][flet.Page.views].
963963
result: Optional value delivered to
964-
[`on_view_pop_result`][flet.Page.on_view_pop_result] on the
964+
[`on_views_pop_until`][flet.Page.on_views_pop_until] on the
965965
destination view.
966966
967967
Raises:
@@ -987,17 +987,17 @@ async def go_back(ev):
987987
# Update browser URL
988988
await self.push_route(route)
989989

990-
# Fire on_view_pop_result for the destination view
991-
if self.on_view_pop_result:
990+
# Fire on_views_pop_until for the destination view
991+
if self.on_views_pop_until:
992992
target_view = unwrap_component(views[target_idx])
993-
e = ViewPopResultEvent(
994-
name="view_pop_result",
993+
e = ViewsPopUntilEvent(
994+
name="views_pop_until",
995995
control=self,
996996
route=route,
997997
result=result,
998998
view=target_view,
999999
)
1000-
await self._trigger_event("view_pop_result", event_data=None, e=e)
1000+
await self._trigger_event("views_pop_until", event_data=None, e=e)
10011001

10021002
self.update()
10031003

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)