Context
_validate_single_evalcase_param walks the function's type hints at decorator time (wrapper.py:143-156), while _find_case matches on runtime values with isinstance(v, EvalCase) over all kwargs (wrapper.py:164-169).
A parameter annotated as something else (e.g. Annotated[Database, Use(db)]) whose fixture happens to return an EvalCase instance is invisible to the registration guard, but visible to _find_case — which silently picks whichever comes first in kwargs order. The carefully built loud error (MultipleEvalCaseParamsError) can thus be bypassed by the exact scenario it exists to prevent.
Impact
Edge case, but the failure is the bad kind: wrong case name/expected/inputs attributed to the eval, no error anywhere.
Suggestion
Make _find_case defensive: if more than one kwarg value is an EvalCase, raise MultipleEvalCaseParamsError at runtime too (same error, second line of defense, mirrors the registration/runtime pairing used elsewhere).
Context
_validate_single_evalcase_paramwalks the function's type hints at decorator time (wrapper.py:143-156), while_find_casematches on runtime values withisinstance(v, EvalCase)over all kwargs (wrapper.py:164-169).A parameter annotated as something else (e.g.
Annotated[Database, Use(db)]) whose fixture happens to return anEvalCaseinstance is invisible to the registration guard, but visible to_find_case— which silently picks whichever comes first in kwargs order. The carefully built loud error (MultipleEvalCaseParamsError) can thus be bypassed by the exact scenario it exists to prevent.Impact
Edge case, but the failure is the bad kind: wrong case name/expected/inputs attributed to the eval, no error anywhere.
Suggestion
Make
_find_casedefensive: if more than one kwarg value is anEvalCase, raiseMultipleEvalCaseParamsErrorat runtime too (same error, second line of defense, mirrors the registration/runtime pairing used elsewhere).