diff --git a/src/textual/_callback.py b/src/textual/_callback.py index d2fd2403c2..6cf94daefc 100644 --- a/src/textual/_callback.py +++ b/src/textual/_callback.py @@ -1,7 +1,7 @@ from __future__ import annotations import asyncio -from functools import lru_cache, partial +from functools import partial from inspect import isawaitable, signature from typing import TYPE_CHECKING, Any, Callable @@ -16,16 +16,25 @@ def count_parameters(func: Callable) -> int: """Count the number of parameters in a callable""" - if isinstance(func, partial): - return _count_parameters(func.func) + len(func.args) - if hasattr(func, "__self__"): - # Bound method - func = func.__func__ # type: ignore - return _count_parameters(func) - 1 - return _count_parameters(func) + from ._profile import timer + + with timer("count"): + try: + return func._param_count + except AttributeError: + pass + if isinstance(func, partial): + param_count = _count_parameters(func) + len(func.args) + elif hasattr(func, "__self__"): + # Bound method + func = func.__func__ # type: ignore + param_count = _count_parameters(func) - 1 + else: + param_count = _count_parameters(func) + func._param_count = param_count + return param_count -@lru_cache(maxsize=2048) def _count_parameters(func: Callable) -> int: """Count the number of parameters in a callable""" return len(signature(func).parameters) diff --git a/src/textual/app.py b/src/textual/app.py index b721507249..0f4dade599 100644 --- a/src/textual/app.py +++ b/src/textual/app.py @@ -1784,7 +1784,8 @@ async def run_auto_pilot( await asyncio.shield(app._shutdown()) except asyncio.CancelledError: pass - + active_app.set(None) + active_message_pump.set(None) return app.return_value def run( @@ -3029,6 +3030,8 @@ async def _close_all(self) -> None: if stack_screen._running: await self._prune(stack_screen) stack.clear() + self._installed_screens.clear() + self._modes.clear() # Close any remaining nodes # Should be empty by now diff --git a/src/textual/widget.py b/src/textual/widget.py index b71cc971ae..8b3998eb67 100644 --- a/src/textual/widget.py +++ b/src/textual/widget.py @@ -3676,6 +3676,7 @@ async def _message_loop_exit(self) -> None: parent._nodes._remove(self) self.app._registry.discard(self) self._detach() + self._arrangement_cache.clear() async def _on_idle(self, event: events.Idle) -> None: """Called when there are no more events on the queue.