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) ## 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 - Bug fix: Building Menu contrib menu no using Replace over Union mergetype to
avoid clashing with in-game commands while building avoid clashing with in-game commands while building
- Feature: RPSystem contrib `sdesc` command can now view/delete your sdesc. - Feature: RPSystem contrib `sdesc` command can now view/delete your sdesc.

View file

@ -137,10 +137,9 @@ import copy
import hashlib import hashlib
import time import time
import evennia
from django.conf import settings from django.conf import settings
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
import evennia
from evennia.objects.models import ObjectDB from evennia.objects.models import ObjectDB
from evennia.prototypes import prototypes as protlib from evennia.prototypes import prototypes as protlib
from evennia.prototypes.prototypes import ( from evennia.prototypes.prototypes import (
@ -151,7 +150,7 @@ from evennia.prototypes.prototypes import (
value_to_obj_or_any, value_to_obj_or_any,
) )
from evennia.utils import logger 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") _CREATE_OBJECT_KWARGS = ("key", "location", "home", "destination")
_PROTOTYPE_META_NAMES = ( _PROTOTYPE_META_NAMES = (
@ -979,8 +978,13 @@ def spawn(*prototypes, caller=None, **kwargs):
val = prot.pop("destination", None) val = prot.pop("destination", None)
create_kwargs["db_destination"] = init_spawn_value(val, value_to_obj, **init_spawn_kwargs) 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) 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 # extract calls to handlers
val = prot.pop("permissions", []) val = prot.pop("permissions", [])

View file

@ -10,12 +10,15 @@ from time import time
import mock import mock
from anything import Something from anything import Something
from django.test.utils import override_settings 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 menus as olc_menus
from evennia.prototypes import protfuncs as protofuncs from evennia.prototypes import protfuncs as protofuncs
from evennia.prototypes import prototypes as protlib from evennia.prototypes import prototypes as protlib
from evennia.prototypes import spawner from evennia.prototypes import spawner
from evennia.prototypes.prototypes import _PROTOTYPE_TAG_META_CATEGORY 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 from evennia.utils.tests.test_evmenu import TestEvMenu
_PROTPARENTS = { _PROTPARENTS = {
@ -1047,3 +1050,28 @@ class TestIssue2908(BaseEvenniaTest):
obj = spawner.spawn(prot, caller=self.char1) obj = spawner.spawn(prot, caller=self.char1)
self.assertEqual(obj[0].location, self.room1) 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)