brutils 2.4.0__tar.gz → 2.5.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. {brutils-2.4.0 → brutils-2.5.0}/PKG-INFO +18 -6
  2. {brutils-2.4.0 → brutils-2.5.0}/README.md +16 -4
  3. {brutils-2.4.0 → brutils-2.5.0}/brutils/cnpj.py +63 -8
  4. {brutils-2.4.0 → brutils-2.5.0}/pyproject.toml +3 -3
  5. {brutils-2.4.0 → brutils-2.5.0}/LICENSE +0 -0
  6. {brutils-2.4.0 → brutils-2.5.0}/brutils/__init__.py +0 -0
  7. {brutils-2.4.0 → brutils-2.5.0}/brutils/cep.py +0 -0
  8. {brutils-2.4.0 → brutils-2.5.0}/brutils/cnh.py +0 -0
  9. {brutils-2.4.0 → brutils-2.5.0}/brutils/cpf.py +0 -0
  10. {brutils-2.4.0 → brutils-2.5.0}/brutils/currency.py +0 -0
  11. {brutils-2.4.0 → brutils-2.5.0}/brutils/data/cities_code.json +0 -0
  12. {brutils-2.4.0 → brutils-2.5.0}/brutils/data/enums/__init__.py +0 -0
  13. {brutils-2.4.0 → brutils-2.5.0}/brutils/data/enums/better_enum.py +0 -0
  14. {brutils-2.4.0 → brutils-2.5.0}/brutils/data/enums/months.py +0 -0
  15. {brutils-2.4.0 → brutils-2.5.0}/brutils/data/enums/uf.py +0 -0
  16. {brutils-2.4.0 → brutils-2.5.0}/brutils/data/legal_process_ids.json +0 -0
  17. {brutils-2.4.0 → brutils-2.5.0}/brutils/date_utils.py +0 -0
  18. {brutils-2.4.0 → brutils-2.5.0}/brutils/email.py +0 -0
  19. {brutils-2.4.0 → brutils-2.5.0}/brutils/exceptions/__init__.py +0 -0
  20. {brutils-2.4.0 → brutils-2.5.0}/brutils/exceptions/cep.py +0 -0
  21. {brutils-2.4.0 → brutils-2.5.0}/brutils/ibge/__init__.py +0 -0
  22. {brutils-2.4.0 → brutils-2.5.0}/brutils/ibge/municipality.py +0 -0
  23. {brutils-2.4.0 → brutils-2.5.0}/brutils/ibge/uf.py +0 -0
  24. {brutils-2.4.0 → brutils-2.5.0}/brutils/legal_nature.py +0 -0
  25. {brutils-2.4.0 → brutils-2.5.0}/brutils/legal_process.py +0 -0
  26. {brutils-2.4.0 → brutils-2.5.0}/brutils/license_plate.py +0 -0
  27. {brutils-2.4.0 → brutils-2.5.0}/brutils/passport.py +0 -0
  28. {brutils-2.4.0 → brutils-2.5.0}/brutils/phone.py +0 -0
  29. {brutils-2.4.0 → brutils-2.5.0}/brutils/pis.py +0 -0
  30. {brutils-2.4.0 → brutils-2.5.0}/brutils/renavam.py +0 -0
  31. {brutils-2.4.0 → brutils-2.5.0}/brutils/schemas/__init__.py +0 -0
  32. {brutils-2.4.0 → brutils-2.5.0}/brutils/schemas/address.py +0 -0
  33. {brutils-2.4.0 → brutils-2.5.0}/brutils/voter_id.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: brutils
3
- Version: 2.4.0
3
+ Version: 2.5.0
4
4
  Summary: Utils library for specific Brazilian businesses
5
5
  License: MIT
6
6
  License-File: LICENSE
@@ -24,7 +24,7 @@ Classifier: Topic :: Office/Business
24
24
  Classifier: Topic :: Software Development :: Internationalization
25
25
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
26
26
  Requires-Dist: coverage (>=7.2.7,<8.0.0)
27
- Requires-Dist: holidays (>=0.58,<0.95)
27
+ Requires-Dist: holidays (>=0.58,<0.99)
28
28
  Requires-Dist: num2words (==0.5.14)
29
29
  Project-URL: Repository, https://github.com/brazilian-utils/python
30
30
  Description-Content-Type: text/markdown
@@ -244,7 +244,8 @@ Exemplo:
244
244
 
245
245
  Verifica se os dígitos de verificação do CNPJ (Cadastro Nacional da Pessoa
246
246
  Jurídica) fornecido correspondem ao seu número base. A entrada deve ser uma
247
- string de dígitos com o comprimento apropriado. Esta função não verifica a
247
+ string de 14 caracteres, permitindo dígitos e letras maiúsculas nas 12
248
+ primeiras posições e dígitos nas 2 últimas. Esta função não verifica a
248
249
  existência do CNPJ; ela só valida o formato da string.
249
250
 
250
251
  Argumentos:
@@ -316,12 +317,16 @@ Exemplo:
316
317
 
317
318
  ### generate_cnpj
318
319
 
319
- Gera uma string de dígitos CNPJ válida aleatória. Um número de filial
320
- opcional pode ser fornecido; o padrão é 1.
320
+ Gera uma string de CNPJ válida aleatória. Um número de filial opcional pode ser
321
+ fornecido; o padrão é 1. Use `alphanumeric=True` para gerar um CNPJ cujas 12
322
+ primeiras posições podem conter dígitos e letras maiúsculas.
321
323
 
322
324
  Argumentos:
323
325
 
324
- - branch (int): Um número de filial opcional a ser incluído no CNPJ.
326
+ - branch (int | str): Um número de filial opcional a ser incluído no CNPJ.
327
+ Valores de filial alfanuméricos são aceitos apenas com
328
+ `alphanumeric=True`.
329
+ - alphanumeric (bool): Define se o CNPJ gerado deve ser alfanumérico.
325
330
 
326
331
  Retorna:
327
332
 
@@ -335,6 +340,13 @@ Exemplo:
335
340
  '34665388000161'
336
341
  >>> generate_cnpj(1234)
337
342
  "01745284123455"
343
+ >>> generate_cnpj(alphanumeric=True)
344
+ "9359QAG9000184"
345
+ >>> generate_cnpj(branch="AB12", alphanumeric=True)
346
+ "BR2026UTAB1290"
347
+ >>> generate_cnpj(branch="CD34", alphanumeric=True)
348
+ # CNPJ inválido para exemplos de validação:
349
+ "NX9K79E2CD3400"
338
350
  ```
339
351
 
340
352
  ## CEP
@@ -213,7 +213,8 @@ Exemplo:
213
213
 
214
214
  Verifica se os dígitos de verificação do CNPJ (Cadastro Nacional da Pessoa
215
215
  Jurídica) fornecido correspondem ao seu número base. A entrada deve ser uma
216
- string de dígitos com o comprimento apropriado. Esta função não verifica a
216
+ string de 14 caracteres, permitindo dígitos e letras maiúsculas nas 12
217
+ primeiras posições e dígitos nas 2 últimas. Esta função não verifica a
217
218
  existência do CNPJ; ela só valida o formato da string.
218
219
 
219
220
  Argumentos:
@@ -285,12 +286,16 @@ Exemplo:
285
286
 
286
287
  ### generate_cnpj
287
288
 
288
- Gera uma string de dígitos CNPJ válida aleatória. Um número de filial
289
- opcional pode ser fornecido; o padrão é 1.
289
+ Gera uma string de CNPJ válida aleatória. Um número de filial opcional pode ser
290
+ fornecido; o padrão é 1. Use `alphanumeric=True` para gerar um CNPJ cujas 12
291
+ primeiras posições podem conter dígitos e letras maiúsculas.
290
292
 
291
293
  Argumentos:
292
294
 
293
- - branch (int): Um número de filial opcional a ser incluído no CNPJ.
295
+ - branch (int | str): Um número de filial opcional a ser incluído no CNPJ.
296
+ Valores de filial alfanuméricos são aceitos apenas com
297
+ `alphanumeric=True`.
298
+ - alphanumeric (bool): Define se o CNPJ gerado deve ser alfanumérico.
294
299
 
295
300
  Retorna:
296
301
 
@@ -304,6 +309,13 @@ Exemplo:
304
309
  '34665388000161'
305
310
  >>> generate_cnpj(1234)
306
311
  "01745284123455"
312
+ >>> generate_cnpj(alphanumeric=True)
313
+ "9359QAG9000184"
314
+ >>> generate_cnpj(branch="AB12", alphanumeric=True)
315
+ "BR2026UTAB1290"
316
+ >>> generate_cnpj(branch="CD34", alphanumeric=True)
317
+ # CNPJ inválido para exemplos de validação:
318
+ "NX9K79E2CD3400"
307
319
  ```
308
320
 
309
321
  ## CEP
@@ -1,5 +1,6 @@
1
1
  from itertools import chain
2
- from random import randint
2
+ from random import choices, randint
3
+ from string import ascii_uppercase, digits
3
4
 
4
5
  # FORMATTING
5
6
  ############
@@ -83,7 +84,12 @@ def display(cnpj: str) -> str | None:
83
84
  backward compatibility.
84
85
  """
85
86
 
86
- if not cnpj.isdigit() or len(cnpj) != 14 or len(set(cnpj)) == 1:
87
+ if (
88
+ len(cnpj) != 14
89
+ or not _is_alphanumeric(cnpj[:12])
90
+ or not cnpj[12:].isdigit()
91
+ or len(set(cnpj)) == 1
92
+ ):
87
93
  return None
88
94
  return "{}.{}.{}/{}-{}".format(
89
95
  cnpj[:2], cnpj[2:5], cnpj[5:8], cnpj[8:12], cnpj[12:]
@@ -124,6 +130,27 @@ def format_cnpj(cnpj: str) -> str | None:
124
130
  ############
125
131
 
126
132
 
133
+ def _is_alphanumeric(cnpj: str) -> bool:
134
+ """
135
+ Checks whether all characters are digits or uppercase letters.
136
+
137
+ Args:
138
+ cnpj (str): The CNPJ string to be validated.
139
+
140
+ Returns:
141
+ bool: True if all characters are either digits or uppercase letters,
142
+ False otherwise.
143
+
144
+ Example:
145
+ >>> _is_alphanumeric("035ABC1400Z142")
146
+ True
147
+ >>> _is_alphanumeric("0011-22200013!")
148
+ False
149
+ """
150
+
151
+ return all(char in (digits + ascii_uppercase) for char in cnpj)
152
+
153
+
127
154
  def validate(cnpj: str) -> bool:
128
155
  """
129
156
  Validates a CNPJ (Brazilian Company Registration Number) by comparing its
@@ -151,7 +178,12 @@ def validate(cnpj: str) -> bool:
151
178
  backward compatibility.
152
179
  """
153
180
 
154
- if not cnpj.isdigit() or len(cnpj) != 14 or len(set(cnpj)) == 1:
181
+ if (
182
+ len(cnpj) != 14
183
+ or not _is_alphanumeric(cnpj[:12])
184
+ or not cnpj[12:].isdigit()
185
+ or len(set(cnpj)) == 1
186
+ ):
155
187
  return False
156
188
  return all(
157
189
  _hashdigit(cnpj, i + 13) == int(v) for i, v in enumerate(cnpj[12:])
@@ -183,13 +215,18 @@ def is_valid(cnpj: str) -> bool:
183
215
  return isinstance(cnpj, str) and validate(cnpj)
184
216
 
185
217
 
186
- def generate(branch: int = 1) -> str:
218
+ def generate(branch: int | str = 1, alphanumeric: bool = False) -> str:
187
219
  """
188
- Generates a random valid CNPJ digit string. An optional branch number
189
- parameter can be given; it defaults to 1.
220
+ Generates a random valid CNPJ string. An optional branch number parameter
221
+ can be given; it defaults to 1. Use alphanumeric=True to generate a CNPJ
222
+ whose first 12 characters may contain digits and uppercase letters.
190
223
 
191
224
  Args:
192
- branch (int): An optional branch number to be included in the CNPJ.
225
+ branch (int | str): An optional branch number to be included in the
226
+ CNPJ. Alphanumeric branch values are accepted only with
227
+ alphanumeric=True.
228
+ alphanumeric (bool): Whether the generated CNPJ should be
229
+ alphanumeric.
193
230
 
194
231
  Returns:
195
232
  str: A randomly generated valid CNPJ string.
@@ -199,8 +236,23 @@ def generate(branch: int = 1) -> str:
199
236
  "30180536000105"
200
237
  >>> generate(1234)
201
238
  "01745284123455"
239
+ >>> generate(branch="AB12", alphanumeric=True)
240
+ "NX9K79E2AB1200"
202
241
  """
203
242
 
243
+ if alphanumeric:
244
+ branch = str(branch)
245
+ branch = branch[:4] if len(branch) >= 4 else branch.zfill(4)
246
+ branch = (
247
+ "0001"
248
+ if branch == "0000" or not _is_alphanumeric(branch)
249
+ else branch
250
+ )
251
+ base = "".join(choices(digits * 3 + ascii_uppercase, k=8)) + branch
252
+
253
+ return base + _checksum(base)
254
+
255
+ branch = int(branch)
204
256
  branch %= 10000
205
257
  branch += int(branch == 0)
206
258
  branch = str(branch).zfill(4)
@@ -230,7 +282,10 @@ def _hashdigit(cnpj: str, position: int) -> int:
230
282
 
231
283
  weightgen = chain(range(position - 8, 1, -1), range(9, 1, -1))
232
284
  val = (
233
- sum(int(digit) * weight for digit, weight in zip(cnpj, weightgen)) % 11
285
+ sum(
286
+ (ord(digit) - 48) * weight for digit, weight in zip(cnpj, weightgen)
287
+ )
288
+ % 11
234
289
  )
235
290
  return 0 if val < 2 else 11 - val
236
291
 
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "brutils"
3
- version = "2.4.0"
3
+ version = "2.5.0"
4
4
  description = "Utils library for specific Brazilian businesses"
5
5
  authors = ["The Brazilian Utils Organization"]
6
6
  license = "MIT"
@@ -26,7 +26,7 @@ classifiers = [
26
26
 
27
27
  [tool.poetry.dependencies]
28
28
  python = "^3.10"
29
- holidays = ">=0.58,<0.95"
29
+ holidays = ">=0.58,<0.99"
30
30
  num2words = "0.5.14"
31
31
  coverage = "^7.2.7"
32
32
 
@@ -34,7 +34,7 @@ coverage = "^7.2.7"
34
34
  coverage = "^7.2.7"
35
35
 
36
36
  [tool.poetry.group.dev.dependencies]
37
- ruff = "0.15.10"
37
+ ruff = "0.15.17"
38
38
 
39
39
  [tool.ruff]
40
40
  line-length = 80
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes