diff --git a/changelogs/fragments/remove-deprecated-default-callback-without-doc.yml b/changelogs/fragments/remove-deprecated-default-callback-without-doc.yml new file mode 100644 index 00000000000..3eb310c3c74 --- /dev/null +++ b/changelogs/fragments/remove-deprecated-default-callback-without-doc.yml @@ -0,0 +1,2 @@ +removed_features: + - "Remove deprecated functionality that allows subclassing ``DefaultCallback`` without the corresponding ``doc_fragment``." diff --git a/lib/ansible/plugins/callback/default.py b/lib/ansible/plugins/callback/default.py index ee2d798468a..b9bfc8b8c6b 100644 --- a/lib/ansible/plugins/callback/default.py +++ b/lib/ansible/plugins/callback/default.py @@ -27,22 +27,6 @@ from ansible.plugins.callback import CallbackBase from ansible.utils.color import colorize, hostcolor from ansible.utils.fqcn import add_internal_fqcns -# These values use ansible.constants for historical reasons, mostly to allow -# unmodified derivative plugins to work. However, newer options added to the -# plugin are not also added to ansible.constants, so authors of derivative -# callback plugins will eventually need to add a reference to the common docs -# fragment for the 'default' callback plugin - -# these are used to provide backwards compat with old plugins that subclass from default -# but still don't use the new config system and/or fail to document the options -# TODO: Change the default of check_mode_markers to True in a future release (2.13) -COMPAT_OPTIONS = (('display_skipped_hosts', C.DISPLAY_SKIPPED_HOSTS), - ('display_ok_hosts', True), - ('show_custom_stats', C.SHOW_CUSTOM_STATS), - ('display_failed_stderr', False), - ('check_mode_markers', False), - ('show_per_host_start', False)) - class CallbackModule(CallbackBase): @@ -63,20 +47,6 @@ class CallbackModule(CallbackBase): self._task_type_cache = {} super(CallbackModule, self).__init__() - def set_options(self, task_keys=None, var_options=None, direct=None): - - super(CallbackModule, self).set_options(task_keys=task_keys, var_options=var_options, direct=direct) - - # for backwards compat with plugins subclassing default, fallback to constants - for option, constant in COMPAT_OPTIONS: - try: - value = self.get_option(option) - except (AttributeError, KeyError): - self._display.deprecated("'%s' is subclassing DefaultCallback without the corresponding doc_fragment." % self._load_name, - version='2.14', collection_name='ansible.builtin') - value = constant - setattr(self, option, value) - def v2_runner_on_failed(self, result, ignore_errors=False): host_label = self.host_label(result) @@ -85,7 +55,7 @@ class CallbackModule(CallbackBase): if self._last_task_banner != result._task._uuid: self._print_task_banner(result._task) - self._handle_exception(result._result, use_stderr=self.display_failed_stderr) + self._handle_exception(result._result, use_stderr=self.get_option('display_failed_stderr')) self._handle_warnings(result._result) if result._task.loop and 'results' in result._result: @@ -95,7 +65,7 @@ class CallbackModule(CallbackBase): if self._display.verbosity < 2 and self.get_option('show_task_path_on_failure'): self._print_task_path(result._task) msg = "fatal: [%s]: FAILED! => %s" % (host_label, self._dump_results(result._result)) - self._display.display(msg, color=C.COLOR_ERROR, stderr=self.display_failed_stderr) + self._display.display(msg, color=C.COLOR_ERROR, stderr=self.get_option('display_failed_stderr')) if ignore_errors: self._display.display("...ignoring", color=C.COLOR_SKIP) @@ -115,7 +85,7 @@ class CallbackModule(CallbackBase): msg = "changed: [%s]" % (host_label,) color = C.COLOR_CHANGED else: - if not self.display_ok_hosts: + if not self.get_option('display_ok_hosts'): return if self._last_task_banner != result._task._uuid: @@ -137,7 +107,7 @@ class CallbackModule(CallbackBase): def v2_runner_on_skipped(self, result): - if self.display_skipped_hosts: + if self.get_option('display_skipped_hosts'): self._clean_results(result._result, result._task.action) @@ -158,7 +128,7 @@ class CallbackModule(CallbackBase): host_label = self.host_label(result) msg = "fatal: [%s]: UNREACHABLE! => %s" % (host_label, self._dump_results(result._result)) - self._display.display(msg, color=C.COLOR_UNREACHABLE, stderr=self.display_failed_stderr) + self._display.display(msg, color=C.COLOR_UNREACHABLE, stderr=self.get_option('display_failed_stderr')) def v2_playbook_on_no_hosts_matched(self): self._display.display("skipping: no hosts matched", color=C.COLOR_SKIP) @@ -186,7 +156,7 @@ class CallbackModule(CallbackBase): self._last_task_name = task.get_name().strip() # Display the task banner immediately if we're not doing any filtering based on task result - if self.display_skipped_hosts and self.display_ok_hosts: + if self.get_option('display_skipped_hosts') and self.get_option('display_ok_hosts'): self._print_task_banner(task) def _print_task_banner(self, task): @@ -210,7 +180,7 @@ class CallbackModule(CallbackBase): if task_name is None: task_name = task.get_name().strip() - if task.check_mode and self.check_mode_markers: + if task.check_mode and self.get_option('check_mode_markers'): checkmsg = " [CHECK MODE]" else: checkmsg = "" @@ -233,7 +203,7 @@ class CallbackModule(CallbackBase): def v2_playbook_on_play_start(self, play): name = play.get_name().strip() - if play.check_mode and self.check_mode_markers: + if play.check_mode and self.get_option('check_mode_markers'): checkmsg = " [CHECK MODE]" else: checkmsg = "" @@ -274,7 +244,7 @@ class CallbackModule(CallbackBase): msg = 'changed' color = C.COLOR_CHANGED else: - if not self.display_ok_hosts: + if not self.get_option('display_ok_hosts'): return if self._last_task_banner != result._task._uuid: @@ -295,18 +265,18 @@ class CallbackModule(CallbackBase): host_label = self.host_label(result) self._clean_results(result._result, result._task.action) - self._handle_exception(result._result, use_stderr=self.display_failed_stderr) + self._handle_exception(result._result, use_stderr=self.get_option('display_failed_stderr')) msg = "failed: [%s]" % (host_label,) self._handle_warnings(result._result) self._display.display( msg + " (item=%s) => %s" % (self._get_item_label(result._result), self._dump_results(result._result)), color=C.COLOR_ERROR, - stderr=self.display_failed_stderr + stderr=self.get_option('display_failed_stderr') ) def v2_runner_item_on_skipped(self, result): - if self.display_skipped_hosts: + if self.get_option('display_skipped_hosts'): if self._last_task_banner != result._task._uuid: self._print_task_banner(result._task) @@ -361,7 +331,7 @@ class CallbackModule(CallbackBase): self._display.display("", screen_only=True) # print custom stats if required - if stats.custom and self.show_custom_stats: + if stats.custom and self.get_option('show_custom_stats'): self._display.banner("CUSTOM STATS: ") # per host # TODO: come up with 'pretty format' @@ -376,7 +346,7 @@ class CallbackModule(CallbackBase): self._display.display('\tRUN: %s' % self._dump_results(stats.custom['_run'], indent=1).replace('\n', '')) self._display.display("", screen_only=True) - if context.CLIARGS['check'] and self.check_mode_markers: + if context.CLIARGS['check'] and self.get_option('check_mode_markers'): self._display.banner("DRY RUN") def v2_playbook_on_start(self, playbook): @@ -395,7 +365,7 @@ class CallbackModule(CallbackBase): if val: self._display.display('%s: %s' % (argument, val), color=C.COLOR_VERBOSE, screen_only=True) - if context.CLIARGS['check'] and self.check_mode_markers: + if context.CLIARGS['check'] and self.get_option('check_mode_markers'): self._display.banner("DRY RUN") def v2_runner_retry(self, result): diff --git a/test/sanity/ignore.txt b/test/sanity/ignore.txt index 3a75f30a32f..6129674e125 100644 --- a/test/sanity/ignore.txt +++ b/test/sanity/ignore.txt @@ -331,5 +331,4 @@ lib/ansible/module_utils/compat/_selectors2.py mypy-3.8:assignment # vendored c lib/ansible/module_utils/compat/_selectors2.py mypy-3.9:assignment # vendored code lib/ansible/module_utils/compat/_selectors2.py mypy-3.10:assignment # vendored code lib/ansible/module_utils/compat/_selectors2.py mypy-2.7:attr-defined # vendored code -lib/ansible/plugins/callback/default.py pylint:ansible-deprecated-version test/support/integration/plugins/modules/ec2.py pylint:ansible-deprecated-version