| import io | |
| import sys | |
| import ast | |
| from logger import logger | |
| def run_code(code): | |
| """ | |
| Executes user-provided Python code and captures its output. | |
| Handles user input dynamically and detects defined functions. | |
| Parameters: | |
| code (str): Python code entered by the user. | |
| Returns: | |
| dict: Captured output and logged inputs. | |
| """ | |
| # Redirect stdout to capture code output | |
| old_stdout = sys.stdout | |
| redirected_output = sys.stdout = io.StringIO() | |
| # Create a dedicated execution namespace | |
| exec_globals = {} | |
| # Store user inputs | |
| input_log = [] | |
| # Custom input function to simulate input() behavior | |
| def custom_input(prompt=""): | |
| user_input = input(prompt) # Prompt the user dynamically | |
| input_log.append(user_input) | |
| return user_input | |
| # Add the custom input function to the execution namespace | |
| exec_globals["input"] = custom_input | |
| try: | |
| # Parse the code to detect function definitions | |
| tree = ast.parse(code) | |
| function_names = [ | |
| node.name for node in ast.walk(tree) if isinstance(node, ast.FunctionDef) | |
| ] | |
| # Execute the code in the dedicated namespace | |
| exec(code, exec_globals) | |
| # Check if functions are defined but not called | |
| captured_output = redirected_output.getvalue() | |
| if function_names: | |
| captured_output += f"\n\nDefined functions: {', '.join(function_names)}\n" | |
| captured_output += "Note: Functions need to be explicitly called to see their output." | |
| return {"output": captured_output, "inputs": input_log} | |
| except Exception as e: | |
| logger.error(f"Execution error: {e}") | |
| return {"output": f"Error: {e}", "inputs": input_log} | |
| finally: | |
| # Reset stdout | |
| sys.stdout = old_stdout | |