pyinterfaces 0.1.1__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.
@@ -1,16 +1,14 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyinterfaces
3
- Version: 0.1.1
3
+ Version: 0.3.0
4
4
  Summary: Interface in POO with Python
5
5
  License-Expression: MIT
6
6
  License-File: license.txt
7
7
  Keywords: interface,java,syntax,brunozolotareff,pyinterfaces
8
8
  Author: Bruno Zolotareff
9
9
  Author-email: brunozolotareff@gmail.com
10
- Requires-Python: >=3.8
10
+ Requires-Python: >=3.10
11
11
  Classifier: Programming Language :: Python :: 3
12
- Classifier: Programming Language :: Python :: 3.8
13
- Classifier: Programming Language :: Python :: 3.9
14
12
  Classifier: Programming Language :: Python :: 3.10
15
13
  Classifier: Programming Language :: Python :: 3.11
16
14
  Classifier: Programming Language :: Python :: 3.12
@@ -0,0 +1,113 @@
1
+ import codecs
2
+ import io
3
+ import re
4
+
5
+ def converter_tipos_java_para_python(argumentos_str: str) -> str:
6
+ """
7
+ Transforma 'String titular, int idade' em 'titular: str, idade: int'.
8
+ Também garante que o 'self' seja mantido corretamente se o usuário colocar.
9
+ """
10
+ mapa_tipos = {
11
+ 'String': 'str',
12
+ 'int': 'int',
13
+ 'double': 'float',
14
+ 'float': 'float',
15
+ 'boolean': 'bool',
16
+ 'void': 'None',
17
+ 'List': 'list',
18
+ 'Map': 'dict'
19
+ }
20
+
21
+ argumentos_limpos = argumentos_str.strip()
22
+ if not argumentos_limpos:
23
+ return "self"
24
+
25
+ partes = [p.strip() for p in argumentos_limpos.split(',')]
26
+ novos_args = []
27
+
28
+ if len(partes) > 0 and partes[0] == 'self':
29
+ novos_args.append('self')
30
+ partes = partes[1:]
31
+ else:
32
+ novos_args.append('self')
33
+
34
+ for parte in partes:
35
+ if not parte:
36
+ continue
37
+ componentes = re.split(r'\s+', parte)
38
+ if len(componentes) == 2:
39
+ tipo_java, nome_var = componentes
40
+ tipo_python = mapa_tipos.get(tipo_java, tipo_java)
41
+ novos_args.append(f"{nome_var}: {tipo_python}")
42
+ else:
43
+ novos_args.append(parte)
44
+
45
+ return ", ".join(novos_args)
46
+
47
+ def traduzir_sintaxe_java(texto: str) -> str:
48
+ """
49
+ Varre o arquivo de texto substituindo a sintaxe 'Interface Nome:'
50
+ por classes Python puras usando abc.ABC, mantendo a indentação nativa.
51
+ """
52
+ linhas = texto.split('\n')
53
+ resultado = ["from abc import ABC, abstractmethod\n"]
54
+ dentro_da_interface = False
55
+
56
+ for linha in linhas:
57
+ # 1. Detecta o início da declaração: 'Interface Nome:' (com ou sem espaços)
58
+ inicio_match = re.match(r'\s*Interface\s+(\w+)\s*:', linha)
59
+ if inicio_match:
60
+ nome_interface = inicio_match.group(1)
61
+ resultado.append(f"class {nome_interface}(ABC):")
62
+ dentro_da_interface = True
63
+ continue
64
+
65
+ # Detecta se a linha voltou para a parede esquerda (fim do bloco da interface)
66
+ if dentro_da_interface and linha.strip() and not linha.startswith(' '):
67
+ dentro_da_interface = False
68
+
69
+ if dentro_da_interface:
70
+ # 2. Captura os métodos indentados de dentro da interface
71
+ linha_limpa = linha.strip()
72
+ if linha_limpa:
73
+ metodo_match = re.match(r'(?:\w+\s+)?(\w+)\s*\((.*?)\)', linha_limpa)
74
+ if metodo_match:
75
+ nome_metodo = metodo_match.group(1)
76
+ args_brutos = metodo_match.group(2)
77
+
78
+ args_traduzidos = converter_tipos_java_para_python(args_brutos)
79
+
80
+ resultado.append(f" @abstractmethod")
81
+ resultado.append(f" def {nome_metodo}({args_traduzidos}):")
82
+ resultado.append(f" pass")
83
+ else:
84
+ resultado.append(linha)
85
+
86
+ return '\n'.join(resultado)
87
+
88
+ # --- INFRAESTRUTURA DE CODEC DO PYTHON ---
89
+
90
+ class JavaInterfaceDecoder(codecs.BufferedIncrementalDecoder):
91
+ def _buffer_decode(self, input, errors, final):
92
+ if final:
93
+ dados_em_bytes = bytes(input)
94
+ texto_traduzido = traduzir_sintaxe_java(dados_em_bytes.decode('utf-8'))
95
+ return (texto_traduzido, len(input))
96
+ return ('', 0)
97
+
98
+ def buscar_codec(nome_codec):
99
+ if nome_codec == 'py_interface':
100
+ return codecs.CodecInfo(
101
+ name='py_interface',
102
+ encode=codecs.utf_8_encode,
103
+ decode=lambda input, errors='strict': (traduzir_sintaxe_java(bytes(input).decode('utf-8')), len(input)),
104
+ incrementalencoder=codecs.utf_8_encode,
105
+ incrementaldecoder=JavaInterfaceDecoder,
106
+ streamreader=lambda stream, errors='strict': io.StringIO(traduzir_sintaxe_java(stream.read().decode('utf-8'))),
107
+ streamwriter=codecs.utf_8_encode
108
+ )
109
+ return None
110
+
111
+ def registrar_syntax():
112
+ """Registra o tradutor de código dentro do núcleo de encodings do Python"""
113
+ codecs.register(buscar_codec)
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "pyinterfaces"
3
- version = "0.1.1"
3
+ version = "0.3.0"
4
4
  description = "Interface in POO with Python"
5
5
  authors = [
6
6
  {name = "Bruno Zolotareff",email = "brunozolotareff@gmail.com"}
@@ -9,7 +9,7 @@ readme = "README.md"
9
9
  keywords = ["interface", "java", "syntax", "brunozolotareff", "pyinterfaces"]
10
10
  packages = [{include = "pyinterfaces"}]
11
11
  license = "MIT"
12
- requires-python = ">=3.8"
12
+ requires-python = ">=3.10"
13
13
  dependencies = [
14
14
  ]
15
15
 
@@ -17,3 +17,8 @@ dependencies = [
17
17
  [build-system]
18
18
  requires = ["poetry-core>=2.0.0,<3.0.0"]
19
19
  build-backend = "poetry.core.masonry.api"
20
+
21
+ [dependency-groups]
22
+ dev = [
23
+ "pytest (>=9.1.1,<10.0.0)"
24
+ ]
@@ -1,69 +0,0 @@
1
- import codecs
2
- import io
3
- import re
4
-
5
- def traduzir_sintaxe_java(texto: str) -> str:
6
- """
7
- Varre o arquivo de texto substituindo a sintaxe 'Interface Nome { ... }'
8
- por classes Python puras usando abc.ABC e @abstractmethod.
9
- """
10
- linhas = texto.split('\n')
11
- resultado = ["from abc import ABC, abstractmethod\n"]
12
- dentro_da_interface = False
13
-
14
- for linha in linhas:
15
- # 1. Detecta o início da declaração: 'Interface Nome {'
16
- inicio_match = re.match(r'\s*Interface\s+(\w+)\s*\{', linha)
17
- if inicio_match:
18
- nome_interface = inicio_match.group(1)
19
- resultado.append(f"class {nome_interface}(ABC):")
20
- dentro_da_interface = True
21
- continue
22
-
23
- if dentro_da_interface:
24
- # 2. Detecta o fechamento da interface com a chave '}'
25
- if '}' in linha:
26
- dentro_da_interface = False
27
- continue
28
-
29
- # 3. Limpa pontos e vírgulas do estilo Java e captura o método
30
- metodo_limpo = linha.strip().replace(';', '')
31
- if metodo_limpo:
32
- # Transforma a assinatura em um método abstrato Python
33
- resultado.append(f" @abstractmethod")
34
- resultado.append(f" def {metodo_limpo}:")
35
- resultado.append(f" pass")
36
- else:
37
- # Mantém qualquer outra linha de código Python normal intacta
38
- resultado.append(linha)
39
-
40
- return '\n'.join(resultado)
41
-
42
- # --- INFRAESTRUTURA DE CODEC DO PYTHON (ATUALIZADA) ---
43
-
44
- class JavaInterfaceDecoder(codecs.BufferedIncrementalDecoder):
45
- def _buffer_decode(self, input, errors, final):
46
- if final:
47
- # CORREÇÃO: Força a conversão para bytes caso o Python envie um memoryview
48
- dados_em_bytes = bytes(input)
49
- texto_traduzido = traduzir_sintaxe_java(dados_em_bytes.decode('utf-8'))
50
- return (texto_traduzido, len(input))
51
- return ('', 0)
52
-
53
- def buscar_codec(nome_codec):
54
- if nome_codec == 'py_interface':
55
- return codecs.CodecInfo(
56
- name='py_interface',
57
- encode=codecs.utf_8_encode,
58
- # CORREÇÃO: Aplicamos o cast de bytes(input) também na leitura direta do decode
59
- decode=lambda input, errors='strict': (traduzir_sintaxe_java(bytes(input).decode('utf-8')), len(input)),
60
- incrementalencoder=codecs.utf_8_encode,
61
- incrementaldecoder=JavaInterfaceDecoder,
62
- streamreader=lambda stream, errors='strict': io.StringIO(traduzir_sintaxe_java(stream.read().decode('utf-8'))),
63
- streamwriter=codecs.utf_8_encode
64
- )
65
- return None
66
-
67
- def registrar_syntax():
68
- """Registra o tradutor de código dentro do núcleo de encodings do Python"""
69
- codecs.register(buscar_codec)
File without changes
File without changes