How to typecheck a decorator that does not return a function in a class body? #11342
Replies: 1 comment
|
The short version: you can't fix this from That diagnostic fires when pyright analyses the I tried the obvious ways to signal it from the decorator, all on pyright 1.1.411, and none of them move it: def wrapper_any(f: Callable[[Any], str]) -> str: ... # widen the parameter
class E:
@wrapper_any
def foo(x: int): ... # still: parameter "x" must be a supertype of its class "E"
class Taking(Protocol): # Protocol, positional-only
def __call__(self, x: int, /) -> str: ...
class F:
@wrapper_proto
def foo(x: int, /): ... # still errors
class G:
@wrapper
def foo(x: int, /): ... # positional-only on the def: still errorsNaming the parameter So class B:
@wrapper
@staticmethod
def foo(x: int) -> str:
return "B" * x
reveal_type(B.foo) # str
b = B()
reveal_type(b.foo) # strIf the extra line per function is the real problem, the other clean option is to define the functions outside the class body and apply the wrapper on assignment — same result type, no def _foo(x: int) -> str:
return "H" * x
class H:
foo = wrapper(_foo)
reveal_type(H.foo) # str
reveal_type(H().foo) # strBoth check clean. Which one is less noise depends on whether the bodies are worth keeping next to each other in the class, or whether they'd read fine as module-level functions — with "a LOT of lines" it's probably the second, since you also stop repeating the decorator entirely and get to group the plain functions however you like. The one thing neither form gives you is a way to keep the current syntax exactly as written, so if that was the goal, this is the point to abandon it. |
Uh oh!
There was an error while loading. Please reload this page.
This code works, but pyright thinks the x: int annotation is conflicting with it being typed as Self@A:
error: Type of parameter "x" must be a supertype of its class "A". Clearly I'm missing something to communicate to the type checker that this body shouldn't be interpreted as an instance method. I can write staticmethod and that works but I would really like to find some solution that just adjusts the signature and body ofwrappersince this is gonna be a LOT of lines in the code I'm trying to write.All reactions