Skip to content

BUG: allow kwargs in Styler apply_index and map_index#1725

Merged
loicdiridollou merged 2 commits into
pandas-dev:mainfrom
eosti:styler-kwargs
May 26, 2026
Merged

BUG: allow kwargs in Styler apply_index and map_index#1725
loicdiridollou merged 2 commits into
pandas-dev:mainfrom
eosti:styler-kwargs

Conversation

@eosti
Copy link
Copy Markdown
Contributor

@eosti eosti commented Apr 15, 2026

Adds ability to pass a function with **kwargs to Styler apply_index and map_index. The apply and map functions already supported this.

self, series: Series, /, *args: Any, **kwargs: Any
) -> list[Any] | Series: ...

class _SeriesStrFunc(Protocol):
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I tried on my end and this protocol thing works but is a bit of overkill for what you are trying to do here. Turns out since args and kwargs here are just Any, you can drop it in exchange for:
Callable[Concatenate[Series, ...]], list[str] | np_ndarray_str | Series[str]]
This will make it a lot cleaner and simpler to understand.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I tried swapping it out for the Callable that you mentioned and it fails on mypy:

tests/test_styler.py:72: error: Argument 1 to "apply_index" of "Styler" has incompatible type "Callable[[Series[Any]], ndarray[tuple[Any, ...], dtype[str_]]]"; expected "Callable[[[Series[Any], VarArg(Any), KwArg(Any)]], list[str] | ndarray[tuple[Any, ...], dtype[str_]] | Series[str]]"  [arg-type]
tests/test_styler.py:77: error: Argument 1 to "apply_index" of "Styler" has incompatible type "Callable[[Series[Any]], Series[str]]"; expected "Callable[[[Series[Any], VarArg(Any), KwArg(Any)]], list[str] | ndarray[tuple[Any, ...], dtype[str_]] | Series[str]]"  [arg-type]
tests/test_styler.py:84: error: Argument 1 to "apply_index" of "Styler" has incompatible type "Callable[[Series[Any], str], list[str]]"; expected "Callable[[[Series[Any], VarArg(Any), KwArg(Any)]], list[str] | ndarray[tuple[Any, ...], dtype[str_]] | Series[str]]"  [arg-type]

This is a bit of a complex way of doing it, but it aligns with what is used in the other Styler functions (see #921) so I'm inclined to match that style.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Sorry made a typo above, you should pass:
Callable[Concatenate[Series, ...], list[str] | np_ndarray_str | Series[str]]
(there was a bracket misplaced).
Let me know if that works. The use of Protocol is needed if you have a / in the function definition but since here it works without we should try to go with simplicity and readability if you agree

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@Dr-Irv any guidance on which you see as the most appropriate way forward?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I ran the tests with the current version of this PR, so I think this should be acceptable. @loicdiridollou do final review.

It's possible that @eosti wasn't using mypy 2.0.0 or higher. The tests in CI were run with mypy 2.1.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Yes this works, I was just looking for a simpler solution (suggested above), compared to the Protocol class.
Eventually let's not block this one, this works well and should fix users errors.

Copy link
Copy Markdown
Member

@loicdiridollou loicdiridollou left a comment

Choose a reason for hiding this comment

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

There is an opportunity to simplify here, the tests though are looking good!

Comment thread tests/test_styler.py Outdated
check(assert_type(DF.style.apply_index(f1), Styler), Styler)

# GH 1723
def highlight_odd(index: pd.Series, /, color: str) -> list[str]:
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

No need for the /, it should work without it since it is hardly a usecase you see in production code.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The /s were added in response to #919, but I tried it out without the /s and it worked fine... So I guess something changed in the last two years; I'll remove these.

Copy link
Copy Markdown
Member

@loicdiridollou loicdiridollou left a comment

Choose a reason for hiding this comment

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

See comments

@loicdiridollou
Copy link
Copy Markdown
Member

Hey @eosti,
Do you have time to respond to the feedback soon?
Thanks!

@eosti
Copy link
Copy Markdown
Contributor Author

eosti commented May 23, 2026

Thanks for the ping, this completely slipped my mind! I'll take a look now.

Copy link
Copy Markdown
Member

@loicdiridollou loicdiridollou left a comment

Choose a reason for hiding this comment

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

Nice one @eosti, thanks for your contribution!

@loicdiridollou loicdiridollou merged commit 84e7d1a into pandas-dev:main May 26, 2026
14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Styler apply_* and map functions do not accept **kwargs

3 participants