1
1
#!/usr/bin/python3
2
2
import argparse
3
+ import glob
3
4
import logging
4
- import sys
5
5
import os
6
- import glob
7
6
import subprocess
7
+ import sys
8
8
import time
9
9
from enum import Enum
10
10
from pathlib import Path
@@ -32,16 +32,21 @@ class ExecStatus(Enum):
32
32
33
33
class ExecResult :
34
34
35
- def __init__ (self , status : ExecStatus , output : str = None , elapsed_sec : float = None ):
35
+ def __init__ (self , status : ExecStatus , output : str = None , stderr : str = None , elapsed_sec : float = None ):
36
36
self .status = status
37
37
self .output = output
38
+ self .stderr = stderr
39
+
38
40
if elapsed_sec is not None :
39
41
self .elapsed_ms = int (elapsed_sec * 1000 + 0.5 )
40
42
else :
41
43
self .elapsed_ms = None
42
44
43
45
def is_correct_output (self , answer_text ):
44
- return answer_text == self .output
46
+ return self .status == ExecStatus .NORMAL and answer_text == self .output
47
+
48
+ def has_stderr (self ):
49
+ return len (self .stderr ) > 0
45
50
46
51
47
52
def is_executable_file (file_name ):
@@ -76,14 +81,23 @@ def infer_case_num(sample_filename: str):
76
81
def run_program (exec_file : str , input_file : str , timeout_sec : int ) -> ExecResult :
77
82
try :
78
83
elapsed_sec = - time .time ()
79
- out_data = subprocess .check_output (
80
- [exec_file , "" ], stdin = open (input_file , 'r' ), universal_newlines = True , timeout = timeout_sec )
84
+ proc = subprocess .run (
85
+ [exec_file , "" ], stdin = open (input_file , 'r' ), universal_newlines = True , timeout = timeout_sec ,
86
+ stdout = subprocess .PIPE ,
87
+ stderr = subprocess .PIPE ,
88
+ )
89
+
90
+ if proc .returncode == 0 :
91
+ code = ExecStatus .NORMAL
92
+ else :
93
+ code = ExecStatus .RE
94
+
81
95
elapsed_sec += time .time ()
82
- return ExecResult (ExecStatus . NORMAL , out_data , elapsed_sec )
83
- except subprocess .TimeoutExpired :
84
- return ExecResult (ExecStatus .TLE )
85
- except subprocess .CalledProcessError :
86
- return ExecResult (ExecStatus .RE )
96
+ return ExecResult (code , proc . stdout , proc . stderr , elapsed_sec = elapsed_sec )
97
+ except subprocess .TimeoutExpired as e :
98
+ return ExecResult (ExecStatus .TLE , e . stdout , e . stderr )
99
+ except subprocess .CalledProcessError as e :
100
+ return ExecResult (ExecStatus .RE , e . stdout , e . stderr )
87
101
88
102
89
103
def build_details_str (exec_res : ExecResult , input_file : str , output_file : str ) -> str :
@@ -93,21 +107,23 @@ def append(text: str, end='\n'):
93
107
nonlocal res
94
108
res += text + end
95
109
96
- append ("[Input]" )
110
+ append (with_color ( "[Input]" , Fore . LIGHTMAGENTA_EX ) )
97
111
with open (input_file , "r" ) as f :
98
112
append (f .read (), end = '' )
99
113
100
- append ("[Expected]" )
114
+ append (with_color ( "[Expected]" , Fore . LIGHTMAGENTA_EX ) )
101
115
with open (output_file , "r" ) as f :
102
116
append (f .read (), end = '' )
103
117
104
- if exec_res .status == ExecStatus .NORMAL :
105
- append ("[Received]" )
106
- if exec_res .status == ExecStatus .NORMAL :
107
- append (exec_res .output , end = '' )
108
- else :
109
- append ("[Log]" )
110
- append (exec_res .status .name )
118
+ append (with_color ("[Received]" , Fore .LIGHTMAGENTA_EX ))
119
+ append (exec_res .output , end = '' )
120
+ if exec_res .status != ExecStatus .NORMAL :
121
+ append (with_color ("Aborted ({})\n " .format (
122
+ exec_res .status .name ), Fore .LIGHTYELLOW_EX ))
123
+
124
+ if exec_res .has_stderr ():
125
+ append (with_color ("[Error]" , Fore .LIGHTYELLOW_EX ))
126
+ append (exec_res .stderr , end = '' )
111
127
return res
112
128
113
129
@@ -123,24 +139,31 @@ def run_for_samples(exec_file: str, sample_pair_list: List[Tuple[str, str]], tim
123
139
answer_text = f .read ()
124
140
125
141
is_correct = exec_res .is_correct_output (answer_text )
126
- if is_correct :
142
+ passed = is_correct and not exec_res .has_stderr ()
143
+
144
+ if passed :
127
145
message = "{} {elapsed} ms" .format (
128
146
with_color ("PASSED" , Fore .LIGHTGREEN_EX ),
129
147
elapsed = exec_res .elapsed_ms )
130
148
success_count += 1
131
149
else :
132
- if exec_res .status == ExecStatus .NORMAL :
133
- message = with_color ("WA" , Fore .LIGHTRED_EX )
150
+ if is_correct :
151
+ message = with_color (
152
+ "CORRECT but with stderr (Please remove stderr!)" , Fore .LIGHTYELLOW_EX )
134
153
else :
135
- message = with_color (exec_res .status .name , Fore .LIGHTYELLOW_EX )
154
+ if exec_res .status == ExecStatus .NORMAL :
155
+ message = with_color ("WA" , Fore .LIGHTRED_EX )
156
+ else :
157
+ message = with_color (
158
+ exec_res .status .name , Fore .LIGHTYELLOW_EX )
136
159
137
160
print ("# {case_name} ... {message}" .format (
138
161
case_name = os .path .basename (in_sample_file ),
139
162
message = message ,
140
163
))
141
164
142
165
# Output details for incorrect results.
143
- if not is_correct :
166
+ if not passed :
144
167
print ('{}\n ' .format (build_details_str (
145
168
exec_res , in_sample_file , out_sample_file )))
146
169
if knock_out :
0 commit comments