From c19e39b928b3bed041a05ef4ecb2375c78f755e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sven=20M=C3=A4der?= <maeder@phys.ethz.ch> Date: Tue, 12 Mar 2024 13:46:16 +0100 Subject: [PATCH] Fix SyntaxError when compiling multiple python statements --- exec/runner/python.py | 20 +++++++++++++++++--- exec/runner/shell.py | 1 - 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/exec/runner/python.py b/exec/runner/python.py index b6b6845..cdef61a 100644 --- a/exec/runner/python.py +++ b/exec/runner/python.py @@ -14,7 +14,7 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see <https://www.gnu.org/licenses/>. from typing import Dict, Any, Optional, Tuple, AsyncGenerator, Type, NamedTuple -from types import TracebackType +from types import TracebackType, CodeType from io import IOBase, StringIO import contextlib import traceback @@ -23,7 +23,7 @@ import inspect import ast import sys -from mautrix.util.manhole import compile_async +from mautrix.util.manhole import insert_returns, ASYNC_EVAL_WRAPPER from .base import Runner, OutputType, AsyncTextOutput @@ -126,10 +126,24 @@ class PythonRunner(Runner): f"{''.join(traceback.format_list(tb))}" f"{self._format_exc(exc_info.exc)}") + def compile_async(self, tree: ast.AST) -> CodeType: + flags = 0 + if TOP_LEVEL_AWAIT: + flags += ast.PyCF_ALLOW_TOP_LEVEL_AWAIT + node_to_compile = tree + else: + insert_returns(tree.body) + wrapper_node: ast.AST = ast.parse(ASYNC_EVAL_WRAPPER, "<async eval wrapper>", "single") + method_stmt = wrapper_node.body[0] + try_stmt = method_stmt.body[0] + try_stmt.body = tree.body + node_to_compile = wrapper_node + return compile(node_to_compile, "<input>", "exec", optimize=1, flags=flags) + async def run(self, code: str, stdin: str = "", loop: Optional[asyncio.AbstractEventLoop] = None ) -> AsyncGenerator[Tuple[OutputType, Any], None]: loop = loop or asyncio.get_event_loop() - codeobj = compile_async(code) + codeobj = self.compile_async(code) namespace = {**self.namespace} if self.per_run_namespace else self.namespace if TOP_LEVEL_AWAIT: with self._redirect_io(SyncTextProxy(loop), StringIO(stdin)) as output: diff --git a/exec/runner/shell.py b/exec/runner/shell.py index 827328e..1b0aec3 100644 --- a/exec/runner/shell.py +++ b/exec/runner/shell.py @@ -91,7 +91,6 @@ class ShellRunner(Runner): waiter = asyncio.ensure_future(self._wait_proc(proc, output), loop=loop) async for part in output: yield part - print(output) yield (OutputType.RETURN, await waiter) def format_exception(self, exc_info: Any) -> Tuple[Optional[str], Optional[str]]: -- GitLab