Skip to content
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

No overload variant of "apply" of "Styler" matches argument types "Callable[[Series[int], str], list[str]]", "str", "int" #919

Closed
Suprabat opened this issue May 10, 2024 · 2 comments · Fixed by #921

Comments

@Suprabat
Copy link

Describe the bug
Following the example in pandas website, I defined a function to highlight the maximum of each row. However, mypy does not recognize the call signature.

To Reproduce

  1. Minimal working example
from typing import List

import numpy as np
import pandas as pd


def highlight_max(x: 'pd.Series[int]', color: str) -> List[str]:
    """Highlight max."""
    return [f"color: {color}" if val == x.max() else "" for val in x]


df = pd.DataFrame(np.random.randint(0, high=100, size=(10, 3)))
styler = df.style.apply(highlight_max, color='red', axis=1)
styler.to_html("output.html")
  1. I'm using mypy
  2. Show the error message received from that type checker while checking your example.
    In terminal
$ mypy --explicit-package-bases --strict .
proj.py:14: error: No overload variant of "apply" of "Styler" matches argument types "Callable[[Series[int], str], list[str]]", "str", "int"  [call-overload]
proj.py:14: note: Possible overload variants:
proj.py:14: note:     def apply(self, func: Callable[[Series[Any]], Union[list[Any], Series[Any]]], axis: Union[Literal['index', 0], Literal['columns', 1]] = ..., subset: Optional[Union[_IndexSlice, slice, tuple[slice, ...], list[Any], Index[Any]]] = ..., **kwargs: Any) -> Styler
proj.py:14: note:     def apply(self, func: Callable[[DataFrame], Union[ndarray[Any, dtype[Any]], DataFrame]], axis: None, subset: Optional[Union[_IndexSlice, slice, tuple[slice, ...], list[Any], Index[Any]]] = ..., **kwargs: Any) -> Styler
Found 1 error in 1 file (checked 1 source file)

Please complete the following information:

  • OS: Mac OS
  • OS Version 14.4.1
  • python version: Python 3.9.6
  • version of type checker: mypy 1.8.0 (compiled: yes)
  • version of installed pandas-stubs: from pip list: pandas-stubs 2.2.1.240316
@Dr-Irv
Copy link
Collaborator

Dr-Irv commented May 12, 2024

Thanks for the report. This is non-trivial to fix. We have overloads that test whether you are passing a Callable that takes a Series or DataFrame, as that pairs with the axis argument of Styler.apply(). But there really aren't signatures for callables that have keyword arguments, and the recommended way to handle that is to use Protocol. But that has issues - see microsoft/pyright#7898 because it forces the callable to have a specific name for the first argument.

I'll have to see what the typing experts have to say about this.

@Dr-Irv
Copy link
Collaborator

Dr-Irv commented May 12, 2024

I found a fix based on the response to the pyright issue I reported. However, it will require you to change the declaration of your function to be:

def highlight_max(x: 'pd.Series[int]', /, color: str) -> List[str]:
    """Highlight max."""
    return [f"color: {color}" if val == x.max() else "" for val in x]

The / in the function declaration tells the type checker that color is a keyword argument, while the first argument is positional.

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 a pull request may close this issue.

2 participants