mirror of
https://github.com/Textualize/textual.git
synced 2025-10-17 02:38:12 +03:00
Move aliasing/normalisation logic into Key
This commit is contained in:
@@ -1,12 +1,13 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING, Awaitable, Callable, Type, TypeVar
|
||||
from typing import TYPE_CHECKING, Awaitable, Callable, Type, TypeVar, Iterable
|
||||
|
||||
import rich.repr
|
||||
from rich.style import Style
|
||||
|
||||
from ._types import MessageTarget
|
||||
from .geometry import Offset, Size
|
||||
from .keys import _get_key_aliases
|
||||
from .message import Message
|
||||
|
||||
MouseEventT = TypeVar("MouseEventT", bound="MouseEvent")
|
||||
@@ -209,7 +210,13 @@ class Key(InputEvent):
|
||||
@property
|
||||
def key_name(self) -> str | None:
|
||||
"""Name of a key suitable for use as a Python identifier."""
|
||||
return self.key.replace("+", "_")
|
||||
return _normalize_key(self.key)
|
||||
|
||||
@property
|
||||
def key_aliases(self) -> Iterable[str]:
|
||||
"""Get the aliases for the key, including the key itself"""
|
||||
for alias in _get_key_aliases(self.key):
|
||||
yield _normalize_key(alias)
|
||||
|
||||
@property
|
||||
def is_printable(self) -> bool:
|
||||
@@ -222,6 +229,11 @@ class Key(InputEvent):
|
||||
return False if self.char is None else self.char.isprintable()
|
||||
|
||||
|
||||
def _normalize_key(key: str) -> str:
|
||||
"""Convert the key string to a name suitable for use as a Python identifier."""
|
||||
return key.replace("+", "_")
|
||||
|
||||
|
||||
@rich.repr.auto
|
||||
class MouseEvent(InputEvent, bubble=True):
|
||||
"""Sent in response to a mouse event.
|
||||
|
||||
@@ -548,11 +548,6 @@ class MessagePump(metaclass=MessagePumpMeta):
|
||||
private_handler_name = f"_key_{key}"
|
||||
private_handler = getattr(pump, private_handler_name, None)
|
||||
|
||||
if public_handler and private_handler:
|
||||
_raise_duplicate_key_handlers_error(
|
||||
key, public_handler_name, private_handler_name
|
||||
)
|
||||
|
||||
return public_handler or private_handler
|
||||
|
||||
invoked_method = None
|
||||
@@ -560,9 +555,8 @@ class MessagePump(metaclass=MessagePumpMeta):
|
||||
if not key_name:
|
||||
return False
|
||||
|
||||
key_aliases = _get_key_aliases(event.key)
|
||||
for key_alias in key_aliases:
|
||||
key_method = get_key_handler(self, key_alias.replace("+", "_"))
|
||||
for key_alias in event.key_aliases:
|
||||
key_method = get_key_handler(self, key_alias)
|
||||
if key_method is not None:
|
||||
if invoked_method:
|
||||
_raise_duplicate_key_handlers_error(
|
||||
|
||||
@@ -47,14 +47,6 @@ class DuplicateHandlersWidget(Widget):
|
||||
self.called_by = self.key_ctrl_i
|
||||
|
||||
|
||||
async def test_dispatch_key_raises_when_public_and_private_handlers():
|
||||
"""When both a public and private handler exists for one key, we fail fast via exception."""
|
||||
widget = DuplicateHandlersWidget()
|
||||
with pytest.raises(DuplicateKeyHandlers):
|
||||
await widget.dispatch_key(Key(widget, key="x", char="x"))
|
||||
assert widget.called_by is None
|
||||
|
||||
|
||||
async def test_dispatch_key_raises_when_conflicting_handler_aliases():
|
||||
"""If you've got a handler for e.g. ctrl+i and a handler for tab, that's probably a mistake.
|
||||
In the terminal, they're the same thing, so we fail fast via exception here."""
|
||||
|
||||
Reference in New Issue
Block a user