From 541ac22a7ece4a57a996f3f51b6f5aea083cdca4 Mon Sep 17 00:00:00 2001 From: Yingzhou Li <yingzhouli0417@gmail.com> Date: Mon, 7 Feb 2022 16:09:47 +0800 Subject: [PATCH] Updated exec to be compatible with current mautrix library and python 3.8+ --- .github/workflows/main.yml | 39 ++++++++++++++++++++++++++++++ .gitlab-ci.yml | 27 --------------------- README.md | 10 ++++++++ exec/runner/python.py | 49 ++++++++++++++++++++++++++------------ maubot.yaml | 2 +- mbcbuild.sh | 1 + 6 files changed, 85 insertions(+), 43 deletions(-) create mode 100644 .github/workflows/main.yml delete mode 100644 .gitlab-ci.yml create mode 100755 mbcbuild.sh diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 0000000..738c97d --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,39 @@ +name: tag-release +on: + push: + tags: + - 'v*' + +jobs: + build: + name: tag-release + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Zip + run: | + zip -9r smartpoll.mbp polls maubot.yaml upload.py + - name: Get the version + id: get_version + run: echo ::set-output name=VERSION::${GITHUB_REF/refs\/tags\//} + - name: Create Release + id: create_release + uses: actions/create-release@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + tag_name: ${{steps.get_version.outputs.VERSION}} + release_name: Release ${{steps.get_version.outputs.VERSION}} + draft: false + prerelease: false + - name: Upload Release Asset + id: upload-release-asset + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ steps.create_release.outputs.upload_url }} + asset_path: ./smartpoll.mbp + asset_name: smartpoll-${{steps.get_version.outputs.VERSION}}.mbp + asset_content_type: application/zip diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml deleted file mode 100644 index c649b91..0000000 --- a/.gitlab-ci.yml +++ /dev/null @@ -1,27 +0,0 @@ -image: dock.mau.dev/maubot/maubot - -stages: -- build - -variables: - PYTHONPATH: /opt/maubot - -build: - stage: build - except: - - tags - script: - - python3 -m maubot.cli build -o xyz.maubot.$CI_PROJECT_NAME-$CI_COMMIT_REF_NAME-$CI_COMMIT_SHORT_SHA.mbp - artifacts: - paths: - - "*.mbp" - -build tags: - stage: build - only: - - tags - script: - - python3 -m maubot.cli build -o xyz.maubot.$CI_PROJECT_NAME-$CI_COMMIT_TAG.mbp - artifacts: - paths: - - "*.mbp" diff --git a/README.md b/README.md index ae28e49..b7dd7dc 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ # exec A [maubot](https://github.com/maubot/maubot) that executes code. +exec is updated to be compatible with python 3.8+. ## Usage The bot is triggered by a specific message prefix (defaults to `!exec`) and @@ -34,3 +35,12 @@ If running in userbot mode, the bot will edit your original message instead of making a new reply message. Currently, the bot supports `python` and `shell` as languages. + + +## Contributors + + <a href="https://github.com/YingzhouLi/exec/graphs/contributors"> + <img src="https://contrib.rocks/image?repo=YingzhouLi/exec" /> + </a> + + Made with [contrib.rocks](https://contrib.rocks). diff --git a/exec/runner/python.py b/exec/runner/python.py index 1fdf0ad..b6b6845 100644 --- a/exec/runner/python.py +++ b/exec/runner/python.py @@ -19,13 +19,15 @@ from io import IOBase, StringIO import contextlib import traceback import asyncio +import inspect import ast import sys -from mautrix.util.manhole import asyncify +from mautrix.util.manhole import compile_async from .base import Runner, OutputType, AsyncTextOutput +TOP_LEVEL_AWAIT = sys.version_info >= (3, 8) class SyncTextProxy(AsyncTextOutput): writers: Dict[OutputType, 'ProxyWriter'] @@ -116,7 +118,7 @@ class PythonRunner(Runner): line: traceback.FrameSummary for i, line in enumerate(tb): if line.filename == "<input>": - line.name = "<module>" + line.name = "<node>" tb = tb[i:] break @@ -127,17 +129,34 @@ class PythonRunner(Runner): 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 = asyncify(compile(code, "<input>", "exec", optimize=1, flags=ast.PyCF_ONLY_AST), - module="<input>") + codeobj = compile_async(code) namespace = {**self.namespace} if self.per_run_namespace else self.namespace - exec(codeobj, namespace) - with self._redirect_io(SyncTextProxy(loop), StringIO(stdin)) as output: - task = asyncio.ensure_future(self._wait_task(namespace, output), loop=loop) - async for part in output: - yield part - try: - return_value = await task - except Exception: - yield (OutputType.EXCEPTION, ExcInfo(*sys.exc_info())) - else: - yield (OutputType.RETURN, return_value) + if TOP_LEVEL_AWAIT: + with self._redirect_io(SyncTextProxy(loop), StringIO(stdin)) as output: + try: + value = eval(codeobj, namespace) + finally: + output.close() + async for part in output: + yield part + try: + if codeobj.co_flags & inspect.CO_COROUTINE: + return_value = await value + else: + return_value = value + except Exception: + yield (OutputType.EXCEPTION, ExcInfo(*sys.exc_info())) + else: + yield (OutputType.RETURN, return_value) + else: + exec(codeobj, namespace) + with self._redirect_io(SyncTextProxy(loop), StringIO(stdin)) as output: + task = asyncio.create_task(self._wait_task(namespace, output)) + async for part in output: + yield part + try: + return_value = await task + except Exception: + yield (OutputType.EXCEPTION, ExcInfo(*sys.exc_info())) + else: + yield (OutputType.RETURN, return_value) \ No newline at end of file diff --git a/maubot.yaml b/maubot.yaml index a18f155..b316d5d 100644 --- a/maubot.yaml +++ b/maubot.yaml @@ -1,6 +1,6 @@ maubot: 0.1.0 id: xyz.maubot.exec -version: 0.1.0 +version: 0.2.0 license: AGPL-3.0-or-later modules: - exec diff --git a/mbcbuild.sh b/mbcbuild.sh new file mode 100755 index 0000000..201a951 --- /dev/null +++ b/mbcbuild.sh @@ -0,0 +1 @@ +zip -9r exec-develop.mbp exec maubot.yaml base-config.yaml -- GitLab