From 3bee981cffcb1cd50192e5a9cfe3ea0910641b23 Mon Sep 17 00:00:00 2001 From: Griatch Date: Thu, 12 Nov 2020 22:28:14 +0100 Subject: [PATCH] Delay import of module-prototypes to avoid init-clash. Resolves #2232. --- evennia/__init__.py | 6 ++- evennia/prototypes/prototypes.py | 64 +++++++++++++++++--------------- 2 files changed, 40 insertions(+), 30 deletions(-) diff --git a/evennia/__init__.py b/evennia/__init__.py index 4bb82ebaf2..828bec77fe 100644 --- a/evennia/__init__.py +++ b/evennia/__init__.py @@ -392,8 +392,12 @@ def _init(): BASE_GUEST_TYPECLASS = class_from_module(settings.BASE_GUEST_TYPECLASS) del class_from_module - # delayed starts + # delayed starts - important so as to not back-access evennia before it has + # finished initializing GLOBAL_SCRIPTS.start() + from .prototypes import prototypes + prototypes.load_module_prototypes() + del prototypes def set_trace(term_size=(140, 80), debugger="auto"): diff --git a/evennia/prototypes/prototypes.py b/evennia/prototypes/prototypes.py index e2c39d5700..185b9dfc5d 100644 --- a/evennia/prototypes/prototypes.py +++ b/evennia/prototypes/prototypes.py @@ -144,35 +144,41 @@ def homogenize_prototype(prototype, custom_keys=None): # module-based prototypes -for mod in settings.PROTOTYPE_MODULES: - # to remove a default prototype, override it with an empty dict. - # internally we store as (key, desc, locks, tags, prototype_dict) - prots = [] - for variable_name, prot in all_from_module(mod).items(): - if isinstance(prot, dict): - if "prototype_key" not in prot: - prot["prototype_key"] = variable_name.lower() - prots.append((prot["prototype_key"], homogenize_prototype(prot))) - # assign module path to each prototype_key for easy reference - _MODULE_PROTOTYPE_MODULES.update({prototype_key.lower(): mod for prototype_key, _ in prots}) - # make sure the prototype contains all meta info - for prototype_key, prot in prots: - actual_prot_key = prot.get("prototype_key", prototype_key).lower() - prot.update( - { - "prototype_key": actual_prot_key, - "prototype_desc": prot["prototype_desc"] if "prototype_desc" in prot else mod, - "prototype_locks": ( - prot["prototype_locks"] - if "prototype_locks" in prot - else "use:all();edit:false()" - ), - "prototype_tags": list( - set(list(make_iter(prot.get("prototype_tags", []))) + ["module"]) - ), - } - ) - _MODULE_PROTOTYPES[actual_prot_key] = prot +def load_module_prototypes(): + """ + This is called by `evennia.__init__` as Evennia initializes. It's important + to do this late so as to not interfere with evennia initialization. + + """ + for mod in settings.PROTOTYPE_MODULES: + # to remove a default prototype, override it with an empty dict. + # internally we store as (key, desc, locks, tags, prototype_dict) + prots = [] + for variable_name, prot in all_from_module(mod).items(): + if isinstance(prot, dict): + if "prototype_key" not in prot: + prot["prototype_key"] = variable_name.lower() + prots.append((prot["prototype_key"], homogenize_prototype(prot))) + # assign module path to each prototype_key for easy reference + _MODULE_PROTOTYPE_MODULES.update({prototype_key.lower(): mod for prototype_key, _ in prots}) + # make sure the prototype contains all meta info + for prototype_key, prot in prots: + actual_prot_key = prot.get("prototype_key", prototype_key).lower() + prot.update( + { + "prototype_key": actual_prot_key, + "prototype_desc": prot["prototype_desc"] if "prototype_desc" in prot else mod, + "prototype_locks": ( + prot["prototype_locks"] + if "prototype_locks" in prot + else "use:all();edit:false()" + ), + "prototype_tags": list( + set(list(make_iter(prot.get("prototype_tags", []))) + ["module"]) + ), + } + ) + _MODULE_PROTOTYPES[actual_prot_key] = prot # Db-based prototypes