Skip to content

wait_combine crashes with TypeError when shared kwargs don't match all sub-generators #52

Description

@Llucs

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions