Skip to content

Instantly share code, notes, and snippets.

@arvidfm
Created January 4, 2024 23:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save arvidfm/a57eb3f451ab76c26b881c3dd515f3bc to your computer and use it in GitHub Desktop.
Save arvidfm/a57eb3f451ab76c26b881c3dd515f3bc to your computer and use it in GitHub Desktop.
textual worker typing
> poetry run mypy --strict worker_typing.py
worker_typing.py:10: error: Value of type variable "NodeType" of function cannot be "int" [type-var]
worker_typing.py:17: error: Value of type variable "NodeType" of function cannot be "NotAWidget" [type-var]
worker_typing.py:28: error: Argument 1 has incompatible type "Callable[[MyWidget, float], set[str]]"; expected "Callable[[MyWidget, float], Coroutine[None, None, Never]]" [arg-type]
worker_typing.py:28: note: This is likely because "blocking_local_worker of MyWidget" has named arguments: "self". Consider marking them positional-only
worker_typing.py:41: error: Argument 1 to "work" has incompatible type "Callable[[MyWidget, float], int]"; expected "Callable[[MyWidget, float], Coroutine[None, None, Never]]" [arg-type]
worker_typing.py:41: note: This is likely because "blocking_simple_decorator of MyWidget" has named arguments: "self". Consider marking them positional-only
worker_typing.py:51: error: Missing positional arguments "arg1", "arg2" in call to "my_widget_worker" of "MyWidget" [call-arg]
worker_typing.py:53: error: Argument 1 to "my_widget_worker" of "MyWidget" has incompatible type "str"; expected "int" [arg-type]
worker_typing.py:55: error: Incompatible types in assignment (expression has type "bool", variable has type "str") [assignment]
worker_typing.py:60: note: Revealed type is "def (builtins.int, arg2: builtins.str) -> textual.worker.Worker[builtins.bool]"
worker_typing.py:61: note: Revealed type is "def (worker_typing.NotAWidget, arg1: builtins.int, arg2: builtins.str) -> textual.worker.Worker[builtins.bool]"
worker_typing.py:62: note: Revealed type is "def (worker_typing.MyWidget, value: builtins.float) -> textual.worker.Worker[Never]"
worker_typing.py:63: note: Revealed type is "def (worker_typing.MyWidget, value: builtins.float) -> textual.worker.Worker[Never]"
worker_typing.py:66: note: Revealed type is "def (worker_typing.MyWidget, arg1: builtins.int, arg2: builtins.str) -> textual.worker.Worker[builtins.bool]"
worker_typing.py:67: note: Revealed type is "def (worker_typing.MyWidget, value: builtins.float) -> textual.worker.Worker[builtins.list[builtins.str]]"
worker_typing.py:68: note: Revealed type is "def (worker_typing.MyWidget, value: builtins.float) -> textual.worker.Worker[builtins.bytes]"
worker_typing.py:69: note: Revealed type is "def (worker_typing.MyWidget, value: builtins.float) -> textual.worker.Worker[builtins.str]"
Found 7 errors in 1 file (checked 1 source file)
> poetry run mypy --strict worker_typing.py
worker_typing.py:60: note: Revealed type is "def (*Any, **Any) -> textual.worker.Worker[ReturnType?]"
worker_typing.py:61: note: Revealed type is "def (*Any, **Any) -> textual.worker.Worker[ReturnType?]"
worker_typing.py:62: note: Revealed type is "def (*Any, **Any) -> textual.worker.Worker[ReturnType?]"
worker_typing.py:63: note: Revealed type is "def (self: worker_typing.MyWidget, value: builtins.float) -> textual.worker.Worker[builtins.int]"
worker_typing.py:66: note: Revealed type is "def (*Any, **Any) -> textual.worker.Worker[ReturnType?]"
worker_typing.py:67: note: Revealed type is "def (*Any, **Any) -> textual.worker.Worker[ReturnType?]"
worker_typing.py:68: note: Revealed type is "def (*Any, **Any) -> textual.worker.Worker[ReturnType?]"
worker_typing.py:69: note: Revealed type is "def (self: worker_typing.MyWidget, value: builtins.float) -> textual.worker.Worker[builtins.str]"
Success: no issues found in 1 source file
> poetry run pyright worker_typing.py
worker_typing.py
worker_typing.py:10:2 - error: Argument of type "(arg1: int, arg2: str) -> Coroutine[Any, Any, bool]" cannot be assigned to parameter of type "AsyncWorkerFunc[NodeType@work, FactoryParamSpec@work, ReturnType@work]"
  Type "(arg1: int, arg2: str) -> Coroutine[Any, Any, bool]" cannot be assigned to type "AsyncWorkerFunc[NodeType@work, FactoryParamSpec@work, ReturnType@work]"
    Parameter 1: type "NodeType@work" cannot be assigned to type "int"
      "DOMNode*" is incompatible with "int" (reportGeneralTypeIssues)
worker_typing.py:17:6 - error: Argument of type "(self: Self@NotAWidget, arg1: int, arg2: str) -> Coroutine[Any, Any, bool]" cannot be assigned to parameter of type "AsyncWorkerFunc[NodeType@work, FactoryParamSpec@work, ReturnType@work]"
  Type "(self: Self@NotAWidget, arg1: int, arg2: str) -> Coroutine[Any, Any, bool]" cannot be assigned to type "AsyncWorkerFunc[NodeType@work, FactoryParamSpec@work, ReturnType@work]"
    Parameter 1: type "NodeType@work" cannot be assigned to type "Self@NotAWidget"
      Type "NodeType@work" cannot be assigned to type "Self@NotAWidget" (reportGeneralTypeIssues)
worker_typing.py:28:6 - error: Argument of type "(self: Self@MyWidget, value: float) -> set[str]" cannot be assigned to parameter of type "AsyncWorkerFunc[NodeType@work, FactoryParamSpec@work, ReturnType@work]"
  Type "(self: Self@MyWidget, value: float) -> set[str]" cannot be assigned to type "AsyncWorkerFunc[NodeType@work, FactoryParamSpec@work, ReturnType@work]"
    Function return type "set[str]" is incompatible with type "Coroutine[None, None, ReturnType@work]"
      "set[str]" is incompatible with "Coroutine[None, None, ReturnType@work]" (reportGeneralTypeIssues)
worker_typing.py:41:6 - error: No overloads for "work" match the provided arguments (reportGeneralTypeIssues)
worker_typing.py:41:6 - error: Argument of type "(self: Self@MyWidget, value: float) -> int" cannot be assigned to parameter "method" of type "None" in function "work"
  "function" is incompatible with "None" (reportGeneralTypeIssues)
worker_typing.py:41:6 - error: Untyped function decorator obscures type of function; ignoring decorator (reportUntypedFunctionDecorator)
worker_typing.py:51:9 - error: Arguments missing for parameters "arg1", "arg2" (reportGeneralTypeIssues)
worker_typing.py:53:31 - error: Argument of type "Literal['test']" cannot be assigned to parameter "arg1" of type "int"
  "Literal['test']" is incompatible with "int" (reportGeneralTypeIssues)
worker_typing.py:55:18 - error: Expression of type "bool" cannot be assigned to declared type "str"
  "bool" is incompatible with "str" (reportGeneralTypeIssues)
worker_typing.py:60:17 - information: Type of "non_class_worker" is "(NodeType@work, arg2: str) -> Worker[bool]"
worker_typing.py:61:17 - information: Type of "NotAWidget.not_a_widget_worker" is "(NodeType@work, arg1: int, arg2: str) -> Worker[bool]"
worker_typing.py:62:17 - information: Type of "MyWidget.blocking_local_worker" is "(MyWidget, value: float) -> Worker[ReturnType@work]"
worker_typing.py:63:17 - information: Type of "MyWidget.blocking_simple_decorator" is "(self: MyWidget, value: float) -> int"
worker_typing.py:66:17 - information: Type of "MyWidget.my_widget_worker" is "(MyWidget, arg1: int, arg2: str) -> Worker[bool]"
worker_typing.py:67:17 - information: Type of "MyWidget.blocking_threaded_worker" is "(MyWidget, value: float) -> Worker[list[str]]"
worker_typing.py:68:17 - information: Type of "MyWidget.async_threaded_worker" is "(MyWidget, value: float) -> Worker[bytes]"
worker_typing.py:69:17 - information: Type of "MyWidget.async_simple_decorator" is "(MyWidget, value: float) -> Worker[str]"
9 errors, 0 warnings, 8 informations
> poetry run pyright worker_typing.py
worker_typing.py
worker_typing.py:55:18 - error: Expression of type "bool" cannot be assigned to declared type "str"
  "bool" is incompatible with "str" (reportGeneralTypeIssues)
worker_typing.py:60:17 - information: Type of "non_class_worker" is "(...) -> Worker[bool]"
worker_typing.py:61:17 - information: Type of "NotAWidget.not_a_widget_worker" is "(...) -> Worker[bool]"
worker_typing.py:62:17 - information: Type of "MyWidget.blocking_local_worker" is "(...) -> Worker[set[str]]"
worker_typing.py:63:17 - information: Type of "MyWidget.blocking_simple_decorator" is "(self: MyWidget, value: float) -> Worker[int]"
worker_typing.py:66:17 - information: Type of "MyWidget.my_widget_worker" is "(...) -> Worker[bool]"
worker_typing.py:67:17 - information: Type of "MyWidget.blocking_threaded_worker" is "(...) -> Worker[list[str]]"
worker_typing.py:68:17 - information: Type of "MyWidget.async_threaded_worker" is "(...) -> Worker[bytes]"
worker_typing.py:69:17 - information: Type of "MyWidget.async_simple_decorator" is "(self: MyWidget, value: float) -> Worker[str]"
1 error, 0 warnings, 8 informations
# pyright: strict
from typing import reveal_type
import textual
from textual.widget import Widget
# should error - defined outside of a DOMNode class
@textual.work()
async def non_class_worker(arg1: int, arg2: str) -> bool:
return True
class NotAWidget:
# should error - class does not inherit from DOMNode
@textual.work()
async def not_a_widget_worker(self, arg1: int, arg2: str) -> bool:
return True
class MyWidget(Widget):
@textual.work()
async def my_widget_worker(self, arg1: int, arg2: str) -> bool:
return True
# should error - blocking workers not allowed with thread=False
@textual.work()
def blocking_local_worker(self, value: float) -> set[str]:
return set()
@textual.work(thread=True)
def blocking_threaded_worker(self, value: float) -> list[str]:
return []
@textual.work(thread=True, is_async=True)
async def async_threaded_worker(self, value: float) -> bytes:
return b""
# should error - blocking workers not allowed with thread=False
@textual.work
def blocking_simple_decorator(self, value: float) -> int:
return 0
@textual.work
async def async_simple_decorator(self, value: float) -> str:
return ""
async def on_mount(self) -> None:
# should error - missing parameters
self.my_widget_worker()
# should error - wrong parameter type
self.my_widget_worker("test", "hello")
# should error - wrong return type
_: str = await self.my_widget_worker(42, "don't panic").wait()
if __name__ == '__main__':
# the bad ones
reveal_type(non_class_worker)
reveal_type(NotAWidget.not_a_widget_worker)
reveal_type(MyWidget.blocking_local_worker)
reveal_type(MyWidget.blocking_simple_decorator)
# the good ones
reveal_type(MyWidget.my_widget_worker)
reveal_type(MyWidget.blocking_threaded_worker)
reveal_type(MyWidget.async_threaded_worker)
reveal_type(MyWidget.async_simple_decorator)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment