You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Substituir a configuração de qualidade de código e testes por um pyproject.toml na raiz do projeto, adotando Ruff como ferramenta única de lint e formatação, e migrando as opções hoje em pytest.ini para [tool.pytest.ini_options].
Estado atual
Arquivos
Situação
pytest.ini
Configuração pytest na raiz (DJANGO_SETTINGS_MODULE, python_files, addopts = --reuse-db)
pyproject.toml
Existe apenas em apps/spsvalidator/ (black, isort, pytest)
Targets test, test-fast, test-cov via Docker + pytest
Regra Cursor
.cursor/rules/python-black-isort.mdc referencia pyproject.toml na raiz, que ainda não existe
Objetivo
pyproject.toml na raiz como fonte única de configuração para Ruff e pytest.
Ruff substitui black + isort (lint + format, line-length 88, regras alinhadas ao Django).
Ruff / Bandit (S) detecta credenciais e senhas hardcoded no código, SQL injection, pickle inseguro, YAML/load perigoso e outras más práticas de segurança estáticas.
pytest permanece como runner de testes (pytest-django, fixtures, pytest.mark.django_db em tests/test_smoke.py e apps/spsvalidator/tests/); apenas a configuração deixa de viver em pytest.ini.
CI e Makefile expõem comandos reproduzíveis (ruff check, ruff format --check).
Nota de escopo: Ruff não executa testes. Esta issue trata da infraestrutura de configuração e qualidade estática, não da remoção do pytest como runner. Unificar manage.py test + pytest num único runner fica fora do âmbito (issue separada, se desejado).
Âmbito
Área
Acção
Raiz do repo
Criar pyproject.toml com [tool.ruff], [tool.ruff.lint], [tool.ruff.lint.flake8-bandit], [tool.ruff.format], [tool.pytest.ini_options]
pytest.ini
Remover após migração equivalente em pyproject.toml
Dependências
Adicionar ruff a requirements/local.txt (ou grupo dev documentado); avaliar remoção de black/isort onde forem substituídos
apps/spsvalidator/pyproject.toml
Alinhar: trocar [tool.black] / [tool.isort] por Ruff; manter [tool.pytest.ini_options] local coerente
CI
Activar job linter com ruff check . e ruff format --check . (excluir dist/, build/, migrations geradas, se aplicável)
Makefile
Targets lint / format / lint-fix (via container ou documentação para host)
Substituir python-black-isort.mdc por regra Ruff + pyproject.toml
Fora do âmbito
Reescrever testes para deixar de usar pytest.
Eliminar o runner legado python manage.py test do CI (mantém-se até decisão explícita).
Introduzir pre-commit hooks (pode ser follow-up).
Alterar lógica de negócio ou apps Django.
Regras de segurança no Ruff (Bandit)
O conjunto S (flake8-bandit) cobre análise estática de segurança. Não substitui validadores de senha em runtime do Django (AUTH_PASSWORD_VALIDATORS), mas impede que segredos e más práticas entrem no código.
Regra
O que detecta
S105
String com senha/token hardcoded (password = "...", api_key = "...")
S106
Argumento de função com senha hardcoded (connect(password="secret"))
S107
Valor default de parâmetro com senha hardcoded (def f(password="x"))
S608
Expressão SQL construída por concatenação/f-string (risco de injection)
S301 / S302
Uso de pickle / cPickle (deserialização insegura)
S506
yaml.load sem Loader seguro
S501
requests/urllib sem verificação de certificado SSL
S113
Chamadas HTTP sem timeout
S104
Bind em 0.0.0.0 (expor serviço a todas as interfaces)
S110
try/except: pass que oculta falhas de segurança
Boas práticas complementares já no Ruff
Conjunto
Uso
B (bugbear)
Padrões propensos a bugs (B904 raise sem chain, etc.)
UP (pyupgrade)
Sintaxe moderna e APIs deprecadas
T20 (opcional)
print em código de produção (útil em apps web; ignorar em scripts CLI)
Excepções controladas
Testes podem usar strings fictícias (password="pytest-pass"); aplicar per-file-ignores mínimos em tests/** e **/test_*.py apenas para S105–S107, não para o conjunto S inteiro.
Fixtures e settings de teste (config/settings/test.py) devem preferir variáveis de ambiente ou valores obviamente fictícios; evitar ignorar regras em config/settings/base.py ou production.py.
Configuração de referência (proposta)
Valores iniciais sugeridos para revisão na implementação:
Ajustar known-first-party, exclude, per-file-ignores e regras Django (DJ do ruff-django, se adoptado) conforme estrutura real dos apps. Revisar violações S608 e S501 no código existente antes de activar o CI bloqueante.
Subtarefas
Criar pyproject.toml na raiz com secções [tool.pytest.ini_options], [tool.ruff] (lint + format) e [tool.ruff.lint.flake8-bandit].
Activar conjunto S (Bandit) com foco em senhas/credenciais (S105, S106, S107) e regras de injection/deserialização (S608, S301, S506).
Definir per-file-ignores para testes (apenas S105–S107) e documentar justificativa; não ignorar segurança em config/settings/.
Verificar paridade com pytest.ini actual (DJANGO_SETTINGS_MODULE, python_files, --reuse-db) e remover pytest.ini.
Adicionar ruff às dependências de desenvolvimento (requirements/local.txt e/ou documentação de instalação).
Actualizar apps/spsvalidator/pyproject.toml: Ruff em vez de black/isort; remover dependências dev obsoletas do optional dev.
Activar job linter em .github/workflows/ci.yml com ruff check e ruff format --check.
Adicionar targets lint, format e lint-fix ao Makefile (ou equivalente documentado para Docker).
Correr Ruff no código existente e corrigir violações bloqueantes de segurança (credenciais hardcoded, SQL dinâmico, pickle, YAML inseguro) e estilo.
Auditar config/settings/base.py: confirmar que segredos vêm de env (django-environ); nenhuma chave SECRET_KEY, senha de BD ou token em literal no repositório.
Actualizar README.md e docs/desenvolvimento-local-make.md (comandos de lint/format; CI passa a incluir Ruff).
Actualizar .cursor/rules/python-black-isort.mdc para Ruff + pyproject.toml na raiz.
Smoke test local: ruff check ., ruff format --check ., make test / pytest inalterados em comportamento.
Critérios de aceite
Existe pyproject.toml na raiz; pytest.ini foi removido.
pytest continua a passar com a mesma suíte (raiz + apps/spsvalidator), sem alteração de comportamento dos testes.
ruff check . e ruff format --check . passam no CI (job linter), incluindo regras S sem falsos positivos não documentados.
Nenhuma credencial real detectável por S105–S107 fora de testes (ou excepções justificadas em per-file-ignores).
apps/spsvalidator não depende de black/isort para desenvolvimento quotidiano.
Documentação local descreve como correr lint, format e testes antes de abrir PR.
Nenhuma referência obsoleta a black/isort como padrão do monorepo (excepto histórico em PRs antigos).
Como testar manualmente
Instalar dependências de desenvolvimento (ambiente local ou container Django).
docker compose -f local.yml run --rm django pytest --collect-only -q
Executar suíte completa:
make django_test
make test
Em apps/spsvalidator:
cd apps/spsvalidator && pip install -e ".[dev]"&& pytest -q
Considerações e notas
Ruff vs pytest: Ruff cobre lint e format; pytest continua responsável por descoberta e execução de testes. A “troca” pedida é da infraestrutura de configuração (pytest.ini + black/isort implícitos) para pyproject.toml + Ruff.
Monorepo:apps/spsvalidator tem pyproject.toml próprio (app standalone). Manter coerência de line-length e estilo entre raiz e subprojeto.
Docker: Decidir se Ruff corre no host (mais rápido no CI linter) ou no container django (paridade com pytest). Recomendação: host no job linter (já tem setup-python); opcional target Make no container para quem só usa Docker.
Primeira execução: Esperar diff grande só de formatação Ruff; pode ser commit dedicado style: apply ruff format para facilitar revisão.
Ruff vs validadores Django:AUTH_PASSWORD_VALIDATORS em config/settings/base.py (já com os quatro validadores padrão do Django) regula senhas de utilizadores em runtime. O Ruff S105–S107 regula segredos no código-fonte. As duas camadas são complementares; esta issue não altera política de comprimento mínimo de senha de utilizador (follow-up se quiserem MinimumLengthValidator com OPTIONS: {"min_length": 12}).
S101 ignorado globalmente:assert é comum em testes; ignorar só S101, não todo o conjunto S.
Follow-up opcional: pre-commit com ruff-check + ruff-format; unificar runners de teste; adoptar ruff-django para regras específicas do framework; pip-audit ou dependabot para CVEs em dependências (fora do Ruff).
Descrição da tarefa
Substituir a configuração de qualidade de código e testes por um
pyproject.tomlna raiz do projeto, adotando Ruff como ferramenta única de lint e formatação, e migrando as opções hoje empytest.inipara[tool.pytest.ini_options].Estado atual
pytest.iniDJANGO_SETTINGS_MODULE,python_files,addopts = --reuse-db)pyproject.tomlapps/spsvalidator/(black, isort, pytest)requirements/local.txtpytest,pytest-django,pytest-covpinados.github/workflows/ci.yml)lintervazio (pre-commit comentado); jobtestsexecutamanage.py testepytestMakefiletest,test-fast,test-covvia Docker + pytest.cursor/rules/python-black-isort.mdcreferenciapyproject.tomlna raiz, que ainda não existeObjetivo
pyproject.tomlna raiz como fonte única de configuração para Ruff e pytest.S) detecta credenciais e senhas hardcoded no código, SQL injection,pickleinseguro, YAML/load perigoso e outras más práticas de segurança estáticas.pytest-django, fixtures,pytest.mark.django_dbemtests/test_smoke.pyeapps/spsvalidator/tests/); apenas a configuração deixa de viver empytest.ini.Makefileexpõem comandos reproduzíveis (ruff check,ruff format --check).Nota de escopo: Ruff não executa testes. Esta issue trata da infraestrutura de configuração e qualidade estática, não da remoção do pytest como runner. Unificar
manage.py test+ pytest num único runner fica fora do âmbito (issue separada, se desejado).Âmbito
pyproject.tomlcom[tool.ruff],[tool.ruff.lint],[tool.ruff.lint.flake8-bandit],[tool.ruff.format],[tool.pytest.ini_options]pytest.inipyproject.tomlruffarequirements/local.txt(ou grupo dev documentado); avaliar remoção de black/isort onde forem substituídosapps/spsvalidator/pyproject.toml[tool.black]/[tool.isort]por Ruff; manter[tool.pytest.ini_options]local coerentelintercomruff check .eruff format --check .(excluirdist/,build/, migrations geradas, se aplicável)Makefilelint/format/lint-fix(via container ou documentação para host)README.md,docs/desenvolvimento-local-make.mdpython-black-isort.mdcpor regra Ruff +pyproject.tomlFora do âmbito
python manage.py testdo CI (mantém-se até decisão explícita).Regras de segurança no Ruff (Bandit)
O conjunto
S(flake8-bandit) cobre análise estática de segurança. Não substitui validadores de senha em runtime do Django (AUTH_PASSWORD_VALIDATORS), mas impede que segredos e más práticas entrem no código.password = "...",api_key = "...")connect(password="secret"))def f(password="x"))pickle/cPickle(deserialização insegura)yaml.loadsemLoadersegurorequests/urllibsem verificação de certificado SSLtimeout0.0.0.0(expor serviço a todas as interfaces)try/except: passque oculta falhas de segurançaBoas práticas complementares já no Ruff
B904raise sem chain, etc.)printem código de produção (útil em apps web; ignorar em scripts CLI)Excepções controladas
password="pytest-pass"); aplicarper-file-ignoresmínimos emtests/**e**/test_*.pyapenas para S105–S107, não para o conjuntoSinteiro.config/settings/test.py) devem preferir variáveis de ambiente ou valores obviamente fictícios; evitar ignorar regras emconfig/settings/base.pyouproduction.py.Configuração de referência (proposta)
Valores iniciais sugeridos para revisão na implementação:
Ajustar
known-first-party,exclude,per-file-ignorese regras Django (DJdo ruff-django, se adoptado) conforme estrutura real dos apps. Revisar violações S608 e S501 no código existente antes de activar o CI bloqueante.Subtarefas
pyproject.tomlna raiz com secções[tool.pytest.ini_options],[tool.ruff](lint + format) e[tool.ruff.lint.flake8-bandit].S(Bandit) com foco em senhas/credenciais (S105, S106, S107) e regras de injection/deserialização (S608, S301, S506).per-file-ignorespara testes (apenas S105–S107) e documentar justificativa; não ignorar segurança emconfig/settings/.pytest.iniactual (DJANGO_SETTINGS_MODULE,python_files,--reuse-db) e removerpytest.ini.ruffàs dependências de desenvolvimento (requirements/local.txte/ou documentação de instalação).apps/spsvalidator/pyproject.toml: Ruff em vez de black/isort; remover dependências dev obsoletas do optionaldev.linterem.github/workflows/ci.ymlcomruff checkeruff format --check.lint,formatelint-fixaoMakefile(ou equivalente documentado para Docker).pickle, YAML inseguro) e estilo.config/settings/base.py: confirmar que segredos vêm de env (django-environ); nenhuma chaveSECRET_KEY, senha de BD ou token em literal no repositório.README.mdedocs/desenvolvimento-local-make.md(comandos de lint/format; CI passa a incluir Ruff)..cursor/rules/python-black-isort.mdcpara Ruff +pyproject.tomlna raiz.ruff check .,ruff format --check .,make test/pytestinalterados em comportamento.Critérios de aceite
pyproject.tomlna raiz;pytest.inifoi removido.pytestcontinua a passar com a mesma suíte (raiz +apps/spsvalidator), sem alteração de comportamento dos testes.ruff check .eruff format --check .passam no CI (joblinter), incluindo regras S sem falsos positivos não documentados.per-file-ignores).apps/spsvalidatornão depende de black/isort para desenvolvimento quotidiano.Como testar manualmente
pyproject.toml:make django_test make testapps/spsvalidator:Considerações e notas
pytest.ini+ black/isort implícitos) parapyproject.toml+ Ruff.apps/spsvalidatortempyproject.tomlpróprio (app standalone). Manter coerência de line-length e estilo entre raiz e subprojeto.linter) ou no containerdjango(paridade com pytest). Recomendação: host no joblinter(já temsetup-python); opcional target Make no container para quem só usa Docker.style: apply ruff formatpara facilitar revisão.AUTH_PASSWORD_VALIDATORSemconfig/settings/base.py(já com os quatro validadores padrão do Django) regula senhas de utilizadores em runtime. O Ruff S105–S107 regula segredos no código-fonte. As duas camadas são complementares; esta issue não altera política de comprimento mínimo de senha de utilizador (follow-up se quiseremMinimumLengthValidatorcomOPTIONS: {"min_length": 12}).asserté comum em testes; ignorar só S101, não todo o conjuntoS.ruff-check+ruff-format; unificar runners de teste; adoptarruff-djangopara regras específicas do framework;pip-auditoudependabotpara CVEs em dependências (fora do Ruff).Referências
pytest.ini,requirements/local.txt,.github/workflows/ci.yml,apps/spsvalidator/pyproject.toml.cursor/rules/python-black-isort.mdc