1
1
import ast
2
+ import copy
2
3
import inspect
3
4
import re
4
5
import sys
7
8
import types
8
9
import warnings
9
10
from functools import wraps
10
- from typing import List , Optional , Tuple
11
+ from typing import Any , List , Optional , Tuple
11
12
12
13
from widget_code_input import WidgetCodeInput
13
14
from widget_code_input .utils import (
@@ -34,6 +35,8 @@ class CodeInput(WidgetCodeInput):
34
35
`"x, y = 5"`
35
36
:param docstring: The docstring of the function
36
37
:param function_body: The function definition without indentation
38
+ :param builtins: A dict of variable name and value that is added to the
39
+ globals __builtins__ and thus available on initialization
37
40
"""
38
41
39
42
valid_code_themes = ["nord" , "solarizedLight" , "basicLight" ]
@@ -45,6 +48,7 @@ def __init__(
45
48
function_parameters : Optional [str ] = None ,
46
49
docstring : Optional [str ] = None ,
47
50
function_body : Optional [str ] = None ,
51
+ builtins : Optional [dict [str , Any ]] = None ,
48
52
code_theme : str = "basicLight" ,
49
53
):
50
54
if function is not None :
@@ -69,6 +73,7 @@ def __init__(
69
73
function_parameters = "" if function_parameters is None else function_parameters
70
74
docstring = "\n " if docstring is None else docstring
71
75
function_body = "" if function_body is None else function_body
76
+ self ._builtins = {} if builtins is None else builtins
72
77
super ().__init__ (
73
78
function_name , function_parameters , docstring , function_body , code_theme
74
79
)
@@ -94,13 +99,17 @@ def unwrapped_function(self) -> types.FunctionType:
94
99
:raise SyntaxError: if the function code has syntax errors (or if
95
100
the function name is not a valid identifier)
96
101
"""
102
+ # we shallow copy the builtins to be able to overwrite it
103
+ # if self.builtins changes
97
104
globals_dict = {
98
- "__builtins__" : globals ()["__builtins__" ],
105
+ "__builtins__" : copy . copy ( globals ()["__builtins__" ]) ,
99
106
"__name__" : "__main__" ,
100
107
"__doc__" : None ,
101
108
"__package__" : None ,
102
109
}
103
110
111
+ globals_dict ["__builtins__" ].update (self ._builtins )
112
+
104
113
if not is_valid_variable_name (self .function_name ):
105
114
raise SyntaxError ("Invalid function name '{}'" .format (self .function_name ))
106
115
@@ -275,6 +284,14 @@ def wrapper(*args, **kwargs):
275
284
276
285
return catch_exceptions (self .unwrapped_function )
277
286
287
+ @property
288
+ def builtins (self ) -> dict [str , Any ]:
289
+ return self ._builtins
290
+
291
+ @builtins .setter
292
+ def builtins (self , value : dict [str , Any ]):
293
+ self ._builtins = value
294
+
278
295
279
296
# Temporary fix until https://github.com/osscar-org/widget-code-input/pull/26
280
297
# is merged
0 commit comments