Bug: wait_combine crashes with TypeError when shared kwargs don't match all sub-generators
Severity: Medium
File: _wait_gen.py:39-40 (_CombinedWait.__call__)
Version: 4.2.3 (commit cc8a399)
Description
When wait_combine (or the + operator, which also creates _CombinedWait) is used with keyword arguments passed through a decorator or retry() function, those kwargs are forwarded to every sub-generator. If a sub-generator doesn't accept a particular kwarg, it raises TypeError.
For example, _Expo.__init__ accepts base, factor, max_value but not interval. _Constant.__init__ accepts interval but not base. When used together via wait_combine with shared kwargs, one of them will reject the kwargs.
To Reproduce
import backon
from backon import wait_combine
@backon.on_exception(
wait_combine(backon.expo, backon.constant),
ValueError,
max_tries=3,
jitter=None,
base=3,
interval=0.5,
)
def fail():
raise ValueError("boom")
try:
fail()
except TypeError as e:
print(f"TYPE ERROR: {e}")
Output:
TYPE ERROR: _Expo.__init__() got an unexpected keyword argument 'interval'
(The error changes depending on which generator rejects first.)
Workaround
Pre-configure each generator separately with the + operator:
wait = backon.expo(base=3) + backon.constant(interval=0.5)
@backon.on_exception(wait, ValueError, max_tries=3, jitter=None)
def fail():
...
But note that even + will share any extra kwargs passed via **wait_gen_kwargs.
Suggested Fix
In _CombinedWait.__call__ (or _Wait.__call__), filter kwargs per sub-generator by inspecting __init__ signature, or document more clearly that wait_combine should be used with pre-configured generators.
Bug:
wait_combinecrashes withTypeErrorwhen shared kwargs don't match all sub-generatorsSeverity: Medium
File:
_wait_gen.py:39-40(_CombinedWait.__call__)Version: 4.2.3 (commit cc8a399)
Description
When
wait_combine(or the+operator, which also creates_CombinedWait) is used with keyword arguments passed through a decorator orretry()function, those kwargs are forwarded to every sub-generator. If a sub-generator doesn't accept a particular kwarg, it raisesTypeError.For example,
_Expo.__init__acceptsbase,factor,max_valuebut notinterval._Constant.__init__acceptsintervalbut notbase. When used together viawait_combinewith shared kwargs, one of them will reject the kwargs.To Reproduce
Output:
(The error changes depending on which generator rejects first.)
Workaround
Pre-configure each generator separately with the
+operator:But note that even
+will share any extra kwargs passed via**wait_gen_kwargs.Suggested Fix
In
_CombinedWait.__call__(or_Wait.__call__), filter kwargs per sub-generator by inspecting__init__signature, or document more clearly thatwait_combineshould be used with pre-configured generators.