ansible-core 2.19.0b1__py3-none-any.whl → 2.19.0b3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (92) hide show
  1. ansible/_internal/_ansiballz.py +1 -4
  2. ansible/_internal/_collection_proxy.py +47 -0
  3. ansible/_internal/_errors/_handler.py +4 -4
  4. ansible/_internal/_json/__init__.py +47 -4
  5. ansible/_internal/_json/_profiles/_legacy.py +2 -3
  6. ansible/_internal/_templating/_datatag.py +3 -4
  7. ansible/_internal/_templating/_engine.py +6 -1
  8. ansible/_internal/_templating/_jinja_bits.py +4 -4
  9. ansible/_internal/_templating/_jinja_plugins.py +7 -17
  10. ansible/cli/__init__.py +12 -5
  11. ansible/cli/arguments/option_helpers.py +4 -1
  12. ansible/cli/doc.py +14 -8
  13. ansible/config/base.yml +17 -20
  14. ansible/config/manager.py +2 -2
  15. ansible/constants.py +0 -62
  16. ansible/errors/__init__.py +6 -2
  17. ansible/executor/module_common.py +11 -7
  18. ansible/executor/process/worker.py +31 -26
  19. ansible/executor/task_executor.py +38 -31
  20. ansible/executor/task_queue_manager.py +62 -52
  21. ansible/executor/task_result.py +168 -72
  22. ansible/galaxy/api.py +1 -1
  23. ansible/galaxy/collection/__init__.py +3 -3
  24. ansible/inventory/manager.py +2 -1
  25. ansible/module_utils/_internal/_ansiballz.py +4 -30
  26. ansible/module_utils/_internal/_datatag/_tags.py +3 -25
  27. ansible/module_utils/_internal/_deprecator.py +134 -0
  28. ansible/module_utils/_internal/_plugin_info.py +25 -0
  29. ansible/module_utils/_internal/_validation.py +14 -0
  30. ansible/module_utils/ansible_release.py +1 -1
  31. ansible/module_utils/basic.py +68 -23
  32. ansible/module_utils/common/arg_spec.py +8 -3
  33. ansible/module_utils/common/messages.py +40 -23
  34. ansible/module_utils/common/process.py +0 -1
  35. ansible/module_utils/common/respawn.py +0 -7
  36. ansible/module_utils/common/warnings.py +13 -13
  37. ansible/module_utils/datatag.py +13 -13
  38. ansible/modules/async_status.py +1 -1
  39. ansible/modules/dnf5.py +1 -1
  40. ansible/modules/get_url.py +1 -1
  41. ansible/parsing/utils/jsonify.py +40 -0
  42. ansible/parsing/yaml/objects.py +16 -5
  43. ansible/playbook/included_file.py +25 -12
  44. ansible/playbook/task.py +0 -2
  45. ansible/plugins/__init__.py +18 -8
  46. ansible/plugins/action/__init__.py +6 -14
  47. ansible/plugins/action/gather_facts.py +2 -4
  48. ansible/plugins/callback/__init__.py +173 -86
  49. ansible/plugins/callback/default.py +79 -79
  50. ansible/plugins/callback/junit.py +20 -19
  51. ansible/plugins/callback/minimal.py +17 -17
  52. ansible/plugins/callback/oneline.py +23 -16
  53. ansible/plugins/callback/tree.py +13 -6
  54. ansible/plugins/connection/local.py +1 -1
  55. ansible/plugins/connection/paramiko_ssh.py +9 -2
  56. ansible/plugins/doc_fragments/action_core.py +1 -1
  57. ansible/plugins/filter/core.py +12 -2
  58. ansible/plugins/inventory/__init__.py +2 -2
  59. ansible/plugins/loader.py +194 -130
  60. ansible/plugins/lookup/url.py +2 -2
  61. ansible/plugins/strategy/__init__.py +76 -82
  62. ansible/plugins/strategy/free.py +4 -4
  63. ansible/plugins/strategy/linear.py +11 -9
  64. ansible/plugins/test/core.py +1 -1
  65. ansible/release.py +1 -1
  66. ansible/template/__init__.py +8 -6
  67. ansible/utils/collection_loader/_collection_meta.py +5 -3
  68. ansible/utils/display.py +141 -79
  69. ansible/utils/py3compat.py +1 -7
  70. ansible/utils/ssh_functions.py +4 -1
  71. ansible/utils/vars.py +23 -0
  72. ansible/vars/clean.py +1 -1
  73. ansible/vars/manager.py +18 -27
  74. ansible/vars/plugins.py +4 -4
  75. {ansible_core-2.19.0b1.dist-info → ansible_core-2.19.0b3.dist-info}/METADATA +1 -1
  76. {ansible_core-2.19.0b1.dist-info → ansible_core-2.19.0b3.dist-info}/RECORD +89 -85
  77. ansible_test/_internal/commands/sanity/pylint.py +1 -0
  78. ansible_test/_internal/docker_util.py +4 -3
  79. ansible_test/_util/controller/sanity/pylint/plugins/deprecated_calls.py +475 -0
  80. ansible_test/_util/controller/sanity/pylint/plugins/deprecated_comment.py +137 -0
  81. ansible/module_utils/_internal/_dataclass_annotation_patch.py +0 -64
  82. ansible/module_utils/_internal/_plugin_exec_context.py +0 -49
  83. ansible_test/_util/controller/sanity/pylint/plugins/deprecated.py +0 -399
  84. {ansible_core-2.19.0b1.dist-info → ansible_core-2.19.0b3.dist-info}/Apache-License.txt +0 -0
  85. {ansible_core-2.19.0b1.dist-info → ansible_core-2.19.0b3.dist-info}/BSD-3-Clause.txt +0 -0
  86. {ansible_core-2.19.0b1.dist-info → ansible_core-2.19.0b3.dist-info}/COPYING +0 -0
  87. {ansible_core-2.19.0b1.dist-info → ansible_core-2.19.0b3.dist-info}/MIT-license.txt +0 -0
  88. {ansible_core-2.19.0b1.dist-info → ansible_core-2.19.0b3.dist-info}/PSF-license.txt +0 -0
  89. {ansible_core-2.19.0b1.dist-info → ansible_core-2.19.0b3.dist-info}/WHEEL +0 -0
  90. {ansible_core-2.19.0b1.dist-info → ansible_core-2.19.0b3.dist-info}/entry_points.txt +0 -0
  91. {ansible_core-2.19.0b1.dist-info → ansible_core-2.19.0b3.dist-info}/simplified_bsd.txt +0 -0
  92. {ansible_core-2.19.0b1.dist-info → ansible_core-2.19.0b3.dist-info}/top_level.txt +0 -0
@@ -24,15 +24,14 @@ import re
24
24
  import sys
25
25
  import textwrap
26
26
  import typing as t
27
+ import collections.abc as _c
27
28
 
28
29
  from typing import TYPE_CHECKING
29
30
 
30
- from collections.abc import MutableMapping
31
31
  from copy import deepcopy
32
32
 
33
33
  from ansible import constants as C
34
34
  from ansible.module_utils._internal import _datatag
35
- from ansible.module_utils.common.messages import ErrorSummary
36
35
  from ansible._internal._yaml import _dumper
37
36
  from ansible.plugins import AnsiblePlugin
38
37
  from ansible.utils.color import stringc
@@ -44,7 +43,7 @@ from ansible._internal._templating import _engine
44
43
  import yaml
45
44
 
46
45
  if TYPE_CHECKING:
47
- from ansible.executor.task_result import TaskResult
46
+ from ansible.executor.task_result import CallbackTaskResult
48
47
 
49
48
  global_display = Display()
50
49
 
@@ -59,6 +58,19 @@ _YAML_BREAK_CHARS = '\n\x85\u2028\u2029' # NL, NEL, LS, PS
59
58
  _SPACE_BREAK_RE = re.compile(fr' +([{_YAML_BREAK_CHARS}])')
60
59
 
61
60
 
61
+ _T_callable = t.TypeVar("_T_callable", bound=t.Callable)
62
+
63
+
64
+ def _callback_base_impl(wrapped: _T_callable) -> _T_callable:
65
+ """
66
+ Decorator for the no-op methods on the `CallbackBase` base class.
67
+ Used to avoid unnecessary dispatch overhead to no-op base callback methods.
68
+ """
69
+ wrapped._base_impl = True
70
+
71
+ return wrapped
72
+
73
+
62
74
  class _AnsibleCallbackDumper(_dumper.AnsibleDumper):
63
75
  def __init__(self, *args, lossy: bool = False, **kwargs):
64
76
  super().__init__(*args, **kwargs)
@@ -87,6 +99,8 @@ class _AnsibleCallbackDumper(_dumper.AnsibleDumper):
87
99
  def _register_representers(cls) -> None:
88
100
  super()._register_representers()
89
101
 
102
+ # exact type checks occur first against representers, then subclasses against multi-representers
103
+ cls.add_representer(str, cls._pretty_represent_str)
90
104
  cls.add_multi_representer(str, cls._pretty_represent_str)
91
105
 
92
106
 
@@ -140,12 +154,17 @@ class CallbackBase(AnsiblePlugin):
140
154
  custom actions.
141
155
  """
142
156
 
143
- def __init__(self, display=None, options=None):
157
+ def __init__(self, display: Display | None = None, options: dict[str, t.Any] | None = None) -> None:
158
+ super().__init__()
159
+
144
160
  if display:
145
161
  self._display = display
146
162
  else:
147
163
  self._display = global_display
148
164
 
165
+ # FUTURE: fix double-loading of non-collection stdout callback plugins that don't set CALLBACK_NEEDS_ENABLED
166
+
167
+ # FUTURE: this code is jacked for 2.x- it should just use the type names and always assume 2.0+ for normal cases
149
168
  if self._display.verbosity >= 4:
150
169
  name = getattr(self, 'CALLBACK_NAME', 'unnamed')
151
170
  ctype = getattr(self, 'CALLBACK_TYPE', 'old')
@@ -155,7 +174,8 @@ class CallbackBase(AnsiblePlugin):
155
174
  self.disabled = False
156
175
  self.wants_implicit_tasks = False
157
176
 
158
- self._plugin_options = {}
177
+ self._plugin_options: dict[str, t.Any] = {}
178
+
159
179
  if options is not None:
160
180
  self.set_options(options)
161
181
 
@@ -164,6 +184,8 @@ class CallbackBase(AnsiblePlugin):
164
184
  'ansible_loop_var', 'ansible_index_var', 'ansible_loop',
165
185
  )
166
186
 
187
+ self._current_task_result: CallbackTaskResult | None = None
188
+
167
189
  # helper for callbacks, so they don't all have to include deepcopy
168
190
  _copy_result = deepcopy
169
191
 
@@ -185,25 +207,30 @@ class CallbackBase(AnsiblePlugin):
185
207
  self._plugin_options = C.config.get_plugin_options(self.plugin_type, self._load_name, keys=task_keys, variables=var_options, direct=direct)
186
208
 
187
209
  @staticmethod
188
- def host_label(result):
189
- """Return label for the hostname (& delegated hostname) of a task
190
- result.
191
- """
192
- label = "%s" % result._host.get_name()
193
- if result._task.delegate_to and result._task.delegate_to != result._host.get_name():
210
+ def host_label(result: CallbackTaskResult) -> str:
211
+ """Return label for the hostname (& delegated hostname) of a task result."""
212
+ label = result.host.get_name()
213
+ if result.task.delegate_to and result.task.delegate_to != result.host.get_name():
194
214
  # show delegated host
195
- label += " -> %s" % result._task.delegate_to
215
+ label += " -> %s" % result.task.delegate_to
196
216
  # in case we have 'extra resolution'
197
- ahost = result._result.get('_ansible_delegated_vars', {}).get('ansible_host', result._task.delegate_to)
198
- if result._task.delegate_to != ahost:
217
+ ahost = result.result.get('_ansible_delegated_vars', {}).get('ansible_host', result.task.delegate_to)
218
+ if result.task.delegate_to != ahost:
199
219
  label += "(%s)" % ahost
200
220
  return label
201
221
 
202
- def _run_is_verbose(self, result, verbosity=0):
203
- return ((self._display.verbosity > verbosity or result._result.get('_ansible_verbose_always', False) is True)
204
- and result._result.get('_ansible_verbose_override', False) is False)
205
-
206
- def _dump_results(self, result, indent=None, sort_keys=True, keep_invocation=False, serialize=True):
222
+ def _run_is_verbose(self, result: CallbackTaskResult, verbosity: int = 0) -> bool:
223
+ return ((self._display.verbosity > verbosity or result.result.get('_ansible_verbose_always', False) is True)
224
+ and result.result.get('_ansible_verbose_override', False) is False)
225
+
226
+ def _dump_results(
227
+ self,
228
+ result: _c.Mapping[str, t.Any],
229
+ indent: int | None = None,
230
+ sort_keys: bool = True,
231
+ keep_invocation: bool = False,
232
+ serialize: bool = True,
233
+ ) -> str:
207
234
  try:
208
235
  result_format = self.get_option('result_format')
209
236
  except KeyError:
@@ -253,10 +280,12 @@ class CallbackBase(AnsiblePlugin):
253
280
  # that want to further modify the result, or use custom serialization
254
281
  return abridged_result
255
282
 
283
+ # DTFIX-RELEASE: Switch to stock json/yaml serializers here? We should always have a transformed plain-types result.
284
+
256
285
  if result_format == 'json':
257
286
  return json.dumps(abridged_result, cls=_fallback_to_str.Encoder, indent=indent, ensure_ascii=False, sort_keys=sort_keys)
258
287
 
259
- elif result_format == 'yaml':
288
+ if result_format == 'yaml':
260
289
  # None is a sentinel in this case that indicates default behavior
261
290
  # default behavior for yaml is to prettify results
262
291
  lossy = pretty_results in (None, True)
@@ -281,22 +310,28 @@ class CallbackBase(AnsiblePlugin):
281
310
  ' ' * (indent or 4)
282
311
  )
283
312
 
284
- def _handle_warnings(self, res: dict[str, t.Any]) -> None:
285
- """Display warnings and deprecation warnings sourced by task execution."""
286
- for warning in res.pop('warnings', []):
287
- # DTFIX-RELEASE: what to do about propagating wrap_text from the original display.warning call?
288
- self._display._warning(warning, wrap_text=False)
289
-
290
- for warning in res.pop('deprecations', []):
291
- self._display._deprecated(warning)
313
+ # DTFIX-RELEASE: add test to exercise this case
314
+ raise ValueError(f'Unsupported result_format {result_format!r}.')
292
315
 
293
- def _handle_exception(self, result: dict[str, t.Any], use_stderr: bool = False) -> None:
294
- error_summary: ErrorSummary | None
295
-
296
- if error_summary := result.pop('exception', None):
297
- self._display._error(error_summary, wrap_text=False, stderr=use_stderr)
298
-
299
- def _handle_warnings_and_exception(self, result: TaskResult) -> None:
316
+ def _handle_warnings(self, res: _c.MutableMapping[str, t.Any]) -> None:
317
+ """Display warnings and deprecation warnings sourced by task execution."""
318
+ if res.pop('warnings', None) and self._current_task_result and (warnings := self._current_task_result.warnings):
319
+ # display warnings from the current task result if `warnings` was not removed from `result` (or made falsey)
320
+ for warning in warnings:
321
+ # DTFIX-RELEASE: what to do about propagating wrap_text from the original display.warning call?
322
+ self._display._warning(warning, wrap_text=False)
323
+
324
+ if res.pop('deprecations', None) and self._current_task_result and (deprecations := self._current_task_result.deprecations):
325
+ # display deprecations from the current task result if `deprecations` was not removed from `result` (or made falsey)
326
+ for deprecation in deprecations:
327
+ self._display._deprecated(deprecation)
328
+
329
+ def _handle_exception(self, result: _c.MutableMapping[str, t.Any], use_stderr: bool = False) -> None:
330
+ if result.pop('exception', None) and self._current_task_result and (exception := self._current_task_result.exception):
331
+ # display exception from the current task result if `exception` was not removed from `result` (or made falsey)
332
+ self._display._error(exception, wrap_text=False, stderr=use_stderr)
333
+
334
+ def _handle_warnings_and_exception(self, result: CallbackTaskResult) -> None:
300
335
  """Standardized handling of warnings/deprecations and exceptions from a task/item result."""
301
336
  # DTFIX-RELEASE: make/doc/porting-guide a public version of this method?
302
337
  try:
@@ -304,8 +339,8 @@ class CallbackBase(AnsiblePlugin):
304
339
  except KeyError:
305
340
  use_stderr = False
306
341
 
307
- self._handle_warnings(result._result)
308
- self._handle_exception(result._result, use_stderr=use_stderr)
342
+ self._handle_warnings(result.result)
343
+ self._handle_exception(result.result, use_stderr=use_stderr)
309
344
 
310
345
  def _serialize_diff(self, diff):
311
346
  try:
@@ -322,7 +357,8 @@ class CallbackBase(AnsiblePlugin):
322
357
 
323
358
  if result_format == 'json':
324
359
  return json.dumps(diff, sort_keys=True, indent=4, separators=(u',', u': ')) + u'\n'
325
- elif result_format == 'yaml':
360
+
361
+ if result_format == 'yaml':
326
362
  # None is a sentinel in this case that indicates default behavior
327
363
  # default behavior for yaml is to prettify results
328
364
  lossy = pretty_results in (None, True)
@@ -338,6 +374,9 @@ class CallbackBase(AnsiblePlugin):
338
374
  ' '
339
375
  )
340
376
 
377
+ # DTFIX-RELEASE: add test to exercise this case
378
+ raise ValueError(f'Unsupported result_format {result_format!r}.')
379
+
341
380
  def _get_diff(self, difflist):
342
381
 
343
382
  if not isinstance(difflist, list):
@@ -356,7 +395,7 @@ class CallbackBase(AnsiblePlugin):
356
395
  if 'before' in diff and 'after' in diff:
357
396
  # format complex structures into 'files'
358
397
  for x in ['before', 'after']:
359
- if isinstance(diff[x], MutableMapping):
398
+ if isinstance(diff[x], _c.Mapping):
360
399
  diff[x] = self._serialize_diff(diff[x])
361
400
  elif diff[x] is None:
362
401
  diff[x] = ''
@@ -398,7 +437,7 @@ class CallbackBase(AnsiblePlugin):
398
437
  ret.append(diff['prepared'])
399
438
  return u''.join(ret)
400
439
 
401
- def _get_item_label(self, result):
440
+ def _get_item_label(self, result: _c.Mapping[str, t.Any]) -> t.Any:
402
441
  """ retrieves the value to be displayed as a label for an item entry from a result object"""
403
442
  if result.get('_ansible_no_log', False):
404
443
  item = "(censored due to no_log)"
@@ -406,9 +445,9 @@ class CallbackBase(AnsiblePlugin):
406
445
  item = result.get('_ansible_item_label', result.get('item'))
407
446
  return item
408
447
 
409
- def _process_items(self, result):
448
+ def _process_items(self, result: CallbackTaskResult) -> None:
410
449
  # just remove them as now they get handled by individual callbacks
411
- del result._result['results']
450
+ del result.result['results']
412
451
 
413
452
  def _clean_results(self, result, task_name):
414
453
  """ removes data from results for display """
@@ -434,74 +473,97 @@ class CallbackBase(AnsiblePlugin):
434
473
  def set_play_context(self, play_context):
435
474
  pass
436
475
 
476
+ @_callback_base_impl
437
477
  def on_any(self, *args, **kwargs):
438
478
  pass
439
479
 
480
+ @_callback_base_impl
440
481
  def runner_on_failed(self, host, res, ignore_errors=False):
441
482
  pass
442
483
 
484
+ @_callback_base_impl
443
485
  def runner_on_ok(self, host, res):
444
486
  pass
445
487
 
488
+ @_callback_base_impl
446
489
  def runner_on_skipped(self, host, item=None):
447
490
  pass
448
491
 
492
+ @_callback_base_impl
449
493
  def runner_on_unreachable(self, host, res):
450
494
  pass
451
495
 
496
+ @_callback_base_impl
452
497
  def runner_on_no_hosts(self):
453
498
  pass
454
499
 
500
+ @_callback_base_impl
455
501
  def runner_on_async_poll(self, host, res, jid, clock):
456
502
  pass
457
503
 
504
+ @_callback_base_impl
458
505
  def runner_on_async_ok(self, host, res, jid):
459
506
  pass
460
507
 
508
+ @_callback_base_impl
461
509
  def runner_on_async_failed(self, host, res, jid):
462
510
  pass
463
511
 
512
+ @_callback_base_impl
464
513
  def playbook_on_start(self):
465
514
  pass
466
515
 
516
+ @_callback_base_impl
467
517
  def playbook_on_notify(self, host, handler):
468
518
  pass
469
519
 
520
+ @_callback_base_impl
470
521
  def playbook_on_no_hosts_matched(self):
471
522
  pass
472
523
 
524
+ @_callback_base_impl
473
525
  def playbook_on_no_hosts_remaining(self):
474
526
  pass
475
527
 
528
+ @_callback_base_impl
476
529
  def playbook_on_task_start(self, name, is_conditional):
477
530
  pass
478
531
 
532
+ @_callback_base_impl
479
533
  def playbook_on_vars_prompt(self, varname, private=True, prompt=None, encrypt=None, confirm=False, salt_size=None, salt=None, default=None, unsafe=None):
480
534
  pass
481
535
 
536
+ @_callback_base_impl
482
537
  def playbook_on_setup(self):
483
538
  pass
484
539
 
540
+ @_callback_base_impl
485
541
  def playbook_on_import_for_host(self, host, imported_file):
486
542
  pass
487
543
 
544
+ @_callback_base_impl
488
545
  def playbook_on_not_import_for_host(self, host, missing_file):
489
546
  pass
490
547
 
548
+ @_callback_base_impl
491
549
  def playbook_on_play_start(self, name):
492
550
  pass
493
551
 
552
+ @_callback_base_impl
494
553
  def playbook_on_stats(self, stats):
495
554
  pass
496
555
 
556
+ @_callback_base_impl
497
557
  def on_file_diff(self, host, diff):
498
558
  pass
499
559
 
500
560
  # V2 METHODS, by default they call v1 counterparts if possible
561
+ @_callback_base_impl
501
562
  def v2_on_any(self, *args, **kwargs):
502
563
  self.on_any(args, kwargs)
503
564
 
504
- def v2_runner_on_failed(self, result: TaskResult, ignore_errors: bool = False) -> None:
565
+ @_callback_base_impl
566
+ def v2_runner_on_failed(self, result: CallbackTaskResult, ignore_errors: bool = False) -> None:
505
567
  """Process results of a failed task.
506
568
 
507
569
  Note: The value of 'ignore_errors' tells Ansible whether to
@@ -512,7 +574,7 @@ class CallbackBase(AnsiblePlugin):
512
574
  issues (for example, missing packages), or syntax errors.
513
575
 
514
576
  :param result: The parameters of the task and its results.
515
- :type result: TaskResult
577
+ :type result: CallbackTaskResult
516
578
  :param ignore_errors: Whether Ansible should continue \
517
579
  running tasks on the host where the task failed.
518
580
  :type ignore_errors: bool
@@ -520,147 +582,172 @@ class CallbackBase(AnsiblePlugin):
520
582
  :return: None
521
583
  :rtype: None
522
584
  """
523
- host = result._host.get_name()
524
- self.runner_on_failed(host, result._result, ignore_errors)
585
+ host = result.host.get_name()
586
+ self.runner_on_failed(host, result.result, ignore_errors)
525
587
 
526
- def v2_runner_on_ok(self, result: TaskResult) -> None:
588
+ @_callback_base_impl
589
+ def v2_runner_on_ok(self, result: CallbackTaskResult) -> None:
527
590
  """Process results of a successful task.
528
591
 
529
592
  :param result: The parameters of the task and its results.
530
- :type result: TaskResult
593
+ :type result: CallbackTaskResult
531
594
 
532
595
  :return: None
533
596
  :rtype: None
534
597
  """
535
- host = result._host.get_name()
536
- self.runner_on_ok(host, result._result)
598
+ host = result.host.get_name()
599
+ self.runner_on_ok(host, result.result)
537
600
 
538
- def v2_runner_on_skipped(self, result: TaskResult) -> None:
601
+ @_callback_base_impl
602
+ def v2_runner_on_skipped(self, result: CallbackTaskResult) -> None:
539
603
  """Process results of a skipped task.
540
604
 
541
605
  :param result: The parameters of the task and its results.
542
- :type result: TaskResult
606
+ :type result: CallbackTaskResult
543
607
 
544
608
  :return: None
545
609
  :rtype: None
546
610
  """
547
611
  if C.DISPLAY_SKIPPED_HOSTS:
548
- host = result._host.get_name()
549
- self.runner_on_skipped(host, self._get_item_label(getattr(result._result, 'results', {})))
612
+ host = result.host.get_name()
613
+ self.runner_on_skipped(host, self._get_item_label(getattr(result.result, 'results', {})))
550
614
 
551
- def v2_runner_on_unreachable(self, result: TaskResult) -> None:
615
+ @_callback_base_impl
616
+ def v2_runner_on_unreachable(self, result: CallbackTaskResult) -> None:
552
617
  """Process results of a task if a target node is unreachable.
553
618
 
554
619
  :param result: The parameters of the task and its results.
555
- :type result: TaskResult
620
+ :type result: CallbackTaskResult
556
621
 
557
622
  :return: None
558
623
  :rtype: None
559
624
  """
560
- host = result._host.get_name()
561
- self.runner_on_unreachable(host, result._result)
625
+ host = result.host.get_name()
626
+ self.runner_on_unreachable(host, result.result)
562
627
 
563
- def v2_runner_on_async_poll(self, result: TaskResult) -> None:
628
+ @_callback_base_impl
629
+ def v2_runner_on_async_poll(self, result: CallbackTaskResult) -> None:
564
630
  """Get details about an unfinished task running in async mode.
565
631
 
566
632
  Note: The value of the `poll` keyword in the task determines
567
633
  the interval at which polling occurs and this method is run.
568
634
 
569
635
  :param result: The parameters of the task and its status.
570
- :type result: TaskResult
636
+ :type result: CallbackTaskResult
571
637
 
572
638
  :rtype: None
573
639
  :rtype: None
574
640
  """
575
- host = result._host.get_name()
576
- jid = result._result.get('ansible_job_id')
641
+ host = result.host.get_name()
642
+ jid = result.result.get('ansible_job_id')
577
643
  # FIXME, get real clock
578
644
  clock = 0
579
- self.runner_on_async_poll(host, result._result, jid, clock)
645
+ self.runner_on_async_poll(host, result.result, jid, clock)
580
646
 
581
- def v2_runner_on_async_ok(self, result: TaskResult) -> None:
647
+ @_callback_base_impl
648
+ def v2_runner_on_async_ok(self, result: CallbackTaskResult) -> None:
582
649
  """Process results of a successful task that ran in async mode.
583
650
 
584
651
  :param result: The parameters of the task and its results.
585
- :type result: TaskResult
652
+ :type result: CallbackTaskResult
586
653
 
587
654
  :return: None
588
655
  :rtype: None
589
656
  """
590
- host = result._host.get_name()
591
- jid = result._result.get('ansible_job_id')
592
- self.runner_on_async_ok(host, result._result, jid)
657
+ host = result.host.get_name()
658
+ jid = result.result.get('ansible_job_id')
659
+ self.runner_on_async_ok(host, result.result, jid)
593
660
 
594
- def v2_runner_on_async_failed(self, result):
595
- host = result._host.get_name()
661
+ @_callback_base_impl
662
+ def v2_runner_on_async_failed(self, result: CallbackTaskResult) -> None:
663
+ host = result.host.get_name()
596
664
  # Attempt to get the async job ID. If the job does not finish before the
597
665
  # async timeout value, the ID may be within the unparsed 'async_result' dict.
598
- jid = result._result.get('ansible_job_id')
599
- if not jid and 'async_result' in result._result:
600
- jid = result._result['async_result'].get('ansible_job_id')
601
- self.runner_on_async_failed(host, result._result, jid)
666
+ jid = result.result.get('ansible_job_id')
667
+ if not jid and 'async_result' in result.result:
668
+ jid = result.result['async_result'].get('ansible_job_id')
669
+ self.runner_on_async_failed(host, result.result, jid)
602
670
 
671
+ @_callback_base_impl
603
672
  def v2_playbook_on_start(self, playbook):
604
673
  self.playbook_on_start()
605
674
 
675
+ @_callback_base_impl
606
676
  def v2_playbook_on_notify(self, handler, host):
607
677
  self.playbook_on_notify(host, handler)
608
678
 
679
+ @_callback_base_impl
609
680
  def v2_playbook_on_no_hosts_matched(self):
610
681
  self.playbook_on_no_hosts_matched()
611
682
 
683
+ @_callback_base_impl
612
684
  def v2_playbook_on_no_hosts_remaining(self):
613
685
  self.playbook_on_no_hosts_remaining()
614
686
 
687
+ @_callback_base_impl
615
688
  def v2_playbook_on_task_start(self, task, is_conditional):
616
689
  self.playbook_on_task_start(task.name, is_conditional)
617
690
 
618
691
  # FIXME: not called
692
+ @_callback_base_impl
619
693
  def v2_playbook_on_cleanup_task_start(self, task):
620
694
  pass # no v1 correspondence
621
695
 
696
+ @_callback_base_impl
622
697
  def v2_playbook_on_handler_task_start(self, task):
623
698
  pass # no v1 correspondence
624
699
 
700
+ @_callback_base_impl
625
701
  def v2_playbook_on_vars_prompt(self, varname, private=True, prompt=None, encrypt=None, confirm=False, salt_size=None, salt=None, default=None, unsafe=None):
626
702
  self.playbook_on_vars_prompt(varname, private, prompt, encrypt, confirm, salt_size, salt, default, unsafe)
627
703
 
628
704
  # FIXME: not called
629
- def v2_playbook_on_import_for_host(self, result, imported_file):
630
- host = result._host.get_name()
705
+ @_callback_base_impl
706
+ def v2_playbook_on_import_for_host(self, result: CallbackTaskResult, imported_file) -> None:
707
+ host = result.host.get_name()
631
708
  self.playbook_on_import_for_host(host, imported_file)
632
709
 
633
710
  # FIXME: not called
634
- def v2_playbook_on_not_import_for_host(self, result, missing_file):
635
- host = result._host.get_name()
711
+ @_callback_base_impl
712
+ def v2_playbook_on_not_import_for_host(self, result: CallbackTaskResult, missing_file) -> None:
713
+ host = result.host.get_name()
636
714
  self.playbook_on_not_import_for_host(host, missing_file)
637
715
 
716
+ @_callback_base_impl
638
717
  def v2_playbook_on_play_start(self, play):
639
718
  self.playbook_on_play_start(play.name)
640
719
 
720
+ @_callback_base_impl
641
721
  def v2_playbook_on_stats(self, stats):
642
722
  self.playbook_on_stats(stats)
643
723
 
644
- def v2_on_file_diff(self, result):
645
- if 'diff' in result._result:
646
- host = result._host.get_name()
647
- self.on_file_diff(host, result._result['diff'])
724
+ @_callback_base_impl
725
+ def v2_on_file_diff(self, result: CallbackTaskResult) -> None:
726
+ if 'diff' in result.result:
727
+ host = result.host.get_name()
728
+ self.on_file_diff(host, result.result['diff'])
648
729
 
730
+ @_callback_base_impl
649
731
  def v2_playbook_on_include(self, included_file):
650
732
  pass # no v1 correspondence
651
733
 
652
- def v2_runner_item_on_ok(self, result: TaskResult) -> None:
734
+ @_callback_base_impl
735
+ def v2_runner_item_on_ok(self, result: CallbackTaskResult) -> None:
653
736
  pass
654
737
 
655
- def v2_runner_item_on_failed(self, result: TaskResult) -> None:
738
+ @_callback_base_impl
739
+ def v2_runner_item_on_failed(self, result: CallbackTaskResult) -> None:
656
740
  pass
657
741
 
658
- def v2_runner_item_on_skipped(self, result: TaskResult) -> None:
742
+ @_callback_base_impl
743
+ def v2_runner_item_on_skipped(self, result: CallbackTaskResult) -> None:
659
744
  pass
660
745
 
661
- def v2_runner_retry(self, result):
746
+ @_callback_base_impl
747
+ def v2_runner_retry(self, result: CallbackTaskResult) -> None:
662
748
  pass
663
749
 
750
+ @_callback_base_impl
664
751
  def v2_runner_on_start(self, host, task):
665
752
  """Event used when host begins execution of a task
666
753