【发布时间】:2017-12-27 08:07:16
【问题描述】:
提供详细信息:这是一个受限环境,包含 Python 2.7.14、Pylint 1.8.1 和 Astroid 1.6.0 以及各种其他模块,但我无法轻松安装新模块,例如 mypy(甚至使用 virtualenv)或对代码库进行重大更改。
由于https://github.com/PyCQA/pylint/issues/400,我的某些代码的 pylint 出现错误。我已经以一种骇人听闻的方式解决了这个问题(通过删除 wait() 方法的整数参数),现在我没有收到错误,但没有进行检查(pylint 无法确定变量的类型完全没有)。
我真正想做的是告诉 pylint 返回类型是什么。我已经尝试阅读 Astroid 文档,仔细阅读各种 astroid/brains 文件,并查看其他 SO 问题和答案,例如Set multiple inferred types based on arguments for pylint plugin 和pylint, coroutines, decorators and type inferencing,但我想我只是不明白。我添加了自己的load-plugins,并且我知道它是在 pylint 期间加载的(因为它一开始有语法错误:))。但我只是不确定它需要做什么。
假设我有这个代码:
class Peer(object):
def get_domain(self):
return "foo"
class TestListener(object):
def __init__(self):
self._latest = None
def get(self, timeout):
# tricks here
return self._latest
def peer_joined(self, peer):
self._latest = peer
peer = TestListener().get(3)
print(peer.get_domain())
print(peer.get_foo())
在# tricks here 期间,我们确实在等待threading.Event(),在此期间,另一个线程将调用peer_joined() 并传递Peer() 类型的对象,但pylint 并不理解这一点。
我想做的是注释 TestListener.get() 方法告诉 pylint 它将返回一个 Peer 对象,以便 pylint 将在第二次打印调用中捕获错误。
我已经尝试过了,但显然我遗漏了一些基本的东西,因为我的转换方法似乎从未被调用过(如果我调用了一个虚假的方法调用,则不会打印任何错误):
from astroid import MANAGER, register_module_extender
from astroid.builder import AstroidBuilder
def TestListener_transform():
return AstroidBuilder(MANAGER).string_build('''
class TestListener(object):
def get(self, timeout):
return Peer()
''')
register_module_extender(MANAGER, 'TestListener', TestListener_transform)
# for pylint load-plugins
def register(linter):
pass
【问题讨论】:
-
我认为 mypy(静态类型)会是一个更好的工具。你考虑过吗?
-
不幸的是,我处于一个受限制的环境中,无法轻松添加大量新模块,而 pylint 是我可用的。
-
添加文档字符串没有帮助;请参阅下面的答案。所以我不认为这是重复的。谢谢!