Skip to content

feat(array): only consider arg position, NOT defaultness or keywardness, when binding lambdas in Array.map() and Array.filter() #11116

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

NickCrews
Copy link
Contributor

@NickCrews NickCrews commented Apr 10, 2025

I have this util function:

def is_happy(
    x: ibis.Table | ir.StructValue | None = None,
) -> ir.BooleanValue:
    if x is None:
        x = _
    return ibis.or_(
        x.mood == "HAPPY",
        x.has_eaten_ice_cream,
    )

which I want to be able to use as my_table.filter(is_happy) or my_array_of_structs.filter(is_happy). Before this PR, this fails. Now, it works.

This is a breaking change. Before, this worked: my_array.map(functools.partial(lambda x, y, idx: x + y + idx, y=2)). I don't think this should have ever worked, because this isn't a valid function to call with 2 positional arguments:

>>> import functools
>>> f = functools.partial(lambda x, y, idx: x + y + idx, y=8)
>>> f(1,2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: <lambda>() got multiple values for argument 'y'

Now, the user MUST supply a function that works as either f(x) or f(x, y) (ie 1 or 2 positional arguments)

This also makes it so that positional-only functions work. Before, def f(x, /) would fail. Now, it works.
This also makes it so that

  • func(*args) functions work. We call them as func(elem, idx).
  • func(x, *args) functions work. We call them as func(elem, idx).

Basically, the way to explain this is fairly simple, and what I wrote in the docstrings:

           	Callables will be called as `func(element)` or `func(element, idx)`
            depending on if the function accepts 1 or 2+ positional parameters.
            The `idx` argument is the **zero**-based index of each element in the array.

@github-actions github-actions bot added the tests Issues or PRs related to tests label Apr 10, 2025
@NickCrews NickCrews force-pushed the array-funcs-with-defaults branch from b782c23 to 3ca11aa Compare April 13, 2025 16:36
@NickCrews NickCrews added the breaking change Changes that introduce an API break at any level label Apr 13, 2025
@NickCrews NickCrews force-pushed the array-funcs-with-defaults branch from 3ca11aa to ac7f3f7 Compare April 13, 2025 18:49
@NickCrews NickCrews added the feature Features or general enhancements label Apr 13, 2025
@@ -710,52 +718,6 @@ def test_array_filter_with_index(con, input, output, predicate):
)


@builtin_array
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is just a duplicate test of the above test_array_filter_with_index, that's why I'm deleting it.

Copy link
Contributor

ACTION NEEDED

Ibis follows the Conventional Commits specification for release automation.

The PR title and description are used as the merge commit message.

Please update your PR title and description to match the specification.

See https://github.com/ibis-project/ibis/blob/main/.releaserc.js
for the list of acceptable prefixes, eg "feat:", "fix:", "chore:", etc.

The commitlint output is:

⧗   input: feat(array): only use argument position, NOT defaultness or kwargness, when binding lambdas in Array.map() and Array.filter()
✖   header must not be longer than 120 characters, current length is 125 [header-max-length]

✖   found 1 problems, 0 warnings
ⓘ   Get help: https://github.com/conventional-changelog/commitlint/#what-is-commitlint

…nding lambda args in Array.map() and .filter()
@NickCrews NickCrews force-pushed the array-funcs-with-defaults branch from ac7f3f7 to 55699db Compare April 13, 2025 20:13
@NickCrews NickCrews changed the title feat(array): only consider argument position, NOT defaultness, when binding lambdas in Array.map() and Array.filter() feat(array): only consider arg position, NOT defaultness or keywardness, when binding lambdas in Array.map() and Array.filter() Apr 14, 2025
@NickCrews
Copy link
Contributor Author

@cpcloud this is ready for a review whenever you get the chance! I can talk it through with you to if you want. I'd love to get this in as a breaking change in 11.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
breaking change Changes that introduce an API break at any level feature Features or general enhancements tests Issues or PRs related to tests
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant