From 2b95446dd0e7ed1081caa21d18dfeeae1912ee5e Mon Sep 17 00:00:00 2001 From: Griatch Date: Sun, 29 Sep 2024 12:34:16 +0200 Subject: [PATCH] Fix infinite loop if using `print()` in `py` cmd. Resolve #3616 --- CHANGELOG.md | 2 ++ docs/source/Coding/Changelog.md | 19 ++++++++++++++++++- docs/source/index.md | 2 +- evennia/commands/default/system.py | 23 ++++++++++++++++++++--- 4 files changed, 41 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7e8af411ac..c29dad3596 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -35,6 +35,7 @@ did not add it to the handler's object (Griatch) - [Fix][issue3612]: Make sure help entries' `subtopic_separator_char` is respected (Griatch) - [Fix][issue3624]: Setting tags with integer names caused errors on postgres (Griatch) +- [Fix][issue3615]: Using `print()` in `py` caused an infinite loop (Griatch) - [Docs][issue3591]: Fix of NPC reaction tutorial code (Griatch) - Docs: Tutorial fixes (Griatch, aMiss-aWry, feyrkh) @@ -44,6 +45,7 @@ did not add it to the handler's object (Griatch) [issue3519]: https://github.com/evennia/evennia/issues/3519 [issue3612]: https://github.com/evennia/evennia/issues/3612 [issue3624]: https://github.com/evennia/evennia/issues/3624 +[issue3615]: https://github.com/evennia/evennia/issues/3615 [pull3595]: https://github.com/evennia/evennia/pull/3595 [pull3533]: https://github.com/evennia/evennia/pull/3533 [pull3594]: https://github.com/evennia/evennia/pull/3594 diff --git a/docs/source/Coding/Changelog.md b/docs/source/Coding/Changelog.md index 53c166e008..7e8af411ac 100644 --- a/docs/source/Coding/Changelog.md +++ b/docs/source/Coding/Changelog.md @@ -8,6 +8,11 @@ with dynamic keys (rather than just relying on typeclass' key) (Griatch) - Feat: Make Sqlite3 PRAGMAs configurable via settings (Griatch) - [Feat][pull3592]: Revised German locationlization ('Du' instead of 'Sie', cleanup) (Drakon72) +- [Feat][pull3541]: Rework main Object searching to respect partial matches, empty + search now partial matching all candidates, overall cleanup (InspectorCaracal) +- [Feat][pull3588]: New `DefaultObject` hooks: `at_object_post_creation`, called once after + first creation but after any prototypes have been applied, and +`at_object_post_spawn(prototype)`, called only after creation/update with a prototype (InspectorCaracal) - [Fix][pull3494]: Update/clean some Evennia dependencies (0xDEADFED5) - [Fix][issue3556]: Better error if trying to treat ObjectDB as a typeclass (Griatch) - [Fix][issue3590]: Make `examine` command properly show `strattr` type @@ -24,13 +29,21 @@ did not add it to the handler's object (Griatch) - [Fix][pull3597]: Address timing issue for testing `new_task_waiting_input `on Windows (0xDEADFED5) - [Fix][pull3611]: Fix and update for Reports contrib (InspectorCaracal) +- [Fix][pull3625]: Lycanthropy tutorial page had some issues (feyrkh) +- [Fix][pull3622]: Fix for examine command tracebacking with strvalue error + (aMiss-aWry) +- [Fix][issue3612]: Make sure help entries' `subtopic_separator_char` is + respected (Griatch) +- [Fix][issue3624]: Setting tags with integer names caused errors on postgres (Griatch) - [Docs][issue3591]: Fix of NPC reaction tutorial code (Griatch) -- Docs: Tutorial fixes (Griatch, aMiss-aWry) +- Docs: Tutorial fixes (Griatch, aMiss-aWry, feyrkh) [issue3591]: https://github.com/evennia/evennia/issues/3591 [issue3590]: https://github.com/evennia/evennia/issues/3590 [issue3556]: https://github.com/evennia/evennia/issues/3556 [issue3519]: https://github.com/evennia/evennia/issues/3519 +[issue3612]: https://github.com/evennia/evennia/issues/3612 +[issue3624]: https://github.com/evennia/evennia/issues/3624 [pull3595]: https://github.com/evennia/evennia/pull/3595 [pull3533]: https://github.com/evennia/evennia/pull/3533 [pull3594]: https://github.com/evennia/evennia/pull/3594 @@ -39,6 +52,10 @@ did not add it to the handler's object (Griatch) [pull3605]: https://github.com/evennia/evennia/pull/3605 [pull3597]: https://github.com/evennia/evennia/pull/3597 [pull3611]: https://github.com/evennia/evennia/pull/3611 +[pull3541]: https://github.com/evennia/evennia/pull/3541 +[pull3588]: https://github.com/evennia/evennia/pull/3588 +[pull3625]: https://github.com/evennia/evennia/pull/3625 +[pull3622]: https://github.com/evennia/evennia/pull/3622 ## Evennia 4.3.0 diff --git a/docs/source/index.md b/docs/source/index.md index 9b0ef8b545..42b6c5ef1f 100644 --- a/docs/source/index.md +++ b/docs/source/index.md @@ -1,6 +1,6 @@ # Evennia Documentation -This is the manual of [Evennia](https://www.evennia.com), the open source Python `MU*` creation system. Use the Search bar on the left to find or discover interesting articles. This manual was last updated September 10, 2024, see the [Evennia Changelog](Coding/Changelog.md). Latest released Evennia version is 4.3.0. +This is the manual of [Evennia](https://www.evennia.com), the open source Python `MU*` creation system. Use the Search bar on the left to find or discover interesting articles. This manual was last updated September 29, 2024, see the [Evennia Changelog](Coding/Changelog.md). Latest released Evennia version is 4.3.0. - [Introduction](./Evennia-Introduction.md) - what is this Evennia thing? - [Evennia in Pictures](./Evennia-In-Pictures.md) - a visual overview of Evennia diff --git a/evennia/commands/default/system.py b/evennia/commands/default/system.py index d6e2466dc5..ceecfd27f3 100644 --- a/evennia/commands/default/system.py +++ b/evennia/commands/default/system.py @@ -12,10 +12,9 @@ import time import traceback import django +import evennia import twisted from django.conf import settings - -import evennia from evennia.accounts.models import AccountDB from evennia.scripts.taskhandler import TaskHandlerTask from evennia.utils import gametime, logger, search, utils @@ -48,6 +47,11 @@ __all__ = ( ) +class PrintRecursionError(RecursionError): + # custom error for recursion in print + pass + + class CmdReload(COMMAND_DEFAULT_CLASS): """ reload the server @@ -203,7 +207,14 @@ def _run_code_snippet( self.caller = caller def write(self, string): - self.caller.msg(text=(string.rstrip("\n"), {"type": "py_output"})) + try: + self.caller.msg(text=(string.rstrip("\n"), {"type": "py_output"})) + except RecursionError: + tb = traceback.extract_tb(sys.exc_info()[2]) + if any("print(" in frame.line for frame in tb): + # We are in a print loop (likely because msg() contains a print), + # exit the stdout reroute prematurely + raise PrintRecursionError fake_std = FakeStd(caller) sys.stdout = fake_std @@ -225,6 +236,12 @@ def _run_code_snippet( else: ret = eval(pycode_compiled, {}, available_vars) + except PrintRecursionError: + ret = ( + "<<< Error: Recursive print() found (probably in custom msg()). " + "Since `py` reroutes `print` to `msg()`, this causes a loop. Remove `print()` " + "from msg-related code to resolve." + ) except Exception: errlist = traceback.format_exc().split("\n") if len(errlist) > 4: