在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源,请指出我的具体情况:)
在这里可以看到我用pychecker
和pyflakes
所遇到的问题的总结 – 他们已经被certificate对于一般用途来说是非常不稳定的。 (pychecker的情况下,崩溃起源于pychecker代码 – 不是来源加载/调用。)
不要通过添加ignores
或generated-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类中。 丑,但工作。