If an on_startup handler is assigned the result of a method rather than the method itself, _main_loop will prematurely execute, any_filter_thread_present() or self._at_least_one_every will be False, and the keeper will immediately terminate before the Lifecycle instance has been fully configured.
A better behavior would be to type-check the passed parameter to ensure it is a function, raising a ValueError if something unexpected was passed.