talonvoice / talon

Issue Tracker for the main Talon app
85 stars 0 forks source link

using type variables can result in ActionImplError on module reload #429

Open rntz opened 2 years ago

rntz commented 2 years ago

generictypes.py

from talon import Module, Context
from typing import TypeVar

mod = Module()
ctx = Context()

T = TypeVar("T")

@mod.action_class
class Actions:
    def foo(x: T):
        """"""
        pass

@ctx.action_class('user')
class ContextActions:
    def foo(x: T):
        pass

force the above file to get reloaded (eg. edit it) and you will receive the following error:

2021-11-16 23:54:51 DEBUG [~] /home/rntz/.talon/user/regression/generictypes.py
2021-11-16 23:54:51 ERROR user.regression.generictypes (/home/rntz/.talon/user/regression/generictypes.py) import failed
   18:          lib/python3.9/threading.py:930* # cron thread
   17:          lib/python3.9/threading.py:973* 
   16:          lib/python3.9/threading.py:910* 
   15:                       talon/cron.py:155| 
   14:                       talon/cron.py:106| 
   13:                         talon/fs.py:64 | 
   12:                         talon/fs.py:57 | 
   11:             talon/scripting/rctx.py:233| # 'fs' main:on_change()
   10:             app/resources/loader.py:689| 
    9:             app/resources/loader.py:639| 
    8:             app/resources/loader.py:413| # [stack splice]
    7: lib/python3.9/importlib/__init__.py:127| 
    6:             app/resources/loader.py:243| 
    5:             app/resources/loader.py:238| 
    4:     user/regression/generictypes.py:16 | class ContextActions:
    3:          talon/scripting/context.py:360| 
    2:          talon/scripting/context.py:379| 
    1:            talon/scripting/types.py:151| 
talon.scripting.types.ActionImplError: Function 'user.foo' incompatible with prototype 'user.foo'
  Signature: (x: ~T)
  Expected:  (x: ~T)
  - Parameter 'x' type annotation does not match prototype. Found '~T', expected '~T' (or no annotation)

An error like this was occurring in the wild in knausj with the function create_spoken_forms_from_map, although the cause of this behavior appears to be far more subtle in that case.

lunixbochs commented 2 years ago

The difference with create_spoken_forms_from_map, is the call happens during the update_decls event. I've been thinking about it and I'm not sure it's actually safe to call actions during that callback, so I might disallow actions during that specific event.

(The repro reported in this issue has a different solution but afaik no user has actually hit it)