我非常希望将pylint集成到我的python项目的构建过程中,但我遇到了一个show-stopper:我觉得非常有用的一种错误类型 - :E1101: *%s %r has no %r
member*
- 在使用常见的django时不断报告错误字段,例如:
E1101:125:get_user_tags: Class 'Tag' has no 'objects' member
这是由这段代码引起的:
def get_user_tags(username):
"""
Gets all the tags that username has used.
Returns a query set.
"""
return Tag.objects.filter( ## This line triggers the error.
tagownership__users__username__exact=username).distinct()
# Here is the Tag class, models.Model is provided by Django:
class Tag(models.Model):
"""
Model for user-defined strings that help categorize Events on
on a per-user basis.
"""
name = models.CharField(max_length=500, null=False, unique=True)
def __unicode__(self):
return self.name
如何调整Pylint以正确考虑对象等字段? (我也查看了Django源代码,我一直无法找到objects
的实现,所以我怀疑它不仅仅是“一个”类字段。另一方面,我对python来说相当新,所以我很可能忽视了一些事情。)
编辑:我发现告诉pylint没有警告这些警告的唯一方法是阻止所有类型的错误(E1101)这是不可接受的解决方案,因为(在我看来)这是一个非常有用的错误。如果有另一种方式,没有增加pylint源,请指出具体信息:)
请参阅here,了解我与pychecker
和pyflakes
所遇到的问题的总结 - 它们已被证明对于一般用途来说是不稳定的。 (在pychecker的情况下,崩溃起源于pychecker代码 - 而不是源代码正在加载/调用。)
不要通过添加ignores
或generated-members
来禁用或削弱Pylint功能。
使用一个了解Django的积极开发的Pylint插件。
This Pylint plugin for Django工作得很好:
pip install pylint-django
当运行pylint时,在命令中添加以下标志:
--load-plugins pylint_django
详细的博客文章here。
在这个other question中提出的解决方案只需将get_attr添加到Tag类中。丑,但有效。
到目前为止,我找不到真正的解决方案,但解决方法:
对于neovim & vim8
使用w0rp's ale
插件。如果您已经正确安装了所有内容,包括w0rp's ale
,pylint
和pylint-django
。在您的vimrc
中添加以下行并使用django开发Web应用程序。谢谢。
let g:ale_python_pylint_options = '--load-plugins pylint_django'
我使用以下内容:pylint --generated-members=objects
我的〜/ .pylintrc包含
[TYPECHECK]
generated-members=REQUEST,acl_users,aq_parent,objects,_meta,id
最后两个是专门为Django。
请注意,有一个bug in PyLint 0.21.1需要修补才能完成这项工作。
编辑:经过多次讨论之后,我决定稍微破解PyLint以允许我将上述内容扩展为:
[TYPECHECK]
generated-members=REQUEST,acl_users,aq_parent,objects,_meta,id,[a-zA-Z]+_set
我简单地说:
import re
for pattern in self.config.generated_members:
if re.match(pattern, node.attrname):
return
在错误报告中提到的修复之后(即,在第129行)。
快乐的时光!
如果您使用Visual Studio代码,请执行以下操作:
pip install pylint-django
并添加到VSC配置:
"python.linting.pylintArgs": [
"--load-plugins=pylint_django"
],
django-lint是一个很好的工具,用django特定设置包装pylint:http://chris-lamb.co.uk/projects/django-lint/
github项目:https://github.com/lamby/django-lint
由于pylint如何工作(它检查源本身,而不让Python实际执行它),因此pylint很难弄清楚元类和复杂基类实际上如何影响类及其实例。 'pychecker'工具在这方面要好一些,因为它实际上让Python执行代码;它导入模块并检查生成的对象。但是,这种方法还有其他问题,因为它实际上让Python执行代码:-)
你可以扩展pylint来教它关于Django使用的魔法,或者让它更好地理解元类或复杂的基类,或者在检测到一个或多个它不太明白的特性之后忽略这些情况。我认为这不会特别容易。您也可以通过源代码,命令行选项或.pylintrc文件中的特殊注释告诉pylint不要警告这些事情。
我辞职了使用pylint / pychecker而不是使用带有Django代码的pyflakes - 它只是尝试导入模块并报告它找到的任何问题,例如未使用的导入或未初始化的本地名称。
这不是解决方案,但您可以在不改变任何行为的情况下将objects = models.Manager()
添加到Django模型中。
我自己只使用pyflakes,主要是由于我的pylint和懒惰的一些哑默认(不想查找如何更改默认值)。
尝试运行pylint
pylint --ignored-classes=Tags
如果可以的话,添加所有其他Django类 - 可能使用脚本,比如python:P
--ignore-classes
的文档是:
--ignored-classes=<members names>
不应检查成员属性的类名列表(对于具有动态设置属性的类很有用)。 [当前:%默认]
我应该补充一点,在我看来,这不是一个特别优雅的解决方案,但它应该有效。