Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@
.coverage
.coverage.*
.eggs/
.idea/
.installed.cfg
Comment thread
loechel marked this conversation as resolved.
.mr.developer.cfg
.python-version
.tox/
.vscode/
__pycache__/
Expand Down
5 changes: 4 additions & 1 deletion src/RestrictedPython/Guards.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
'EOFError',
'EnvironmentError',
'Exception',
'ExceptionGroup',
'FloatingPointError',
'FutureWarning',
'GeneratorExit',
Expand Down Expand Up @@ -107,7 +108,9 @@
safe_builtins[name] = getattr(builtins, name)

for name in _safe_exceptions:
safe_builtins[name] = getattr(builtins, name)
builtin = getattr(builtins, name, None)
if builtin:
safe_builtins[name] = getattr(builtins, name)


# Wrappers provided by this module:
Expand Down
1 change: 1 addition & 0 deletions src/RestrictedPython/_compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@
IS_PY37_OR_GREATER = _version.major == 3 and _version.minor >= 7
IS_PY38_OR_GREATER = _version.major == 3 and _version.minor >= 8
IS_PY310_OR_GREATER = _version.major == 3 and _version.minor >= 10
IS_PY311_OR_GREATER = _version.major == 3 and _version.minor >= 11

IS_CPYTHON = platform.python_implementation() == 'CPython'
4 changes: 4 additions & 0 deletions src/RestrictedPython/transformer.py
Original file line number Diff line number Diff line change
Expand Up @@ -1127,6 +1127,10 @@ def visit_Try(self, node):
"""Allow `try` without restrictions."""
return self.node_contents_visit(node)

def visit_TryStar(self, node):
"""Allow `ExceptionGroup` without restrictions."""
return self.node_contents_visit(node)

def visit_ExceptHandler(self, node):
"""Protect exception handlers."""
node = self.node_contents_visit(node)
Expand Down
26 changes: 26 additions & 0 deletions tests/transformer/test_try.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from RestrictedPython import compile_restricted_exec
from RestrictedPython._compat import IS_PY311_OR_GREATER
from tests.helper import restricted_exec


Expand Down Expand Up @@ -47,6 +48,31 @@ def test_RestrictingNodeTransformer__visit_Try__2(
])


TRY_EXCEPT_STAR = """
def try_except_star(m):
try:
m('try')
raise ExceptionGroup("group", [IndentationError('f1'), ValueError(65)])
except* IndentationError:
m('IndentetionError')
Comment thread
loechel marked this conversation as resolved.
Outdated
except* ValueError:
m('ValueError')
"""


def test_RestrictingNodeTransformer__visit_Try__3(mocker):
Comment thread
loechel marked this conversation as resolved.
Outdated
Comment thread
eikichi18 marked this conversation as resolved.
Outdated
"""It allows try-except statements."""
if IS_PY311_OR_GREATER:
Comment thread
loechel marked this conversation as resolved.
Outdated
trace = mocker.stub()
restricted_exec(TRY_EXCEPT_STAR)['try_except_star'](trace)

trace.assert_has_calls([
mocker.call('try'),
mocker.call('IndentetionError'),
mocker.call('ValueError')
])


TRY_FINALLY = """
def try_finally(m):
try:
Expand Down