Skip to content

Commit

Permalink
apply review comments
Browse files Browse the repository at this point in the history
  • Loading branch information
loechel committed May 5, 2017
1 parent 6049ddc commit fff4271
Show file tree
Hide file tree
Showing 8 changed files with 45 additions and 24 deletions.
17 changes: 8 additions & 9 deletions .coveragerc
Expand Up @@ -2,15 +2,14 @@
branch = True
source = RestrictedPython
omit =
bootstrap.py
tests/*.py
src/RestrictedPython/tests
src/RestrictedPython/tests/*.py
# Explicit exclude old implementation for the moment.
# should be removed when those files have gone.
src/RestrictedPython/SelectCompiler.py
src/RestrictedPython/MutatingWalker.py
src/RestrictedPython/RestrictionMutator.py
# Tests are classically not part of source code
# and should not be calculated into coverage sum
# on the other hand, the coverage tools do a handy job on highlighting
# code branches and tests that that did not get executed.
# Therefore we include tests into coverage analysis for the moment.
#tests/*.py
#src/RestrictedPython/tests
#src/RestrictedPython/tests/*.py

[report]
precision = 3
1 change: 0 additions & 1 deletion setup.cfg
Expand Up @@ -52,4 +52,3 @@ ignore =
N805,
N806,
N812,
E301
12 changes: 12 additions & 0 deletions src/RestrictedPython/RCompile.py
Expand Up @@ -144,6 +144,18 @@ def compile_restricted_eval(source, filename='<string>'):
return compileAndTuplize(gen)


def compile_restricted_single(source, filename='<string>'):
"""Compiles a restricted expression."""
warnings.warn(
"RestrictedPython.RCompile.compile_restricted_single is deprecated"
"use RestrictedPython.compile_restricted_single instead.",
category=PendingDeprecationWarning,
stacklevel=1
)
gen = RInteractive(source, filename)
return compileAndTuplize(gen)


def compile_restricted(source, filename, mode):
"""Replacement for the builtin compile() function."""
warnings.warn(
Expand Down
8 changes: 4 additions & 4 deletions src/RestrictedPython/compile.py
Expand Up @@ -116,7 +116,7 @@ def compile_restricted_function(
body,
name,
filename='<string>',
globalize=None, # List of globals (e.g. )
globalize=None, # List of globals (e.g. ['here', 'context', ...])
flags=0,
dont_inherit=False,
policy=RestrictingNodeTransformer):
Expand All @@ -137,7 +137,7 @@ def compile_restricted_function(
>>> safe_locals = {}
>>> safe_globals = {}
>>> exec(compiled.code, safe_globals, safe_locals)
>>> compiled_function = safe_locals.values()[0]
>>> compiled_function = safe_locals['function_name']
>>> result = compiled_function(*[], **{})
Then if you want to controll the globals for a specific call to this
Expand All @@ -147,10 +147,10 @@ def compile_restricted_function(
>>> safe_globals = safe_globals.copy()
>>> safe_globals.update(my_call_specific_global_bindings)
>>> import types
>>> new_function = types.FunctionType(compiled_function.func_code, \
>>> new_function = types.FunctionType(compiled_function.__code__, \
safe_globals, \
'<function_name>', \
compiled_function.func_defaults or \
compiled_function.__defaults__ or \
() \
)
>>> result = new_function(*[], **{})
Expand Down
5 changes: 3 additions & 2 deletions tests/__init__.py
Expand Up @@ -73,14 +73,15 @@ def _function(source, glb=None):
c_single = ('c_single', [RestrictedPython.compile.compile_restricted_single])
e_single = ('e_single', [_single(RestrictedPython.compile.compile_restricted_single)]) # NOQA: E501


if IS_PY2:
from RestrictedPython import RCompile
c_exec[1].append(RCompile.compile_restricted_exec)
c_eval[1].append(RCompile.compile_restricted_eval)
# c_single[1].append(lambda source, filename: RCompile.compile_restricted(source, filename, 'single')) # NOQA: E501
c_single[1].append(RCompile.compile_restricted_single)
c_function[1].append(RCompile.compile_restricted_function)

e_exec[1].append(_exec(RCompile.compile_restricted_exec))
e_eval[1].append(_eval(RCompile.compile_restricted_eval))
# e_single[1].append(_single(lambda source, filename: RCompile.compile_restricted(source, filename, 'single'))) # NOQA: E501
e_single[1].append(_single(RCompile.compile_restricted_single))
e_function[1].append(_function(RCompile.compile_restricted_function))
18 changes: 14 additions & 4 deletions tests/test_compile.py
Expand Up @@ -164,10 +164,15 @@ def test_compile__compile_restricted_eval__used_names(c_eval):
def test_compile__compile_restricted_csingle(c_single):
"""It compiles code as an Expression."""
result = c_single('4 * 6')
assert result.code is None
assert result.errors == (
'Line None: Interactive statements are not allowed.',
)
if c_single is RestrictedPython.compile.compile_restricted_single:
# New implementation disallows single mode
assert result.code is None
assert result.errors == (
'Line None: Interactive statements are not allowed.',
)
else: # RestrictedPython.RCompile.compile_restricted_single
assert result.code is not None
assert result.errors == ()


PRINT_EXAMPLE = """
Expand All @@ -181,6 +186,9 @@ def a():
reason="Print statement is gone in Python 3."
"Test Deprecation Warming in Python 2")
def test_compile_restricted():
"""This test checks compile_restricted itself if that emit Python warnings.
For actual tests for print statement see: test_print_stmt.py
"""
with pytest.warns(SyntaxWarning) as record:
result = compile_restricted(PRINT_EXAMPLE, '<string>', 'exec')
assert isinstance(result, types.CodeType)
Expand All @@ -199,6 +207,8 @@ def a():


def test_compile_restricted_eval():
"""This test checks compile_restricted itself if that raise Python errors.
"""
with pytest.raises(SyntaxError,
message="Line 3: Eval calls are not allowed."):
compile_restricted(EVAL_EXAMPLE, '<string>', 'exec')
6 changes: 3 additions & 3 deletions tests/test_compile_restricted_function.py
Expand Up @@ -76,9 +76,9 @@ def test_compile_restricted_function_func_wrapped(c_function):

@pytest.mark.parametrize(*c_function)
def test_compile_restricted_function_with_arguments(c_function):
p = 'input'
p = 'input1, input2'
body = """
print(input)
print(input1 + input2)
return printed
"""
name = "hello_world"
Expand All @@ -105,7 +105,7 @@ def test_compile_restricted_function_with_arguments(c_function):
exec(result.code, safe_globals, safe_locals)
hello_world = safe_locals['hello_world']
assert type(hello_world) == FunctionType
assert hello_world('Hello World!') == 'Hello World!\n'
assert hello_world('Hello ', 'World!') == 'Hello World!\n'


@pytest.mark.parametrize(*c_function)
Expand Down
2 changes: 1 addition & 1 deletion tox.ini
Expand Up @@ -22,7 +22,7 @@ extras =
test
commands =
pytest --cov=src --cov-report=xml --html=report-{envname}.html --self-contained-html {posargs}
#pytest --doctest-modules src/RestrictedPython/compile.py {posargs}
pytest --doctest-modules src/RestrictedPython/compile.py {posargs}
setenv =
COVERAGE_FILE=.coverage.{envname}
deps =
Expand Down

0 comments on commit fff4271

Please sign in to comment.