pyinterfaces 0.4.0__tar.gz → 0.5.1__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.
- {pyinterfaces-0.4.0 → pyinterfaces-0.5.1}/PKG-INFO +1 -1
- pyinterfaces-0.5.1/pyinterfaces/cli.py +45 -0
- {pyinterfaces-0.4.0 → pyinterfaces-0.5.1}/pyinterfaces/compilador.py +47 -7
- {pyinterfaces-0.4.0 → pyinterfaces-0.5.1}/pyproject.toml +2 -1
- {pyinterfaces-0.4.0 → pyinterfaces-0.5.1}/README.md +0 -0
- {pyinterfaces-0.4.0 → pyinterfaces-0.5.1}/license.txt +0 -0
- {pyinterfaces-0.4.0 → pyinterfaces-0.5.1}/pyinterfaces/__init__.py +0 -0
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import json
|
|
3
|
+
|
|
4
|
+
def inicializar_projeto():
|
|
5
|
+
print("\n🚀 Inicializando ambiente pyinterfaces...")
|
|
6
|
+
|
|
7
|
+
# 1. Caminho da pasta .vscode
|
|
8
|
+
pasta_vscode = ".vscode"
|
|
9
|
+
arquivo_settings = os.path.join(pasta_vscode, "settings.json")
|
|
10
|
+
|
|
11
|
+
# 2. Configurações que queremos injetar automaticamente
|
|
12
|
+
configuracoes = {
|
|
13
|
+
"python.analysis.diagnosticSeverityOverrides": {
|
|
14
|
+
"reportUndefinedVariable": "none",
|
|
15
|
+
"reportGeneralTypeIssues": "none",
|
|
16
|
+
"reportMissingImports": "none"
|
|
17
|
+
},
|
|
18
|
+
"python.analysis.ignore": [
|
|
19
|
+
"**/models/*.py",
|
|
20
|
+
"**/interfaces/*.py",
|
|
21
|
+
"*.py"
|
|
22
|
+
]
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
try:
|
|
26
|
+
# Cria a pasta .vscode se ela não existir
|
|
27
|
+
if not os.path.exists(pasta_vscode):
|
|
28
|
+
os.makedirs(pasta_vscode)
|
|
29
|
+
print("📁 Pasta '.vscode' criada com sucesso.")
|
|
30
|
+
|
|
31
|
+
# Escreve o arquivo settings.json bonitinho
|
|
32
|
+
with open(arquivo_settings, "w", encoding="utf-8") as f:
|
|
33
|
+
json.dump(configuracoes, f, indent=4, ensure_ascii=False)
|
|
34
|
+
|
|
35
|
+
# 3. Cria as pastas padrões para o desenvolvedor usar
|
|
36
|
+
for pasta in ["models", "interfaces"]:
|
|
37
|
+
if not os.path.exists(pasta):
|
|
38
|
+
os.makedirs(pasta)
|
|
39
|
+
print(f"📁 Pasta '{pasta}' estruturada automaticamente.")
|
|
40
|
+
|
|
41
|
+
print("\n✨ Ambiente configurado com 100% de sucesso! Nenhuma linha amarela ou vermelha vai te incomodar.")
|
|
42
|
+
print("💡 Lembre-se de colocar '# -*- coding: py_interface -*-' no topo das suas interfaces.\n")
|
|
43
|
+
|
|
44
|
+
except Exception as e:
|
|
45
|
+
print(f"❌ Erro ao configurar o ambiente: {e}")
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import codecs
|
|
2
2
|
import io
|
|
3
3
|
import re
|
|
4
|
+
import sys
|
|
5
|
+
from importlib.abc import Loader, MetaPathFinder
|
|
6
|
+
from importlib.machinery import ModuleSpec
|
|
4
7
|
|
|
5
8
|
def traduzir_sintaxe_java(texto: str) -> str:
|
|
6
9
|
"""
|
|
@@ -12,7 +15,6 @@ def traduzir_sintaxe_java(texto: str) -> str:
|
|
|
12
15
|
dentro_da_interface = False
|
|
13
16
|
|
|
14
17
|
for linha in linhas:
|
|
15
|
-
# 1. Detecta o início da declaração: 'Interface Nome:' (com ou sem espaços)
|
|
16
18
|
inicio_match = re.match(r'\s*Interface\s+(\w+)\s*:', linha)
|
|
17
19
|
if inicio_match:
|
|
18
20
|
nome_interface = inicio_match.group(1)
|
|
@@ -20,19 +22,14 @@ def traduzir_sintaxe_java(texto: str) -> str:
|
|
|
20
22
|
dentro_da_interface = True
|
|
21
23
|
continue
|
|
22
24
|
|
|
23
|
-
# Detecta se o bloco da interface acabou (linha sem espaços na esquerda)
|
|
24
25
|
if dentro_da_interface and linha.strip() and not linha.startswith(' '):
|
|
25
26
|
dentro_da_interface = False
|
|
26
27
|
|
|
27
28
|
if dentro_da_interface:
|
|
28
29
|
linha_limpa = linha.strip()
|
|
29
|
-
# 2. Captura métodos que começam com 'def' dentro da interface
|
|
30
30
|
if linha_limpa.startswith('def '):
|
|
31
|
-
# Garante que o método termine com ':' esperado pelo Python
|
|
32
31
|
if not linha_limpa.endswith(':'):
|
|
33
32
|
linha_limpa += ':'
|
|
34
|
-
|
|
35
|
-
# Injeta o 'self' automaticamente caso o usuário não tenha colocado
|
|
36
33
|
if '(self' not in linha_limpa:
|
|
37
34
|
linha_limpa = linha_limpa.replace('(', '(self, ').replace('(self, )', '(self)')
|
|
38
35
|
|
|
@@ -44,6 +41,46 @@ def traduzir_sintaxe_java(texto: str) -> str:
|
|
|
44
41
|
|
|
45
42
|
return '\n'.join(resultado)
|
|
46
43
|
|
|
44
|
+
# --- SISTEMA DE IMPORTAÇÃO NATIVA DO PYTHON (GANCHO) ---
|
|
45
|
+
|
|
46
|
+
class InterfaceLoader(Loader):
|
|
47
|
+
def __init__(self, filename):
|
|
48
|
+
self.filename = filename
|
|
49
|
+
|
|
50
|
+
def create_module(self, spec):
|
|
51
|
+
return None # Usa o carregador padrão do Python para criar o módulo
|
|
52
|
+
|
|
53
|
+
def exec_module(self, module):
|
|
54
|
+
with open(self.filename, 'r', encoding='utf-8') as f:
|
|
55
|
+
conteudo = f.read()
|
|
56
|
+
|
|
57
|
+
# Passa o código pelo nosso compilador antes de executar
|
|
58
|
+
codigo_traduzido = traduzir_sintaxe_java(conteudo)
|
|
59
|
+
code_obj = compile(codigo_traduzido, self.filename, 'exec')
|
|
60
|
+
exec(code_obj, module.__dict__)
|
|
61
|
+
|
|
62
|
+
class InterfaceFinder(MetaPathFinder):
|
|
63
|
+
def find_spec(self, fullname, path, target=None):
|
|
64
|
+
# Transforma o nome do módulo em caminho (ex: interfaces.banco -> interfaces/banco.py)
|
|
65
|
+
mod_name = fullname.split('.')[-1]
|
|
66
|
+
|
|
67
|
+
# Caminhos possíveis para buscar o arquivo
|
|
68
|
+
search_paths = path if path else sys.path
|
|
69
|
+
import os
|
|
70
|
+
|
|
71
|
+
for p in search_paths:
|
|
72
|
+
base_path = os.path.join(p, mod_name)
|
|
73
|
+
filename = base_path + ".py"
|
|
74
|
+
|
|
75
|
+
if os.path.exists(filename):
|
|
76
|
+
with open(filename, 'r', encoding='utf-8') as f:
|
|
77
|
+
primeira_linha = f.readline()
|
|
78
|
+
|
|
79
|
+
# Se o arquivo tiver o nosso cabeçalho mágico, nós assumimos o controle da compilação!
|
|
80
|
+
if "py_interface" in primeira_linha:
|
|
81
|
+
return ModuleSpec(fullname, InterfaceLoader(filename), origin=filename)
|
|
82
|
+
return None
|
|
83
|
+
|
|
47
84
|
# --- INFRAESTRUTURA DE CODEC DO PYTHON ---
|
|
48
85
|
|
|
49
86
|
class JavaInterfaceDecoder(codecs.BufferedIncrementalDecoder):
|
|
@@ -68,5 +105,8 @@ def buscar_codec(nome_codec):
|
|
|
68
105
|
return None
|
|
69
106
|
|
|
70
107
|
def registrar_syntax():
|
|
71
|
-
"""Registra o tradutor de código
|
|
108
|
+
"""Registra o tradutor de código no núcleo do Python e injeta o Import Hook"""
|
|
72
109
|
codecs.register(buscar_codec)
|
|
110
|
+
# Injeta o nosso buscador de arquivos customizados no topo do sistema do Python
|
|
111
|
+
if not any(isinstance(f, InterfaceFinder) for f in sys.meta_path):
|
|
112
|
+
sys.meta_path.insert(0, InterfaceFinder())
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "pyinterfaces"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.5.1"
|
|
4
4
|
description = "Interface in POO with Python"
|
|
5
5
|
authors = [
|
|
6
6
|
{name = "Bruno Zolotareff",email = "brunozolotareff@gmail.com"}
|
|
@@ -8,6 +8,7 @@ authors = [
|
|
|
8
8
|
readme = "README.md"
|
|
9
9
|
keywords = ["interface", "java", "syntax", "brunozolotareff", "pyinterfaces"]
|
|
10
10
|
packages = [{include = "pyinterfaces"}]
|
|
11
|
+
pyinterfaces-init = "pyinterfaces.cli:inicializar_projeto"
|
|
11
12
|
license = "MIT"
|
|
12
13
|
requires-python = ">=3.10"
|
|
13
14
|
dependencies = [
|
|
File without changes
|
|
File without changes
|
|
File without changes
|