Skip to content

Careful reordering when adding keyword-only params to a list that already has a variadic keyword. #17

Closed

Description

@thorwhalen

To reproduce:

from i2 import partialx

@partialx(partialx, x=2, _allow_reordering=True)
def foo(x, y, z=0):
    return x + y * z

leads to:

ValueError: wrong parameter order: variadic keyword parameter before keyword-only parameter

We don't get the problem if we use functools.partial on the external partial:

import functools

@functools.partial(partialx, x=2, _allow_reordering=True)
...

The problem is that we find ourselves in this situation:

[<Parameter "func">, <Parameter "*args">, <Parameter "**kwargs">, <Parameter "__name__=None">, <Parameter "_rm_partialize=False">, <Parameter "_allow_reordering=False">]

Hypothesis: Somewhere in the process, the parameters should probably be loosely reordered. We don't want to allow complete reordering, but just enough to allow variadics to be in their proper place (the keyword arguments before the kwargs.

┆Issue is synchronized with this Asana task by Unito

Activity

  1. thorwhalen commented on Sep 22, 2026

    @thorwhalen
    MemberAuthor

    Still reproduces on master (70125c02), same fundamental error (now raised from i2.wrapper.move_params_to_the_end -> include_exclude -> Sig.__getitem__ -> Sig.from_params, which builds a plain inspect.Signature from reordered params without re-validating/re-sorting variadic-keyword-vs-keyword-only ordering):

    ```python
    from i2 import partialx

    @partialx(partialx, x=2, _allow_reordering=True)
    def foo(x, y, z=0):
    return x + y * z

    ValueError: wrong parameter order: variadic keyword parameter before keyword-only parameter

    ```

    Root cause looks to be in i2/wrapper.py::move_params_to_the_end (calls include_exclude -> include_exclude_ingress_factory -> Ingress(inner_sig=sig, outer_sig=sig[include], ...)), where sig[include] re-orders params but doesn't guarantee the "keyword-only params before **kwargs" invariant inspect.Signature requires. Related: Sig.__getitem__/Sig.from_params also silently drops the return annotation on re-indexing (found while fixing #48, #88) -- these two are probably worth fixing together as a Sig.__getitem__ hardening pass, since several other issues touch the same code path. Leaving as a plan item; not attempting a fix here given the surface area (any change to Sig.__getitem__'s reordering affects most of the wrapper/deco module).

  2. added 3 commits that reference this issue on Sep 26, 2026
    11c8d61
    2bbe248
    d572784
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

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