From bb751ad2ffc00622e3b520855f1669f0133c68cc Mon Sep 17 00:00:00 2001 From: Griatch Date: Sun, 11 Aug 2024 17:20:58 +0200 Subject: [PATCH] Adding an already instantiated Script to ScriptHandler.add didn't add it to the handler's object. --- CHANGELOG.md | 2 ++ evennia/scripts/scripthandler.py | 23 ++++++++++++++++------- evennia/scripts/tests.py | 12 ++++++++++-- 3 files changed, 28 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b04b182dab..edcb866942 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ Attribute values (Griatch) [Fix][issue3519]: `GLOBAL_SCRIPTS` container didn't list global scripts not defined explicitly to be restarted/recrated in settings.py (Griatch) +Fix: Passing an already instantiated Script to `obj.scripts.add` (`ScriptHandler.add`) +did not add it to the handler's object (Griatch) [Docs][issue3591]: Fix of NPC reaction tutorial code (Griatch) [issue3591]: https://github.com/evennia/evennia/issues/3591 diff --git a/evennia/scripts/scripthandler.py b/evennia/scripts/scripthandler.py index 2d5e1b413f..35971669bf 100644 --- a/evennia/scripts/scripthandler.py +++ b/evennia/scripts/scripthandler.py @@ -72,18 +72,27 @@ class ScriptHandler(object): Script: The newly created Script. """ - if self.obj.__dbclass__.__name__ == "AccountDB": - # we add to an Account, not an Object - script = create.create_script( - scriptclass, key=key, account=self.obj, autostart=autostart - ) - elif isinstance(scriptclass, str) or callable(scriptclass): + if isinstance(scriptclass, str) or callable(scriptclass): # a str or class to use create before adding to an Object. We wait to autostart # so we can differentiate a failing creation from a script that immediately starts/stops. - script = create.create_script(scriptclass, key=key, obj=self.obj, autostart=False) + if self.obj.__dbclass__.__name__ == "AccountDB": + # we add to an Account, not an Object + script = create.create_script( + scriptclass, key=key, account=self.obj, autostart=False + ) + else: + script = create.create_script(scriptclass, key=key, obj=self.obj, autostart=False) else: # already an instantiated class script = scriptclass + if script.db_obj and script.db_obj != self.obj: + logger.log_err( + f"Script instance {script} already belongs to " + f"another object: {script.db_obj}." + ) + return None + script.db_obj = self.obj + script.save() if not script: logger.log_err(f"Script {scriptclass} failed to be created.") diff --git a/evennia/scripts/tests.py b/evennia/scripts/tests.py index 8bf6983e21..e1277b8584 100644 --- a/evennia/scripts/tests.py +++ b/evennia/scripts/tests.py @@ -6,8 +6,6 @@ Unit tests for the scripts package from collections import defaultdict from unittest import TestCase, mock -from parameterized import parameterized - from evennia import DefaultScript from evennia.objects.objects import DefaultObject from evennia.scripts.manager import ScriptDBManager @@ -19,6 +17,7 @@ from evennia.scripts.tickerhandler import TickerHandler from evennia.utils.create import create_script from evennia.utils.dbserialize import dbserialize from evennia.utils.test_resources import BaseEvenniaTest, EvenniaTest +from parameterized import parameterized class TestScript(BaseEvenniaTest): @@ -105,6 +104,15 @@ class TestScriptHandler(BaseEvenniaTest): script = self.obj.scripts.get("interval_test") self.assertTrue(bool(script)) + def test_add_already_existing_script(self): + "Checks that Scripthandler add function adds script correctly" + + # make a new script with no obj connection + script = create_script(TestingListIntervalScript, key="interval_test2") + self.obj.scripts.add(script) + self.assertEqual([script], list(self.obj.scripts.get("interval_test2"))) + self.assertTrue(bool(self.obj.scripts.get("interval_test"))) + class TestScriptDB(TestCase): "Check the singleton/static ScriptDB object works correctly"