Make spawner store correct typeclass_path also for aliases. Resolve #3101

This commit is contained in:
Griatch 2023-02-26 15:24:25 +01:00
parent 798272f985
commit 30707a6b56
3 changed files with 39 additions and 5 deletions

View file

@ -2,6 +2,8 @@
## Main branch (git)
- Bug fix: Make sure spawned objects get `typeclass_path` pointing to the true
location rather than alias (in line with `create_object`).
- Bug fix: Building Menu contrib menu no using Replace over Union mergetype to
avoid clashing with in-game commands while building
- Feature: RPSystem contrib `sdesc` command can now view/delete your sdesc.

View file

@ -137,10 +137,9 @@ import copy
import hashlib
import time
import evennia
from django.conf import settings
from django.utils.translation import gettext as _
import evennia
from evennia.objects.models import ObjectDB
from evennia.prototypes import prototypes as protlib
from evennia.prototypes.prototypes import (
@ -151,7 +150,7 @@ from evennia.prototypes.prototypes import (
value_to_obj_or_any,
)
from evennia.utils import logger
from evennia.utils.utils import is_iter, make_iter
from evennia.utils.utils import class_from_module, is_iter, make_iter
_CREATE_OBJECT_KWARGS = ("key", "location", "home", "destination")
_PROTOTYPE_META_NAMES = (
@ -979,8 +978,13 @@ def spawn(*prototypes, caller=None, **kwargs):
val = prot.pop("destination", None)
create_kwargs["db_destination"] = init_spawn_value(val, value_to_obj, **init_spawn_kwargs)
# we need the 'true' path to the typeclass (not its alias), so we make sure to load the typeclass
# and use its path directly
val = prot.pop("typeclass", settings.BASE_OBJECT_TYPECLASS)
create_kwargs["db_typeclass_path"] = init_spawn_value(val, str, **init_spawn_kwargs)
typeclass = class_from_module(
init_spawn_value(val, str, **init_spawn_kwargs), settings.TYPECLASS_PATHS
)
create_kwargs["db_typeclass_path"] = f"{typeclass.__module__}.{typeclass.__name__}"
# extract calls to handlers
val = prot.pop("permissions", [])

View file

@ -10,12 +10,15 @@ from time import time
import mock
from anything import Something
from django.test.utils import override_settings
from evennia.commands.default import building
from evennia.objects.models import ObjectDB
from evennia.prototypes import menus as olc_menus
from evennia.prototypes import protfuncs as protofuncs
from evennia.prototypes import prototypes as protlib
from evennia.prototypes import spawner
from evennia.prototypes.prototypes import _PROTOTYPE_TAG_META_CATEGORY
from evennia.utils.test_resources import BaseEvenniaTest
from evennia.utils.create import create_object
from evennia.utils.test_resources import BaseEvenniaTest, EvenniaCommandTest
from evennia.utils.tests.test_evmenu import TestEvMenu
_PROTPARENTS = {
@ -1047,3 +1050,28 @@ class TestIssue2908(BaseEvenniaTest):
obj = spawner.spawn(prot, caller=self.char1)
self.assertEqual(obj[0].location, self.room1)
class TestIssue3101(EvenniaCommandTest):
"""
Spawning and using create_object should store the same `typeclass_path` if using
the same actual typeclass.
"""
def test_spawn_vs_create_paths(self):
self.call(
building.CmdSpawn(),
'{"key": "first thing", "typeclass": "evennia.DefaultObject"}',
"Spawned first thing",
)
self.call(
building.CmdCreate(),
"second thing:evennia.DefaultObject",
"You create a new DefaultObject: second thing",
)
obj1 = ObjectDB.objects.get(db_key="first thing")
obj2 = ObjectDB.objects.get(db_key="second thing")
self.assertEqual(obj1.typeclass_path, obj2.typeclass_path)