11import ast
2+ import copy
23import inspect
34import re
45import sys
78import types
89import warnings
910from functools import wraps
10- from typing import List , Optional , Tuple
11+ from typing import Any , List , Optional , Tuple
1112
1213from widget_code_input import WidgetCodeInput
1314from widget_code_input .utils import (
@@ -34,6 +35,8 @@ class CodeInput(WidgetCodeInput):
3435 `"x, y = 5"`
3536 :param docstring: The docstring of the function
3637 :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
3740 """
3841
3942 valid_code_themes = ["nord" , "solarizedLight" , "basicLight" ]
@@ -45,6 +48,7 @@ def __init__(
4548 function_parameters : Optional [str ] = None ,
4649 docstring : Optional [str ] = None ,
4750 function_body : Optional [str ] = None ,
51+ builtins : Optional [dict [str , Any ]] = None ,
4852 code_theme : str = "basicLight" ,
4953 ):
5054 if function is not None :
@@ -69,6 +73,7 @@ def __init__(
6973 function_parameters = "" if function_parameters is None else function_parameters
7074 docstring = "\n " if docstring is None else docstring
7175 function_body = "" if function_body is None else function_body
76+ self ._builtins = {} if builtins is None else builtins
7277 super ().__init__ (
7378 function_name , function_parameters , docstring , function_body , code_theme
7479 )
@@ -94,13 +99,17 @@ def unwrapped_function(self) -> types.FunctionType:
9499 :raise SyntaxError: if the function code has syntax errors (or if
95100 the function name is not a valid identifier)
96101 """
102+ # we shallow copy the builtins to be able to overwrite it
103+ # if self.builtins changes
97104 globals_dict = {
98- "__builtins__" : globals ()["__builtins__" ],
105+ "__builtins__" : copy . copy ( globals ()["__builtins__" ]) ,
99106 "__name__" : "__main__" ,
100107 "__doc__" : None ,
101108 "__package__" : None ,
102109 }
103110
111+ globals_dict ["__builtins__" ].update (self ._builtins )
112+
104113 if not is_valid_variable_name (self .function_name ):
105114 raise SyntaxError ("Invalid function name '{}'" .format (self .function_name ))
106115
@@ -275,6 +284,14 @@ def wrapper(*args, **kwargs):
275284
276285 return catch_exceptions (self .unwrapped_function )
277286
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+
278295
279296# Temporary fix until https://github.com/osscar-org/widget-code-input/pull/26
280297# is merged
0 commit comments