Repository: pandas-dev/pandas-stubs (language: python)

Issue:
Problem accessing `.loc` with tuple for MultiIndex Series
**Describe the bug**
When accessing with tuples a MultiIndex Serie, I get an `Invalid index type error`

The example code is from the offical pandas user guides:

https://pandas.pydata.org/docs/user_guide/advanced.html#advanced-indexing-with-hierarchical-index

It seems the type is simply not in the expected types, but it should by, as this is an offical way of accessing multi-index timeseries.

**To Reproduce**
Minimal runnable `pandas` example that is not properly checked by the stubs:
```
 import pandas as pd
s = pd.Series(

    [1, 2, 3, 4, 5, 6],

    index=pd.MultiIndex.from_product([["A", "B"], ["c", "d", "e"]]),

)

s.loc[[("A", "c"), ("B", "d")]]
```
using `mypy`

receiving:


```
 error: Invalid index type "list[tuple[str, str]]" for "_LocIndexerSeries[int]"; expected type "Series[bool] | ndarray[Any, dtype[bool_]] | list[bool] | Index[Any] | Sequence[float] | list[str] | slice | tuple[Index[Any] | Series[bool] | ndarray[Any, dtype[bool_]] | list[bool] | str | bytes | date | datetime | timedelta | datetime64 | timedelta64 | bool | int | float | Timestamp | Timedelta | complex | list[Any] | slice | tuple[str | bytes | date | datetime | timedelta | datetime64 | timedelta64 | bool | int | float | Timestamp | Timedelta | complex, ...], ...] | Callable[..., Any]"  [index]

```



 - OS: Windows
 - OS Version 10
 - python version 3.12
 - version of type checker 1.9.0
 - version of installed `pandas-stubs` 2.2.1.240316




Problem accessing `.loc` with tuple for MultiIndex Series
**Describe the bug**
When accessing with tuples a MultiIndex Serie, I get an `Invalid index type error`

The example code is from the offical pandas user guides:

https://pandas.pydata.org/docs/user_guide/advanced.html#advanced-indexing-with-hierarchical-index

It seems the type is simply not in the expected types, but it should by, as this is an offical way of accessing multi-index timeseries.

**To Reproduce**
Minimal runnable `pandas` example that is not properly checked by the stubs:
```
 import pandas as pd
s = pd.Series(

    [1, 2, 3, 4, 5, 6],

    index=pd.MultiIndex.from_product([["A", "B"], ["c", "d", "e"]]),

)

s.loc[[("A", "c"), ("B", "d")]]
```
using `mypy`

receiving:


```
 error: Invalid index type "list[tuple[str, str]]" for "_LocIndexerSeries[int]"; expected type "Series[bool] | ndarray[Any, dtype[bool_]] | list[bool] | Index[Any] | Sequence[float] | list[str] | slice | tuple[Index[Any] | Series[bool] | ndarray[Any, dtype[bool_]] | list[bool] | str | bytes | date | datetime | timedelta | datetime64 | timedelta64 | bool | int | float | Timestamp | Timedelta | complex | list[Any] | slice | tuple[str | bytes | date | datetime | timedelta | datetime64 | timedelta64 | bool | int | float | Timestamp | Timedelta | complex, ...], ...] | Callable[..., Any]"  [index]

```



 - OS: Windows
 - OS Version 10
 - python version 3.12
 - version of type checker 1.9.0
 - version of installed `pandas-stubs` 2.2.1.240316




Problem accessing `.loc` with tuple for MultiIndex Series
**Describe the bug**
When accessing with tuples a MultiIndex Serie, I get an `Invalid index type error`

The example code is from the offical pandas user guides:

https://pandas.pydata.org/docs/user_guide/advanced.html#advanced-indexing-with-hierarchical-index

It seems the type is simply not in the expected types, but it should by, as this is an offical way of accessing multi-index timeseries.

**To Reproduce**
Minimal runnable `pandas` example that is not properly checked by the stubs:
```
 import pandas as pd
s = pd.Series(

    [1, 2, 3, 4, 5, 6],

    index=pd.MultiIndex.from_product([["A", "B"], ["c", "d", "e"]]),

)

s.loc[[("A", "c"), ("B", "d")]]
```
using `mypy`

receiving:


```
 error: Invalid index type "list[tuple[str, str]]" for "_LocIndexerSeries[int]"; expected type "Series[bool] | ndarray[Any, dtype[bool_]] | list[bool] | Index[Any] | Sequence[float] | list[str] | slice | tuple[Index[Any] | Series[bool] | ndarray[Any, dtype[bool_]] | list[bool] | str | bytes | date | datetime | timedelta | datetime64 | timedelta64 | bool | int | float | Timestamp | Timedelta | complex | list[Any] | slice | tuple[str | bytes | date | datetime | timedelta | datetime64 | timedelta64 | bool | int | float | Timestamp | Timedelta | complex, ...], ...] | Callable[..., Any]"  [index]

```



 - OS: Windows
 - OS Version 10
 - python version 3.12
 - version of type checker 1.9.0
 - version of installed `pandas-stubs` 2.2.1.240316






Discussion / hints:
Thanks for the report.

I think that if we add `list[_IndexSliceTuple]` to:
https://github.com/pandas-dev/pandas-stubs/blob/0342d9096be0201d53179b107144501b18770d6a/pandas-stubs/core/series.pyi#L194-L201

that will fix this.  PR with tests welcome.

Thanks for the report.

I think that if we add `list[_IndexSliceTuple]` to:
https://github.com/pandas-dev/pandas-stubs/blob/0342d9096be0201d53179b107144501b18770d6a/pandas-stubs/core/series.pyi#L194-L201

that will fix this.  PR with tests welcome.

Thanks for the report.

I think that if we add `list[_IndexSliceTuple]` to:
https://github.com/pandas-dev/pandas-stubs/blob/0342d9096be0201d53179b107144501b18770d6a/pandas-stubs/core/series.pyi#L194-L201

that will fix this.  PR with tests welcome.


Fix patch:
diff --git a/pandas-stubs/core/series.pyi b/pandas-stubs/core/series.pyi
index d38b54da..6b1cf01b 100644
--- a/pandas-stubs/core/series.pyi
+++ b/pandas-stubs/core/series.pyi
@@ -198,6 +198,7 @@ class _LocIndexerSeries(_LocIndexer, Generic[S1]):
             | list[str]
             | slice
             | _IndexSliceTuple
+            | Sequence[_IndexSliceTuple]
             | Callable
         ),
         # _IndexSliceTuple is when having a tuple that includes a slice.  Could just


Test patch:
diff --git a/tests/test_series.py b/tests/test_series.py
index 8bbe0f8d..ea6110ec 100644
--- a/tests/test_series.py
+++ b/tests/test_series.py
@@ -176,6 +176,20 @@ def test_multiindex_loc() -> None:
     check(assert_type(s.loc[1, "a"], int), np.int_)
 
 
+def test_multiindex_loc_str_tuple() -> None:
+    s = pd.Series(
+        [1, 2, 3, 4, 5, 6],
+        index=pd.MultiIndex.from_product([["A", "B"], ["c", "d", "e"]]),
+        dtype=int,
+    )
+    check(assert_type(s.loc[("A", "c")], int), np.int_)
+    check(
+        assert_type(s.loc[[("A", "c"), ("B", "d")]], "pd.Series[int]"),
+        pd.Series,
+        np.int_,
+    )
+
+
 def test_types_boolean_indexing() -> None:
     s = pd.Series([0, 1, 2])
     s[s > 1]