portugython 0.4.1__tar.gz → 0.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 (57) hide show
  1. {portugython-0.4.1 → portugython-0.5.0}/CHANGELOG.md +32 -1
  2. {portugython-0.4.1 → portugython-0.5.0}/PKG-INFO +64 -68
  3. {portugython-0.4.1 → portugython-0.5.0}/README.md +62 -66
  4. {portugython-0.4.1 → portugython-0.5.0}/portugython/__init__.py +2 -1
  5. portugython-0.5.0/portugython/_codec.py +99 -0
  6. {portugython-0.4.1 → portugython-0.5.0}/portugython/_importador.py +2 -0
  7. portugython-0.5.0/portugython/chaves.py +31 -0
  8. portugython-0.5.0/portugython-codec.pth +1 -0
  9. {portugython-0.4.1 → portugython-0.5.0}/pyproject.toml +5 -2
  10. portugython-0.5.0/tests/exemplo_codec.ptpy +22 -0
  11. portugython-0.5.0/tests/test_codec.py +245 -0
  12. {portugython-0.4.1 → portugython-0.5.0}/tests/test_portugython.py +1 -1
  13. {portugython-0.4.1 → portugython-0.5.0}/.gitignore +0 -0
  14. {portugython-0.4.1 → portugython-0.5.0}/LICENSE +0 -0
  15. {portugython-0.4.1 → portugython-0.5.0}/portugython/abstrato.py +0 -0
  16. {portugython-0.4.1 → portugython-0.5.0}/portugython/aleatorio.py +0 -0
  17. {portugython-0.4.1 → portugython-0.5.0}/portugython/argumentos.py +0 -0
  18. {portugython-0.4.1 → portugython-0.5.0}/portugython/assincronico.py +0 -0
  19. {portugython-0.4.1 → portugython-0.5.0}/portugython/bisecao.py +0 -0
  20. {portugython-0.4.1 → portugython-0.5.0}/portugython/calendario.py +0 -0
  21. {portugython-0.4.1 → portugython-0.5.0}/portugython/caminho.py +0 -0
  22. {portugython-0.4.1 → portugython-0.5.0}/portugython/classe_dados.py +0 -0
  23. {portugython-0.4.1 → portugython-0.5.0}/portugython/codificacao.py +0 -0
  24. {portugython-0.4.1 → portugython-0.5.0}/portugython/colecoes.py +0 -0
  25. {portugython-0.4.1 → portugython-0.5.0}/portugython/compressao.py +0 -0
  26. {portugython-0.4.1 → portugython-0.5.0}/portugython/configuracao.py +0 -0
  27. {portugython-0.4.1 → portugython-0.5.0}/portugython/contexto.py +0 -0
  28. {portugython-0.4.1 → portugython-0.5.0}/portugython/copia.py +0 -0
  29. {portugython-0.4.1 → portugython-0.5.0}/portugython/csv_pt.py +0 -0
  30. {portugython-0.4.1 → portugython-0.5.0}/portugython/depuracao.py +0 -0
  31. {portugython-0.4.1 → portugython-0.5.0}/portugython/enumeracao.py +0 -0
  32. {portugython-0.4.1 → portugython-0.5.0}/portugython/estatistica.py +0 -0
  33. {portugython-0.4.1 → portugython-0.5.0}/portugython/estrutura.py +0 -0
  34. {portugython-0.4.1 → portugython-0.5.0}/portugython/expressao.py +0 -0
  35. {portugython-0.4.1 → portugython-0.5.0}/portugython/formatacao.py +0 -0
  36. {portugython-0.4.1 → portugython-0.5.0}/portugython/funcional.py +0 -0
  37. {portugython-0.4.1 → portugython-0.5.0}/portugython/hash_pt.py +0 -0
  38. {portugython-0.4.1 → portugython-0.5.0}/portugython/identificador.py +0 -0
  39. {portugython-0.4.1 → portugython-0.5.0}/portugython/iteradores.py +0 -0
  40. {portugython-0.4.1 → portugython-0.5.0}/portugython/json.py +0 -0
  41. {portugython-0.4.1 → portugython-0.5.0}/portugython/matematica.py +0 -0
  42. {portugython-0.4.1 → portugython-0.5.0}/portugython/py.typed +0 -0
  43. {portugython-0.4.1 → portugython-0.5.0}/portugython/rede.py +0 -0
  44. {portugython-0.4.1 → portugython-0.5.0}/portugython/registro.py +0 -0
  45. {portugython-0.4.1 → portugython-0.5.0}/portugython/serializacao.py +0 -0
  46. {portugython-0.4.1 → portugython-0.5.0}/portugython/sistema.py +0 -0
  47. {portugython-0.4.1 → portugython-0.5.0}/portugython/soquete.py +0 -0
  48. {portugython-0.4.1 → portugython-0.5.0}/portugython/subprocesso.py +0 -0
  49. {portugython-0.4.1 → portugython-0.5.0}/portugython/tempo.py +0 -0
  50. {portugython-0.4.1 → portugython-0.5.0}/portugython/threads.py +0 -0
  51. {portugython-0.4.1 → portugython-0.5.0}/portugython/tipagem.py +0 -0
  52. {portugython-0.4.1 → portugython-0.5.0}/portugython/transpilador.py +0 -0
  53. {portugython-0.4.1 → portugython-0.5.0}/tests/__init__.py +0 -0
  54. {portugython-0.4.1 → portugython-0.5.0}/tests/ola_mundo.ptpy +0 -0
  55. {portugython-0.4.1 → portugython-0.5.0}/tests/test_importador.py +0 -0
  56. {portugython-0.4.1 → portugython-0.5.0}/tests/test_submodulos.py +0 -0
  57. {portugython-0.4.1 → portugython-0.5.0}/tests/test_transpilador.py +0 -0
@@ -1,6 +1,37 @@
1
1
  # Changelog
2
2
 
3
- ## 0.4.1 (2026-06-26)
3
+ ## 0.5.0 (2026-06-26)
4
+
5
+ Adiciona **codec de fonte `portugues`**: a forma mais natural de escrever Python em português.
6
+
7
+ Adicione `# -*- coding: portugues -*-` ao topo de qualquer arquivo `.py` e escreva
8
+ Python com palavras-chave em português diretamente. Não é necessária nenhuma ferramenta
9
+ extra além do Python padrão.
10
+
11
+ Exemplo completo:
12
+
13
+ ```python
14
+ # -*- coding: portugues -*-
15
+ de chaves importe *
16
+
17
+ defina fatorial(n):
18
+ se n <= 1:
19
+ retorne 1
20
+ senao:
21
+ retorne n * fatorial(n - 1)
22
+
23
+ para i em intervalo(1, 6):
24
+ escreva(f"{i}! = {fatorial(i)}")
25
+ ```
26
+
27
+ Novos módulos:
28
+
29
+ - `portugython._codec`: codec `portugues` que traduz palavras-chave antes do parse;
30
+ registrado automaticamente via `portugython-codec.pth` ao instalar.
31
+ - `portugython.chaves`: re-exporta todos os identificadores em português do
32
+ portugython para uso com `from chaves import *`.
33
+
34
+
4
35
 
5
36
  Corrige acentuação em toda a documentação (README, CHANGELOG, docstrings).
6
37
  Sem alterações na API ou no código.
@@ -1,7 +1,7 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: portugython
3
- Version: 0.4.1
4
- Summary: A Portuguese translation of Python: functions, modules and syntax
3
+ Version: 0.5.0
4
+ Summary: Escreva Python em Português: codec de sintaxe, módulos e funções traduzidos
5
5
  Project-URL: Homepage, https://github.com/spacemany2k38/portugython
6
6
  Project-URL: Bug Tracker, https://github.com/spacemany2k38/portugython/issues
7
7
  Author: Victor Kolis
@@ -31,7 +31,7 @@ Description-Content-Type: text/markdown
31
31
  [![Python versions](https://img.shields.io/pypi/pyversions/portugython.svg)](https://pypi.org/project/portugython/)
32
32
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
33
33
 
34
- Escreva Python em Português. Portugython traduz funções, tipos e módulos da biblioteca padrão do Python para nomes em português.
34
+ Escreva Python em Português. Portugython traduz funções, tipos e módulos da biblioteca padrão do Python para nomes em português, e inclui um **codec de sintaxe** que permite escrever palavras-chave (`se`, `para`, `defina`, etc.) nativamente em qualquer arquivo `.py`.
35
35
 
36
36
  ## Instalação
37
37
 
@@ -39,7 +39,59 @@ Escreva Python em Português. Portugython traduz funções, tipos e módulos da
39
39
  pip install portugython
40
40
  ```
41
41
 
42
- ## Uso básico
42
+ O codec é registrado automaticamente ao instalar. Basta adicionar `# -*- coding: portugues -*-` ao topo do arquivo.
43
+
44
+ ## Uso: Python em Português nativo
45
+
46
+ ```python
47
+ # -*- coding: portugues -*-
48
+ de chaves importe *
49
+
50
+ defina fatorial(n):
51
+ se n <= 1:
52
+ retorne 1
53
+ senao:
54
+ retorne n * fatorial(n - 1)
55
+
56
+ defina verificar_primo(n):
57
+ se n < 2:
58
+ retorne Falso
59
+ para i em intervalo(2, n):
60
+ se n % i == 0:
61
+ retorne Falso
62
+ retorne Verdadeiro
63
+
64
+ primos = [x para x em intervalo(2, 20) se verificar_primo(x)]
65
+ escreva("Primos:", primos)
66
+
67
+ para n em intervalo(1, 6):
68
+ escreva(f"{n}! = {fatorial(n)}")
69
+
70
+ tente:
71
+ resultado = 10 / 0
72
+ exceto ZeroDivisionError como err:
73
+ escreva("Erro capturado:", err)
74
+ finalmente:
75
+ escreva("Pronto!")
76
+ ```
77
+
78
+ Salve como `programa.py` e execute com `python programa.py`. Nenhuma ferramenta extra necessária.
79
+
80
+ > **Nota sobre palavras ambíguas**: `e`, `ou`, `de`, `com`, `em` são palavras-chave
81
+ > reservadas em arquivos com `# -*- coding: portugues -*-`. Evite usá-las como
82
+ > nomes de variáveis (use `err` em vez de `e` para exceções, por exemplo).
83
+
84
+ ## Como funciona
85
+
86
+ O codec `portugues` é registrado automaticamente via `portugython-codec.pth` ao instalar
87
+ o pacote. Quando Python encontra `# -*- coding: portugues -*-`, chama o codec para
88
+ decodificar o arquivo antes de parsear, traduzindo palavras-chave em português para
89
+ Python padrão de forma transparente.
90
+
91
+ O módulo `chaves` exporta todos os aliases de funções em português (`escreva`, `leia`,
92
+ `intervalo`, `tamanho`, `Lista`, `Dicionario`, etc.) para uso direto via `from chaves import *`.
93
+
94
+ ## Uso básico sem codec
43
95
 
44
96
  ```python
45
97
  from portugython import *
@@ -281,84 +333,28 @@ if email.encontrar("contato@example.com"):
281
333
  | `filtro(f, it)` | `list(filter(f, it))` |
282
334
  | `reduzido(f, it)` | `functools.reduce(f, it)` |
283
335
 
284
- ## Transpilador de palavras-chave
336
+ ## Transpilador (API programática)
285
337
 
286
- Portugython inclui um transpilador completo que traduz a sintaxe do Python
287
- (palavras-chave) para português. Isso permite escrever programas Python
288
- inteiramente em português.
289
-
290
- ### CLI: ptpy
291
-
292
- ```bash
293
- ptpy meu_programa.ptpy # executa um arquivo .ptpy
294
- ptpy -c 'para i em intervalo(3): escreva(i)' # executa inline
295
- ptpy --mostrar meu_programa.ptpy # imprime o Python equivalente
296
- ```
297
-
298
- ### API Python
338
+ Além do codec, `portugython.transpilador` expõe funções para tradução programática:
299
339
 
300
340
  ```python
301
341
  from portugython import traduzir, executar_texto, executar_arquivo
302
342
 
303
- # Traduzir uma string
304
- codigo_pt = """
305
- defina fatorial(n):
306
- se n <= 1:
307
- retorne 1
308
- senao:
309
- retorne n * fatorial(n - 1)
310
- """
311
- print(traduzir(codigo_pt))
312
- # def fatorial(n):
313
- # if n <= 1:
314
- # return 1
315
- # else:
316
- # return n * fatorial(n - 1)
343
+ # Ver o Python equivalente
344
+ print(traduzir("se x > 0:\n retorne x"))
345
+ # if x > 0:
346
+ # return x
317
347
 
318
348
  # Executar diretamente
319
349
  executar_texto("para i em intervalo(3):\n escreva(i)")
320
350
 
321
351
  # Executar um arquivo .ptpy
322
- executar_arquivo("meu_programa.ptpy")
352
+ executar_arquivo("programa.ptpy")
323
353
  ```
324
354
 
325
- ### Programa completo em português (.ptpy)
326
-
327
- ```python
328
- # fatorial.ptpy
329
- importe portugython
330
-
331
- defina fatorial(n):
332
- se n <= 1:
333
- retorne 1
334
- senao:
335
- retorne n * fatorial(n - 1)
336
-
337
- defina verificar_primo(n):
338
- se n < 2:
339
- retorne Falso
340
- para i em intervalo(2, n):
341
- se n % i == 0:
342
- retorne Falso
343
- retorne Verdadeiro
344
-
345
- primos = [x para x em intervalo(2, 20) se verificar_primo(x)]
346
- escreva("Primos:", primos)
347
-
348
- para n em intervalo(1, 8):
349
- escreva(f"{n}! = {fatorial(n)}")
350
-
351
- tente:
352
- resultado = 10 / 0
353
- exceto ZeroDivisionError como err:
354
- escreva("Erro capturado:", err)
355
- finalmente:
356
- escreva("Pronto!")
357
- ```
355
+ ## Tabela de palavras-chave
358
356
 
359
- ### Tabela de palavras-chave
360
357
 
361
- | Português | Python | | Português | Python |
362
358
  |-----------|--------|-|-----------|--------|
363
359
  | `se` | `if` | | `senao` | `else` |
364
360
  | `senaose` | `elif` | | `para` | `for` |
@@ -4,7 +4,7 @@
4
4
  [![Python versions](https://img.shields.io/pypi/pyversions/portugython.svg)](https://pypi.org/project/portugython/)
5
5
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
6
6
 
7
- Escreva Python em Português. Portugython traduz funções, tipos e módulos da biblioteca padrão do Python para nomes em português.
7
+ Escreva Python em Português. Portugython traduz funções, tipos e módulos da biblioteca padrão do Python para nomes em português, e inclui um **codec de sintaxe** que permite escrever palavras-chave (`se`, `para`, `defina`, etc.) nativamente em qualquer arquivo `.py`.
8
8
 
9
9
  ## Instalação
10
10
 
@@ -12,7 +12,59 @@ Escreva Python em Português. Portugython traduz funções, tipos e módulos da
12
12
  pip install portugython
13
13
  ```
14
14
 
15
- ## Uso básico
15
+ O codec é registrado automaticamente ao instalar. Basta adicionar `# -*- coding: portugues -*-` ao topo do arquivo.
16
+
17
+ ## Uso: Python em Português nativo
18
+
19
+ ```python
20
+ # -*- coding: portugues -*-
21
+ de chaves importe *
22
+
23
+ defina fatorial(n):
24
+ se n <= 1:
25
+ retorne 1
26
+ senao:
27
+ retorne n * fatorial(n - 1)
28
+
29
+ defina verificar_primo(n):
30
+ se n < 2:
31
+ retorne Falso
32
+ para i em intervalo(2, n):
33
+ se n % i == 0:
34
+ retorne Falso
35
+ retorne Verdadeiro
36
+
37
+ primos = [x para x em intervalo(2, 20) se verificar_primo(x)]
38
+ escreva("Primos:", primos)
39
+
40
+ para n em intervalo(1, 6):
41
+ escreva(f"{n}! = {fatorial(n)}")
42
+
43
+ tente:
44
+ resultado = 10 / 0
45
+ exceto ZeroDivisionError como err:
46
+ escreva("Erro capturado:", err)
47
+ finalmente:
48
+ escreva("Pronto!")
49
+ ```
50
+
51
+ Salve como `programa.py` e execute com `python programa.py`. Nenhuma ferramenta extra necessária.
52
+
53
+ > **Nota sobre palavras ambíguas**: `e`, `ou`, `de`, `com`, `em` são palavras-chave
54
+ > reservadas em arquivos com `# -*- coding: portugues -*-`. Evite usá-las como
55
+ > nomes de variáveis (use `err` em vez de `e` para exceções, por exemplo).
56
+
57
+ ## Como funciona
58
+
59
+ O codec `portugues` é registrado automaticamente via `portugython-codec.pth` ao instalar
60
+ o pacote. Quando Python encontra `# -*- coding: portugues -*-`, chama o codec para
61
+ decodificar o arquivo antes de parsear, traduzindo palavras-chave em português para
62
+ Python padrão de forma transparente.
63
+
64
+ O módulo `chaves` exporta todos os aliases de funções em português (`escreva`, `leia`,
65
+ `intervalo`, `tamanho`, `Lista`, `Dicionario`, etc.) para uso direto via `from chaves import *`.
66
+
67
+ ## Uso básico sem codec
16
68
 
17
69
  ```python
18
70
  from portugython import *
@@ -254,84 +306,28 @@ if email.encontrar("contato@example.com"):
254
306
  | `filtro(f, it)` | `list(filter(f, it))` |
255
307
  | `reduzido(f, it)` | `functools.reduce(f, it)` |
256
308
 
257
- ## Transpilador de palavras-chave
309
+ ## Transpilador (API programática)
258
310
 
259
- Portugython inclui um transpilador completo que traduz a sintaxe do Python
260
- (palavras-chave) para português. Isso permite escrever programas Python
261
- inteiramente em português.
262
-
263
- ### CLI: ptpy
264
-
265
- ```bash
266
- ptpy meu_programa.ptpy # executa um arquivo .ptpy
267
- ptpy -c 'para i em intervalo(3): escreva(i)' # executa inline
268
- ptpy --mostrar meu_programa.ptpy # imprime o Python equivalente
269
- ```
270
-
271
- ### API Python
311
+ Além do codec, `portugython.transpilador` expõe funções para tradução programática:
272
312
 
273
313
  ```python
274
314
  from portugython import traduzir, executar_texto, executar_arquivo
275
315
 
276
- # Traduzir uma string
277
- codigo_pt = """
278
- defina fatorial(n):
279
- se n <= 1:
280
- retorne 1
281
- senao:
282
- retorne n * fatorial(n - 1)
283
- """
284
- print(traduzir(codigo_pt))
285
- # def fatorial(n):
286
- # if n <= 1:
287
- # return 1
288
- # else:
289
- # return n * fatorial(n - 1)
316
+ # Ver o Python equivalente
317
+ print(traduzir("se x > 0:\n retorne x"))
318
+ # if x > 0:
319
+ # return x
290
320
 
291
321
  # Executar diretamente
292
322
  executar_texto("para i em intervalo(3):\n escreva(i)")
293
323
 
294
324
  # Executar um arquivo .ptpy
295
- executar_arquivo("meu_programa.ptpy")
325
+ executar_arquivo("programa.ptpy")
296
326
  ```
297
327
 
298
- ### Programa completo em português (.ptpy)
299
-
300
- ```python
301
- # fatorial.ptpy
302
- importe portugython
303
-
304
- defina fatorial(n):
305
- se n <= 1:
306
- retorne 1
307
- senao:
308
- retorne n * fatorial(n - 1)
309
-
310
- defina verificar_primo(n):
311
- se n < 2:
312
- retorne Falso
313
- para i em intervalo(2, n):
314
- se n % i == 0:
315
- retorne Falso
316
- retorne Verdadeiro
317
-
318
- primos = [x para x em intervalo(2, 20) se verificar_primo(x)]
319
- escreva("Primos:", primos)
320
-
321
- para n em intervalo(1, 8):
322
- escreva(f"{n}! = {fatorial(n)}")
323
-
324
- tente:
325
- resultado = 10 / 0
326
- exceto ZeroDivisionError como err:
327
- escreva("Erro capturado:", err)
328
- finalmente:
329
- escreva("Pronto!")
330
- ```
328
+ ## Tabela de palavras-chave
331
329
 
332
- ### Tabela de palavras-chave
333
330
 
334
- | Português | Python | | Português | Python |
335
331
  |-----------|--------|-|-----------|--------|
336
332
  | `se` | `if` | | `senao` | `else` |
337
333
  | `senaose` | `elif` | | `para` | `for` |
@@ -4,6 +4,7 @@ from __future__ import annotations
4
4
 
5
5
  from functools import reduce as _reduce
6
6
 
7
+ import portugython._codec # registra o codec 'portugues' automaticamente # noqa: F401
7
8
  from portugython._importador import (
8
9
  desinstalar,
9
10
  instalar,
@@ -19,7 +20,7 @@ from portugython.transpilador import (
19
20
  traduzir_para_portugues,
20
21
  )
21
22
 
22
- __version__ = "0.4.1"
23
+ __version__ = "0.5.0"
23
24
 
24
25
  # Instala o gancho de importação automaticamente
25
26
  instalar()
@@ -0,0 +1,99 @@
1
+ """_codec - codec 'portugues' que habilita sintaxe Python em português.
2
+
3
+ Quando registrado, qualquer arquivo com:
4
+
5
+ # -*- coding: portugues -*-
6
+
7
+ pode usar palavras-chave em português diretamente. Python chama este codec
8
+ para decodificar o código-fonte antes de parsear, então a tradução é
9
+ transparente para o interpretador.
10
+
11
+ O codec é registrado automaticamente ao importar portugython, e também
12
+ via o arquivo portugython-codec.pth instalado em site-packages (que
13
+ registra o codec ao iniciar o Python, antes de qualquer código do usuário).
14
+ """
15
+
16
+ from __future__ import annotations
17
+
18
+ import codecs
19
+ import encodings.utf_8
20
+
21
+
22
+ def _decode(input_bytes: bytes, errors: str = "strict") -> tuple[str, int]:
23
+ """Decodifica bytes de fonte Python em português para Python padrão.
24
+
25
+ Chamado pelo Python quando encontra '# -*- coding: portugues -*-'.
26
+
27
+ Args:
28
+ input_bytes: Bytes do arquivo-fonte.
29
+ errors: Política de tratamento de erros de encoding.
30
+
31
+ Returns:
32
+ Tupla (código_python_str, bytes_consumidos).
33
+ """
34
+ from portugython.transpilador import traduzir # noqa: PLC0415
35
+
36
+ fonte = input_bytes.decode("utf-8", errors)
37
+ return traduzir(fonte), len(input_bytes)
38
+
39
+
40
+ class _DecodificadorIncremental(codecs.BufferedIncrementalDecoder):
41
+ """Decodificador incremental necessário pela interface de codecs."""
42
+
43
+ def _buffer_decode(
44
+ self, entrada: bytes, erros: str, final: bool
45
+ ) -> tuple[str, int]:
46
+ return _decode(entrada, erros)
47
+
48
+
49
+ class _LeitorFluxo(codecs.StreamReader):
50
+ """Leitor de fluxo necessário pela interface de codecs."""
51
+
52
+ def decode(self, entrada: bytes, erros: str = "strict") -> tuple[str, int]:
53
+ return _decode(entrada, erros)
54
+
55
+
56
+ _CODEC_INFO = codecs.CodecInfo(
57
+ name="portugues",
58
+ encode=encodings.utf_8.encode,
59
+ decode=_decode,
60
+ incrementaldecoder=_DecodificadorIncremental,
61
+ streamreader=_LeitorFluxo,
62
+ )
63
+
64
+ _NOMES_CODEC: frozenset[str] = frozenset(
65
+ ("portugues", "portugues_br", "pt_br", "português", "português_br")
66
+ )
67
+
68
+
69
+ def _buscar_codec(nome: str) -> codecs.CodecInfo | None:
70
+ """Função de busca registrada no sistema de codecs do Python.
71
+
72
+ Args:
73
+ nome: Nome do codec solicitado pelo Python.
74
+
75
+ Returns:
76
+ CodecInfo se o nome for 'portugues', None caso contrário.
77
+ """
78
+ if nome.replace("-", "_").lower() in _NOMES_CODEC:
79
+ return _CODEC_INFO
80
+ return None
81
+
82
+
83
+ def registrar() -> None:
84
+ """Registra o codec 'portugues' no sistema de codecs do Python.
85
+
86
+ Após registrar, arquivos com '# -*- coding: portugues -*-'
87
+ podem usar palavras-chave em português nativamente.
88
+
89
+ Chamado automaticamente ao importar portugython e pelo arquivo
90
+ portugython-codec.pth no arranque do Python.
91
+
92
+ Example:
93
+ from portugython._codec import registrar
94
+ registrar()
95
+ """
96
+ codecs.register(_buscar_codec)
97
+
98
+
99
+ registrar()
@@ -69,6 +69,8 @@ MAPA_MODULOS: dict[str, str] = {
69
69
  "estrutura": "portugython.estrutura",
70
70
  "depuracao": "portugython.depuracao",
71
71
  "csv_pt": "portugython.csv_pt",
72
+ # Namespace principal em português
73
+ "chaves": "portugython.chaves",
72
74
  }
73
75
 
74
76
 
@@ -0,0 +1,31 @@
1
+ """chaves - exporta todos os identificadores em português do portugython.
2
+
3
+ Uso típico junto com o codec 'portugues':
4
+
5
+ # -*- coding: portugues -*-
6
+ de chaves importe *
7
+
8
+ se 4 > 5:
9
+ passe
10
+ senao:
11
+ escreva("correto!")
12
+
13
+ defina fatorial(n):
14
+ se n <= 1:
15
+ retorne 1
16
+ senao:
17
+ retorne n * fatorial(n - 1)
18
+
19
+ para i em intervalo(1, 6):
20
+ escreva(f"{i}! = {fatorial(i)}")
21
+
22
+ Também pode ser importado com a sintaxe Python padrão:
23
+
24
+ # -*- coding: portugues -*-
25
+ from chaves import *
26
+ """
27
+
28
+ from portugython import * # noqa: F401, F403
29
+ from portugython import __all__ # noqa: F401
30
+
31
+ __all__ = list(__all__)
@@ -0,0 +1 @@
1
+ import portugython._codec
@@ -4,8 +4,8 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "portugython"
7
- version = "0.4.1"
8
- description = "A Portuguese translation of Python: functions, modules and syntax"
7
+ version = "0.5.0"
8
+ description = "Escreva Python em Português: codec de sintaxe, módulos e funções traduzidos"
9
9
  readme = "README.md"
10
10
  license = {text = "MIT"}
11
11
  requires-python = ">=3.10"
@@ -29,6 +29,9 @@ classifiers = [
29
29
  Homepage = "https://github.com/spacemany2k38/portugython"
30
30
  "Bug Tracker" = "https://github.com/spacemany2k38/portugython/issues"
31
31
 
32
+ [tool.hatch.build.targets.wheel]
33
+ force-include = {"portugython-codec.pth" = "portugython-codec.pth"}
34
+
32
35
  [project.scripts]
33
36
  ptpy = "portugython.transpilador:_main"
34
37
 
@@ -0,0 +1,22 @@
1
+ # -*- coding: portugues -*-
2
+ de chaves importe *
3
+
4
+ defina fatorial(n):
5
+ se n <= 1:
6
+ retorne 1
7
+ senao:
8
+ retorne n * fatorial(n - 1)
9
+
10
+ defina verificar_primo(n):
11
+ se n < 2:
12
+ retorne Falso
13
+ para i em intervalo(2, n):
14
+ se n % i == 0:
15
+ retorne Falso
16
+ retorne Verdadeiro
17
+
18
+ resultados = []
19
+ para n em intervalo(1, 6):
20
+ resultados.adicione(fatorial(n))
21
+
22
+ primos = [x para x em intervalo(2, 20) se verificar_primo(x)]
@@ -0,0 +1,245 @@
1
+ """Testes para o codec 'portugues' e o módulo chaves."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import codecs
6
+ import sys
7
+ import textwrap
8
+
9
+ # ---------------------------------------------------------------------------
10
+ # Testes do codec
11
+ # ---------------------------------------------------------------------------
12
+
13
+
14
+ def test_codec_registrado():
15
+ """O codec 'portugues' deve estar disponível após importar portugython."""
16
+ import portugython # noqa: F401
17
+
18
+ info = codecs.lookup("portugues")
19
+ assert info.name == "portugues"
20
+
21
+
22
+ def test_codec_decodifica_se():
23
+ info = codecs.lookup("portugues")
24
+ codigo = b"se x > 0: passar"
25
+ resultado, _ = info.decode(codigo)
26
+ assert "if" in resultado
27
+ assert "pass" in resultado
28
+
29
+
30
+ def test_codec_decodifica_para():
31
+ info = codecs.lookup("portugues")
32
+ codigo = b"para i em intervalo(3): passar"
33
+ resultado, _ = info.decode(codigo)
34
+ assert "for" in resultado
35
+ assert "in" in resultado
36
+ assert "pass" in resultado
37
+
38
+
39
+ def test_codec_decodifica_defina_retorne():
40
+ info = codecs.lookup("portugues")
41
+ codigo = b"defina f(x):\n retorne x * 2"
42
+ resultado, _ = info.decode(codigo)
43
+ assert "def f(x):" in resultado
44
+ assert "return x * 2" in resultado
45
+
46
+
47
+ def test_codec_preserva_strings():
48
+ info = codecs.lookup("portugues")
49
+ codigo = b'x = "se para enquanto defina"'
50
+ resultado, _ = info.decode(codigo)
51
+ assert '"se para enquanto defina"' in resultado
52
+
53
+
54
+ def test_codec_preserva_comentarios():
55
+ info = codecs.lookup("portugues")
56
+ codigo = b"# se para enquanto\nx = 1"
57
+ resultado, _ = info.decode(codigo)
58
+ assert "# se para enquanto" in resultado
59
+
60
+
61
+ def test_codec_encode_utf8():
62
+ """Encode deve ser UTF-8 normal (sem transformação)."""
63
+ info = codecs.lookup("portugues")
64
+ texto = "olá mundo"
65
+ codificado, _ = info.encode(texto)
66
+ assert codificado == texto.encode("utf-8")
67
+
68
+
69
+ # ---------------------------------------------------------------------------
70
+ # Testes do módulo chaves
71
+ # ---------------------------------------------------------------------------
72
+
73
+
74
+ def test_chaves_importavel():
75
+ from chaves import Falso, Nenhum, Verdadeiro, escreva, intervalo # noqa: F401
76
+
77
+ assert escreva is print
78
+ assert intervalo is range
79
+ assert Verdadeiro is True
80
+ assert Falso is False
81
+ assert Nenhum is None
82
+
83
+
84
+ def test_chaves_tem_all():
85
+ import chaves
86
+
87
+ assert hasattr(chaves, "__all__")
88
+ assert len(chaves.__all__) > 20
89
+
90
+
91
+ def test_chaves_escreva(capsys):
92
+ from chaves import escreva
93
+
94
+ escreva("olá do chaves")
95
+ assert "olá do chaves" in capsys.readouterr().out
96
+
97
+
98
+ def test_chaves_lista_classe():
99
+ from chaves import Lista, tamanho
100
+
101
+ lista = Lista([1, 2, 3])
102
+ lista.adicione(4)
103
+ assert tamanho(lista) == 4
104
+
105
+
106
+ def test_chaves_tamanho():
107
+ from chaves import tamanho
108
+
109
+ assert tamanho([1, 2, 3]) == 3
110
+ assert tamanho("abc") == 3
111
+
112
+
113
+ # ---------------------------------------------------------------------------
114
+ # Testes de execução com codec via arquivo .ptpy
115
+ # ---------------------------------------------------------------------------
116
+
117
+
118
+ def test_arquivo_ptpy_com_declaracao_codec(tmp_path, capsys):
119
+ """Arquivo com # -*- coding: portugues -*- é executado com palavras-chave em PT."""
120
+ arquivo = tmp_path / "teste.ptpy"
121
+ arquivo.write_text(
122
+ textwrap.dedent("""
123
+ # -*- coding: portugues -*-
124
+ de chaves importe *
125
+
126
+ defina quadrado(n):
127
+ retorne n * n
128
+
129
+ para i em intervalo(1, 4):
130
+ escreva(quadrado(i))
131
+ """).strip(),
132
+ encoding="utf-8",
133
+ )
134
+
135
+ from portugython.transpilador import executar_arquivo
136
+
137
+ executar_arquivo(arquivo)
138
+ saida = capsys.readouterr().out
139
+ assert "1" in saida
140
+ assert "4" in saida
141
+ assert "9" in saida
142
+
143
+
144
+ def test_ptpy_se_senao(tmp_path, capsys):
145
+ arquivo = tmp_path / "cond.ptpy"
146
+ arquivo.write_text(
147
+ textwrap.dedent("""
148
+ # -*- coding: portugues -*-
149
+ de chaves importe *
150
+
151
+ x = 10
152
+ se x > 5:
153
+ escreva("grande")
154
+ senaose x == 5:
155
+ escreva("exato")
156
+ senao:
157
+ escreva("pequeno")
158
+ """).strip(),
159
+ encoding="utf-8",
160
+ )
161
+ from portugython.transpilador import executar_arquivo
162
+
163
+ executar_arquivo(arquivo)
164
+ assert "grande" in capsys.readouterr().out
165
+
166
+
167
+ def test_ptpy_tente_exceto(tmp_path, capsys):
168
+ arquivo = tmp_path / "erro.ptpy"
169
+ arquivo.write_text(
170
+ textwrap.dedent("""
171
+ # -*- coding: portugues -*-
172
+ de chaves importe *
173
+
174
+ tente:
175
+ levante ValueError("teste")
176
+ exceto ValueError como err:
177
+ escreva("capturado:", err)
178
+ finalmente:
179
+ escreva("pronto")
180
+ """).strip(),
181
+ encoding="utf-8",
182
+ )
183
+ from portugython.transpilador import executar_arquivo
184
+
185
+ executar_arquivo(arquivo)
186
+ saida = capsys.readouterr().out
187
+ assert "capturado" in saida
188
+ assert "pronto" in saida
189
+
190
+
191
+ def test_ptpy_enquanto(tmp_path, capsys):
192
+ arquivo = tmp_path / "loop.ptpy"
193
+ arquivo.write_text(
194
+ textwrap.dedent("""
195
+ # -*- coding: portugues -*-
196
+ de chaves importe *
197
+
198
+ i = 0
199
+ enquanto i < 3:
200
+ escreva(i)
201
+ i = i + 1
202
+ """).strip(),
203
+ encoding="utf-8",
204
+ )
205
+ from portugython.transpilador import executar_arquivo
206
+
207
+ executar_arquivo(arquivo)
208
+ saida = capsys.readouterr().out
209
+ assert "0" in saida
210
+ assert "2" in saida
211
+
212
+
213
+ # ---------------------------------------------------------------------------
214
+ # Testes de importação via hook (.ptpy como módulo)
215
+ # ---------------------------------------------------------------------------
216
+
217
+
218
+ def test_importar_modulo_ptpy(tmp_path):
219
+ """Módulos .ptpy podem ser importados via import normal com o hook ativo."""
220
+ import portugython # garante hook ativo # noqa: F401
221
+
222
+ modulo_py = tmp_path / "meu_modulo.ptpy"
223
+ modulo_py.write_text(
224
+ textwrap.dedent("""
225
+ de chaves importe *
226
+
227
+ defina dobrar(x):
228
+ retorne x * 2
229
+
230
+ VALOR = dobrar(21)
231
+ """).strip(),
232
+ encoding="utf-8",
233
+ )
234
+
235
+ sys.path.insert(0, str(tmp_path))
236
+ try:
237
+ if "meu_modulo" in sys.modules:
238
+ del sys.modules["meu_modulo"]
239
+ import meu_modulo # noqa: PLC0415
240
+
241
+ assert meu_modulo.VALOR == 42
242
+ assert meu_modulo.dobrar(5) == 10
243
+ finally:
244
+ sys.path.remove(str(tmp_path))
245
+ sys.modules.pop("meu_modulo", None)
@@ -33,7 +33,7 @@ from portugython import (
33
33
 
34
34
  def test_version():
35
35
  """Testa a versao do pacote."""
36
- assert __version__ == "0.4.1"
36
+ assert __version__ == "0.5.0"
37
37
 
38
38
 
39
39
  def test_type_functions():
File without changes
File without changes