Linter

Um linter ou o linting, é uma ferramenta/processo de execução de um programa que irá analisar o código buscando erros ou vulnerabilidades em potencial. Em nosso desenvolvimento utilizamos três ferramentas de linting para nos auxiliar:

Black

O Black é um formatador de código Python, que toma o controle sob a formatação do seu código, mantendo o que foi escrito, porém revisado e ajustado de acordo com as configurações de formatação estabelecidas. Por padrão o Black já está instalado nas máquinas da equipe de engenharia através do provisionamento, porém caso não tenha sido utilizado o provisionamento você pode instalá-lo através do pip.

python3.6 -m pip install black

Para utilizá-lo, basta usar seu comando direto no terminal, informando um arquivo ou diretório para formatar.

black ~/git/itflex/server/backend

Configuração

Dentro do projeto, no local onde está o código do backend existe um arquivo chamado pyproject.toml, que fica responsável pelas configurações de formatação do Black.

Não é necessário e nem recomendado que você altere, pois o objetivo é padronizar o código da equipe em questões de formatação, esta parte da configuração é somente para fins de conhecimento.

Nele é possível definir qual versão do interpretador do python estamos utilizando, limite de caracteres, arquivos a ignorar, entre outras definições.

Utilizamos o python3.6 e o limite de 79 caracteres por questões de legibilidade do código.

Uso

Black pode ser usado fora de um ambiente virtual, quanto dentro. O recomendado é rodar ele utilizando sua virtual env, pois ele pode ser integrado com outras ferramentas. Como criamos a venv no diretório do backend, o Black pode ser chamado da seguinte maneira: ./venv/bin/black

Por modificarmos muitos arquivos durante o desenvolvimento, na maioria dos casos utilizamos um script que executa todo os linters do backend, porém em alterações pequenas, torna-se viável usar diretamente os linters. Nessa situação, existem dois parâmetros no comando que merecem ter uma atenção, o --check e o --diff.

O --check utilizamos em nosso script, ele não formata o código, apenas informa em quais arquivos estão as incongruências, utilizamos dessa maneira para nos acostumarmos a escrever o código no padrão.

Exemplo:

$ ./venv/bin/black ~/git/itflex/server/backend --check
would reformat /home/carlosm/git/itflex/server/backend/itflex_alert/notifications/tests/test_use_cases.py

O --diff serve para mostrar as linhas com formatação incorreta e a mesma formatada “lado a lado” para mostrar a comparação.

Exemplo:

$ ./venv/bin/black ~/git/itflex/server/backend --diff
would reformat /home/carlosm/git/itflex/server/backend/itflex_alert/notifications/tests/test_use_cases.py

--- ~/git/itflex/server/backend/itflex_alert/notifications/tests/test_use_cases.py	2021-02-18 14:35:46.733015 +0000
+++ ~/git/itflex/server/backend/itflex_alert/notifications/tests/test_use_cases.py	2021-02-18 17:08:41.589570 +0000
@@ -107,12 +107,12 @@
 def test_get_notifications_by_consumer_id(
     use_cases: NotificationsUseCases,
     notifications_repo: Mock,
     notification: Notification,
 ):
-    notifications_repo.get_notifications_by_consumer_id.return_value = ItemsResp(  # noqa
-        items=[notification]
+    notifications_repo.get_notifications_by_consumer_id.return_value = (
+        ItemsResp(items=[notification])  # noqa
     )
     resp = use_cases.get_notifications_by_consumer_id(
         GetNotificationsByConsumerId(consumer_id="user:1")
     )

Erros

Em algum momento pode ocorrer de ao executar o linter, ele não conseguir formatar seus arquivos e apresentar algum erro, na maioria dos casos isso ocorre devido a alguma troca na versão do interpretador do python utilizado, cache da versão do Black ou algum problema no seu ambiente virtual de desenvolvimento que conflita com o cache que o Black cria ao realizar as formatações. A maneira mais rápida e simples, é remover esse cache, já que ele não irá impactar em como será formatado seu código.

O local em que ele fica armazenado no Linux geralmente é ~/.cache/black/{version} separado em pastas pela versão utilizado do linter.

Playground

O formatador tambem possue um playground, onde há um código de exemplo para que você pode visualizar como ele funciona, além de formatar seu próprio código enquanto escreve.

flake8

O flake8 é wrapper em volta das ferramenta pyflakes, pycodestyle e mccabe, executado por um único comando flake8.

python3.6 -m pip install flake8

Para utilizá-lo, basta usar seu comando direto no terminal, informando um arquivo python ou diretório contendo os arquivos.

flake8 ~/git/itflex/server/backend

Configuração

Dentro do projeto, no local onde está o código do backend existe um arquivo chamado setup.cfg, que fica responsável pelas configurações do flake8.

Não é necessário e nem recomendado que você altere, pois o objetivo é padronizar o código da equipe em questões de formatação, esta parte da configuração é somente para fins de conhecimento.

Nele é possível definir as extensões de arquivos a ignorar, quais tipos erros serão ignorados ao executar a ferramenta, entre outras definições.

Uso

flake8 pode ser usado fora de um ambiente virtual, quanto dentro. O recomendado é rodar ele utilizando sua virtual env. Como criamos a venv no diretório do backend, o flake8 pode ser chamado da seguinte maneira: ./venv/bin/flake8

Sobre os erros / violações ignorados nos códigos

Nos códigos do backend, existem alguns erros que “ignoramos”, através de uma tag que o flake8 utiliza para identificação, assim essas violações são ignoradas no momento que a ferramenta está analisando o código.

isort

O isort é um organizador de imports de código Python, ele busca organizar seus imports em ordem alfabética e separar por seção e tipo.

python3.6 -m pip install isort

Para utilizá-lo, basta usar seu comando direto no terminal, informando um arquivo python ou diretório contendo os arquivos.

cd /itflex/server/backend
isort -rc -ns .

Uso

Dentro do projeto, no local onde está o código do backend existe um arquivo chamado .isort.cfg, que fica responsável pelas configurações do isort.

Não é necessário e nem recomendado que você altere, pois o objetivo é padronizar o código da equipe em questões de ordenação de imports, esta parte da configuração é somente para fins de conhecimento.

Nele é possível definir limite de linhas, combinação de imports, entre outras definições.