1+ import builtins
12import contextlib
3+ import io
24import json
35import os
46import sys
5- import io
67import time
78
89from unittests import test
910
11+ # Save the real stdout/stderr for our own use
12+ _real_stdout = sys .__stdout__
13+ _real_stderr = sys .__stderr__
14+
15+ # Close and replace sys.__stdout__ and sys.__stderr__ before importing usercode
16+ # This prevents usercode from using sys.__stdout__ to bypass redirection
17+ try :
18+ # Create closed file objects that will raise ValueError if accessed
19+ closed_file = open (os .devnull , "w" )
20+ closed_file .close ()
21+
22+ # Replace the dunder attributes with closed files
23+ sys .__stdout__ = closed_file
24+ sys .__stderr__ = closed_file
25+ except Exception as e :
26+ _real_stderr .write (f"Warning: Could not close __stdout__/__stderr__: { e } \n " )
27+
1028try :
1129 from usercode import solution
1230except ImportError :
13- sys . __stdout__ .write (
31+ _real_stdout .write (
1432 json .dumps (
1533 {
1634 "runalyzer_errors" : "Solution function not found." ,
@@ -51,7 +69,7 @@ def truncate_output(output, max_chars=256):
5169 duration = end - start
5270
5371 except Exception as e :
54- sys . __stderr__ .write (str (e ))
72+ _real_stderr .write (str (e ))
5573 exit (1 )
5674
5775 # Get captured output and truncate
@@ -62,7 +80,7 @@ def truncate_output(output, max_chars=256):
6280 with open (os .devnull , "w" ) as devnull :
6381 with contextlib .redirect_stdout (devnull ), contextlib .redirect_stderr (devnull ):
6482 # Print final results (this goes to the original stdout before redirection)
65- sys . __stdout__ .write (
83+ _real_stdout .write (
6684 json .dumps (
6785 {
6886 "test_result" : test_res ,
0 commit comments