@@ -98,15 +98,70 @@ def run_file(
9898 if not file .is_file ():
9999 raise RuntimeError (f"{ file } is not a file." )
100100 code_type = self ._check_code_type (code_type )
101- cmd = shlex .split (
102- self ._CODE_EXECUTE_CMD_MAPPING [code_type ].format (
103- file_name = str (file )
101+ if code_type == "python" :
102+ # For Python code, use ast to analyze and modify the code
103+ import ast
104+
105+ import astor
106+
107+ with open (file , 'r' ) as f :
108+ source = f .read ()
109+
110+ # Parse the source code
111+ try :
112+ tree = ast .parse (source )
113+ # Get the last node
114+ if tree .body :
115+ last_node = tree .body [- 1 ]
116+ # If it's an expression, wrap it in a print
117+ if isinstance (last_node , ast .Expr ):
118+ tree .body [- 1 ] = ast .Expr (
119+ value = ast .Call (
120+ func = ast .Name (id = 'print' , ctx = ast .Load ()),
121+ args = [
122+ ast .Call (
123+ func = ast .Name (
124+ id = 'repr' , ctx = ast .Load ()
125+ ),
126+ args = [last_node .value ],
127+ keywords = [],
128+ )
129+ ],
130+ keywords = [],
131+ )
132+ )
133+ # Fix missing source locations
134+ ast .fix_missing_locations (tree )
135+ # Convert back to source
136+ modified_source = astor .to_source (tree )
137+ # Create a temporary file with the modified source
138+ temp_file = self ._create_temp_file (modified_source , "py" )
139+ cmd = shlex .split (f"python { temp_file !s} " )
140+ except SyntaxError :
141+ # If parsing fails, run the original file
142+ cmd = shlex .split (
143+ self ._CODE_EXECUTE_CMD_MAPPING [code_type ].format (
144+ file_name = str (file )
145+ )
146+ )
147+ else :
148+ # For non-Python code, use standard execution
149+ cmd = shlex .split (
150+ self ._CODE_EXECUTE_CMD_MAPPING [code_type ].format (
151+ file_name = str (file )
152+ )
104153 )
105- )
154+
106155 proc = subprocess .Popen (
107156 cmd , stdout = subprocess .PIPE , stderr = subprocess .PIPE , text = True
108157 )
109158 stdout , stderr = proc .communicate ()
159+ return_code = proc .returncode
160+
161+ # Clean up temporary file if it was created
162+ if code_type == "python" and 'temp_file' in locals ():
163+ temp_file .unlink ()
164+
110165 if self .print_stdout and stdout :
111166 print ("======stdout======" )
112167 print (Fore .GREEN + stdout + Fore .RESET )
@@ -115,8 +170,19 @@ def run_file(
115170 print ("======stderr======" )
116171 print (Fore .RED + stderr + Fore .RESET )
117172 print ("==================" )
118- exec_result = f"{ stdout } "
119- exec_result += f"(stderr: { stderr } )" if stderr else ""
173+
174+ # Build the execution result
175+ exec_result = ""
176+ if stdout :
177+ exec_result += stdout
178+ if stderr :
179+ exec_result += f"(stderr: { stderr } )"
180+ if return_code != 0 :
181+ error_msg = f"(Execution failed with return code { return_code } )"
182+ if not stderr :
183+ exec_result += error_msg
184+ elif error_msg not in stderr :
185+ exec_result += error_msg
120186 return exec_result
121187
122188 def run (
0 commit comments