PyCharm无法推断@cache-d方法的返回类型

sg24os4d  于 12个月前  发布在  PyCharm
关注(0)|答案(1)|浏览(236)

PyCharm的类型检查器可以很好地工作:

from functools import cache

class MyType:
  pass

@cache
def f() -> MyType:
  ...

v = f()  # v: MyType

字符串
但不是这个

class C:

  @cache
  def m(self) -> MyType:
    ...

v = C().m()  # v: Any


我应该怎么做才能获得好的自动完成功能?

wdebmtf2

wdebmtf21#

这是YouTrack/PY-49635(截至2023年11月开放)。
我目前的解决方法如下:

from functools import cache
from typing import TypeVar

if TYPE_CHECKING:
  # To be read by mypy and other proper typecheckers

  _cache = cache

else:
  # To be read by PyCharm
  # This is not actually type-safe since T is unbound, but whatever.

  T = TypeVar('T')

  def _cache(function: T) -> T:
    '''
    Workaround for `PY-49635\
    <https://youtrack.jetbrains.com/issue/PY-49635>`_.
        
    :param function: A callable.
    :return: The same callable, wrapped in :func:`functools.cache`.
    '''
        
    return cache(function)

字符串
else块中的任何内容都应该被类型检查器忽略,并且总是由解释器运行。然而,PyCharm并不荣誉这一点。在某种程度上,这是好的:它允许我们编写不会引起任何不必要的警告的代码。Mypy/Pyright/Your-decent-typechecker足够聪明,可以对我们的解决方法视而不见,PyCharm也足够宽容,不会警告我们。
这是非常脆弱的,可能会在未来的PyCharm版本中打破。也就是说,如果JetBrains的家伙“修复”这种行为。
使用方法:

@_cache
def f() -> YourType:
  ...

class C:

  @_cache
  def m(self) -> YourType:
    ...

v = f()      # v: YourType
v = C().m()  # v: YourType


上面的解决方法在PyCharm 2023.2.5中有效。我还没有在其他版本中测试过。

相关问题