python - visual - Identificación de código "sensible" en su aplicación
visual code python linter (6)
Eche un vistazo a sys.setprofile
: le permite instalar una función de generador de perfiles.
Su uso se detalla en http://docs.python.org/library/profile.html#profile , para un jumpstart vaya here .
Si no puede crear un perfil de su aplicación, estará vinculado al enfoque de cobertura.
Otra cosa que podrías tener en cuenta es a los decoradores, puedes escribir un decorator debugging y aplicarlo a un conjunto de funciones que sospechas. Eche un vistazo here para ver cómo aplicar el decorador a un módulo completo.
También puede echar un vistazo al gráfico de llamadas de Python , mientras que no generará todo lo que desea, le muestra con qué frecuencia una función llama a otra:
Si su código se ejecuta en la entrada del usuario, esto será difícil, ya que tendría que simular el uso "típico".
No hay más que decirle, solo recuerde profiling
como palabra clave.
Buscando mejorar la calidad de un proyecto Python bastante grande. Estoy feliz con los tipos de advertencias que PyLint me da. Sin embargo, son demasiado numerosos y difíciles de imponer en una gran organización. También creo que algunos códigos son más críticos / sensibles que otros con respecto a dónde puede llegar el próximo error. Por ejemplo, me gustaría dedicar más tiempo a validar un método de biblioteca que es usado por 100 módulos en lugar de un script que se tocó por última vez hace 2 años y no se puede usar en producción. También sería interesante conocer módulos que se actualizan con frecuencia.
¿Hay alguien que esté familiarizado con las herramientas para Python o que ayude con este tipo de análisis?
Estoy de acuerdo con los demás, ya que todavía tengo que encontrar una buena herramienta de análisis de tiempo de ejecución para Python que hará esto. Hay algunas maneras de lidiar con eso, pero ninguna es trivial.
El más robusto, creo, sería obtener la fuente de Python y recompilar los binarios con algún tipo de registro de tiempo de ejecución incorporado. De esa manera, simplemente puede deslizarlo en el entorno existente sin ningún cambio de código en su proyecto. Por supuesto, eso no es precisamente trivial, pero tiene la ventaja de que algún día podría ser capaz de volver a unirlo al tronco para las generaciones futuras y qué no.
Para los enfoques sin recompilación, el primer lugar que buscaría es la sección de perfiles deterministas de la biblioteca de perfiles .
La forma de implementarlo dependerá en gran medida de la configuración de su entorno. ¿Tiene muchos guiones y proyectos individuales que se ejecutan de forma independiente, o solo el guión o módulo o paquete principal que es usado por todos los demás, y solo desea saber qué partes pueden recortarse para facilitar el mantenimiento? ¿Es una carga una vez, ejecutar el tipo de configuración para siempre, o una situación en la que simplemente ejecutas los scripts de forma atómica en algún tipo de programación?
Puede implementar el registro de todo el proyecto (como se menciona en la respuesta de @ Hardbyte), pero eso requeriría pasar por el proyecto y agregar las líneas de registro a todo su código. Si haces eso, también puedes hacerlo usando el profiler
incorporado, creo.
Las herramientas de control de fuente pueden proporcionar una buena indicación de los módulos que se actualizan con frecuencia, lo que a menudo indica puntos problemáticos.
Si no tiene control de código fuente pero el proyecto se ejecuta desde una ubicación compartida, elimine todas las carpetas de pycache o los archivos .pyc . Con el tiempo / bajo uso, vea qué archivos se recrean para indicar su uso.
Analizando las importaciones de Python impresas cuando se ejecuta desde puntos de entrada particulares con
python -v entry_point
puede dar una idea de qué módulos se están utilizando. Aunque si tiene puntos de acceso conocidos debe probar el módulo de Coverage .
Para una solución más intrusiva, considere la posibilidad de configurar el registro de todo el proyecto. Puede registrar métricas de forma bastante sencilla, incluso en programas distribuidos.
Me temo que estás mayormente solo.
Si tiene un conjunto decente de pruebas, observe la cobertura del código y el código muerto.
Si tiene una configuración de perfiles decente, úselo para echar un vistazo a lo que se usa más.
Al final, parece que estás más interesado en el análisis fan-in / fan-out, no conozco ninguna buena herramienta para Python, principalmente porque el análisis estático es terriblemente poco confiable contra un lenguaje dinámico, y hasta ahora no lo hice. No veo ninguna herramienta de análisis estadístico.
Reconozco que esta información está disponible en los compiladores JIT: cualquiera que sea (función, tipos de argumento) está en la memoria caché (compilada), son los que más se utilizan. Si puede o no obtener esta información, por ejemplo, PyPy, realmente no tengo ni idea.
Pylint a veces da advertencias de que (después de una cuidadosa consideración) no están justificadas. En cuyo caso, es útil utilizar los #pylint: disable=X0123
especiales de #pylint: disable=X0123
(donde X0123 es el número real del mensaje de error / advertencia ) si el código no se puede volver a marcar para no activar la advertencia.
Me gustaría secundar la mención de Hardbyte de usar los registros de control de origen para ver qué archivos se modifican con mayor frecuencia.
Si está trabajando en un sistema que tiene instalado, grep
y sort
instalado, la siguiente es una forma de verificar qué archivo importa qué;
find . -name ''*.py'' -exec grep -EH ''^import|^from .* import'' {} /+| sort |less
Para encontrar las importaciones más populares en todos los archivos;
find . -name ''*.py'' -exec grep -Eh ''^import|^from .* import'' {} /+ | sort | less
Estos dos comandos le ayudarán a encontrar los módulos más utilizados de su proyecto.
Su problema es similar al que respondí en SQA https://sqa.stackexchange.com/a/3082 . Este problema se asoció con Java, lo que hizo que las herramientas fueran un poco más fáciles, pero a continuación tengo algunas sugerencias.
Una serie de otras respuestas sugieren que no hay buenas herramientas de tiempo de ejecución para Python. No estoy de acuerdo en esto de varias maneras:
- Las herramientas de cobertura funcionan muy bien.
- Basándome en mi experiencia en herramientas en Java, las herramientas de análisis estático y dinámico en Python son más débiles que en un lenguaje menos dinámico fuertemente tipado, pero funcionarán lo suficientemente bien como para proporcionar buenas heurísticas aquí. A menos que use un número patológico inusualmente grande de funciones dinámicas (que incluyen agregar y eliminar métodos, interceptar invocaciones de propiedades y métodos, jugar con la importación, modificar manualmente el espacio de nombres), en cuyo caso cualquier problema que tenga puede estar asociado con este dinamismo. .
- Pylint resuelve problemas más simples y no detectará problemas con modificaciones dinámicas de clase / instancia y decoradores, por lo que no importa que las herramientas métricas no midan estos
- En cualquier caso, el enfoque útil puede determinarse por mucho más que un gráfico de dependencia.
Heurísticas para seleccionar código
Encuentro que hay una serie de consideraciones diferentes para seleccionar el código de mejora que funciona de forma individual y conjunta. Recuerde que, al principio, todo lo que necesita hacer es encontrar un trabajo productivo, no necesita encontrar el código absolutamente peor antes de comenzar.
Usa tu juicio.
Después de unos pocos ciclos a través del código base, tendrá una gran cantidad de información y estará mucho mejor posicionado para continuar su trabajo, si es que se necesita hacer más.
Dicho esto, aquí están mis sugerencias:
Alto valor para el negocio : por ejemplo, cualquier código que pueda costar mucho dinero a su empresa. Muchos de estos pueden ser obvios o ampliamente conocidos (porque son importantes), o pueden detectarse ejecutando los casos de uso importantes en un sistema con el perfilador de tiempo de ejecución habilitado. Yo uso la Coverage .
Métricas de código estático : hay muchas métricas, pero las que nos preocupan son:
- Acoplamientos de alta aferencia . Este es un código del que dependen muchos otros archivos. Si bien no tengo una herramienta que snakefood esto directamente, snakefood es una buena manera de volcar las dependencias directamente en el archivo, una línea por dependencia, cada una de las cuales es una tupla de archivos aferentes y eferentes. Odio decirlo, pero calcular el valor de acoplamiento aferente de este archivo es un ejercicio simple que queda para el lector.
- Alta complejidad de McCabe (ciclomática) : este es un código más complejo. PyMetrics parece producir esta medida aunque no he utilizado la herramienta.
- Tamaño : puede obtener una cantidad sorprendente de información al ver el tamaño de su proyecto utilizando un visualizador (por ejemplo, https://superuser.com/questions/8248/how-can-i-visualize-the-file-system-usage-on-windows o https://superuser.com/questions/86194/good-program-to-visualize-file-system-usage-on-mac?lq=1 . Linux tiene KDirStat en Filelight). Los archivos grandes son un buen lugar para comenzar, ya que corregir un archivo corrige muchas advertencias.
Tenga en cuenta que estas herramientas están basadas en archivos. Esta es probablemente una resolución lo suficientemente buena, ya que usted menciona que el proyecto tiene cientos de módulos (archivos).
Cambios frecuentes : el código que cambia frecuentemente es altamente sospechoso. El código puede:
- Históricamente han tenido muchos defectos, y empíricamente pueden continuar haciéndolo.
- Estar experimentando cambios desde el desarrollo de funciones (gran cantidad de revisiones en su VCS)
Encuentre áreas de cambio utilizando una herramienta de visualización VCS como las que se analizan más adelante en esta respuesta.
Código descubierto : Código no cubierto por pruebas.
Si ejecuta (o puede ejecutar) sus pruebas de unidad, sus otras pruebas automatizadas y las pruebas de usuario típicas con cobertura, eche un vistazo a los paquetes y archivos con casi sin cobertura. Hay dos razones lógicas por las que no hay cobertura:
- El código es necesario (e importante) pero no se ha probado en absoluto (al menos automáticamente). Estas áreas son de riesgo extremadamente alto.
- El código puede estar sin uso y es un candidato para su eliminación.
Pregunte a otros desarrolladores
Es posible que se sorprenda de las métricas de ''olor'' que puede recopilar tomando un café con los desarrolladores de mayor servicio. Apuesto a que estarán muy felices si alguien limpia un área sucia de la base de código donde solo las almas más valientes se aventurarán.
Visibilidad - detección de cambios en el tiempo.
Supongo que su entorno tiene un DVCS (como Git o Mercurial) o al menos un VCS (por ejemplo, SVN). Espero que también estés usando algún problema o rastreador de errores de algún tipo. Si es así, hay una gran cantidad de información disponible. Es incluso mejor si los desarrolladores se han registrado de forma confiable con comentarios y números de problemas. ¿Pero cómo lo visualizas y lo usas?
Si bien puede abordar el problema en un solo escritorio, probablemente sea una buena idea configurar un entorno de integración continua (CI), tal vez utilizando una herramienta como Jenkins . Para mantener la respuesta corta, asumiré de ahora en adelante a Jenkins. Jenkins viene con una gran cantidad de complementos que realmente ayudan con el análisis de código. Yo suelo:
- py.test con el resultado de la prueba JUnit recogido por el complemento de Jenkins del informe de prueba JUnit
- Coverage con el complemento Cobertura.
- SLOCCount y el complemento SLOCCount
- Plugin Pylint y Violaciones
- Aparentemente hay un complemento para la complejidad de McCabe (ciclométrica) para Python , aunque no lo he usado. Ciertamente parece interesante.
Esto me da visibilidad de los cambios a lo largo del tiempo, y puedo profundizar desde allí. Por ejemplo, supongamos que las infracciones de PyLint comienzan a aumentar en un módulo: tengo evidencia del aumento y conozco el paquete o archivo en el que se está produciendo, para poder averiguar quién está involucrado y hablar con ellos.
Si necesita datos históricos y acaba de instalar Jenkins, vea si puede ejecutar algunas compilaciones manuales que comiencen al inicio del proyecto y tome una serie de saltos hacia adelante hasta el presente. Puede elegir etiquetas de lanzamiento de hitos (o fechas) del VCS.
Otra área importante, como se mencionó anteriormente, es detectar los lugares de cambios en el código base. Realmente me ha gustado Atlassian Fisheye por esto. Además de ser realmente bueno en la búsqueda de mensajes de confirmación (por ejemplo, identificación de error) o contenido del archivo en cualquier momento, me permite ver fácilmente las métricas:
- Linecount por directorio y subdirectorio
- Compromisos en cualquier momento o en directorios y / o archivos específicos
- Patrones de confirmación, tanto por tiempo como por ubicación en el código fuente