Skip to content

refactor: Melhorias nas funções de validação de CNPJ - #754

Open
rennerocha wants to merge 5 commits into
brazilian-utils:mainfrom
rennerocha:refactor-cnpj
Open

rennerocha wants to merge 5 commits into
brazilian-utils:mainfrom
rennerocha:refactor-cnpj

Conversation

@rennerocha

Copy link
Copy Markdown

Descrição

Este PR simplifica o código para validação e geração de CNPJs.

Mudanças Propostas

  • Utiliza uma expressão regular para validar se a string de CNPJ a ser validada contém apenas caracteres e dimensões válidas (removendo a necessidade de verificar a comprimento da string e checar cada caracteres como dígito)
  • Utiliza uma expressão regular para a limpeza de strings
  • Simplifica o método para geração de números de CNPJ aleatórios utilizando funções disponíveis no módulo random

Checklist de Revisão

  • Eu li o Contributing.md
  • Os testes foram adicionados ou atualizados para refletir as mudanças (se aplicável).
  • Foi adicionada uma entrada no changelog / Meu PR não necessita de uma nova entrada no changelog.
  • A documentação em português foi atualizada ou criada, se necessário.
  • Se feita a documentação, a atualização do arquivo em inglês.
  • Eu documentei as minhas mudanças no código, adicionando docstrings e comentários. Instruções
  • O código segue as diretrizes de estilo e padrões de codificação do projeto.
  • Todos os testes passam. Instruções
  • O Pull Request foi testado localmente. Instruções
  • Não há conflitos de mesclagem.

Comentários Adicionais (opcional)

  • A string "00000000000000" não podia ser formatada como "00.000.000/0000-00" (display) por não ser um CNPJ válido. Para manter a função mais simples, eu removi essa restrição, assim CNPJ_RE pode ser utilizado nela sem problemas. Dado que é apenas uma função que exibe informação na tela, não considerei algo crítico para o sistema, já que o input é fornecido pela pessoa utilizando a biblioteca.

Issue Relacionada

Não há uma issue. É apenas uma refatoração de código que já está funcionando.

Closes #<numero_da_issue>

@rennerocha
rennerocha requested review from a team as code owners July 2, 2026 11:45
@codecov

codecov Bot commented Jul 2, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 99.08%. Comparing base (525d9c1) to head (18e5d49).
⚠️ Report is 7 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #754      +/-   ##
==========================================
- Coverage   99.09%   99.08%   -0.01%     
==========================================
  Files          26       26              
  Lines         775      767       -8     
==========================================
- Hits          768      760       -8     
  Misses          7        7              

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@its-Sohan its-Sohan left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

overall a nice refactoring. the regex centralization makes the format validation much cleaner than the scattered manual checks. a few observations inline.

@its-Sohan its-Sohan left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

overall a nice refactoring. the regex centralization makes the format validation much cleaner than the scattered manual checks. a few observations inline.

@its-Sohan its-Sohan left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

overall a nice refactoring. the regex centralization makes the format validation much cleaner than the scattered manual checks. a few observations inline.

Comment thread brutils/cnpj.py
@@ -1,7 +1,10 @@
import random
import re
from itertools import chain

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good use of a compiled regex constant. centralizing the format pattern is much cleaner than the repeated manual length + char checks in display() and validate().

Comment thread brutils/cnpj.py
from string import ascii_uppercase, digits

CNPJ_RE = re.compile(r"^[A-Z0-9]{12}[0-9]{2}")

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice simplification. the filter(lambda) pattern was harder to read. re.sub with a character class is both faster and clearer.

Comment thread brutils/cnpj.py
@@ -31,7 +34,7 @@ def sieve(dirty: str) -> str:
backward compatibility.
"""

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this removes the len(set(cnpj)) == 1 check, so 00000000000000 now formats as 00.000.000/0000-00 instead of returning None. you mentioned this in the pr description, which is good. just noting it's a behavioral change for callers that relied on display() rejecting all-same-character inputs.

Comment thread brutils/cnpj.py
return re.sub(r"[\.\/\-]", "", dirty)


def remove_symbols(dirty: str) -> str:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice - removing _is_alphanumeric is the right call since the regex now handles that check. less code to maintain.

Comment thread brutils/cnpj.py
if (
len(cnpj) != 14
or not _is_alphanumeric(cnpj[:12])
or not cnpj[12:].isdigit()

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

one concern here: random.sample() picks without replacement, so the 8-character base will never have repeated characters. random.choices() (which was used before) allows repeats. real cnpjs can have repeated digits (e.g. 11.111.111/0001-11), so sample reduces the space of valid generated cnpjs. consider whether choices was more correct here, or if you want repeats in the generated base.

@its-Sohan its-Sohan left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

desculpe, escrevi a review em ingles sem perceber que o projeto é brasileiro. aqui vai a versão em portugues:

no geral, uma boa refatoração. centralizar a validação de formato com a regex CNPJ_RE ficou muito mais limpo do que as verificações manuais espalhadas.

pontos principais:

  • re.sub no sieve() é mais simples que filter(lambda) - boa simplificação
  • remover o _is_alphanumeric foi a decisão certa já que a regex cobre isso agora
  • o random.sample() vs random.choices(): sample escolhe sem repetição, então os 8 caracteres da base nunca vão ter dígitos repetidos. cpfs reais podem ter repetidos (ex: 11.111.111/0001-11), então sample reduz o espaço de cnPJs válidos gerados. vale reconsiderar usar choices pra permitir repetição.
  • a mudança no display("00000000000000") que agora retorna 00.000.000/0000-00 ao invés de none - voce mencionou na descrição, mas é uma mudança de comportamento que pode afetar quem usava o retorno none.

no mais, bom trabalho!

@github-actions

github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown

📌 Esta mensagem está tanto em português quanto em inglês (mais abaixo) — assim todo mundo consegue acompanhar!
📌 This message is in both Portuguese and English (further down) — so everyone can follow along!

🇧🇷 Português

👋 Olá!

Este PR está obsoleto porque ficou aberto por 30 dias sem atividade. Remova o rótulo de stale ou comente, caso contrário ele será fechado em 15 dias.

🇬🇧 English

Hey there! 👋

This PR is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 15 days.

@github-actions github-actions Bot added the Stale label Aug 7, 2026
@jsbueno jsbueno added priority: medium Normal priority. Important but not urgent. and removed Stale labels Aug 14, 2026
@github-actions

Copy link
Copy Markdown

📌 Esta mensagem está tanto em português quanto em inglês (mais abaixo) — assim todo mundo consegue acompanhar!
📌 This message is in both Portuguese and English (further down) — so everyone can follow along!

🇧🇷 Português

👋 Olá!

Este PR está obsoleto porque ficou aberto por 30 dias sem atividade. Remova o rótulo de stale ou comente, caso contrário ele será fechado em 15 dias.

🇬🇧 English

Hey there! 👋

This PR is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 15 days.

@github-actions github-actions Bot added the Stale label Sep 14, 2026
@rennerocha

Copy link
Copy Markdown
Author

Este projeto está abandonado?

@github-actions github-actions Bot removed the Stale label Sep 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

priority: medium Normal priority. Important but not urgent.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants