Usando Pylint con Django

Me gustaría mucho integrar pylint en el proceso de comstackción de mis proyectos de python, pero me he topado con un solo factor de E1101: *%s %r has no %r member* uno de los tipos de error que encuentro extremadamente útil–: E1101: *%s %r has no %r member* constantemente informa de errores cuando se usan campos de django comunes, por ejemplo:

 E1101:125:get_user_tags: Class 'Tag' has no 'objects' member 

que es causada por este código:

 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 

¿Cómo puedo ajustar Pylint para tener en cuenta campos como los objetos? (También he buscado en la fuente de Django y no he podido encontrar la implementación de objects , así que sospecho que no es “solo” un campo de clase. Por otro lado, soy bastante nuevo en Python, así que Es muy posible que haya pasado por alto algo.

Edición: la única forma que he encontrado para indicar a pylint que no advierta sobre estas advertencias es mediante el locking de todos los errores del tipo (E1101), que no es una solución aceptable, ya que (en mi opinión) es un error extremadamente útil. Si hay otra forma, sin boost la fuente del pylint, indíqueme los detalles 🙂

Vea aquí un resumen de los problemas que he tenido con pychecker y pyflakes : se ha demostrado que son demasiado inestables para el uso general. (En el caso de pychecker, los lockings se originaron en el código de pychecker, no en la fuente que se estaba cargando / invocando).

No deshabilite ni debilite la funcionalidad de Pylint agregando ignores o generated-members .
Utilice un complemento de Pylint desarrollado activamente que comprenda a Django.
Este plugin de Pylint para Django funciona bastante bien:

 pip install pylint-django 

y al ejecutar pylint, agregue la siguiente bandera al comando:

 --load-plugins pylint_django 

Publicación detallada del blog aquí .

Uso lo siguiente: pylint --generated-members=objects

Mi ~ / .pylintrc contiene

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

Los dos últimos son específicamente para Django.

Tenga en cuenta que hay un error en PyLint 0.21.1 que necesita parches para que esto funcione.

Edit: Después de jugar un poco más con esto, decidí hackear PyLint solo un poquito para que me permitiera expandir lo anterior a:

 [TYPECHECK] generated-members=REQUEST,acl_users,aq_parent,objects,_meta,id,[a-zA-Z]+_set 

Simplemente agregué:

  import re for pattern in self.config.generated_members: if re.match(pattern, node.attrname): return 

después de la corrección mencionada en el informe de error (es decir, en la línea 129).

¡Días felices!

django-lint es una buena herramienta que envuelve pylint con configuraciones específicas de django: http://chris-lamb.co.uk/projects/django-lint/

Proyecto github: https://github.com/lamby/django-lint

Debido a la forma en que funciona pylint (examina la fuente en sí misma, sin dejar que Python la ejecute) es muy difícil para pylint descubrir cómo las metaclases y las clases de base complejas realmente afectan a una clase y sus instancias. La herramienta ‘pychecker’ es un poco mejor en este sentido, ya que realmente permite que Python ejecute el código; Importa los módulos y examina los objetos resultantes. Sin embargo, ese enfoque tiene otros problemas, ya que realmente permite que Python ejecute el código 🙂

Podría extender pylint para enseñarle sobre la magia que usa Django, o para hacer que entienda mejor las metaclases o las clases básicas complejas, o simplemente ignorar estos casos después de detectar una o más funciones que no comprende. No creo que sea particularmente fácil. También puede decirle a pylint que no avise sobre estas cosas, a través de comentarios especiales en la fuente, las opciones de la línea de comandos o un archivo .pylintrc.

Si usas Visual Studio Code haz esto:

pip install pylint-django

Y añada a la configuración de VSC:

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

Renuncié al uso de pylint / pychecker en lugar de usar pyflakes con el código Django; simplemente intenta importar el módulo e informar cualquier problema que encuentre, como las importaciones no utilizadas o los nombres locales sin inicializar.

Esto no es una solución, pero puede agregar objects = models.Manager() a sus modelos de Django sin cambiar ningún comportamiento.

Yo solo uso pyflakes, principalmente debido a algunos fallos estúpidos en pylint y la pereza de mi parte (sin querer buscar la forma de cambiar los valores predeterminados).

Intenta ejecutar Pylint con

 pylint --ignored-classes=Tags 

Si eso funciona, agregue todas las demás clases de Django, posiblemente utilizando un script, por ejemplo, python: P

La documentación para --ignore-classes es:

--ignored-classes=
Lista de nombres de clases para los cuales no se deben verificar los atributos de los miembros (útil para las clases con atributos establecidos dinámicamente). [actual:% por defecto]

Debo añadir que esto no es una solución elegante en particular, pero debería funcionar.

La solución propuesta en esta otra pregunta es simplemente agregar get_attr a su clase de etiqueta. Feo, pero funciona.

Hasta el momento no he encontrado una solución real a eso, pero solucionando:

  • En nuestra empresa, requerimos una puntuación de pylint> 8. Esto permite las prácticas de encoding que pylint no comprende, al tiempo que garantiza que el código no sea demasiado “inusual”. Hasta ahora no hemos visto ningún caso en el que el E1101 nos haya impedido alcanzar una puntuación de 8 o superior.
  • Nuestros objectives de “verificar” filtran “porque no tiene ningún miembro ‘objeto'” para eliminar la mayor parte de la distracción causada por el pylint que no comprende a Django.

Para neovim & vim8 use el w0rp's ale . Si ha instalado todo correctamente, incluyendo w0rp's ale , pylint & pylint-django . En su vimrc agregue la siguiente línea y diviértase desarrollando aplicaciones web usando django. Gracias.

 let g:ale_python_pylint_options = '--load-plugins pylint_django' 
  1. Vaya a la configuración en VSC presionando Ctrl +,
  2. Presione Ctrl + Shift + p, escriba Python: Select Linter
  3. Seleccione mypy de la lista desplegable
  4. Instalar mypy si se le solicita.