diff --git a/sopel/bot.py b/sopel/bot.py index 49ae4ffa96..0ec0a70df0 100644 --- a/sopel/bot.py +++ b/sopel/bot.py @@ -165,14 +165,19 @@ def setup(self): stderr("Warning: Couldn't load any modules") def unregister(self, obj): + if not callable(obj): + return if hasattr(obj, 'rule'): # commands and intents have it added for rule in obj.rule: - self._callables[obj.priority][rule].remove(obj) + callb_list = self._callables[obj.priority][rule] + if obj in callb_list: + callb_list.remove(obj) if hasattr(obj, 'interval'): # TODO this should somehow find the right job to remove, rather than # clearing the entire queue. Issue #831 self.scheduler.clear_jobs() - if getattr(obj, '__name__', None) == 'shutdown': + if (getattr(obj, '__name__', None) == 'shutdown' + and obj in self.shutdown_methods): self.shutdown_methods.remove(obj) def register(self, callables, jobs, shutdowns): diff --git a/sopel/loader.py b/sopel/loader.py index d1473f2fbe..4999450066 100644 --- a/sopel/loader.py +++ b/sopel/loader.py @@ -11,6 +11,9 @@ if sys.version_info.major >= 3: basestring = (str, bytes) +# Can be implementation-dependent +_regex_type = type(re.compile('')) + def get_module_description(path): good_file = (os.path.isfile(path) and path.endswith('.py') @@ -108,6 +111,10 @@ def enumerate_modules(config, show_all=False): def compile_rule(nick, pattern): + # Not sure why this happens on reloads, but it shouldn't cause problems… + if isinstance(pattern, _regex_type): + return pattern + pattern = pattern.replace('$nickname', nick) pattern = pattern.replace('$nick', r'{}[,:]\s+'.format(nick)) flags = re.IGNORECASE