Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,17 @@ python:
- pypy-5.4
env:
- ENVIRON=py
- ENVIRON=py27-rp3
- ENVIRON=isort,flake8,docs
matrix:
exclude:
- env: ENVIRON=isort,flake8,docs
- env: ENVIRON=py27-rp3
include:
- python: "3.6"
env: ENVIRON=isort,flake8,docs
- python: "2.7"
env: ENVIRON=py27-rp3
install:
- pip install tox coveralls coverage
script:
Expand Down
24 changes: 0 additions & 24 deletions src/RestrictedPython/tests/security_in_syntax.py

This file was deleted.

19 changes: 0 additions & 19 deletions src/RestrictedPython/tests/security_in_syntax26.py

This file was deleted.

2 changes: 1 addition & 1 deletion src/RestrictedPython/tests/testREADME.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,4 @@

def test_suite():
return unittest.TestSuite([
DocFileSuite('README.txt', package='RestrictedPython'), ])
DocFileSuite('README.rst', package='RestrictedPython'), ])
50 changes: 0 additions & 50 deletions src/RestrictedPython/tests/testRestrictions.py
Original file line number Diff line number Diff line change
Expand Up @@ -296,9 +296,6 @@ def test_Denied(self):
self.fail('%s() did not trip security' % k)

def test_SyntaxSecurity(self):
self._test_SyntaxSecurity('security_in_syntax.py')
if sys.version_info >= (2, 6):
self._test_SyntaxSecurity('security_in_syntax26.py')
if sys.version_info >= (2, 7):
self._test_SyntaxSecurity('security_in_syntax27.py')

Expand Down Expand Up @@ -358,33 +355,6 @@ def test_StackSize(self):
'should have been at least %d, but was only %d'
% (k, ss, rss))

def test_BeforeAndAfter(self):
from RestrictedPython.RCompile import RModule
from RestrictedPython.tests import before_and_after
from compiler import parse

defre = re.compile(r'def ([_A-Za-z0-9]+)_(after|before)\(')

beforel = [name for name in before_and_after.__dict__
if name.endswith("_before")]

for name in beforel:
before = getattr(before_and_after, name)
before_src = get_source(before)
before_src = re.sub(defre, r'def \1(', before_src)
rm = RModule(before_src, '')
tree_before = rm._get_tree()

after = getattr(before_and_after, name[:-6] + 'after')
after_src = get_source(after)
after_src = re.sub(defre, r'def \1(', after_src)
tree_after = parse(after_src)

self.assertEqual(str(tree_before), str(tree_after))

rm.compile()
verify(rm.getCode())

def _test_BeforeAndAfter(self, mod):
from RestrictedPython.RCompile import RModule
from compiler import parse
Expand All @@ -411,26 +381,6 @@ def _test_BeforeAndAfter(self, mod):
rm.compile()
verify(rm.getCode())

if sys.version_info[:2] >= (2, 4):
def test_BeforeAndAfter24(self):
from RestrictedPython.tests import before_and_after24
self._test_BeforeAndAfter(before_and_after24)

if sys.version_info[:2] >= (2, 5):
def test_BeforeAndAfter25(self):
from RestrictedPython.tests import before_and_after25
self._test_BeforeAndAfter(before_and_after25)

if sys.version_info[:2] >= (2, 6):
def test_BeforeAndAfter26(self):
from RestrictedPython.tests import before_and_after26
self._test_BeforeAndAfter(before_and_after26)

if sys.version_info[:2] >= (2, 7):
def test_BeforeAndAfter27(self):
from RestrictedPython.tests import before_and_after27
self._test_BeforeAndAfter(before_and_after27)

def _compile_file(self, name):
path = os.path.join(_HERE, name)
f = open(path, "r")
Expand Down
3 changes: 1 addition & 2 deletions src/RestrictedPython/transformer.py
Original file line number Diff line number Diff line change
Expand Up @@ -1259,8 +1259,7 @@ def visit_ExceptHandler(self, node):
return node

def visit_With(self, node):
"""Protects tuple unpacking on with statements. """

"""Protect tuple unpacking on with statements. """
node = self.node_contents_visit(node)

if IS_PY2:
Expand Down
13 changes: 7 additions & 6 deletions tests/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@

def _execute(compile_func):
"""Factory to create an execute function."""
def _execute(source):
code, errors = compile_func(source)[:2]
assert errors == (), errors
assert code is not None
glb = {}
exec(code, glb)
def _execute(source, glb=None):
result = compile_func(source)
assert result.errors == (), result.errors
assert result.code is not None
if glb is None:
glb = {}
exec(result.code, glb)
return glb
return _execute

Expand Down
117 changes: 97 additions & 20 deletions tests/test_transformer.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ def bad_name():

@pytest.mark.parametrize(*compile)
def test_transformer__RestrictingNodeTransformer__visit_Name__1(compile):
"""It is an error if a variable name starts with `_`."""
"""It is an error if a variable name starts with `__`."""
result = compile(BAD_NAME_STARTING_WITH_UNDERSCORE)
assert result.errors == (
'Line 2: "__" is an invalid variable name because it starts with "_"',)
Expand All @@ -84,7 +84,7 @@ def overrideGuardWithName():

@pytest.mark.parametrize(*compile)
def test_transformer__RestrictingNodeTransformer__visit_Name__2(compile):
"""It is an error if a variable name ends with `__roles__`."""
"""It is an error if a variable name starts with `_`."""
result = compile(BAD_NAME_OVERRIDE_GUARD_WITH_NAME)
assert result.errors == (
'Line 2: "_getattr" is an invalid variable name because '
Expand All @@ -100,7 +100,7 @@ def _getattr(o):

@pytest.mark.parametrize(*compile)
def test_transformer__RestrictingNodeTransformer__visit_Name__3(compile):
"""It is an error if a variable name ends with `__roles__`."""
"""It is an error if a function name starts with `_`."""
result = compile(BAD_NAME_OVERRIDE_OVERRIDE_GUARD_WITH_FUNCTION)
assert result.errors == (
'Line 2: "_getattr" is an invalid variable name because it '
Expand All @@ -116,13 +116,29 @@ class _getattr:

@pytest.mark.parametrize(*compile)
def test_transformer__RestrictingNodeTransformer__visit_Name__4(compile):
"""It is an error if a variable name ends with `__roles__`."""
"""It is an error if a class name starts with `_`."""
result = compile(BAD_NAME_OVERRIDE_GUARD_WITH_CLASS)
assert result.errors == (
'Line 2: "_getattr" is an invalid variable name because it '
'starts with "_"',)


BAD_NAME_IN_WITH = """\
def with_as_bad_name():
with x as _leading_underscore:
pass
"""


@pytest.mark.parametrize(*compile)
def test_transformer__RestrictingNodeTransformer__visit_Name__4_5(compile):
"""It is an error if a variable in with starts with `_`."""
result = compile(BAD_NAME_IN_WITH)
assert result.errors == (
'Line 2: "_leading_underscore" is an invalid variable name because '
'it starts with "_"',)


BAD_NAME_ENDING_WITH___ROLES__ = """\
def bad_name():
myvar__roles__ = 12
Expand Down Expand Up @@ -639,9 +655,10 @@ def test_transformer__RestrictingNodeTransformer__visit_Subscript_2(
_write_.reset_mock()


@pytest.mark.parametrize(*compile)
def test_transformer__RestrictingNodeTransformer__visit_AugAssign(
compile, mocker):
@pytest.mark.parametrize(*execute)
def test_transformer__RestrictingNodeTransformer__visit_AugAssign__1(
execute, mocker):
"""It allows augmented assign for variables."""
_inplacevar_ = mocker.stub()
_inplacevar_.side_effect = lambda op, val, expr: val + expr

Expand All @@ -652,24 +669,47 @@ def test_transformer__RestrictingNodeTransformer__visit_AugAssign(
'z': 0
}

result = compile("a += x + z")
assert result.errors == ()
exec(result.code, glb)

execute("a += x + z", glb)
assert glb['a'] == 2
_inplacevar_.assert_called_once_with('+=', 1, 1)
_inplacevar_.reset_mock()


@pytest.mark.parametrize(*compile)
def test_transformer__RestrictingNodeTransformer__visit_AugAssign__2(compile):
"""It forbids augmented assign of attributes."""
result = compile("a.a += 1")
assert result.errors == (
'Line 1: Augmented assignment of attributes is not allowed.',)


@pytest.mark.parametrize(*compile)
def test_transformer__RestrictingNodeTransformer__visit_AugAssign__3(compile):
"""It forbids augmented assign of subscripts."""
result = compile("a[a] += 1")
assert result.errors == (
'Line 1: Augmented assignment of object items and slices is not '
'allowed.',)


@pytest.mark.parametrize(*compile)
def test_transformer__RestrictingNodeTransformer__visit_AugAssign__4(compile):
"""It forbids augmented assign of slices."""
result = compile("a[x:y] += 1")
assert result.errors == (
'Line 1: Augmented assignment of object items and slices is not '
'allowed.',)


@pytest.mark.parametrize(*compile)
def test_transformer__RestrictingNodeTransformer__visit_AugAssign__5(compile):
"""It forbids augmented assign of slices with steps."""
result = compile("a[x:y:z] += 1")
assert result.errors == (
'Line 1: Augmented assignment of object items and slices is not '
'allowed.',)


# def f(a, b, c): pass
# f(*two_element_sequence, **dict_with_key_c)
#
Expand Down Expand Up @@ -1268,37 +1308,74 @@ def test_transformer__RestrictingNodeTransformer__visit_ExceptHandler__2(
'it starts with "_"',)


@pytest.mark.parametrize(*compile)
def test_transformer__RestrictingNodeTransformer__visit_Import(compile):
errmsg = 'Line 1: "%s" is an invalid variable name ' \
'because it starts with "_"'
import_errmsg = (
'Line 1: "%s" is an invalid variable name because it starts with "_"')


@pytest.mark.parametrize(*compile)
def test_transformer__RestrictingNodeTransformer__visit_Import__1(compile):
"""It allows importing a module."""
result = compile('import a')
assert result.errors == ()
assert result.code is not None


@pytest.mark.parametrize(*compile)
def test_transformer__RestrictingNodeTransformer__visit_Import__2(compile):
"""It denies importing a module starting with `_`."""
result = compile('import _a')
assert result.errors == (errmsg % '_a',)
assert result.errors == (import_errmsg % '_a',)


@pytest.mark.parametrize(*compile)
def test_transformer__RestrictingNodeTransformer__visit_Import__3(compile):
"""It denies importing a module starting with `_` as something."""
result = compile('import _a as m')
assert result.errors == (errmsg % '_a',)
assert result.errors == (import_errmsg % '_a',)


@pytest.mark.parametrize(*compile)
def test_transformer__RestrictingNodeTransformer__visit_Import__4(compile):
"""It denies importing a module as something starting with `_`."""
result = compile('import a as _m')
assert result.errors == (errmsg % '_m',)
assert result.errors == (import_errmsg % '_m',)


@pytest.mark.parametrize(*compile)
def test_transformer__RestrictingNodeTransformer__visit_Import__5(compile):
"""It allows importing from a module."""
result = compile('from a import m')
assert result.errors == ()
assert result.code is not None


@pytest.mark.parametrize(*compile)
def test_transformer__RestrictingNodeTransformer__visit_Import_6(compile):
"""It allows importing from a module starting with `_`."""
result = compile('from _a import m')
assert result.errors == ()
assert result.code is not None


@pytest.mark.parametrize(*compile)
def test_transformer__RestrictingNodeTransformer__visit_Import__7(compile):
"""It denies importing from a module as something starting with `_`."""
result = compile('from a import m as _n')
assert result.errors == (errmsg % '_n',)
assert result.errors == (import_errmsg % '_n',)


@pytest.mark.parametrize(*compile)
def test_transformer__RestrictingNodeTransformer__visit_Import__8(compile):
"""It denies as-importing something starting with `_` from a module."""
result = compile('from a import _m as n')
assert result.errors == (errmsg % '_m',)
assert result.errors == (import_errmsg % '_m',)


@pytest.mark.parametrize(*compile)
def test_transformer__RestrictingNodeTransformer__visit_Import__9(compile):
"""It denies relative from importing as something starting with `_`."""
result = compile('from .x import y as _leading_underscore')
assert result.errors == (import_errmsg % '_leading_underscore',)


@pytest.mark.parametrize(*compile)
Expand Down
Loading