@@ -254,7 +254,7 @@ def setup(self):
254254 """
255255 self .setup_logging ()
256256 self .setup_plugins ()
257- self ._scheduler . start ()
257+ self .post_setup ()
258258
259259 def setup_logging (self ):
260260 """Set up logging based on config options."""
@@ -326,6 +326,34 @@ def setup_plugins(self):
326326 else :
327327 LOGGER .warning ("Warning: Couldn't load any plugins" )
328328
329+ # post setup
330+
331+ def post_setup (self ):
332+ """Perform post-setup actions.
333+
334+ This method handles everything that should happen after all the plugins
335+ are loaded, and before the bot can connect to the IRC server.
336+
337+ At the moment, this method checks for undefined configuration options,
338+ and starts the job scheduler.
339+
340+ .. versionadded:: 7.1
341+ """
342+ settings = self .settings
343+ for section_name , section in settings .get_defined_sections ():
344+ for option_name in settings .parser .options (section_name ):
345+ if not hasattr (section , option_name ):
346+ LOGGER .warning (
347+ 'Config option `%s.%s` is not defined by its section '
348+ 'and may not be recognized by Sopel.' ,
349+ section_name ,
350+ option_name ,
351+ )
352+
353+ self ._scheduler .start ()
354+
355+ # plugins management
356+
329357 def reload_plugin (self , name ):
330358 """Reload a plugin.
331359
@@ -452,6 +480,8 @@ def get_plugin_meta(self, name):
452480
453481 return self ._plugins [name ].get_meta_description ()
454482
483+ # callable management
484+
455485 @deprecated (
456486 reason = "Replaced by specific `unregister_*` methods." ,
457487 version = '7.1' ,
@@ -609,6 +639,8 @@ def msg(self, recipient, text, max_messages=1):
609639 """
610640 self .say (text , recipient , max_messages )
611641
642+ # message dispatch
643+
612644 def call_rule (self , rule , sopel , trigger ):
613645 # rate limiting
614646 if not trigger .admin and not rule .is_unblockable ():
@@ -856,6 +888,8 @@ def _update_running_triggers(self, running_triggers):
856888 self ._running_triggers = [
857889 t for t in running_triggers if t .is_alive ()]
858890
891+ # event handlers
892+
859893 def on_scheduler_error (self , scheduler , exc ):
860894 """Called when the Job Scheduler fails.
861895
@@ -969,6 +1003,8 @@ def _shutdown(self):
9691003 # Avoid calling shutdown methods if we already have.
9701004 self .shutdown_methods = []
9711005
1006+ # URL callbacks management
1007+
9721008 def register_url_callback (self , pattern , callback ):
9731009 """Register a ``callback`` for URLs matching the regex ``pattern``.
9741010
0 commit comments