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

Issue:
@ multiplication of Series is not inferred to a type (but Unknown)
**Describe the bug**
When multiplying two series with the `@` operator, no type is inferred and the resulting type `Unknown` will be assigned.

**To Reproduce**
```python
from typing import reveal_type

import pandas as pd

s1 = pd.Series([0, 1, 2, 3])
s2 = pd.Series([-1, 2, -3, 4])
sc2 = s1 @ s2
reveal_type(sc2) ■ Type of "sc2" is "Unknown"
```

I believe it should return a Scalar at minimum, in some cases Series but it seems like the type hinting of `@` is not in the stubs.

**Please complete the following information:**
 - OS: MacOS
 - OS Version 15.0.1
 - python version 3.13
 - version of type checker 1.13.0
 - version of installed `pandas-stubs` 2.2.3.241009


Discussion / hints:
Issue is actually that `__matmul__` method is not typehinted in `pandas-stubs/core/series.pyi`:
https://github.com/pandas-dev/pandas-stubs/blob/779aab6dd43eb7f17ffde0f5f28efbd88804a143/pandas-stubs/core/series.pyi#L801

Fix patch:
diff --git a/pandas-stubs/core/series.pyi b/pandas-stubs/core/series.pyi
index 457db8de..eb980e79 100644
--- a/pandas-stubs/core/series.pyi
+++ b/pandas-stubs/core/series.pyi
@@ -798,8 +798,18 @@ class Series(IndexOpsMixin[S1], NDFrame):
     def dot(
         self, other: ArrayLike | dict[_str, np.ndarray] | Sequence[S1] | Index[S1]
     ) -> np.ndarray: ...
-    def __matmul__(self, other): ...
-    def __rmatmul__(self, other): ...
+    @overload
+    def __matmul__(self, other: Series) -> Scalar: ...
+    @overload
+    def __matmul__(self, other: DataFrame) -> Series: ...
+    @overload
+    def __matmul__(self, other: np.ndarray) -> np.ndarray: ...
+    @overload
+    def __rmatmul__(self, other: Series) -> Scalar: ...
+    @overload
+    def __rmatmul__(self, other: DataFrame) -> Series: ...
+    @overload
+    def __rmatmul__(self, other: np.ndarray) -> np.ndarray: ...
     @overload
     def searchsorted(
         self,


Test patch:
diff --git a/tests/test_series.py b/tests/test_series.py
index 8e9b60bd..532be062 100644
--- a/tests/test_series.py
+++ b/tests/test_series.py
@@ -1236,16 +1236,17 @@ def test_types_as_type() -> None:
 
 
 def test_types_dot() -> None:
+    """Test typing of multiplication methods (dot and @) for Series."""
     s1 = pd.Series([0, 1, 2, 3])
     s2 = pd.Series([-1, 2, -3, 4])
     df1 = pd.DataFrame([[0, 1], [-2, 3], [4, -5], [6, 7]])
     n1 = np.array([[0, 1], [1, 2], [-1, -1], [2, 0]])
-    sc1: Scalar = s1.dot(s2)
-    sc2: Scalar = s1 @ s2
-    s3: pd.Series = s1.dot(df1)
-    s4: pd.Series = s1 @ df1
-    n2: np.ndarray = s1.dot(n1)
-    n3: np.ndarray = s1 @ n1
+    check(assert_type(s1.dot(s2), Scalar), np.int64)
+    check(assert_type(s1 @ s2, Scalar), np.int64)
+    check(assert_type(s1.dot(df1), "pd.Series[int]"), pd.Series, np.int64)
+    check(assert_type(s1 @ df1, pd.Series), pd.Series)
+    check(assert_type(s1.dot(n1), np.ndarray), np.ndarray)
+    check(assert_type(s1 @ n1, np.ndarray), np.ndarray)
 
 
 def test_series_loc_setitem() -> None: