Skip to content

Commit e01d3ab

Browse files
shaidarblarghmatey
authored andcommitted
fix: Resolves broken tokenization and codejail limits setting
Fixes incompatible tokenization of user submitted code when running under Python 3.x. This is used to add checks to ensure that students are using specific keywords or language features. Fix bug when using codejail limits in xqueue-watcher When the `limits` object is set in the codejail configuration block it causes the command used for launching a watcher process to be invalid. This is because there was a variable name used in a for loop that shadowed a variable from an outer scope that is then returned from the `enable_codejail` method that is used as an argument for the execution. Fixed invalid conversion of conditional dictionary iterator The PR that removed the usage of `six` failed to wrap the conditional `environment or {}` in parentheses before calling `.items()` on the resulting value. This would lead to trying to iterate over _either_ `environment` or `{}.items()` which is not the correct behavior.
1 parent 4eb9700 commit e01d3ab

3 files changed

Lines changed: 10 additions & 12 deletions

File tree

grader_support/gradelib.py

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
import random
44
import re
55
import sys
6-
import tokenize
6+
from tokenize import tokenize, COMMENT, STRING
7+
from io import BytesIO
78

89
import six
910
# the run library should overwrite this with a particular random seed for the test.
@@ -238,11 +239,7 @@ def _tokens(code):
238239
A wrapper around tokenize.generate_tokens.
239240
"""
240241
# Protect against pathological inputs: http://bugs.python.org/issue16152
241-
code = code.rstrip() + "\n"
242-
if isinstance(code, str):
243-
code = code.encode('utf8')
244-
code = "# coding: utf8\n" + code
245-
toks = tokenize.generate_tokens(six.BytesIO(code).readline)
242+
toks = tokenize(BytesIO(code.encode('utf-8')).readline)
246243
return toks
247244

248245
def _count_tokens(code, string):
@@ -253,7 +250,7 @@ def _count_tokens(code, string):
253250

254251
try:
255252
for ttyp, ttok, __, __, __ in _tokens(code):
256-
if ttyp in (tokenize.COMMENT, tokenize.STRING):
253+
if ttyp in (COMMENT, STRING):
257254
continue
258255
if ttok == string:
259256
count += 1
@@ -353,7 +350,7 @@ def count_non_comment_lines(at_least=None, at_most=None, exactly=None, error_msg
353350
def check(code):
354351
linenums = set()
355352
for ttyp, ttok, (srow, __), __, __ in _tokens(code):
356-
if ttyp in (tokenize.COMMENT, tokenize.STRING):
353+
if ttyp in (COMMENT, STRING):
357354
# Comments and strings don't count toward line count. If a string
358355
# is the only thing on a line, then it's probably a docstring, so
359356
# don't count it.
@@ -530,7 +527,7 @@ def invoke_student_function(fn_name, args, environment=None, output_writer=None)
530527
"""
531528
output_writer = output_writer or repr
532529
def doit(submission_module):
533-
for name, value in environment or {}.items():
530+
for name, value in (environment or {}).items():
534531
setattr(submission_module, name, value)
535532
fn = getattr(submission_module, fn_name)
536533
print(output_writer(fn(*args)))

tests/test_manager.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,8 @@ def test_codejail_config(self):
6767
"VMEM": 1024
6868
}
6969
}
70-
self.m.enable_codejail(config)
70+
codejail_return = self.m.enable_codejail(config)
71+
self.assertEqual(codejail_return, config["name"])
7172
self.assertTrue(codejail.jail_code.is_configured("python"))
7273
self.m.enable_codejail({
7374
"name": "other-python",

xqueue_watcher/manager.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,8 +119,8 @@ def enable_codejail(self, codejail_config):
119119
user = codejail_config.get('user', getpass.getuser())
120120
jail_code.configure(name, bin_path, user=user)
121121
limits = codejail_config.get("limits", {})
122-
for name, value in limits.items():
123-
jail_code.set_limit(name, value)
122+
for limit_name, value in limits.items():
123+
jail_code.set_limit(limit_name, value)
124124
self.log.info("configured codejail -> %s %s %s", name, bin_path, user)
125125
return name
126126

0 commit comments

Comments
 (0)