admin管理员组文章数量:1318569
I want to define a decorator as a class to decorate another class's methods.
However, when __init__()
constructor is decorated with that class, mypy reports Unsupported decorated constructor type
error.
Is there any error in my code? Or, is this a bug in mypy?
from types import MethodType
from typing import TypeVar, Callable, Type, ParamSpec, Generic
T = TypeVar("T")
P = ParamSpec("P")
R = TypeVar("R")
class method_decorator(Generic[P, R]):
def __init__(self, method: Callable[P, R]):
self.method = method
def __get__(self, instance: T, cls: Type[T]) -> Callable[..., R]:
return MethodType(self, instance)
def __call__(self, *args: P.args, **kwargs: P.kwargs) -> R:
return self.method(*args, **kwargs)
class Foo:
@method_decorator # error: Unsupported decorated constructor type [misc]
def __init__(self, x: int):
self.x = x
@method_decorator
def mul(self, a: int) -> int:
return self.x * a
def gen_foo(x: int) -> Foo:
return Foo(x) # error: Returning Any from function declared to return "Foo" [no-any-return]
foo = gen_foo(2)
print(foo.mul(3))
Type check result (with MyPy v1.13.0):
$ mypy --strict test.py
test.py:19: error: Unsupported decorated constructor type [misc]
test.py:28: error: Returning Any from function declared to return "Foo" [no-any-return]
Found 2 errors in 1 file (checked 1 source file)
I want to define a decorator as a class to decorate another class's methods.
However, when __init__()
constructor is decorated with that class, mypy reports Unsupported decorated constructor type
error.
Is there any error in my code? Or, is this a bug in mypy?
from types import MethodType
from typing import TypeVar, Callable, Type, ParamSpec, Generic
T = TypeVar("T")
P = ParamSpec("P")
R = TypeVar("R")
class method_decorator(Generic[P, R]):
def __init__(self, method: Callable[P, R]):
self.method = method
def __get__(self, instance: T, cls: Type[T]) -> Callable[..., R]:
return MethodType(self, instance)
def __call__(self, *args: P.args, **kwargs: P.kwargs) -> R:
return self.method(*args, **kwargs)
class Foo:
@method_decorator # error: Unsupported decorated constructor type [misc]
def __init__(self, x: int):
self.x = x
@method_decorator
def mul(self, a: int) -> int:
return self.x * a
def gen_foo(x: int) -> Foo:
return Foo(x) # error: Returning Any from function declared to return "Foo" [no-any-return]
foo = gen_foo(2)
print(foo.mul(3))
Type check result (with MyPy v1.13.0):
$ mypy --strict test.py
test.py:19: error: Unsupported decorated constructor type [misc]
test.py:28: error: Returning Any from function declared to return "Foo" [no-any-return]
Found 2 errors in 1 file (checked 1 source file)
Share
Improve this question
asked Jan 21 at 11:13
s417-lamas417-lama
934 bronze badges
5
|
1 Answer
Reset to default 2This just isn't supported by mypy
, it only understands simple callable decorators on __init__
and __new__
as of 1.14.1. Here's the relevant part:
if e.func.info and e.func.name in ("__init__", "__new__"):
if e.type and not isinstance(get_proper_type(e.type), (FunctionLike, AnyType)):
self.fail(message_registry.BAD_CONSTRUCTOR_TYPE, e)
本文标签:
版权声明:本文标题:python - MyPy "Unsupported decorated constructor type" error when decorating __init__() with a class decorator 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742046886a2417839.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
__init__
needs to returnNone
; I assume theAny
is the bound of yourTypeVar R
. Be aware thatinstance
can also be None in your decorator class; i.e. if you useFoo.__init__
. – Daraan Commented Jan 21 at 11:54reveal_type()
for the decorated__init__()
method showedRevealed type is "test.method_decorator[[self: test.Foo, x: builtins.int], None]
. This suggests thatR
is correctly bound toNone
. – s417-lama Commented Jan 21 at 12:00reveal_type(Foo.__init__) and reveal_type(Foo().__init__)
I get two timesAny
(playground, which is also the reasonreveal_type(Foo())
isAny
and you get theReturning Any from function declared to return Foo
error. With which settings are you getting your output, is it really from mypy? – Daraan Commented Jan 21 at 13:45reveal_type(__init__)
just below the__init__()
definition. – s417-lama Commented Jan 22 at 1:26method_decorator.__init__
which is not really useful as this does not yet invoke the descriptor protocol. At all other access points it will be the result of that object's__get__
which is were we need to put the focus that this one is typed like we need. – Daraan Commented Jan 22 at 8:57