mirror of
https://github.com/ansible-collections/community.general.git
synced 2024-09-14 20:13:21 +02:00
[PR #8766/c84fb557 backport][stable-9] MH deco: minor refactor (#8775)
MH deco: minor refactor (#8766)
* MH deco: minor refactor
* adjustments and improvement in test
* sanity fix
* use func.__self__
* simplify use of self
* add changelog frag
(cherry picked from commit c84fb5577b
)
Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
This commit is contained in:
parent
2f62b6bbc6
commit
0c2642aa2e
3 changed files with 41 additions and 37 deletions
3
changelogs/fragments/8766-mh-deco-improve.yml
Normal file
3
changelogs/fragments/8766-mh-deco-improve.yml
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
minor_changes:
|
||||||
|
- MH module utils - add parameter ``when`` to ``cause_changes`` decorator (https://github.com/ansible-collections/community.general/pull/8766).
|
||||||
|
- MH module utils - minor refactor in decorators (https://github.com/ansible-collections/community.general/pull/8766).
|
|
@ -13,23 +13,26 @@ from functools import wraps
|
||||||
from ansible_collections.community.general.plugins.module_utils.mh.exceptions import ModuleHelperException
|
from ansible_collections.community.general.plugins.module_utils.mh.exceptions import ModuleHelperException
|
||||||
|
|
||||||
|
|
||||||
def cause_changes(on_success=None, on_failure=None):
|
def cause_changes(on_success=None, on_failure=None, when=None):
|
||||||
|
|
||||||
def deco(func):
|
def deco(func):
|
||||||
if on_success is None and on_failure is None:
|
|
||||||
return func
|
|
||||||
|
|
||||||
@wraps(func)
|
@wraps(func)
|
||||||
def wrapper(*args, **kwargs):
|
def wrapper(self, *args, **kwargs):
|
||||||
try:
|
try:
|
||||||
self = args[0]
|
func(self, *args, **kwargs)
|
||||||
func(*args, **kwargs)
|
|
||||||
if on_success is not None:
|
if on_success is not None:
|
||||||
self.changed = on_success
|
self.changed = on_success
|
||||||
|
elif when == "success":
|
||||||
|
self.changed = True
|
||||||
except Exception:
|
except Exception:
|
||||||
if on_failure is not None:
|
if on_failure is not None:
|
||||||
self.changed = on_failure
|
self.changed = on_failure
|
||||||
|
elif when == "failure":
|
||||||
|
self.changed = True
|
||||||
raise
|
raise
|
||||||
|
finally:
|
||||||
|
if when == "always":
|
||||||
|
self.changed = True
|
||||||
|
|
||||||
return wrapper
|
return wrapper
|
||||||
|
|
||||||
|
@ -50,8 +53,6 @@ def module_fails_on_exception(func):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
func(self, *args, **kwargs)
|
func(self, *args, **kwargs)
|
||||||
except SystemExit:
|
|
||||||
raise
|
|
||||||
except ModuleHelperException as e:
|
except ModuleHelperException as e:
|
||||||
if e.update_output:
|
if e.update_output:
|
||||||
self.update_output(e.update_output)
|
self.update_output(e.update_output)
|
||||||
|
@ -73,6 +74,7 @@ def check_mode_skip(func):
|
||||||
def wrapper(self, *args, **kwargs):
|
def wrapper(self, *args, **kwargs):
|
||||||
if not self.module.check_mode:
|
if not self.module.check_mode:
|
||||||
return func(self, *args, **kwargs)
|
return func(self, *args, **kwargs)
|
||||||
|
|
||||||
return wrapper
|
return wrapper
|
||||||
|
|
||||||
|
|
||||||
|
@ -87,7 +89,7 @@ def check_mode_skip_returns(callable=None, value=None):
|
||||||
return func(self, *args, **kwargs)
|
return func(self, *args, **kwargs)
|
||||||
return wrapper_callable
|
return wrapper_callable
|
||||||
|
|
||||||
if value is not None:
|
else:
|
||||||
@wraps(func)
|
@wraps(func)
|
||||||
def wrapper_value(self, *args, **kwargs):
|
def wrapper_value(self, *args, **kwargs):
|
||||||
if self.module.check_mode:
|
if self.module.check_mode:
|
||||||
|
@ -95,7 +97,4 @@ def check_mode_skip_returns(callable=None, value=None):
|
||||||
return func(self, *args, **kwargs)
|
return func(self, *args, **kwargs)
|
||||||
return wrapper_value
|
return wrapper_value
|
||||||
|
|
||||||
if callable is None and value is None:
|
|
||||||
return check_mode_skip
|
|
||||||
|
|
||||||
return deco
|
return deco
|
||||||
|
|
|
@ -119,28 +119,22 @@ def test_variable_meta_change():
|
||||||
assert vd.has_changed('d')
|
assert vd.has_changed('d')
|
||||||
|
|
||||||
|
|
||||||
class MockMH(object):
|
CAUSE_CHG_DECO_PARAMS = ['deco_args', 'expect_exception', 'expect_changed']
|
||||||
changed = None
|
|
||||||
|
|
||||||
def _div(self, x, y):
|
|
||||||
return x / y
|
|
||||||
|
|
||||||
func_none = cause_changes()(_div)
|
|
||||||
func_onsucc = cause_changes(on_success=True)(_div)
|
|
||||||
func_onfail = cause_changes(on_failure=True)(_div)
|
|
||||||
func_onboth = cause_changes(on_success=True, on_failure=True)(_div)
|
|
||||||
|
|
||||||
|
|
||||||
CAUSE_CHG_DECO_PARAMS = ['method', 'expect_exception', 'expect_changed']
|
|
||||||
CAUSE_CHG_DECO = dict(
|
CAUSE_CHG_DECO = dict(
|
||||||
none_succ=dict(method='func_none', expect_exception=False, expect_changed=None),
|
none_succ=dict(deco_args={}, expect_exception=False, expect_changed=None),
|
||||||
none_fail=dict(method='func_none', expect_exception=True, expect_changed=None),
|
none_fail=dict(deco_args={}, expect_exception=True, expect_changed=None),
|
||||||
onsucc_succ=dict(method='func_onsucc', expect_exception=False, expect_changed=True),
|
onsucc_succ=dict(deco_args=dict(on_success=True), expect_exception=False, expect_changed=True),
|
||||||
onsucc_fail=dict(method='func_onsucc', expect_exception=True, expect_changed=None),
|
onsucc_fail=dict(deco_args=dict(on_success=True), expect_exception=True, expect_changed=None),
|
||||||
onfail_succ=dict(method='func_onfail', expect_exception=False, expect_changed=None),
|
onfail_succ=dict(deco_args=dict(on_failure=True), expect_exception=False, expect_changed=None),
|
||||||
onfail_fail=dict(method='func_onfail', expect_exception=True, expect_changed=True),
|
onfail_fail=dict(deco_args=dict(on_failure=True), expect_exception=True, expect_changed=True),
|
||||||
onboth_succ=dict(method='func_onboth', expect_exception=False, expect_changed=True),
|
onboth_succ=dict(deco_args=dict(on_success=True, on_failure=True), expect_exception=False, expect_changed=True),
|
||||||
onboth_fail=dict(method='func_onboth', expect_exception=True, expect_changed=True),
|
onboth_fail=dict(deco_args=dict(on_success=True, on_failure=True), expect_exception=True, expect_changed=True),
|
||||||
|
whensucc_succ=dict(deco_args=dict(when="success"), expect_exception=False, expect_changed=True),
|
||||||
|
whensucc_fail=dict(deco_args=dict(when="success"), expect_exception=True, expect_changed=None),
|
||||||
|
whenfail_succ=dict(deco_args=dict(when="failure"), expect_exception=False, expect_changed=None),
|
||||||
|
whenfail_fail=dict(deco_args=dict(when="failure"), expect_exception=True, expect_changed=True),
|
||||||
|
whenalways_succ=dict(deco_args=dict(when="always"), expect_exception=False, expect_changed=True),
|
||||||
|
whenalways_fail=dict(deco_args=dict(when="always"), expect_exception=True, expect_changed=True),
|
||||||
)
|
)
|
||||||
CAUSE_CHG_DECO_IDS = sorted(CAUSE_CHG_DECO.keys())
|
CAUSE_CHG_DECO_IDS = sorted(CAUSE_CHG_DECO.keys())
|
||||||
|
|
||||||
|
@ -150,12 +144,20 @@ CAUSE_CHG_DECO_IDS = sorted(CAUSE_CHG_DECO.keys())
|
||||||
for param in CAUSE_CHG_DECO_PARAMS]
|
for param in CAUSE_CHG_DECO_PARAMS]
|
||||||
for tc in CAUSE_CHG_DECO_IDS],
|
for tc in CAUSE_CHG_DECO_IDS],
|
||||||
ids=CAUSE_CHG_DECO_IDS)
|
ids=CAUSE_CHG_DECO_IDS)
|
||||||
def test_cause_changes_deco(method, expect_exception, expect_changed):
|
def test_cause_changes_deco(deco_args, expect_exception, expect_changed):
|
||||||
|
|
||||||
|
class MockMH(object):
|
||||||
|
changed = None
|
||||||
|
|
||||||
|
@cause_changes(**deco_args)
|
||||||
|
def div_(self, x, y):
|
||||||
|
return x / y
|
||||||
|
|
||||||
mh = MockMH()
|
mh = MockMH()
|
||||||
if expect_exception:
|
if expect_exception:
|
||||||
with pytest.raises(Exception):
|
with pytest.raises(Exception):
|
||||||
getattr(mh, method)(1, 0)
|
mh.div_(1, 0)
|
||||||
else:
|
else:
|
||||||
getattr(mh, method)(9, 3)
|
mh.div_(9, 3)
|
||||||
|
|
||||||
assert mh.changed == expect_changed
|
assert mh.changed == expect_changed
|
||||||
|
|
Loading…
Reference in a new issue