Skip to content

KeyError in check_input after update to 0.22.0 #1887

Closed
@ypsah

Description

Describe the bug

  • I have checked that this issue has not already been reported.
  • I have confirmed this bug exists on the latest version of pandera.
  • (optional) I have confirmed this bug exists on the main branch of pandera.

Bug introduced in check_input in 0.22.0 when both positional and keyword arguments are passed to the decorated function.

Code Sample, a copy-pastable example

import pandas as pd
import pandera as pa
from pandera.typing import DataFrame


class Iris(pa.DataFrameModel):
    sepal_length: float
    sepal_width: float
    petal_length: float
    petal_width: float
    species: str


@pa.check_input(
    Iris.to_schema()
)
def do_something(
    data: DataFrame[Iris],
    *,
    progress: bool = False
):
    return ...


if __name__ == "__main__":
    do_something(
        pd.read_csv("https://raw.githubusercontent.com/mwaskom/seaborn-data/refs/heads/master/iris.csv"),
        progress=False,
    )

In 0.21.1, the code works as expected. In 0.22.0 the following exception gets raised:

Traceback (most recent call last):
  File "/tmp/tmp.qLV4KDw4CH/test.py", line 26, in <module>
    do_something(
    ~~~~~~~~~~~~^
        pd.read_csv("https://raw.githubusercontent.com/mwaskom/seaborn-data/refs/heads/master/iris.csv"),
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        progress=False,
        ^^^^^^^^^^^^^^^
    )
    ^
  File "/home/ashpy/lib/unionai-oss/pandera/pandera/decorators.py", line 268, in _wrapper
    kwargs[args_names[0]], *validate_args
    ~~~~~~^^^^^^^^^^^^^^^
KeyError: 'data'

Expected behavior

The code works just as well in 0.22.0 as it did in 0.21.1.

Additional context

I tracked the issue down to this commit: e117d2e.

My guess is that the two conditionals should be inverted: first check if there are positional arguments, then check if there are keyword args, not the other way around:

diff --git a/pandera/decorators.py b/pandera/decorators.py
index f4afee8..d166a53 100644
--- a/pandera/decorators.py
+++ b/pandera/decorators.py
@@ -258,23 +258,6 @@ def check_input(
                         pos_args[obj_getter], *validate_args
                     )
                     args = list(pos_args.values())
-            elif obj_getter is None and kwargs:
-                # get the first key in the same order specified in the
-                # function argument.
-                args_names = _get_fn_argnames(wrapped)
-
-                try:
-                    kwargs[args_names[0]] = schema.validate(
-                        kwargs[args_names[0]], *validate_args
-                    )
-                except errors.SchemaError as e:
-                    _handle_schema_error(
-                        "check_input",
-                        wrapped,
-                        schema,
-                        kwargs[args_names[0]],
-                        e,
-                    )
             elif obj_getter is None and args:
                 try:
                     _fn = (
@@ -294,6 +277,23 @@ def check_input(
                     _handle_schema_error(
                         "check_input", wrapped, schema, args[0], e
                     )
+            elif obj_getter is None and kwargs:
+                # get the first key in the same order specified in the
+                # function argument.
+                args_names = _get_fn_argnames(wrapped)
+
+                try:
+                    kwargs[args_names[0]] = schema.validate(
+                        kwargs[args_names[0]], *validate_args
+                    )
+                except errors.SchemaError as e:
+                    _handle_schema_error(
+                        "check_input",
+                        wrapped,
+                        schema,
+                        kwargs[args_names[0]],
+                        e,
+                    )
             else:
                 raise TypeError(
                     f"obj_getter is unrecognized type: {type(obj_getter)}"

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions