#!/usr/bin/env python from __future__ import unicode_literals import sys import traceback import os from os.path import join import importlib from contextlib import contextmanager from textwrap import dedent try: from StringIO import StringIO except ImportError: from io import StringIO # Local imports from .code_evaluator import CodeEvaluator from .file_utils import copy_files, delete_files @contextmanager def redirect_stdout(): new_target = StringIO() old_target, sys.stdout = sys.stdout, new_target # replace sys.stdout try: yield new_target # run some code with the replaced stdout finally: sys.stdout = old_target # restore to the previous value class PythonStdioEvaluator(CodeEvaluator): """Tests the Python code obtained from Code Server""" # def setup(self): # super(PythonStdioEvaluator, self).setup() # self.files = [] # def teardown(self): # # Delete the created file. # if self.files: # delete_files(self.files) # super(PythonStdioEvaluator, self).teardown() def __init__(self, metadata, test_case_data): self.files = [] # Set metadata values self.user_answer = metadata.get('user_answer') self.file_paths = metadata.get('file_paths') self.partial_grading = metadata.get('partial_grading') # Set test case data values self.expected_input = test_case_data.get('expected_input') self.expected_output = test_case_data.get('expected_output') self.weight = test_case_data.get('weight') def compile_code(self): # user_answer, file_paths, expected_input, expected_output, weight): if self.file_paths: self.files = copy_files(self.file_paths) submitted = compile(self.user_answer, '', mode='exec') if self.expected_input: input_buffer = StringIO() input_buffer.write(self.expected_input) input_buffer.seek(0) sys.stdin = input_buffer with redirect_stdout() as output_buffer: exec_scope = {} exec(submitted, exec_scope) self.output_value = output_buffer.getvalue().rstrip("\n") return self.output_value def check_code(self): # user_answer, file_paths, partial_grading, expected_input, expected_output, weight): success = False test_case_weight = 0.0 tb = None if self.output_value == self.expected_output: success = True err = "Correct answer" test_case_weight = self.weight else: success = False err = dedent(""" Incorrect answer: Given input - {0} Expected output - {1} Your output - {2} """.format(self.expected_input, self.expected_output, self.output_value ) ) del tb return success, err, test_case_weight