在Django中使用Pylint

我非常想将pylint整合到我的python项目的构build过程中,但是我遇到了一个显示终止器:我发现其中一个非常有用的错误types – : 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的源代码,我一直无法findobjects的实现,所以我怀疑它不是“只是”一个类的字段。另一方面,我是相当新的Python,所以我可能已经忽略了一些东西。)

编辑:我发现告诉pylint不警告这些警告的唯一方法是通过阻止types(E1101)这不是一个可接受的解决scheme,因为这是(在我看来)一个非常有用的错误的所有错误。 如果有另一种方式,而不是增加pylint源,请指出我的具体情况:)

在这里可以看到我用pycheckerpyflakes所遇到的问题的总结 – 他们已经被certificate对于一般用途来说是非常不稳定的。 (pychecker的情况下,崩溃起源于pychecker代码 – 不是来源加载/调用。)

不要通过添加ignoresgenerated-members禁用或削弱Pylintfunction。
使用一个积极开发的理解 Django的Pylint插件。
Django的这个Pylint插件工作得很好:

 pip install pylint-django 

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

 --load-plugins pylint_django 

这里详细的博客文章。

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

我的〜/ .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 

在bug报告中提到的修复之后(即在第129行)。

快乐的时光!

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使用的魔法,或者使它更好地理解元类或复杂的基类,或者在检测到一个或多个不太明白的特征之后忽略这些情况。 我不认为这会特别容易。 你也可以告诉pylint不要警告这些东西,通过源,命令行选项或.pylintrc文件中的特殊注释。

这不是一个解决scheme,但是你可以添加objects = models.Manager()到你的Django模型而不改变任何行为。

我自己只使用pyflakes,主要是由于pylint和懒惰在我的一些愚蠢的默认(不想查找如何更改默认值)。

我放弃了使用pylint / pychecker而倾向于使用带有Django代码的pyflakes – 它只是尝试导入模块并报告find的任何问题,如未使用的导入或未初始化的本地名称。

尝试运行pylint

 pylint --ignored-classes=Tags 

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

--ignore-classes的文档是:

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

我应该补充一点,在我看来,这不是一个特别优雅的解决scheme,但应该起作用。

到目前为止,我找不到真正的解决scheme,但解决方法:

  • 在我们公司,我们需要一个大于8的pylint分数。这允许编码实践pylint不理解,同时确保代码不是太“不寻常”。 到目前为止,我们还没有看到E1101让我们达不到8分或更高的分数。
  • 我们的“检查”目标过滤掉“没有”对象的“成员”消息,以消除大多数不知道Django的pylint引起的分心。

在这个问题中提出的解决scheme只是简单地将get_attr添加到您的Tag类中。 丑,但工作。