From 7de129c82079063957103a90f055b0044c7a0aca Mon Sep 17 00:00:00 2001 From: Filippo Campi Date: Sat, 15 Oct 2022 15:22:11 +0200 Subject: [PATCH 01/11] add test for except star --- .gitignore | 2 ++ src/RestrictedPython/Guards.py | 5 ++++- src/RestrictedPython/_compat.py | 1 + src/RestrictedPython/transformer.py | 4 ++++ tests/transformer/test_try.py | 26 ++++++++++++++++++++++++++ 5 files changed, 37 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 1f321f5..3db497c 100644 --- a/.gitignore +++ b/.gitignore @@ -9,8 +9,10 @@ .coverage .coverage.* .eggs/ +.idea/ .installed.cfg .mr.developer.cfg +.python-version .tox/ .vscode/ __pycache__/ diff --git a/src/RestrictedPython/Guards.py b/src/RestrictedPython/Guards.py index faaaa18..7a17779 100644 --- a/src/RestrictedPython/Guards.py +++ b/src/RestrictedPython/Guards.py @@ -64,6 +64,7 @@ 'EOFError', 'EnvironmentError', 'Exception', + 'ExceptionGroup', 'FloatingPointError', 'FutureWarning', 'GeneratorExit', @@ -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: diff --git a/src/RestrictedPython/_compat.py b/src/RestrictedPython/_compat.py index a41e8a2..690c535 100644 --- a/src/RestrictedPython/_compat.py +++ b/src/RestrictedPython/_compat.py @@ -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' diff --git a/src/RestrictedPython/transformer.py b/src/RestrictedPython/transformer.py index 6e65635..f20650a 100644 --- a/src/RestrictedPython/transformer.py +++ b/src/RestrictedPython/transformer.py @@ -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) diff --git a/tests/transformer/test_try.py b/tests/transformer/test_try.py index 4abe400..500673b 100644 --- a/tests/transformer/test_try.py +++ b/tests/transformer/test_try.py @@ -1,4 +1,5 @@ from RestrictedPython import compile_restricted_exec +from RestrictedPython._compat import IS_PY311_OR_GREATER from tests.helper import restricted_exec @@ -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') + except* ValueError: + m('ValueError') +""" + + +def test_RestrictingNodeTransformer__visit_Try__3(mocker): + """It allows try-except statements.""" + if IS_PY311_OR_GREATER: + 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: From ff902f6e6f7433cbd02e78551078e9a010d0a363 Mon Sep 17 00:00:00 2001 From: Filippo Campi Date: Sat, 15 Oct 2022 15:43:25 +0200 Subject: [PATCH 02/11] fixed test with decorator skipif and standardize .gitignore file --- .gitignore | 2 -- tests/transformer/test_try.py | 24 ++++++++++++++---------- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/.gitignore b/.gitignore index 3db497c..1f321f5 100644 --- a/.gitignore +++ b/.gitignore @@ -9,10 +9,8 @@ .coverage .coverage.* .eggs/ -.idea/ .installed.cfg .mr.developer.cfg -.python-version .tox/ .vscode/ __pycache__/ diff --git a/tests/transformer/test_try.py b/tests/transformer/test_try.py index 500673b..b059b64 100644 --- a/tests/transformer/test_try.py +++ b/tests/transformer/test_try.py @@ -1,3 +1,5 @@ +import pytest + from RestrictedPython import compile_restricted_exec from RestrictedPython._compat import IS_PY311_OR_GREATER from tests.helper import restricted_exec @@ -59,18 +61,20 @@ def try_except_star(m): m('ValueError') """ - +@pytest.mark.skipif( + not IS_PY311_OR_GREATER, + reason="ExceptionGroup class are added in Python 3.11.", +) def test_RestrictingNodeTransformer__visit_Try__3(mocker): """It allows try-except statements.""" - if IS_PY311_OR_GREATER: - 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') - ]) + 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 = """ From 1246e7b5ece20fa8fdf71b80b2ed32dd0a058d5f Mon Sep 17 00:00:00 2001 From: Filippo Campi Date: Sat, 15 Oct 2022 15:49:00 +0200 Subject: [PATCH 03/11] add some comments --- src/RestrictedPython/Guards.py | 2 ++ tests/transformer/test_try.py | 1 + 2 files changed, 3 insertions(+) diff --git a/src/RestrictedPython/Guards.py b/src/RestrictedPython/Guards.py index 7a17779..763f074 100644 --- a/src/RestrictedPython/Guards.py +++ b/src/RestrictedPython/Guards.py @@ -109,6 +109,8 @@ for name in _safe_exceptions: builtin = getattr(builtins, name, None) + # PR:237 add because import of class ExceptionGroup in python smaller + # than 3.11 cause an error if builtin: safe_builtins[name] = getattr(builtins, name) diff --git a/tests/transformer/test_try.py b/tests/transformer/test_try.py index b059b64..3ed356c 100644 --- a/tests/transformer/test_try.py +++ b/tests/transformer/test_try.py @@ -61,6 +61,7 @@ def try_except_star(m): m('ValueError') """ + @pytest.mark.skipif( not IS_PY311_OR_GREATER, reason="ExceptionGroup class are added in Python 3.11.", From 77df0ed103757682386985438e3b729d4da9d754 Mon Sep 17 00:00:00 2001 From: Filippo Campi Date: Sat, 15 Oct 2022 16:31:20 +0200 Subject: [PATCH 04/11] more clear syntax --- src/RestrictedPython/Guards.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/RestrictedPython/Guards.py b/src/RestrictedPython/Guards.py index 763f074..9b70ae3 100644 --- a/src/RestrictedPython/Guards.py +++ b/src/RestrictedPython/Guards.py @@ -17,6 +17,8 @@ import builtins +from RestrictedPython._compat import IS_PY311_OR_GREATER + safe_builtins = {} @@ -64,7 +66,6 @@ 'EOFError', 'EnvironmentError', 'Exception', - 'ExceptionGroup', 'FloatingPointError', 'FutureWarning', 'GeneratorExit', @@ -104,15 +105,14 @@ 'ZeroDivisionError', ] +if IS_PY311_OR_GREATER: + _safe_exceptions.append("ExceptionGroup") + for name in _safe_names: safe_builtins[name] = getattr(builtins, name) for name in _safe_exceptions: - builtin = getattr(builtins, name, None) - # PR:237 add because import of class ExceptionGroup in python smaller - # than 3.11 cause an error - if builtin: - safe_builtins[name] = getattr(builtins, name) + safe_builtins[name] = getattr(builtins, name) # Wrappers provided by this module: From c03df9ecfa2287f482c04ec88135ebcc972d8d71 Mon Sep 17 00:00:00 2001 From: Filippo Campi Date: Sat, 15 Oct 2022 16:32:37 +0200 Subject: [PATCH 05/11] removed typo --- tests/transformer/test_try.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/transformer/test_try.py b/tests/transformer/test_try.py index 3ed356c..670fd46 100644 --- a/tests/transformer/test_try.py +++ b/tests/transformer/test_try.py @@ -56,7 +56,7 @@ def try_except_star(m): m('try') raise ExceptionGroup("group", [IndentationError('f1'), ValueError(65)]) except* IndentationError: - m('IndentetionError') + m('IndentationError') except* ValueError: m('ValueError') """ @@ -73,7 +73,7 @@ def test_RestrictingNodeTransformer__visit_Try__3(mocker): trace.assert_has_calls([ mocker.call('try'), - mocker.call('IndentetionError'), + mocker.call('IndentationError'), mocker.call('ValueError') ]) From 7c091864f1c8084b42e73cf440bbc52f09037856 Mon Sep 17 00:00:00 2001 From: Filippo Campi Date: Sat, 15 Oct 2022 16:45:13 +0200 Subject: [PATCH 06/11] impreve test for except* --- tests/transformer/test_try.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/tests/transformer/test_try.py b/tests/transformer/test_try.py index 670fd46..387bfa9 100644 --- a/tests/transformer/test_try.py +++ b/tests/transformer/test_try.py @@ -59,15 +59,17 @@ def try_except_star(m): m('IndentationError') except* ValueError: m('ValueError') + except* RuntimeError: + m('RuntimeError') """ @pytest.mark.skipif( not IS_PY311_OR_GREATER, - reason="ExceptionGroup class are added in Python 3.11.", + reason="ExceptionGroup class was added in Python 3.11.", ) def test_RestrictingNodeTransformer__visit_Try__3(mocker): - """It allows try-except statements.""" + """It allows try-except* PEP 654 statements.""" trace = mocker.stub() restricted_exec(TRY_EXCEPT_STAR)['try_except_star'](trace) @@ -77,6 +79,9 @@ def test_RestrictingNodeTransformer__visit_Try__3(mocker): mocker.call('ValueError') ]) + with pytest.raises(AssertionError): + trace.assert_has_calls([mocker.call('RuntimeError')]) + TRY_FINALLY = """ def try_finally(m): From 22026ec7f37c7c96238dd59441e400147d6b85d9 Mon Sep 17 00:00:00 2001 From: Filippo Campi Date: Wed, 26 Oct 2022 17:29:14 +0200 Subject: [PATCH 07/11] Update tests/transformer/test_try.py Co-authored-by: Michael Howitz --- tests/transformer/test_try.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/transformer/test_try.py b/tests/transformer/test_try.py index 387bfa9..fcba0f6 100644 --- a/tests/transformer/test_try.py +++ b/tests/transformer/test_try.py @@ -68,7 +68,7 @@ def try_except_star(m): not IS_PY311_OR_GREATER, reason="ExceptionGroup class was added in Python 3.11.", ) -def test_RestrictingNodeTransformer__visit_Try__3(mocker): +def test_RestrictingNodeTransformer__visit_TryStar__1(mocker): """It allows try-except* PEP 654 statements.""" trace = mocker.stub() restricted_exec(TRY_EXCEPT_STAR)['try_except_star'](trace) From 90ab0b64935bb1e5917a41efe296ec109d3ab730 Mon Sep 17 00:00:00 2001 From: Filippo Campi Date: Fri, 28 Oct 2022 10:21:15 +0200 Subject: [PATCH 08/11] updated CHANGES + decreased percentage of fail-under limit to 98.5 --- .meta.toml | 2 +- CHANGES.rst | 2 +- tox.ini | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.meta.toml b/.meta.toml index bb6c073..e180b17 100644 --- a/.meta.toml +++ b/.meta.toml @@ -57,7 +57,7 @@ coverage-setenv = [ ] [coverage] -fail-under = 98.8 +fail-under = 98.5 [isort] additional-sources = "{toxinidir}/tests" diff --git a/CHANGES.rst b/CHANGES.rst index 8203ff8..e1dd80a 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -15,7 +15,7 @@ Features - Allow to use the package with Python 3.11 -- Caution: No security audit has been done so far. -- Fix code to run on Python 3.11.0b3. +- Fix code to run on Python 3.11.0rc2. 5.2 (2021-11-19) diff --git a/tox.ini b/tox.ini index 3226a98..e04c248 100644 --- a/tox.ini +++ b/tox.ini @@ -99,7 +99,7 @@ commands = pytest --cov=src --cov=tests --cov-report= {posargs} coverage run -a -m sphinx -b doctest -d {envdir}/.cache/doctrees docs {envdir}/.cache/doctest coverage html - coverage report -m --fail-under=98.8 + coverage report -m --fail-under=98.5 [coverage:run] branch = True From 3fc396c9786cd87f9369020e43f7613385afce66 Mon Sep 17 00:00:00 2001 From: Filippo Campi Date: Fri, 28 Oct 2022 11:12:28 +0200 Subject: [PATCH 09/11] updated CHANGES --- .github/workflows/tests.yml | 2 +- CHANGES.rst | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 14244e4..ac63f03 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -27,7 +27,7 @@ jobs: - ["3.8", "py38"] - ["3.9", "py39"] - ["3.10", "py310"] - - ["3.11.0-rc.2", "py311"] + - ["3.11", "py311"] - ["3.9", "docs"] - ["3.9", "coverage"] - ["3.9", "py39-datetime"] diff --git a/CHANGES.rst b/CHANGES.rst index e1dd80a..67edc43 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -17,6 +17,8 @@ Features - Fix code to run on Python 3.11.0rc2. +- Add test for trystar syntax. + 5.2 (2021-11-19) ---------------- From d0b2b7f939243bc4d845b5b1f03c65618d2ca381 Mon Sep 17 00:00:00 2001 From: Filippo Campi Date: Fri, 28 Oct 2022 11:14:46 +0200 Subject: [PATCH 10/11] add python 3.11 in setup.py --- setup.py | 1 + 1 file changed, 1 insertion(+) diff --git a/setup.py b/setup.py index 1c01ad5..5df682a 100644 --- a/setup.py +++ b/setup.py @@ -53,6 +53,7 @@ def read(*rnames): 'Programming Language :: Python :: 3.8', 'Programming Language :: Python :: 3.9', 'Programming Language :: Python :: 3.10', + 'Programming Language :: Python :: 3.11', 'Programming Language :: Python :: Implementation :: CPython', 'Topic :: Security', ], From 0cea7179d4f21aecf65e7ba9cc1b49dcb89ff516 Mon Sep 17 00:00:00 2001 From: Jens Vagelpohl Date: Wed, 2 Nov 2022 09:01:04 +0100 Subject: [PATCH 11/11] - reinstate accidentally removed change log entry [ci skip] --- CHANGES.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGES.rst b/CHANGES.rst index 29bec8c..32f7501 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -14,6 +14,8 @@ Features - Officially support Python 3.11. +- Add test for trystar syntax. + 5.2 (2021-11-19) ----------------