ai-station/.venv/lib/python3.12/site-packages/textual/actions.py

60 lines
1.6 KiB
Python
Raw Normal View History

2025-12-25 14:54:33 +00:00
from __future__ import annotations
import ast
import re
from functools import lru_cache
from typing import Any
from typing_extensions import TypeAlias
ActionParseResult: TypeAlias = "tuple[str, str, tuple[object, ...]]"
"""An action is its name and the arbitrary tuple of its arguments."""
class SkipAction(Exception):
"""Raise in an action to skip the action (and allow any parent bindings to run)."""
class ActionError(Exception):
pass
re_action_args = re.compile(r"([\w\.]+)\((.*)\)")
@lru_cache(maxsize=1024)
def parse(action: str) -> ActionParseResult:
"""Parses an action string.
Args:
action: String containing action.
Raises:
ActionError: If the action has invalid syntax.
Returns:
Action name and arguments.
"""
args_match = re_action_args.match(action)
if args_match is not None:
action_name, action_args_str = args_match.groups()
if action_args_str:
try:
# We wrap `action_args_str` to be able to disambiguate the cases where
# the list of arguments is a comma-separated list of values from the
# case where the argument is a single tuple.
action_args: tuple[Any, ...] = ast.literal_eval(f"({action_args_str},)")
except Exception:
raise ActionError(
f"unable to parse {action_args_str!r} in action {action!r}"
)
else:
action_args = ()
else:
action_name = action
action_args = ()
namespace, _, action_name = action_name.rpartition(".")
return namespace, action_name, action_args