-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathextension.py
More file actions
134 lines (113 loc) · 4.29 KB
/
extension.py
File metadata and controls
134 lines (113 loc) · 4.29 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# extension.py
# Este módulo permite al usuario registrar funciones personalizadas
# y luego usarlas desde otras partes del programa.
import types
import json
import inspect
class FunctionRegistry:
"""
Clase para registrar y evaluar funciones personalizadas de forma segura.
Asegura que las funciones registradas:
- No utilicen palabras clave peligrosas (como 'os', 'eval', etc.).
- No usen nombres reservados como 'SUM', 'IF', etc.
"""
def __init__(self):
"""Inicializa el registro con funciones permitidas y palabras clave peligrosas."""
self._functions = {}
self._reserved = {"SUM", "AVG", "IF", "MAX", "MIN"}
self._dangerous_keywords = [
"os", "open", "eval", "exec", "__import__"
]
def register(self, name: str, func):
"""
Registra una función en el sistema si es segura, no usa el nombre de una función reservada y es válida.
Parámetros:
name (str): Nombre de la función.
func (function): Objeto de función a registrar.
Retorna:
None
"""
if name.upper() in self._reserved:
print(f"Error: El nombre '{name}' está reservado y no se puede usar.")
return
if not isinstance(func, types.FunctionType):
print(f"Error: lo que intentas registrar no es una función.")
return
if not self.isSafe(func):
print(f"Error: lo que intentas registrar no esta permitido.")
return
print(f"Registrando función {name}")
source = inspect.getsource(func)
self._functions[name] = {"func": func, "source": source}
print(f"Función '{name}' registrada con éxito.")
def isSafe(self,func):
"""
Verifica si el código fuente de una función contiene palabras clave peligrosas.
Parámetros:
func (function): Función a inspeccionar.
Retorna:
bool: True si es segura, False si contiene código peligroso.
"""
try:
source = inspect.getsource(func)
for word in self._dangerous_keywords:
if word in source:
return False
return True
except Exception:
return False
def evaluate(self, name, *args):
"""
Evalúa una función registrada con los argumentos dados.
Parámetros:
name (str): Nombre de la función.
*args: Argumentos para la función.
Retorna:
Resultado de la función, o None si hay error o no está registrada.
"""
if name not in self._functions:
print(f"Error: La función '{name}' no ha sido registrada.")
return
try:
result = self._functions[name]["func"](*args)
return result
except Exception as e:
print(f"Error: fallo al ejecutar la función '{name}':", e)
return
def get_registered_functions(self):
"""
Retorna una lista de funciones registradas, incluyendo nombre y código fuente.
Retorna:
list[dict]: Lista de funciones con claves 'name' y 'source'.
"""
return [
{"name": name, "source": data["source"]}
for name, data in self._functions.items()
]
class FunctionSave:
"""
Clase auxiliar para guardar y cargar funciones registradas desde archivos JSON.
"""
def save_functions(self, path="functions.json"):
"""
Guarda las funciones registradas en un archivo JSON.
Parámetros:
registry (FunctionRegistry): Registro de funciones.
path (str): Ruta del archivo JSON.
"""
with open(path, "w", encoding="utf-8") as f:
json.dump(self.get_registered_functions(), f, indent=4, ensure_ascii=False)
def load_functions(path="functions.json"):
"""
Carga funciones desde un archivo JSON.
Parámetros:
path (str): Ruta del archivo JSON.
Retorna:
list[dict]: Lista de funciones con claves 'name' y 'source'.
"""
try:
with open(path, "r") as f:
data = json.load(f)
return data
except FileNotFoundError:
return []