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

refactor: Melhorias nas funções de validação de CNPJ#754
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).

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!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants