OiO.lk Community platform!

Oio.lk is an excellent forum for developers, providing a wide range of resources, discussions, and support for those in the developer community. Join oio.lk today to connect with like-minded professionals, share insights, and stay updated on the latest trends and technologies in the development field.
  You need to log in or register to access the solved answers to this problem.
  • You have reached the maximum number of guest views allowed
  • Please register below to remove this limitation

How to type annotate a decorator to make it Override-friendly?

  • Thread starter Thread starter luochen1990
  • Start date Start date
L

luochen1990

Guest
I find that adding type annotation for a decorator will cause typing error in overriding case in VSCode Pylance strict mode. following is a minimal-complete-example (in Python3.8 or later?):

Code:
from datetime import datetime
from functools import wraps
from typing import Any

_persistent_file = open("./persistent.log", "a")

def to_json(obj: Any) -> str:
    ...

def persistent(class_method: ...):
    @wraps(class_method)
    async def _class_method(ref: Any, *args: Any):
        rst = await class_method(ref, *args)
        print(f'{ datetime.now().strftime("%Y-%m-%d %H:%M:%S") } { to_json(args) } { to_json(rst) }', file=_persistent_file)
        return rst
    return _class_method

class A:
    async def f(self, x: int):
        return x

class B (A):
    @persistent
    async def f(self, x: int):
        return x + 1

Here, B.f will be marked as type error in pylance:

Code:
"f" overrides method of same name in class "A" with incompatible type "_Wrapped[(...), Any, (ref: Any, *args: Any), Coroutine[Any, Any, ...]]"

Pylance (reportIncompatibleMethodOverride)

And I find that remove @wraps will workaround this issue, but I need it to keep the metadata of the function (e.g. __name__).

Hoping for a perfect solution.
<p>I find that adding type annotation for a decorator will cause typing error in overriding case in <strong>VSCode Pylance strict mode</strong>. following is a minimal-complete-example (in Python3.8 <em>or later?</em>):</p>
<pre><code>from datetime import datetime
from functools import wraps
from typing import Any

_persistent_file = open("./persistent.log", "a")

def to_json(obj: Any) -> str:
...

def persistent(class_method: ...):
@wraps(class_method)
async def _class_method(ref: Any, *args: Any):
rst = await class_method(ref, *args)
print(f'{ datetime.now().strftime("%Y-%m-%d %H:%M:%S") } { to_json(args) } { to_json(rst) }', file=_persistent_file)
return rst
return _class_method

class A:
async def f(self, x: int):
return x

class B (A):
@persistent
async def f(self, x: int):
return x + 1
</code></pre>
<p>Here, <code>B.f</code> will be marked as type error in pylance:</p>
<pre><code>"f" overrides method of same name in class "A" with incompatible type "_Wrapped[(...), Any, (ref: Any, *args: Any), Coroutine[Any, Any, ...]]"

Pylance (reportIncompatibleMethodOverride)
</code></pre>
<p>And I find that remove <code>@wraps</code> will workaround this issue, but I need it to keep the metadata of the function (e.g. <code>__name__</code>).</p>
<p>Hoping for a perfect solution.</p>
 

Online statistics

Members online
0
Guests online
2
Total visitors
2
Top