Calidad de código en Python
Hoy decidí hacer un post sobre Flake, Black y Pre-Commit. ¿Existe alguna relación? ¿Me sirven para algo en particular? ¿Debería comenzar a usar estas herramientas en mis proyectos? Hace un buen rato había querido investigar un poco más al respecto de esto y bueno, este es mi resumen.
Linters
Debo ser sincero, he utilizado linters pero nunca he ahondado en ellos, hasta hoy, hoy quiero leer un poco más para conocer más.
Por cierto, no tenía ni idea que la palabra lint
significaba en español motas o pelusas (las que salen en la ropa al lavar). Ahora todo tiene más sentido.
¿Pero bueno y qué es un Linter? ¿Qué hace?
Los linters son programas que analizan el código buscando errores similar a como lo hace el detector de ortografía de cualquier procesador de textos. Existen general, existen dos categorías de detección de los linters:
- Linters lógicos: Se encargan de buscar errores lógicos en nuestro código o que potencialmente puedan conllevar a resultados no esperados.
- Linters de estilo: Se encargan de buscar código que no se encuentra conforme a alguna convención de código como, por ejemplo, en python PEP8.
¿Existen linters para otros los lenguajes?
Respuesta corta: Sí.
Respuesta larga: Busqué un par de lenguajes populares y encontré que la gran mayoría (por no decir todos) cuentan con programas especializados para revisar el código, algunos ejemplos:
- Ruby, https://rubocop.org/
- Java, https://spotbugs.github.io/
- PHP, https://phpmd.org/
En general encontré un montón de linters para cada lenguaje pero para simplificar sólo hablaré de uno en particular.
¿Y Python?
¡Por supuesto! En python también tenemos diferentes alternativas, las dos alternativas más usadas son Flake8 y PyLama. Ambos utilizan librerías especializadas para este análisis. Veamos con más detalle Flake8.
Flake8
Uno de los más conocidos en este campo, permite detectar las dos categorías mencionadas anteriormente (bugs lógicos y de estilo). Tal como lo informan en su documentación, flake8 es un wrapper de tres paquetes:
- PyFlakes: Añade el checkeo lógico del código. Disponible en https://github.com/PyCQA/pyflakes
- pycodestyle: Añade el checkeo de estilos, de hecho, este paquete antes se llamaba PEP8, fue renombrado a
pycodestyle
para disminuir confusiones. Disponible en https://github.com/PyCQA/pycodestyle - Ned Batchelder’s McCabe: Añade checkeo de complejidad del código. Disponible en https://github.com/PyCQA/mccabe
¿Cómo lo utilizo?
Primero que todo, es necesario instalarlo, para esto
Si deseas escanear toda una carpeta:
flake8 /path/to/folder
Si deseas escanear un solo archivo
flake8 /path/to/file.py
En caso de encontrar algún inconveniente, flake8 informará algo similar a lo siguiente:
flake8 path/to/folder
path/to/folder/file.py:1:1: F401 'django.contrib.admin' imported but unused
Un par de anotaciones:
- Si deseas omitir algún archivo para que esta no sea analizado por flake8, basta con añadir en cualquier parte del archivo la línea
# flake8: noqa
- Si lo que deseas es omitir solo una línea, se utiliza
# noqa
al final de la línea
Formateadores
Este grupo de herramientas permite no solo informar de posibles errores en código sino que además intenta corregirlas. Quizás la herramienta más conocida en este grupo es black.
Black
Como ya lo dijimos anteriormente, Black es una herramienta que permite corregir nuestro código teniendo en cuenta las normas definidas en PEP8.
¿Cómo lo utilizo?
Similar a otros paquetes los instalaremos con pip
pip install black
Y bueno, similar a cuando utilizamos flake8
, también podemos utilizar la herramienta sobre un archivo o sobre un directorio, veamos:
black folder/file.py # formatea un archivo específico
black folder/ # formatea todos los archivos de un directorio
¡Y listo!, ya con esto black formateará nuestro código automáticamente; por último, también podemos utilizar un par de flags bastante útiles:
check
: Permite revisar si se realiza un cambio.diff
: Muestra un diff con los cambioscolor
: Cuando se combina condiff
, muestra el resultado formateado con colores
¿Y pre-commit?
Para cerrar este post, hablaremos un poco sobre sobre pre-commit, como su nombre lo dice, permite ejecutar scripts antes de realizar un git commit
, lo mejor es que se puede integrar facilmente con flake8, black y muchas más herramientas.
¿Cómo lo utilizo?
Bueno, antes de utilizarlo, es necesario instalarlo, para ello:
pip install pre-commit
Luego, en nuestro proyecto crearemos un archivo con el nombre .pre-commit-config.yaml
, en este archivo es en el que configuraremos lo que vamos a ejecutar, aquí un archivo de ejemplo:
repos:
- repo: https://gitlab.com/pycqa/flake8
rev: 3.8.3
hooks:
- id: flake8
- repo: https://github.com/ambv/black
rev: 20.8b1
hooks:
- id: black
language_version: python3.6
Como siempre, en la documentación oficial podemos encontrar más información sobre pre-commit.
Por último, solo es necesario instalar la configuración (archivo .yaml creado anteriormente) como un hook de git, para esto ejecutamos pre-commit install
. Y listo, cuando ejecutemos un git commit
se ejecutará flake8 y black.
Y bueno, sólo por responder a mi pregunta inicial: ¿Vale la pena utilizar flake8, black, pre-commit? Sí, definitivamente!