Skip to content

Commit

Permalink
Merge branch 'Python3_update' into remove_six
Browse files Browse the repository at this point in the history
  • Loading branch information
Michael Howitz committed Feb 1, 2017
2 parents dd24bc1 + 2371e05 commit 18d0a92
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 50 deletions.
24 changes: 0 additions & 24 deletions src/RestrictedPython/tests/security_in_syntax.py
Expand Up @@ -12,35 +12,11 @@ def f(_getattr=None):
pass


def bad_name(): # ported
__ = 12


def bad_attr(): # ported
some_ob._some_attr = 15


def no_exec(): # ported
exec 'q = 1'


def no_yield(): # ported
yield 42


def check_getattr_in_lambda(arg=lambda _getattr=(lambda ob, name: name):
_getattr):
42


def import_as_bad_name():
import os as _leading_underscore


def from_import_as_bad_name():
from x import y as _leading_underscore


def except_using_bad_name():
try:
foo
Expand Down
7 changes: 7 additions & 0 deletions src/RestrictedPython/transformer.py
Expand Up @@ -1161,6 +1161,13 @@ def visit_alias(self, node):
"""
return self.node_contents_visit(node)

def visit_Exec(self, node):
"""Deny the usage of the exec statement.
Exists only in Python 2.
"""
self.not_allowed(node)

# Control flow

def visit_If(self, node):
Expand Down
9 changes: 9 additions & 0 deletions tests/__init__.py
@@ -0,0 +1,9 @@
from RestrictedPython._compat import IS_PY2
import RestrictedPython

# Define the arguments for @pytest.mark.parametrize to be able to test both the
# old and the new implementation to be equal:
compile = ('compile', [RestrictedPython.compile.compile_restricted_exec])
if IS_PY2:
from RestrictedPython import RCompile
compile[1].append(RCompile.compile_restricted_exec)
21 changes: 21 additions & 0 deletions tests/test_compile.py
@@ -0,0 +1,21 @@
from . import compile
from RestrictedPython._compat import IS_PY2
import pytest


EXEC_STATEMENT = """\
def no_exec():
exec 'q = 1'
"""


@pytest.mark.skipif(
IS_PY2,
reason="exec statement in Python 2 is handled by RestrictedPython ")
@pytest.mark.parametrize(*compile)
def test_compile__compile_restricted_exec__10(compile):
"""It is a SyntaxError to use the `exec` statement. (Python 3 only)"""
code, errors, warnings, used_names = compile(EXEC_STATEMENT)
assert (
"Line 2: SyntaxError: Missing parentheses in call to 'exec' in on "
"statement: exec 'q = 1'",) == errors
35 changes: 9 additions & 26 deletions tests/test_transformer.py
Expand Up @@ -3,22 +3,17 @@
from RestrictedPython.Guards import guarded_iter_unpack_sequence
from RestrictedPython.Guards import guarded_unpack_sequence

from RestrictedPython._compat import IS_PY2, IS_PY3
from . import compile
import RestrictedPython
import contextlib
import pytest
import RestrictedPython
import types


# Define the arguments for @pytest.mark.parametrize to be able to test both the
# old and the new implementation to be equal:
compile = ('compile', [RestrictedPython.compile.compile_restricted_exec])
if IS_PY2:
from RestrictedPython import RCompile
compile[1].append(RCompile.compile_restricted_exec)


@pytest.mark.parametrize(*compile)
def test_transformer__RestrictingNodeTransformer__generic_visit__1(compile):
def test_transformer__RestrictingNodeTransformer__visit_Num__1(compile):
"""It compiles a number successfully."""
code, errors, warnings, used_names = compile('42')
assert 'code' == str(code.__class__.__name__)
Expand All @@ -28,7 +23,7 @@ def test_transformer__RestrictingNodeTransformer__generic_visit__1(compile):


@pytest.mark.parametrize(*compile)
def test_transformer__RestrictingNodeTransformer__generic_visit__2(compile):
def test_transformer__RestrictingNodeTransformer__visit_Call__1(compile):
"""It compiles a function call successfully and returns the used name."""
code, errors, warnings, used_names = compile('max([1, 2, 3])')
assert errors == ()
Expand All @@ -48,8 +43,8 @@ def no_yield():


@pytest.mark.parametrize(*compile)
def test_transformer__RestrictingNodeTransformer__generic_visit__100(compile):
"""It is an error if the code contains a `yield` statement."""
def test_transformer__RestrictingNodeTransformer__visit_Yield__1(compile):
"""It prevents using the `yield` statement."""
code, errors, warnings, used_names = compile(YIELD)
assert ("Line 2: Yield statements are not allowed.",) == errors
assert warnings == []
Expand All @@ -65,24 +60,12 @@ def no_exec():
@pytest.mark.skipif(IS_PY3,
reason="exec statement no longer exists in Python 3")
@pytest.mark.parametrize(*compile)
def test_transformer__RestrictingNodeTransformer__generic_visit__102(compile):
"""It raises a SyntaxError if the code contains an `exec` statement."""
def test_transformer__RestrictingNodeTransformer__visit_Exec__1(compile):
"""It prevents using the `exec` statement. (Python 2 only)"""
code, errors, warnings, used_names = compile(EXEC_STATEMENT)
assert ('Line 2: Exec statements are not allowed.',) == errors


@pytest.mark.skipif(
IS_PY2,
reason="exec statement in Python 3 raises SyntaxError itself")
@pytest.mark.parametrize(*compile)
def test_transformer__RestrictingNodeTransformer__generic_visit__103(compile):
"""It is an error if the code contains an `exec` statement."""
code, errors, warnings, used_names = compile(EXEC_STATEMENT)
assert (
"Line 2: SyntaxError: Missing parentheses in call to 'exec' in on "
"statement: exec 'q = 1'",) == errors


BAD_NAME_STARTING_WITH_UNDERSCORE = """\
def bad_name():
__ = 12
Expand Down

0 comments on commit 18d0a92

Please sign in to comment.