diff --git a/grader_support/gradelib.py b/grader_support/gradelib.py index 0d05a87..6f16721 100644 --- a/grader_support/gradelib.py +++ b/grader_support/gradelib.py @@ -18,7 +18,7 @@ def __init__(self, message=None): Exception.__init__(self, message) -class Test: +class Test(object): """ A simple class to wrap a test function and its descriptions. @@ -53,7 +53,7 @@ def compare_results(self, expected, actual): return expected == actual -class Grader: +class Grader(object): def __init__(self): """ Create an empty grader. @@ -239,7 +239,7 @@ def _tokens(code): """ # Protect against pathological inputs: http://bugs.python.org/issue16152 code = code.rstrip() + "\n" - if isinstance(code, str): + if isinstance(code, six.text_type): code = code.encode('utf8') code = "# coding: utf8\n" + code toks = tokenize.generate_tokens(six.BytesIO(code).readline) @@ -481,7 +481,7 @@ def exec_wrapped_code(environment=None, post_process=None): environment = {} def test_fn(submission_module): with capture_stdout() as stdout: - exec(submission_module.submission_code, environment) + six.exec_(submission_module.submission_code, environment) stdout_text = stdout.getvalue() if post_process: stdout_text = post_process(stdout_text) @@ -503,7 +503,7 @@ def exec_code_and_inspect_values(environment=None, vars_to_inspect=None, post_pr environment = {} def test_fn(submission_module): with capture_stdout() as stdout: - exec(submission_module.submission_code, environment) + six.exec_(submission_module.submission_code, environment) for var in vars_to_inspect: print(var) @@ -530,7 +530,7 @@ def invoke_student_function(fn_name, args, environment=None, output_writer=None) """ output_writer = output_writer or repr def doit(submission_module): - for name, value in environment or {}.items(): + for name, value in six.iteritems(environment or {}): setattr(submission_module, name, value) fn = getattr(submission_module, fn_name) print(output_writer(fn(*args))) @@ -543,7 +543,7 @@ class InvokeStudentFunctionTest(Test): def __init__(self, fn_name, args, environment=None, output_writer=None, short_desc=None, detailed_desc=None, compare=None): test_fn = invoke_student_function(fn_name, args, environment, output_writer) if short_desc is None: - short_desc = "Test: {}({})".format(fn_name, ", ".join(repr(a) for a in args)) + short_desc = "Test: %s(%s)" % (fn_name, ", ".join(repr(a) for a in args)) Test.__init__(self, test_fn, short_desc, detailed_desc, compare) def round_float_writer(n): diff --git a/grader_support/graderutil.py b/grader_support/graderutil.py index aa560c4..ec8fcd2 100644 --- a/grader_support/graderutil.py +++ b/grader_support/graderutil.py @@ -37,7 +37,7 @@ def captured_stdout(): sys.stdout = old_stdout -class ChangeDirectory: +class ChangeDirectory(object): def __init__(self, new_dir): self.old_dir = os.getcwd() os.chdir(new_dir) @@ -58,7 +58,7 @@ def change_directory(new_dir): cd.clean_up() -class TempDirectory: +class TempDirectory(object): def __init__(self, delete_when_done=True): self.delete_when_done = delete_when_done self.temp_dir = tempfile.mkdtemp(prefix="grader-") @@ -84,7 +84,7 @@ def temp_directory(delete_when_done=True): tmp.clean_up() -class ModuleIsolation: +class ModuleIsolation(object): """ Manage changes to sys.modules so that we can roll back imported modules. diff --git a/grader_support/run.py b/grader_support/run.py index 5323598..9134ac6 100755 --- a/grader_support/run.py +++ b/grader_support/run.py @@ -1,4 +1,5 @@ #!/usr/bin/env python +# -*- coding: utf-8 -*- """ Run a set of tests on a submission, printing the outputs to stdout as a json string. @@ -30,7 +31,10 @@ fallback=True, languages=[graderutil.LANGUAGE] ) -trans.install(names=None) +if six.PY2: + trans.install(names=None, unicode=True) +else: + trans.install(names=None) def run(grader_name, submission_name, seed=1): diff --git a/load_test/mock_xqueue.py b/load_test/mock_xqueue.py index fc3928e..49b05d4 100644 --- a/load_test/mock_xqueue.py +++ b/load_test/mock_xqueue.py @@ -69,7 +69,7 @@ def get_submission(): response = { 'return_code': 0, 'content': flask.json.dumps({ - 'xqueue_header': '{}.{}'.format(next(counter), idx), + 'xqueue_header': '{}.{}'.format(counter.next(), idx), 'xqueue_body': flask.json.dumps({ 'student_response': submission, 'grader_payload': flask.json.dumps(payload) diff --git a/load_test/run.py b/load_test/run.py index 0224ae2..35cb4ab 100644 --- a/load_test/run.py +++ b/load_test/run.py @@ -29,19 +29,19 @@ def start_mock_xqueue(port): cmd = 'gunicorn -w 1 -k gevent -b 0.0.0.0:%s mock_xqueue:app' % port - print(cmd) + print cmd proc = subprocess.Popen(cmd.split()) return proc def start_queue_watcher(config_file, codejail_config_file): cmd = 'python -m xqueue_watcher -f {} -j {}'.format(config_file, codejail_config_file) - print(cmd) + print cmd proc = subprocess.Popen(cmd.split()) return proc def get_stats(server_address): pprint.pprint(requests.get('%s/stats' % server_address).json()) - print('\n') + print '\n' def main(args): parser = argparse.ArgumentParser() @@ -77,7 +77,7 @@ def main(args): watcher_proc = start_queue_watcher(watcher_config.name, codejail_config.name) time.sleep(1) - print(requests.get('%s/start' % args.xqueue_address).json()) + print requests.get('%s/start' % args.xqueue_address).json() else: watcher_proc = None @@ -97,7 +97,7 @@ def main(args): if xqueue_proc: os.kill(xqueue_proc.pid, 15) - print('\n\ndone') + print '\n\ndone' if __name__ == '__main__': main(sys.argv[1:]) \ No newline at end of file diff --git a/xqueue_watcher/client.py b/xqueue_watcher/client.py index d5935ff..574ebae 100644 --- a/xqueue_watcher/client.py +++ b/xqueue_watcher/client.py @@ -10,7 +10,7 @@ log = logging.getLogger(__name__) -class XQueueClient: +class XQueueClient(object): def __init__(self, queue_name, xqueue_server='http://localhost:18040', @@ -20,7 +20,7 @@ def __init__(self, poll_interval=MANAGER_CONFIG_DEFAULTS['POLL_INTERVAL'], login_poll_interval=MANAGER_CONFIG_DEFAULTS['LOGIN_POLL_INTERVAL'], follow_client_redirects=MANAGER_CONFIG_DEFAULTS['FOLLOW_CLIENT_REDIRECTS']): - super().__init__() + super(XQueueClient, self).__init__() self.session = requests.session() self.xqueue_server = xqueue_server self.queue_name = queue_name @@ -97,7 +97,7 @@ def _request(self, method, uri, **kwargs): else: return (False, "Could not log in") else: - message = "Received un expected response status code, {}, calling {}.".format( + message = "Received un expected response status code, {0}, calling {1}.".format( r.status_code,url) log.error(message) return (False, message) @@ -106,7 +106,7 @@ def _login(self): if self.username is None: return True url = self.xqueue_server + '/xqueue/login/' - log.debug("Trying to login to {} with user: {} and pass {}".format(url, self.username, self.password)) + log.debug("Trying to login to {0} with user: {1} and pass {2}".format(url, self.username, self.password)) response = self.session.request('post', url, auth=self.http_basic_auth, data={ 'username': self.username, 'password': self.password, diff --git a/xqueue_watcher/grader.py b/xqueue_watcher/grader.py index 0056859..d3b50d6 100644 --- a/xqueue_watcher/grader.py +++ b/xqueue_watcher/grader.py @@ -17,9 +17,9 @@ def format_errors(errors): error_string = '' error_list = [esc(e) for e in errors or []] if error_list: - items = '\n'.join(['
  • {}
  • \n'.format(e) for e in error_list]) - error_string = '\n'.format(items) - error_string = '
    {}
    '.format(error_string) + items = '\n'.join(['
  • {0}
  • \n'.format(e) for e in error_list]) + error_string = '\n'.format(items) + error_string = '
    {0}
    '.format(error_string) return error_string @@ -28,7 +28,7 @@ def to_dict(result): # TODO: replace with mako template esc = html.escape if result[1]: - long_desc = '

    {}

    '.format(esc(result[1])) + long_desc = '

    {0}

    '.format(esc(result[1])) else: long_desc = '' return {'short-description': esc(result[0]), @@ -39,7 +39,7 @@ def to_dict(result): } -class Grader: +class Grader(object): results_template = """
    Test results
    @@ -126,10 +126,10 @@ def process_item(self, content, queue=None): # However, for debugging, still want to see what the problem is statsd.increment('xqueuewatcher.grader_payload_error') - self.log.debug("error parsing: '{}' -- {}".format(payload, err)) + self.log.debug("error parsing: '{0}' -- {1}".format(payload, err)) raise - self.log.debug("Processing submission, grader payload: {}".format(payload)) + self.log.debug("Processing submission, grader payload: {0}".format(payload)) relative_grader_path = grader_config['grader'] grader_path = (self.grader_root / relative_grader_path).abspath() start = time.time() diff --git a/xqueue_watcher/jailedgrader.py b/xqueue_watcher/jailedgrader.py index b9c4f45..8bab17f 100644 --- a/xqueue_watcher/jailedgrader.py +++ b/xqueue_watcher/jailedgrader.py @@ -18,6 +18,7 @@ import grader_support from .grader import Grader +from six.moves import zip TIMEOUT = 1 @@ -66,7 +67,7 @@ class JailedGrader(Grader): """ def __init__(self, *args, **kwargs): self.codejail_python = kwargs.pop("codejail_python", "python") - super().__init__(*args, **kwargs) + super(JailedGrader, self).__init__(*args, **kwargs) self.locale_dir = self.grader_root / "conf" / "locale" self.fork_per_item = False # it's probably safe not to fork # EDUCATOR-3368: OpenBLAS library is allowed to allocate 1 thread @@ -86,7 +87,7 @@ def _run(self, grader_path, thecode, seed): return r def grade(self, grader_path, grader_config, submission): - if type(submission) != str: + if type(submission) != six.text_type: self.log.warning("Submission is NOT unicode") results = { @@ -122,7 +123,7 @@ def grade(self, grader_path, grader_config, submission): # Import the grader, straight from the original file. (It probably isn't in # sys.path, and we may be in a long running gunicorn process, so we don't # want to add stuff to sys.path either.) - grader_module = imp.load_source("grader_module", str(grader_path)) + grader_module = imp.load_source("grader_module", six.text_type(grader_path)) grader = grader_module.grader # Preprocess for grader-specified errors diff --git a/xqueue_watcher/manager.py b/xqueue_watcher/manager.py index e9c0da1..db64152 100644 --- a/xqueue_watcher/manager.py +++ b/xqueue_watcher/manager.py @@ -13,9 +13,10 @@ from codejail import jail_code from .settings import get_manager_config_values, MANAGER_CONFIG_DEFAULTS +from six.moves import range -class Manager: +class Manager(object): """ Manages polling connections to XQueue. """