portugython 0.2.0__tar.gz → 0.3.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 (49) hide show
  1. {portugython-0.2.0 → portugython-0.3.0}/CHANGELOG.md +22 -1
  2. {portugython-0.2.0 → portugython-0.3.0}/PKG-INFO +1 -1
  3. {portugython-0.2.0 → portugython-0.3.0}/portugython/__init__.py +14 -1
  4. portugython-0.3.0/portugython/_importador.py +136 -0
  5. {portugython-0.2.0 → portugython-0.3.0}/pyproject.toml +1 -1
  6. portugython-0.3.0/tests/test_importador.py +170 -0
  7. {portugython-0.2.0 → portugython-0.3.0}/tests/test_portugython.py +1 -1
  8. {portugython-0.2.0 → portugython-0.3.0}/.gitignore +0 -0
  9. {portugython-0.2.0 → portugython-0.3.0}/LICENSE +0 -0
  10. {portugython-0.2.0 → portugython-0.3.0}/README.md +0 -0
  11. {portugython-0.2.0 → portugython-0.3.0}/portugython/abstrato.py +0 -0
  12. {portugython-0.2.0 → portugython-0.3.0}/portugython/aleatorio.py +0 -0
  13. {portugython-0.2.0 → portugython-0.3.0}/portugython/argumentos.py +0 -0
  14. {portugython-0.2.0 → portugython-0.3.0}/portugython/assincronico.py +0 -0
  15. {portugython-0.2.0 → portugython-0.3.0}/portugython/bisecao.py +0 -0
  16. {portugython-0.2.0 → portugython-0.3.0}/portugython/calendario.py +0 -0
  17. {portugython-0.2.0 → portugython-0.3.0}/portugython/caminho.py +0 -0
  18. {portugython-0.2.0 → portugython-0.3.0}/portugython/classe_dados.py +0 -0
  19. {portugython-0.2.0 → portugython-0.3.0}/portugython/codificacao.py +0 -0
  20. {portugython-0.2.0 → portugython-0.3.0}/portugython/colecoes.py +0 -0
  21. {portugython-0.2.0 → portugython-0.3.0}/portugython/compressao.py +0 -0
  22. {portugython-0.2.0 → portugython-0.3.0}/portugython/configuracao.py +0 -0
  23. {portugython-0.2.0 → portugython-0.3.0}/portugython/contexto.py +0 -0
  24. {portugython-0.2.0 → portugython-0.3.0}/portugython/copia.py +0 -0
  25. {portugython-0.2.0 → portugython-0.3.0}/portugython/csv_pt.py +0 -0
  26. {portugython-0.2.0 → portugython-0.3.0}/portugython/depuracao.py +0 -0
  27. {portugython-0.2.0 → portugython-0.3.0}/portugython/enumeracao.py +0 -0
  28. {portugython-0.2.0 → portugython-0.3.0}/portugython/estatistica.py +0 -0
  29. {portugython-0.2.0 → portugython-0.3.0}/portugython/estrutura.py +0 -0
  30. {portugython-0.2.0 → portugython-0.3.0}/portugython/expressao.py +0 -0
  31. {portugython-0.2.0 → portugython-0.3.0}/portugython/formatacao.py +0 -0
  32. {portugython-0.2.0 → portugython-0.3.0}/portugython/funcional.py +0 -0
  33. {portugython-0.2.0 → portugython-0.3.0}/portugython/hash_pt.py +0 -0
  34. {portugython-0.2.0 → portugython-0.3.0}/portugython/identificador.py +0 -0
  35. {portugython-0.2.0 → portugython-0.3.0}/portugython/iteradores.py +0 -0
  36. {portugython-0.2.0 → portugython-0.3.0}/portugython/json.py +0 -0
  37. {portugython-0.2.0 → portugython-0.3.0}/portugython/matematica.py +0 -0
  38. {portugython-0.2.0 → portugython-0.3.0}/portugython/py.typed +0 -0
  39. {portugython-0.2.0 → portugython-0.3.0}/portugython/rede.py +0 -0
  40. {portugython-0.2.0 → portugython-0.3.0}/portugython/registro.py +0 -0
  41. {portugython-0.2.0 → portugython-0.3.0}/portugython/serializacao.py +0 -0
  42. {portugython-0.2.0 → portugython-0.3.0}/portugython/sistema.py +0 -0
  43. {portugython-0.2.0 → portugython-0.3.0}/portugython/soquete.py +0 -0
  44. {portugython-0.2.0 → portugython-0.3.0}/portugython/subprocesso.py +0 -0
  45. {portugython-0.2.0 → portugython-0.3.0}/portugython/tempo.py +0 -0
  46. {portugython-0.2.0 → portugython-0.3.0}/portugython/threads.py +0 -0
  47. {portugython-0.2.0 → portugython-0.3.0}/portugython/tipagem.py +0 -0
  48. {portugython-0.2.0 → portugython-0.3.0}/tests/__init__.py +0 -0
  49. {portugython-0.2.0 → portugython-0.3.0}/tests/test_submodulos.py +0 -0
@@ -1,6 +1,27 @@
1
1
  # Changelog
2
2
 
3
- ## 0.2.0 (2026-06-26)
3
+ ## 0.3.0 (2026-06-26)
4
+
5
+ Add import hook so all Portuguese module names work as top-level imports.
6
+
7
+ After `import portugython`, the full stdlib-level syntax works:
8
+
9
+ import aleatorio
10
+ from matematica import raiz_quadrada, PI
11
+ from colecoes import Contador, Pilha, Fila
12
+ from tempo import agora, hoje
13
+ from expressao import buscar, encontrar_todos
14
+ from dados import serializar, deserializar # json
15
+ from subprocesso import executar
16
+ from caminho import Caminho
17
+ # ... all 36 modules
18
+
19
+ New exports:
20
+ - `portugython.instalar()` - instala o gancho (chamado automaticamente)
21
+ - `portugython.desinstalar()` - remove o gancho
22
+ - `portugython.listar_modulos()` - retorna o mapa de nomes
23
+
24
+
4
25
 
5
26
  Full stdlib coverage. 36 submodules total, all importable via `from portugython import <modulo>`:
6
27
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: portugython
3
- Version: 0.2.0
3
+ Version: 0.3.0
4
4
  Summary: A Portuguese translation of the Python functions/modules/packages
5
5
  Project-URL: Homepage, https://github.com/spacemany2k38/portugython
6
6
  Project-URL: Bug Tracker, https://github.com/spacemany2k38/portugython/issues
@@ -4,7 +4,16 @@ from __future__ import annotations
4
4
 
5
5
  from functools import reduce as _reduce
6
6
 
7
- __version__ = "0.2.0"
7
+ from portugython._importador import (
8
+ desinstalar,
9
+ instalar,
10
+ listar_modulos,
11
+ )
12
+
13
+ __version__ = "0.3.0"
14
+
15
+ # Instala o gancho de importacao automaticamente
16
+ instalar()
8
17
 
9
18
  # ---------------------------------------------------------------------------
10
19
  # IO
@@ -490,6 +499,10 @@ def imprima(*args: object, sep: str = " ", fim: str = "\n", **kwargs: object) ->
490
499
  # ---------------------------------------------------------------------------
491
500
  __all__ = [
492
501
  "__version__",
502
+ # Importador
503
+ "instalar",
504
+ "desinstalar",
505
+ "listar_modulos",
493
506
  # IO
494
507
  "escreva",
495
508
  "leia",
@@ -0,0 +1,136 @@
1
+ """_importador - gancho de importacao que permite importar modulos em Portugues.
2
+
3
+ Quando ativado, permite usar nomes de modulos em Portugues diretamente:
4
+
5
+ import aleatorio
6
+ from matematica import raiz_quadrada
7
+ from colecoes import Contador
8
+ """
9
+
10
+ from __future__ import annotations
11
+
12
+ import importlib
13
+ import importlib.abc
14
+ import importlib.machinery
15
+ import sys
16
+ from importlib.machinery import ModuleSpec
17
+ from typing import Sequence
18
+
19
+ # Mapeamento de nome em Portugues -> caminho completo do modulo portugython
20
+ MAPA_MODULOS: dict[str, str] = {
21
+ # Matematica e ciencia
22
+ "aleatorio": "portugython.aleatorio",
23
+ "matematica": "portugython.matematica",
24
+ "estatistica": "portugython.estatistica",
25
+ # Tipos e estruturas
26
+ "colecoes": "portugython.colecoes",
27
+ "iteradores": "portugython.iteradores",
28
+ "funcional": "portugython.funcional",
29
+ "bisecao": "portugython.bisecao",
30
+ # Tempo e data
31
+ "tempo": "portugython.tempo",
32
+ "calendario": "portugython.calendario",
33
+ # Sistema e IO
34
+ "sistema": "portugython.sistema",
35
+ "caminho": "portugython.caminho",
36
+ "subprocesso": "portugython.subprocesso",
37
+ "soquete": "portugython.soquete",
38
+ "rede": "portugython.rede",
39
+ # Texto e expressoes
40
+ "expressao": "portugython.expressao",
41
+ "formatacao": "portugython.formatacao",
42
+ # Serialization e codificacao
43
+ "serializacao": "portugython.serializacao",
44
+ "codificacao": "portugython.codificacao",
45
+ "compressao": "portugython.compressao",
46
+ "dados": "portugython.json",
47
+ # Concorrencia
48
+ "threads": "portugython.threads",
49
+ "assincronico": "portugython.assincronico",
50
+ # OOP e tipos
51
+ "abstrato": "portugython.abstrato",
52
+ "enumeracao": "portugython.enumeracao",
53
+ "classe_dados": "portugython.classe_dados",
54
+ "tipagem": "portugython.tipagem",
55
+ # Utilitarios
56
+ "registro": "portugython.registro",
57
+ "argumentos": "portugython.argumentos",
58
+ "contexto": "portugython.contexto",
59
+ "copia": "portugython.copia",
60
+ "hash_pt": "portugython.hash_pt",
61
+ "identificador": "portugython.identificador",
62
+ "configuracao": "portugython.configuracao",
63
+ "estrutura": "portugython.estrutura",
64
+ "depuracao": "portugython.depuracao",
65
+ "csv_pt": "portugython.csv_pt",
66
+ }
67
+
68
+
69
+ class _CarregadorAlias(importlib.abc.Loader):
70
+ """Carrega um modulo portugython sob um nome em Portugues."""
71
+
72
+ def __init__(self, modulo_real: str) -> None:
73
+ self._modulo_real = modulo_real
74
+
75
+ def create_module(self, spec: ModuleSpec): # noqa: ANN001
76
+ """Retorna o modulo real (ja carregado ou carregado agora)."""
77
+ return importlib.import_module(self._modulo_real)
78
+
79
+ def exec_module(self, module) -> None: # noqa: ANN001
80
+ """Nao precisa fazer nada: create_module ja retornou o modulo pronto."""
81
+
82
+
83
+ class ImportadorPortugues(importlib.abc.MetaPathFinder):
84
+ """Intercepta imports de nomes em Portugues e redireciona para portugython.*."""
85
+
86
+ def find_spec(
87
+ self,
88
+ fullname: str,
89
+ path: Sequence[str] | None,
90
+ target=None, # noqa: ANN001
91
+ ) -> ModuleSpec | None:
92
+ """Retorna um ModuleSpec para o modulo em Portugues, se mapeado.
93
+
94
+ Args:
95
+ fullname: Nome completo do modulo sendo importado.
96
+ path: Caminho de busca (ignorado aqui).
97
+ target: Modulo alvo (ignorado aqui).
98
+ """
99
+ if fullname in MAPA_MODULOS:
100
+ modulo_real = MAPA_MODULOS[fullname]
101
+ carregador = _CarregadorAlias(modulo_real)
102
+ return ModuleSpec(fullname, carregador)
103
+ return None
104
+
105
+
106
+ _gancho = ImportadorPortugues()
107
+
108
+
109
+ def instalar() -> None:
110
+ """Instala o importador de modulos em Portugues no sys.meta_path.
111
+
112
+ Apos chamar esta funcao, e possivel importar modulos pelo nome em Portugues:
113
+
114
+ import aleatorio
115
+ from matematica import raiz_quadrada, PI
116
+ from colecoes import Contador, Pilha
117
+ from tempo import agora, hoje
118
+ """
119
+ if not any(isinstance(f, ImportadorPortugues) for f in sys.meta_path):
120
+ sys.meta_path.insert(0, _gancho)
121
+
122
+
123
+ def desinstalar() -> None:
124
+ """Remove o importador de modulos em Portugues do sys.meta_path."""
125
+ sys.meta_path[:] = [
126
+ f for f in sys.meta_path if not isinstance(f, ImportadorPortugues)
127
+ ]
128
+
129
+
130
+ def listar_modulos() -> dict[str, str]:
131
+ """Retorna o mapeamento de nomes em Portugues para modulos portugython.
132
+
133
+ Returns:
134
+ Dicionario com nome_portugues -> caminho_modulo.
135
+ """
136
+ return dict(MAPA_MODULOS)
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "portugython"
7
- version = "0.2.0"
7
+ version = "0.3.0"
8
8
  description = "A Portuguese translation of the Python functions/modules/packages"
9
9
  readme = "README.md"
10
10
  license = {text = "MIT"}
@@ -0,0 +1,170 @@
1
+ """Testa o gancho de importacao de modulos em Portugues."""
2
+
3
+ import importlib
4
+ import sys
5
+
6
+ import portugython
7
+ from portugython._importador import MAPA_MODULOS, ImportadorPortugues
8
+
9
+
10
+ def _limpar_cache(nome: str) -> None:
11
+ sys.modules.pop(nome, None)
12
+
13
+
14
+ def test_hook_instalado():
15
+ """O gancho deve estar instalado apos import portugython."""
16
+ assert any(isinstance(f, ImportadorPortugues) for f in sys.meta_path)
17
+
18
+
19
+ def test_listar_modulos():
20
+ """listar_modulos deve retornar o mapa completo."""
21
+ mapa = portugython.listar_modulos()
22
+ assert "aleatorio" in mapa
23
+ assert "matematica" in mapa
24
+ assert mapa["aleatorio"] == "portugython.aleatorio"
25
+
26
+
27
+ def test_import_aleatorio():
28
+ """import aleatorio deve funcionar como from portugython import aleatorio."""
29
+ _limpar_cache("aleatorio")
30
+ import aleatorio # noqa: PLC0415
31
+ assert hasattr(aleatorio, "inteiro_aleatorio")
32
+ assert hasattr(aleatorio, "escolha")
33
+ assert hasattr(aleatorio, "embaralhe")
34
+ n = aleatorio.inteiro_aleatorio(1, 100)
35
+ assert 1 <= n <= 100
36
+
37
+
38
+ def test_from_aleatorio_import():
39
+ """from aleatorio import deve funcionar."""
40
+ _limpar_cache("aleatorio")
41
+ from aleatorio import escolha, inteiro_aleatorio # noqa: PLC0415
42
+ assert callable(inteiro_aleatorio)
43
+ assert callable(escolha)
44
+ assert escolha([1, 2, 3]) in [1, 2, 3]
45
+
46
+
47
+ def test_import_matematica():
48
+ """import matematica deve expor raiz_quadrada, PI, etc."""
49
+ _limpar_cache("matematica")
50
+ from matematica import PI, raiz_quadrada, seno # noqa: PLC0415
51
+ assert abs(PI - 3.14159) < 0.001
52
+ assert raiz_quadrada(9) == 3.0
53
+ assert abs(seno(PI / 2) - 1.0) < 1e-10
54
+
55
+
56
+ def test_import_tempo():
57
+ """import tempo deve expor agora, hoje, dormir."""
58
+ _limpar_cache("tempo")
59
+ from tempo import agora, hoje # noqa: PLC0415
60
+ assert hoje().ano >= 2024
61
+ assert agora().horas >= 0
62
+
63
+
64
+ def test_import_colecoes():
65
+ """import colecoes deve expor Contador, Pilha, Fila."""
66
+ _limpar_cache("colecoes")
67
+ from colecoes import Contador, Fila, Pilha # noqa: PLC0415
68
+ c = Contador(["a", "a", "b"])
69
+ assert c["a"] == 2
70
+ p = Pilha([1, 2, 3])
71
+ assert p.retire() == 3
72
+ f = Fila()
73
+ f.enfileire("x")
74
+ assert f.desenfileire() == "x"
75
+
76
+
77
+ def test_import_iteradores():
78
+ """import iteradores deve expor combine, encadeie, etc."""
79
+ _limpar_cache("iteradores")
80
+ from iteradores import acumule, encadeie # noqa: PLC0415
81
+ assert list(encadeie([1, 2], [3, 4])) == [1, 2, 3, 4]
82
+ assert list(acumule([1, 2, 3])) == [1, 3, 6]
83
+
84
+
85
+ def test_import_funcional():
86
+ """import funcional deve expor reduzido, parcial, cache."""
87
+ _limpar_cache("funcional")
88
+ from funcional import parcial, reduzido # noqa: PLC0415
89
+ total = reduzido(lambda a, b: a + b, [1, 2, 3, 4, 5])
90
+ assert total == 15
91
+ dobrar = parcial(lambda a, b: a * b, 2)
92
+ assert dobrar(7) == 14
93
+
94
+
95
+ def test_import_expressao():
96
+ """import expressao deve expor buscar, encontrar_todos."""
97
+ _limpar_cache("expressao")
98
+ from expressao import buscar, encontrar_todos # noqa: PLC0415
99
+ m = buscar(r"\d+", "pagina 42")
100
+ assert m.group() == "42"
101
+ assert encontrar_todos(r"\d+", "1 e 2 e 3") == ["1", "2", "3"]
102
+
103
+
104
+ def test_import_sistema():
105
+ """import sistema deve expor diretorio_atual, versao."""
106
+ _limpar_cache("sistema")
107
+ from sistema import diretorio_atual, versao # noqa: PLC0415
108
+ assert isinstance(diretorio_atual(), str)
109
+ assert isinstance(versao, str)
110
+
111
+
112
+ def test_import_caminho():
113
+ """import caminho deve expor Caminho."""
114
+ _limpar_cache("caminho")
115
+ from caminho import Caminho # noqa: PLC0415
116
+ c = Caminho(".")
117
+ assert c.existe()
118
+ assert c.eh_diretorio()
119
+
120
+
121
+ def test_import_dados_json():
122
+ """import dados deve expor serializar/deserializar (json)."""
123
+ _limpar_cache("dados")
124
+ from dados import deserializar, serializar # noqa: PLC0415
125
+ texto = serializar({"chave": "valor", "numero": 42})
126
+ recuperado = deserializar(texto)
127
+ assert recuperado["chave"] == "valor"
128
+
129
+
130
+ def test_import_subprocesso():
131
+ """import subprocesso deve expor executar."""
132
+ _limpar_cache("subprocesso")
133
+ from subprocesso import executar # noqa: PLC0415
134
+ r = executar(["python3", "-c", "print('portugython')"], capturar=True)
135
+ assert "portugython" in r.stdout
136
+
137
+
138
+ def test_import_copia():
139
+ """import copia deve expor copiar_profundo."""
140
+ _limpar_cache("copia")
141
+ from copia import copiar_profundo # noqa: PLC0415
142
+ original = [[1, 2], [3, 4]]
143
+ clon = copiar_profundo(original)
144
+ original[0].append(99)
145
+ assert 99 not in clon[0]
146
+
147
+
148
+ def test_import_estatistica():
149
+ """import estatistica deve expor media, mediana, desvio_padrao."""
150
+ _limpar_cache("estatistica")
151
+ from estatistica import desvio_padrao, media, mediana # noqa: PLC0415
152
+ dados = [1, 2, 3, 4, 5]
153
+ assert media(dados) == 3.0
154
+ assert mediana(dados) == 3.0
155
+ assert desvio_padrao(dados) > 0
156
+
157
+
158
+ def test_desinstalar_reinstalar():
159
+ """desinstalar e instalar devem funcionar corretamente."""
160
+ portugython.desinstalar()
161
+ assert not any(isinstance(f, ImportadorPortugues) for f in sys.meta_path)
162
+ portugython.instalar()
163
+ assert any(isinstance(f, ImportadorPortugues) for f in sys.meta_path)
164
+
165
+
166
+ def test_todos_modulos_mapeados_importaveis():
167
+ """Todos os modulos no MAPA_MODULOS devem ser importaveis."""
168
+ for nome_pt, caminho in MAPA_MODULOS.items():
169
+ mod = importlib.import_module(caminho)
170
+ assert mod is not None, f"Nao foi possivel importar {caminho}"
@@ -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.2.0"
36
+ assert __version__ == "0.3.0"
37
37
 
38
38
 
39
39
  def test_type_functions():
File without changes
File without changes
File without changes