在Django中使用Pylint


140

我非常想将pylint集成到我的python项目的构建过程中,但是我遇到了一个问题:我发现一种非常有用的错误类型:-- 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的来源,请给我指出细节:)

这里对于我已经受够了问题的总结pycheckerpyflakes-他们已经被证明是远远不稳定的一般用途。(在pychecker的情况下,崩溃源于pychecker代码-并非源于正在加载/调用的源。)


4
请参阅@talweiss的帖子以获取最新答案!
布伦丹2015年


1
您能接受@talweiss的回答吗?这是最新,最正确的解决方案。
维杰瓦拉丹

Answers:


155

不要通过添加ignores或禁用或削弱Pylint功能generated-members
使用积极开发的理解 Django的Pylint插件。
这个适用于Django的Pylint插件效果很好:

pip install pylint-django

并且在运行pylint时,将以下标志添加到命令中:

--load-plugins pylint_django

详细的博客文章在这里


2
博客文章的链接已消失(很快)。这是Internet存档archive.is的
Christian Long

3
为了使其能够与Sublime Text的SublimeLinter插件一起使用,我必须添加--load-plugins=pylint_django到linters / pylint / args设置中。注意“ =”符号,没有它就无法工作。
丹尼斯·哥洛马佐夫

这是行不通的。我收到以下错误消息:E:8,0:模块'django.db'中没有名称'models'(模块中没有名称)
最大值

6
您也可以将其添加到您的pylintrc中:[MASTER] load-plugins=pylint_django
azmeuk

3
在vs代码中,它对我不起作用,直到我在用户设置中输入以下内容:{"python.linting.pylintArgs": [ "--load-plugins=pylint_django" ],} tieuminh2510的答案
ali-myousefi

63

我使用以下内容: pylint --generated-members=objects


TYPECHECK下的man pylint(1)--generated-members=<members names>由pylint推理系统动态设置并丢失的成员列表,因此在访问时不应触发E0201和E1101。[当前:REQUEST,acl_users,aq_parent]
马克·米

在PyDev / PyLint部分中的首选项下的eclipse中将其添加到PyDev中。
Mark Mikofski

2
使用生成成员只是向您隐藏了这些错误,当尝试访问错误对象上的对象字段时仍然会出现错误。请改用pylint-django插件。
Vajk Hermecz

5
这是修复Pylint的错误方法-通过禁用其某些功能。您需要做的就是安装一个了解 Django 的Pylint插件。参见stackoverflow.com/a/31000713/78234
Tal Weiss 2015年

31

我的〜/ .pylintrc包含

[TYPECHECK]
generated-members=REQUEST,acl_users,aq_parent,objects,_meta,id

最后两个是专门针对Django的。

请注意,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行)。

快乐的时光!


您应该将您的补丁提交给pylint给维护人员。
slacy 2011年

实际上他们已经在0.24中包含了此补丁,但是他们已经开始使用该shlex软件包,并且现在破坏了其他内容。我必须gen.wordchars += "[]-+"在第135行添加才能使其正常工作...
simon

4
使用生成成员只是向您隐藏了这些错误,尝试访问错误对象上的“对象”字段时仍然会出现错误。请改用pylint-django插件。
Vajk Hermecz

4
这是修复Pylint的错误方法-通过禁用其某些功能。您需要做的就是安装一个了解 Django 的Pylint插件。参见stackoverflow.com/a/31000713/78234
Tal Weiss 2015年

3
@TalWeiss-公平地说,这个答案比现在大三岁pylint-django,所以不赞成投票的人有点苛刻……
simon

27

如果您使用Visual Studio Code,请执行以下操作:

pip install pylint-django

并添加到VSC配置:

"python.linting.pylintArgs": [
    "--load-plugins=pylint_django"
],

2
迄今为止最好的回复:D
serfer2

19

django-lint是一个不错的工具,它使用django特定的设置包装pylint:http ://chris-lamb.co.uk/projects/django-lint/

github项目:https : //github.com/lamby/django-lint


1
我喜欢特定于Django的pylint的想法,但上次尝试时似乎遇到了很多问题。
2010年

3
此外,它还不能通过PyPI使用,并且该网站似乎没有提供足够的信息,例如:当前版本是什么?
2010年

1
我喜欢这个概念,但是这种实现只是半生不熟,并且在任何中等大小的代码库上都无法实现。要使它真正有用,还有很长的路要走。
Cerin

1
@gurney alex,链接已死。
穿梭车

2
看起来pylint-django现在更加活跃,这应该是建议的解决方案。
Vajk Hermecz

16

由于pylint的工作方式(它在不让Python实际执行的情况下检查源代码本身)对pylint来说很难弄清楚元类和复杂的基类实际上如何影响类及其实例。在这方面,“ pychecker”工具要好一些,因为它确实允许Python执行代码。它导入模块并检查生成的对象。但是,该方法还有其他问题,因为它确实允许Python执行代码:-)

您可以扩展pylint来教它有关Django所使用的魔术的知识,或者使它更好地理解元类或复杂的基类,或者在检测到一个或多个它不太了解的功能之后忽略这些情况。我认为这不会特别容易。您还可以通过源代码中的特殊注释,命令行选项或.pylintrc文件,告诉pylint不要警告这些事情。


3
教Pylint关于Django并不容易,但是已经完成了:您需要做的就是安装一个了解 Django 的Pylint插件。参见stackoverflow.com/a/31000713/78234
Tal Weiss

好吧,我安装了它,但是它仍然像QuerySet一样没有删除
薄层

7

我从使用pylint / pychecker辞职,转而将pyflakes与Django代码一起使用-它只是尝试导入模块并报告发现的任何问题,例如未使用的导入或未初始化的本地名称。


有趣-我会再给pyflakes看。
rcreswick


1
无需放弃Pylint-您所需要做的就是安装一个了解 Django 的Pylint插件。参见stackoverflow.com/a/31000713/78234
Tal Weiss

7

这不是解决方案,但是您可以在objects = models.Manager()不更改任何行为的情况下将其添加到Django模型中。

我本人只使用pyflakes,主要是因为我的部分pylint和惰性有些愚蠢的默认设置(不想查看如何更改默认设置)。


啊...谢谢小费。我可以尝试将其添加到django源的本地副本中的Model.models中,然后查看是否这样做。
rcreswick

我认为这是一个很好的解决方案,因为它不会在警告方面妥协。
汤姆·莱斯

1
这是一个不好的解决方案。重复自己并替换可行的内容,稍后将更改(从而引入质量检查问题),只是为了解决不完整的质量检查工具?
克里斯·摩根

2
我不会称这为不好的解决方案:显式比隐式更好。objects无论如何,也许不应该魔术般地添加它。
Will Hardy 2013年

1
我认为这是修复Pylint的错误方法-从某种意义上修补Django。您需要做的就是安装一个了解 Django 的Pylint插件。参见stackoverflow.com/a/31000713/78234
Tal Weiss,2015年

5

尝试与运行pylint

pylint --ignored-classes=Tags

如果可行,添加所有其他Django类-可能使用脚本,例如python:P

该文档--ignore-classes是:

--ignored-classes=<members names>
不应检查其成员属性的类名列表(对于动态设置了属性的类很有用)。[当前:%default]

我认为这并不是一个特别优雅的解决方案,但应该可以。


仅当我从未在这些类中犯任何错误时,它才有效;)。我想尽可能避免忽略代码-我认为让代码库的不同部分分析不同程度的审查是一个非常糟糕的主意。我会忘记是哪一个,并且在调试时会做出错误的假设
rcreswick

1
这是修复Pylint的错误方法-通过禁用其某些功能。您需要做的就是安装一个了解 Django 的Pylint插件。参见stackoverflow.com/a/31000713/78234
Tal Weiss


1

到目前为止,我没有找到真正的解决方案,但是可以解决:

  • 在我们公司,我们要求pylint得分>8。这允许pylint无法理解编码实践,同时确保代码不太“异常”。到目前为止,我们还没有看到E1101阻止我们达到8分或更高分数的情况。
  • 我们的“ make check”目标过滤掉“ for has no'objects member”消息,以消除由于pylint不了解Django引起的大部分干扰。

0

对于neovim & vim8使用w0rp's ale插件。如果您已经安装了正确的一切,包括w0rp's alepylintpylint-django。在您的代码中vimrc添加以下内容,并享受使用django开发Web应用程序的乐趣。谢谢。

let g:ale_python_pylint_options = '--load-plugins pylint_django'
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.