2008-09-22 15 views
113

me gustaría mucho para integrar pylint en el proceso de construcción de mis proyectos Python, pero se han topado con un show-tapón: Uno de los tipos de error que me parece extremadamente useful--: E1101: *%s %r has no %r member* --constantly informes de errores al usar campos Django comunes, por ejemplo: Pylint con Django

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 sintonizar a Pylint tomar apropiadamente campos como objetos en cuenta? (También investigué el origen 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, por lo que yo puedo muy bien haber pasado por alto algo)

Editar:. la única forma que he encontrado para contar pylint a no advertir acerca de estas advertencias es mediante el bloqueo de todos los errores del tipo (E1101), que no es una solución aceptable , ya que eso es (en mi opinión) un error extremadamente útil. Si hay otra manera, sin aumentar la fuente pylint, por favor que me señale detalles :)

Ver here para un resumen de los problemas que he tenido con pychecker y pyflakes - que han demostrado ser muy inestable a para uso general. (En el caso de pychecker, los bloqueos se originaron en el código pychecker, no en el origen que estaba cargando/invocando)

+3

ver el post de @ talweiss por respuesta-actualizada! – Brendan

+0

Se encontró una buena solución en http://stackoverflow.com/a/31000713/78234 – shahjapan

+0

¿Puede aceptar la respuesta de @talweiss? Es la solución más actualizada y correcta. –

Respuesta

16

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

Puede ampliar la lista para enseñarle sobre la magia que utiliza Django, o para hacer que entienda mejor las metaclases o clases base complejas, o simplemente ignórelos después de detectar una o más características que no comprende del todo. No creo que sea particularmente fácil. También puede indicarle a pylint que no advierta sobre estas cosas, a través de comentarios especiales en la fuente, opciones de línea de comandos o un archivo .pylintrc.

+3

No es fácil enseñar Pylint sobre Django, pero ya está hecho: Todo lo que necesita hacer es instalar un plugin Pylint que ** entienda ** Django. Ver http://stackoverflow.com/a/31000713/78234 –

5

Try pylint corriendo con

pylint --ignored-classes=Tags 

Si funciona, añadir todas las otras clases de Django - posiblemente usando un script, en, por ejemplo, pitón: P

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

--ignored-classes=<members names>
List of classes names for which member attributes should not be checked (useful for classes with attributes dynamicaly set). [current: %default]

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

+0

Solo funciona si nunca hago ningún error en esas clases;). Quiero evitar ignorar el código si es posible; creo que es una muy mala idea analizar distintas partes de la base de código con diferentes grados de escrutinio. Olvidaré cuál es cuál y haré suposiciones falsas al depurar – rcreswick

+1

Esta es la manera incorrecta de reparar Pylint, al deshabilitar parte de su funcionalidad. Todo lo que necesita hacer es instalar un plugin Pylint que ** entienda ** Django. Ver http://stackoverflow.com/a/31000713/78234 –

6

Renuncié al uso de pylint/pychecker a favor de usar pyflakes con el código Django; solo trata de importar el módulo e informa cualquier problema que encuentre, como importaciones no utilizadas o nombres locales no inicializados.

+0

interesante - Le daré a pyflakes otra mirada. – rcreswick

+2

PyChecker capta mucho menos que la pildora. http://www.doughellmann.com/articles/CompletelyDifferent-2008-03-linters/index.html –

+1

No es necesario renunciar a Pylint: todo lo que necesita hacer es instalar un plugin Pylint que ** entienda ** Django. Ver http://stackoverflow.com/a/31000713/78234 –

7

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

Yo solo uso pyflakes, principalmente debido a algunos valores predeterminados tontos en la pildora y la pereza de mi parte (no quiero buscar cómo cambiar los valores predeterminados).

+0

Ah ... gracias por la sugerencia. Puedo intentar simplemente agregar eso a Model.models en la copia local de la fuente django, y ver si eso lo hace. – rcreswick

+0

Creo que esta es una gran solución porque no compromete las advertencias. –

+1

Esta es una * mala * solución. Repitiéndose usted mismo y reemplazando algo que es factible, cambiará más adelante (lo que introduce un problema de control de calidad), solo para arreglar una herramienta de control de calidad incompleta. –

2

Hasta el momento no he encontrado ninguna solución real a eso, sino evitar:

  • En nuestra empresa se requiere un pylint puntuación> 8. Esto permite la codificación prácticas pylint no entiende garantizando al mismo tiempo que el código no es demasiado "inusual". Hasta ahora no hemos visto ninguna instancia donde E1101 nos mantuvo de alcanzar una puntuación de 8 o superior.
  • Nuestros 'make check' objetivos filtro de salida "para no 'objetos' miembros" mensajes para eliminar la mayor parte de la distracción causada por pylint no la comprensión de Django.
62

utilizo el siguiente: pylint --generated-members=objects

+1

¿Alguna más? Esto hizo el truco para los objetos warnig. –

+0

[man pylint (1)] (http://manpages.ubuntu.com/manpages/precise/en/man1/pylint.1.html) en TYPECHECK '--generated-members = ' Lista de miembros que se configuran dinámicamente y se pierden por el sistema de inferencia de pylint, por lo que no deberían activarse E0201 y E1101_. [current: REQUEST, acl_users, aq_parent] –

+0

Agrego esto en PyDev en eclipse bajo [preferencias en la sección PyDev/PyLint] (http://pydev.org/manual_adv_pylint.html). –

19

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

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

+1

Me gusta la idea de una pylint específica de Django, pero parece una gran falla la última vez que la probé. – Wernight

+3

Además, no está disponible a través de PyPI y el sitio web no parece proporcionar suficiente información como: ¿Cuál es la versión actual? – Wernight

+1

Me gusta el concepto, pero esta implementación solo está medio hecha y se rompe en cualquier base de código de tamaño moderado. Tiene un largo camino por recorrer antes de que sea realmente útil. – Cerin

29

Mi ~/.pylintrc contiene

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

los dos últimos son specificall y para Django.

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

Editar: Después de jugar un poco con esto un poco más, decidí cortar pylint un poquito que me permita ampliar el anterior en:

[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).

¡Felices días!

+0

Debe enviar su parche a la planilla de regreso a los mantenedores. – slacy

+0

realmente han incluido este parche en 0.24, pero han comenzado a usar el paquete 'shlex', y han roto algo más ahora. He tenido que añadir 'gen.wordchars + = "[] - +" 'en la línea 135 para conseguir que funcione ... – simon

+4

Usando miembros generados simplemente esconde estos errores de usted, todavía puede haber errores al intentar el acceso' campo de objetos en el objeto equivocado. Use el plugin pylint-django en su lugar. –

2

La solución propuesta en este other question es simplemente agregar get_attr a su clase de etiqueta. Feo, pero funciona

89

No deshabilite ni debilite la funcionalidad de Pylint agregando ignores o generated-members.
Utilice un complemento Pylint desarrollado activamente que comprende Django.
This Pylint plugin for Django funciona bastante bien:

pip install pylint-django 

y cuando pylint corriendo añadir el siguiente indicador para el comando:

--load-plugins pylint_django 

el blog detallada posterior here.

+7

Esto tiene que ser la respuesta aceptada ASAP – Brendan

+1

El enlace a la entrada del blog está muerto (tan pronto). Estos son algunos enlaces archivados del [Archivo de Internet] (https://web.archive.org/web/20141008054046/http://blog.landscape.io/using-pylint-on-django-projects-with-pylint- django.html) y desde [archive.is] (http://archive.is/Lb9f0) –

+2

para que funcione con el plugin SublimeLinter de Sublime Text, he tenido que añadir '--load-plugins = pylint_django' de borra de/pylint/configuración args. Tenga en cuenta el signo '=', no funcionó sin él. –

3

Si utiliza código de Visual Studio hacer esto:

pip install pylint-django

y añadir a VSC config:

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