diff --git a/evennia/scripts/taskhandler.py b/evennia/scripts/taskhandler.py index 404e78a2fe..59cbeb12a5 100644 --- a/evennia/scripts/taskhandler.py +++ b/evennia/scripts/taskhandler.py @@ -292,14 +292,25 @@ class TaskHandler(object): if not persistent: continue + safe_callback = callback if getattr(callback, "__self__", None): # `callback` is an instance method obj = callback.__self__ name = callback.__name__ - callback = (obj, name) + safe_callback = (obj, name) # Check if callback can be pickled. args and kwargs have been checked - self.to_save[task_id] = dbserialize((date, callback, args, kwargs)) + try: + dbserialize(safe_callback) + except (TypeError, AttributeError, PickleError) as err: + raise ValueError( + "the specified callback {callback} cannot be pickled. " + "It must be a top-level function in a module or an " + "instance method ({err}).".format(callback=callback, err=err) + ) + + self.to_save[task_id] = dbserialize((date, safe_callback, args, kwargs)) + ServerConfig.objects.conf("delayed_tasks", self.to_save) def add(self, timedelay, callback, *args, **kwargs): @@ -348,17 +359,6 @@ class TaskHandler(object): safe_args = [] safe_kwargs = {} - # an unsaveable callback should immediately abort - try: - dbserialize(callback) - except (TypeError, AttributeError, PickleError) as err: - raise ValueError( - "the specified callback {callback} cannot be pickled. " - "It must be a top-level function in a module or an " - "instance method ({err}).".format(callback=callback, err=err) - ) - return - # Check that args and kwargs contain picklable information for arg in args: try: