Skip to content

Commit

Permalink
CodeInput function property is now wrapped (#90)
Browse files Browse the repository at this point in the history
This is not a breaking change because `inspect.unwrap` did not remove the
try-catch block. The interface for the unwrapped function is now changed
to `unwrapped_function`.
  • Loading branch information
agoscinski authored Dec 17, 2024
1 parent 0f65564 commit 155549a
Showing 1 changed file with 27 additions and 28 deletions.
55 changes: 27 additions & 28 deletions src/scwidgets/code/_widget_code_input.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ def __init__(
)

@property
def function(self) -> types.FunctionType:
def unwrapped_function(self) -> types.FunctionType:
"""
Return the compiled function object.
Expand All @@ -94,11 +94,33 @@ def function(self) -> types.FunctionType:
:raise SyntaxError: if the function code has syntax errors (or if
the function name is not a valid identifier)
"""
return inspect.unwrap(self.wrapped_function)
globals_dict = {
"__builtins__": globals()["__builtins__"],
"__name__": "__main__",
"__doc__": None,
"__package__": None,
}

if not is_valid_variable_name(self.function_name):
raise SyntaxError("Invalid function name '{}'".format(self.function_name))

# Optionally one could do a ast.parse here already, to check syntax
# before execution
try:
exec(
compile(self.full_function_code, __name__, "exec", dont_inherit=True),
globals_dict,
)
except SyntaxError as exc:
raise CodeValidationError(
format_syntax_error_msg(exc), orig_exc=exc
) from exc

return globals_dict[self.function_name]

def __call__(self, *args, **kwargs) -> Check.FunOutParamsT:
"""Calls the wrapped function"""
return self.wrapped_function(*args, **kwargs)
return self.function(*args, **kwargs)

def compatible_with_signature(self, parameters: List[str]) -> str:
"""
Expand Down Expand Up @@ -223,7 +245,7 @@ def get_function_body(function: types.FunctionType) -> str:
return source

@property
def wrapped_function(self) -> types.FunctionType:
def function(self) -> types.FunctionType:
"""
Return the compiled function object wrapped by an try-catch block
raising a `CodeValidationError`.
Expand All @@ -236,29 +258,6 @@ def wrapped_function(self) -> types.FunctionType:
:raise SyntaxError: if the function code has syntax errors (or if
the function name is not a valid identifier)
"""
globals_dict = {
"__builtins__": globals()["__builtins__"],
"__name__": "__main__",
"__doc__": None,
"__package__": None,
}

if not is_valid_variable_name(self.function_name):
raise SyntaxError("Invalid function name '{}'".format(self.function_name))

# Optionally one could do a ast.parse here already, to check syntax
# before execution
try:
exec(
compile(self.full_function_code, __name__, "exec", dont_inherit=True),
globals_dict,
)
except SyntaxError as exc:
raise CodeValidationError(
format_syntax_error_msg(exc), orig_exc=exc
) from exc

function_object = globals_dict[self.function_name]

def catch_exceptions(func):
@wraps(func)
Expand All @@ -274,7 +273,7 @@ def wrapper(*args, **kwargs):

return wrapper

return catch_exceptions(function_object)
return catch_exceptions(self.unwrapped_function)


# Temporary fix until https://github.com/osscar-org/widget-code-input/pull/26
Expand Down

0 comments on commit 155549a

Please sign in to comment.