diff --git a/CHANGELOG.md b/CHANGELOG.md index 0440949e46..970464943a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ### Fixed +- Fixed typing of run_worker to support async def callables under mypy strict checking (https://github.com/Textualize/textual/issues/6386) - Fixed parsing Kitty extended keys with multiple codepoints https://github.com/Textualize/textual/pull/6592 ### Changed diff --git a/src/textual/dom.py b/src/textual/dom.py index 44e1396e36..c0b601bb57 100644 --- a/src/textual/dom.py +++ b/src/textual/dom.py @@ -54,6 +54,7 @@ from textual.worker_manager import WorkerManager if TYPE_CHECKING: + from typing import Awaitable, Coroutine from typing_extensions import Self, TypeAlias from _typeshed import SupportsRichComparison @@ -493,9 +494,10 @@ def trap_focus(self, trap_focus: bool = True) -> None: """ self._trap_focus = trap_focus + @overload def run_worker( self, - work: WorkType[ResultType], + work: Callable[[], Coroutine[Any, Any, ResultType]], name: str | None = "", group: str = "default", description: str = "", @@ -503,7 +505,45 @@ def run_worker( start: bool = True, exclusive: bool = False, thread: bool = False, - ) -> Worker[ResultType]: + ) -> Worker[ResultType]: ... + + @overload + def run_worker( + self, + work: Callable[[], ResultType], + name: str | None = "", + group: str = "default", + description: str = "", + exit_on_error: bool = True, + start: bool = True, + exclusive: bool = False, + thread: bool = False, + ) -> Worker[ResultType]: ... + + @overload + def run_worker( + self, + work: Awaitable[ResultType], + name: str | None = "", + group: str = "default", + description: str = "", + exit_on_error: bool = True, + start: bool = True, + exclusive: bool = False, + thread: bool = False, + ) -> Worker[ResultType]: ... + + def run_worker( + self, + work: WorkType[Any], + name: str | None = "", + group: str = "default", + description: str = "", + exit_on_error: bool = True, + start: bool = True, + exclusive: bool = False, + thread: bool = False, + ) -> Worker[Any]: """Run work in a worker. A worker runs a function, coroutine, or awaitable, in the *background* as an async task or as a thread. @@ -525,10 +565,10 @@ def run_worker( # If we're running a worker from inside a secondary thread, # do so in a thread-safe way. if self.app._thread_id != threading.get_ident(): - creator = partial(self.app.call_from_thread, self.workers._new_worker) + creator: Any = partial(self.app.call_from_thread, self.workers._new_worker) else: creator = self.workers._new_worker - worker: Worker[ResultType] = creator( + worker: Worker[Any] = creator( work, self, name=name, diff --git a/src/textual/worker.py b/src/textual/worker.py index db50ecd3df..7da6c0871e 100644 --- a/src/textual/worker.py +++ b/src/textual/worker.py @@ -15,6 +15,7 @@ from time import monotonic from typing import ( TYPE_CHECKING, + Any, Awaitable, Callable, Coroutine, @@ -98,7 +99,7 @@ class WorkerState(enum.Enum): WorkType: TypeAlias = Union[ - Callable[[], Coroutine[None, None, ResultType]], + Callable[[], Coroutine[Any, Any, ResultType]], Callable[[], ResultType], Awaitable[ResultType], ]