From 3003ac1d1f8f4eb066df27267db76401653a013d Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Sat, 12 Apr 2025 09:35:01 +0100 Subject: [PATCH] Fix a crash when setting a kaymap before app is mounted Fixes #5742. --- CHANGELOG.md | 6 ++++++ src/textual/dom.py | 3 ++- tests/test_keymap.py | 25 +++++++++++++++++++++++++ 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 298e45481..76988284e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). +## Unreleased + +### Fixed + +- Fixed a crash when setting keymap before app mount https://github.com/Textualize/textual/issues/5742 + ## [3.1.0] - 2025-04-12 ### Fixed diff --git a/src/textual/dom.py b/src/textual/dom.py index 00b5595c6..6898f7d3d 100644 --- a/src/textual/dom.py +++ b/src/textual/dom.py @@ -1818,7 +1818,8 @@ class DOMNode(MessagePump): See [actions](/guide/actions#dynamic-actions) for how to use this method. """ - self.screen.refresh_bindings() + if self._is_mounted: + self.screen.refresh_bindings() async def action_toggle(self, attribute_name: str) -> None: """Toggle an attribute on the node. diff --git a/tests/test_keymap.py b/tests/test_keymap.py index fd92ff299..d7615bd05 100644 --- a/tests/test_keymap.py +++ b/tests/test_keymap.py @@ -192,3 +192,28 @@ async def test_keymap_child_with_different_id_overridden(): await pilot.press("i") assert parent_counter == 1 assert child_counter == 1 + + +async def test_set_keymap_before_app_mount(): + """Ensure we can set the keymap before mount without crash. + + https://github.com/Textualize/textual/issues/5742 + """ + + worked = False + + class MyApp(App[None]): + + BINDINGS = [Binding(key="x", action="test", id="test")] + + def __init__(self) -> None: + super().__init__() + self.update_keymap({"test": "y"}) + + def action_test(self) -> None: + nonlocal worked + worked = True + + async with MyApp().run_test() as pilot: + await pilot.press("y") + assert worked is True