Commit 4b234a63 by Ned Batchelder

Future division is really a capa concern, not a general-purpose codejail concern. Move it.

parent 7187b10f
...@@ -3,8 +3,9 @@ ...@@ -3,8 +3,9 @@
import codejail.safe_exec import codejail.safe_exec
# This will set up the name "random" as a properly-seeded stand-in for the # This will set up the name "random" as a properly-seeded stand-in for the
# random module. # random module. Also, capa assumes float-friendly division always.
CODE_PROLOG = """\ CODE_PROLOG = """\
from __future__ import division
import random as random_module import random as random_module
random = random_module.Random(%r) random = random_module.Random(%r)
random.Random = random_module.Random random.Random = random_module.Random
...@@ -17,7 +18,7 @@ def safe_exec(code, globals_dict, locals_dict, random_seed=None, python_path=Non ...@@ -17,7 +18,7 @@ def safe_exec(code, globals_dict, locals_dict, random_seed=None, python_path=Non
""" """
code_prolog = CODE_PROLOG % random_seed code_prolog = CODE_PROLOG % random_seed
codejail.safe_exec.safe_exec( codejail.safe_exec.safe_exec(
code_prolog + code, globals_dict, locals_dict, future_division=True, code_prolog + code, globals_dict, locals_dict,
python_path=python_path, python_path=python_path,
assumed_imports=[ assumed_imports=[
"numpy", "numpy",
......
...@@ -28,15 +28,13 @@ def names_and_modules(assumed_imports): ...@@ -28,15 +28,13 @@ def names_and_modules(assumed_imports):
yield modname, modname yield modname, modname
def safe_exec(code, globals_dict, locals_dict, future_division=False, assumed_imports=None, files=None, python_path=None): def safe_exec(code, globals_dict, locals_dict, assumed_imports=None, files=None, python_path=None):
"""Execute code as "exec" does, but safely. """Execute code as "exec" does, but safely.
`code` is a string of Python code. `globals_dict` and `locals_dict` are `code` is a string of Python code. `globals_dict` and `locals_dict` are
dictionaries to use as the globals and locals. Modifications the code dictionaries to use as the globals and locals. Modifications the code
makes to `locals_dict` are reflected in the dictionary on return. makes to `locals_dict` are reflected in the dictionary on return.
`future_division` determines whether Python-3-style division is used.
`assumed_imports` is a list of modules to make available as implicit `assumed_imports` is a list of modules to make available as implicit
imports for the code. Entries are either a name, "mod", which makes imports for the code. Entries are either a name, "mod", which makes
"import mod" part of the code, or a pair, ("f", "fooey"), which makes "import mod" part of the code, or a pair, ("f", "fooey"), which makes
...@@ -48,9 +46,6 @@ def safe_exec(code, globals_dict, locals_dict, future_division=False, assumed_im ...@@ -48,9 +46,6 @@ def safe_exec(code, globals_dict, locals_dict, future_division=False, assumed_im
the_code = [] the_code = []
files = list(files or ()) files = list(files or ())
if future_division:
the_code.append("from __future__ import division\n")
the_code.append(textwrap.dedent("""\ the_code.append(textwrap.dedent("""\
import json import json
import sys import sys
...@@ -90,7 +85,7 @@ def safe_exec(code, globals_dict, locals_dict, future_division=False, assumed_im ...@@ -90,7 +85,7 @@ def safe_exec(code, globals_dict, locals_dict, future_division=False, assumed_im
locals_dict.update(json.loads(res.stdout)) locals_dict.update(json.loads(res.stdout))
def not_safe_exec(code, globals_dict, locals_dict, future_division=False, assumed_imports=None, files=None, python_path=None): def not_safe_exec(code, globals_dict, locals_dict, assumed_imports=None, files=None, python_path=None):
"""Another implementation of `safe_exec`, but not safe. """Another implementation of `safe_exec`, but not safe.
This can be swapped in for debugging problems in sandboxed Python code. This can be swapped in for debugging problems in sandboxed Python code.
...@@ -115,9 +110,6 @@ def not_safe_exec(code, globals_dict, locals_dict, future_division=False, assume ...@@ -115,9 +110,6 @@ def not_safe_exec(code, globals_dict, locals_dict, future_division=False, assume
jd[k] = v jd[k] = v
return json.loads(json.dumps(jd)) return json.loads(json.dumps(jd))
if future_division:
code = "from __future__ import division\n" + code
g_dict = straw(globals_dict) g_dict = straw(globals_dict)
l_dict = straw(locals_dict) l_dict = straw(locals_dict)
......
...@@ -13,15 +13,6 @@ class SafeExecTests(object): ...@@ -13,15 +13,6 @@ class SafeExecTests(object):
self.safe_exec("a = 17", g, l) self.safe_exec("a = 17", g, l)
self.assertEqual(l['a'], 17) self.assertEqual(l['a'], 17)
def test_division(self):
g, l = {}, {}
# No future division: 1/2 is 0.
self.safe_exec("a = 1/2", g, l)
self.assertEqual(l['a'], 0)
# Future division: 1/2 is 0.5.
self.safe_exec("a = 1/2", g, l, future_division=True)
self.assertEqual(l['a'], 0.5)
def test_assumed_imports(self): def test_assumed_imports(self):
g, l = {}, {} g, l = {}, {}
# Using string without importing it is bad. # Using string without importing it is bad.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment