Skip to content

Commit b41b99d

Browse files
committed
typing
1 parent 9fcaba3 commit b41b99d

File tree

1 file changed

+51
-81
lines changed

1 file changed

+51
-81
lines changed

pandas/core/col.py

Lines changed: 51 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
Any,
1010
)
1111

12+
from pandas.core.dtypes.common import is_scalar
13+
1214
from pandas.core.series import Series
1315

1416
if TYPE_CHECKING:
@@ -32,137 +34,105 @@ def __init__(self, func: Callable[[DataFrame], Any]) -> None:
3234

3335
def __call__(self, df: DataFrame) -> Series:
3436
result = self._func(df)
35-
if not isinstance(result, Series):
37+
if not (isinstance(result, Series) or is_scalar(result)):
3638
msg = (
37-
"Expected function which returns Series, "
39+
"Expected function which returns Series or scalar, "
3840
f"got function which returns: {type(result)}"
3941
)
4042
raise TypeError(msg)
4143
return result
4244

43-
# namespaces
44-
@property
45-
def dt(self) -> NamespaceExpr:
46-
return NamespaceExpr(self, "dt")
47-
48-
@property
49-
def str(self) -> NamespaceExpr:
50-
return NamespaceExpr(self, "str")
51-
52-
@property
53-
def cat(self) -> NamespaceExpr:
54-
return NamespaceExpr(self, "cat")
55-
56-
@property
57-
def list(self) -> NamespaceExpr:
58-
return NamespaceExpr(self, "list")
59-
60-
@property
61-
def sparse(self) -> NamespaceExpr:
62-
return NamespaceExpr(self, "sparse")
63-
64-
@property
65-
def struct(self) -> NamespaceExpr:
66-
return NamespaceExpr(self, "struct")
45+
def _with_binary_op(self, op: str, other: Any) -> Expr:
46+
if isinstance(other, Expr):
47+
return Expr(lambda df: getattr(self._func(df), op)(other._func(df)))
48+
return Expr(lambda df: getattr(self._func(df), op)(other))
6749

6850
# Binary ops
69-
7051
def __add__(self, other: Any) -> Expr:
71-
if isinstance(other, Expr):
72-
return Expr(lambda df: self._func(df).__add__(other._func(df)))
73-
return Expr(lambda df: self._func(df).__add__(other))
52+
return self._with_binary_op("__add__", other)
7453

7554
def __radd__(self, other: Any) -> Expr:
76-
if isinstance(other, Expr):
77-
return Expr(lambda df: self._func(df).__radd__(other._func(df)))
78-
return Expr(lambda df: self._func(df).__radd__(other))
55+
return self._with_binary_op("__radd__", other)
7956

8057
def __sub__(self, other: Any) -> Expr:
81-
if isinstance(other, Expr):
82-
return Expr(lambda df: self._func(df).__sub__(other._func(df)))
83-
return Expr(lambda df: self._func(df).__sub__(other))
58+
return self._with_binary_op("__sub__", other)
8459

8560
def __rsub__(self, other: Any) -> Expr:
86-
if isinstance(other, Expr):
87-
return Expr(lambda df: self._func(df).__rsub__(other._func(df)))
88-
return Expr(lambda df: self._func(df).__rsub__(other))
61+
return self._with_binary_op("__rsub__", other)
8962

9063
def __mul__(self, other: Any) -> Expr:
91-
if isinstance(other, Expr):
92-
return Expr(lambda df: self._func(df).__mul__(other._func(df)))
93-
return Expr(lambda df: self._func(df).__mul__(other))
64+
return self._with_binary_op("__mul__", other)
9465

9566
def __rmul__(self, other: Any) -> Expr:
96-
if isinstance(other, Expr):
97-
return Expr(lambda df: self._func(df).__rmul__(other._func(df)))
98-
return Expr(lambda df: self._func(df).__rmul__(other))
67+
return self._with_binary_op("__rmul__", other)
9968

10069
def __truediv__(self, other: Any) -> Expr:
101-
if isinstance(other, Expr):
102-
return Expr(lambda df: self._func(df).__truediv__(other._func(df)))
103-
return Expr(lambda df: self._func(df).__truediv__(other))
70+
return self._with_binary_op("__truediv__", other)
10471

10572
def __rtruediv__(self, other: Any) -> Expr:
106-
if isinstance(other, Expr):
107-
return Expr(lambda df: self._func(df).__rtruediv__(other._func(df)))
108-
return Expr(lambda df: self._func(df).__rtruediv__(other))
73+
return self._with_binary_op("__rtruediv__", other)
10974

11075
def __floordiv__(self, other: Any) -> Expr:
111-
if isinstance(other, Expr):
112-
return Expr(lambda df: self._func(df).__floordiv__(other._func(df)))
113-
return Expr(lambda df: self._func(df).__floordiv__(other))
76+
return self._with_binary_op("__floordiv__", other)
11477

11578
def __rfloordiv__(self, other: Any) -> Expr:
116-
if isinstance(other, Expr):
117-
return Expr(lambda df: self._func(df).__rfloordiv__(other._func(df)))
118-
return Expr(lambda df: self._func(df).__rfloordiv__(other))
79+
return self._with_binary_op("__rfloordiv__", other)
11980

12081
def __ge__(self, other: Any) -> Expr:
121-
if isinstance(other, Expr):
122-
return Expr(lambda df: self._func(df).__ge__(other._func(df)))
123-
return Expr(lambda df: self._func(df).__ge__(other))
82+
return self._with_binary_op("__ge__", other)
12483

12584
def __gt__(self, other: Any) -> Expr:
126-
if isinstance(other, Expr):
127-
return Expr(lambda df: self._func(df).__gt__(other._func(df)))
128-
return Expr(lambda df: self._func(df).__gt__(other))
85+
return self._with_binary_op("__gt__", other)
12986

13087
def __le__(self, other: Any) -> Expr:
131-
if isinstance(other, Expr):
132-
return Expr(lambda df: self._func(df).__le__(other._func(df)))
133-
return Expr(lambda df: self._func(df).__le__(other))
88+
return self._with_binary_op("__le__", other)
13489

13590
def __lt__(self, other: Any) -> Expr:
136-
if isinstance(other, Expr):
137-
return Expr(lambda df: self._func(df).__lt__(other._func(df)))
138-
return Expr(lambda df: self._func(df).__lt__(other))
91+
return self._with_binary_op("__lt__", other)
13992

14093
def __eq__(self, other: object) -> Expr: # type: ignore[override]
141-
if isinstance(other, Expr):
142-
return Expr(lambda df: self._func(df).__eq__(other._func(df)))
143-
return Expr(lambda df: self._func(df).__eq__(other))
94+
return self._with_binary_op("__eq__", other)
14495

14596
def __ne__(self, other: object) -> Expr: # type: ignore[override]
146-
if isinstance(other, Expr):
147-
return Expr(lambda df: self._func(df).__ne__(other._func(df)))
148-
return Expr(lambda df: self._func(df).__ne__(other))
97+
return self._with_binary_op("__ne__", other)
14998

15099
def __mod__(self, other: Any) -> Expr:
151-
if isinstance(other, Expr):
152-
return Expr(lambda df: self._func(df).__mod__(other._func(df)))
153-
return Expr(lambda df: self._func(df).__mod__(other))
100+
return self._with_binary_op("__mod__", other)
154101

155102
# Everything else
156-
157-
# Function "pandas.core.col.Expr.str" is not valid as a type
158-
def __getattr__(self, attr: str, /) -> Any: # type: ignore[valid-type]
103+
def __getattr__(self, attr: str, /) -> Callable[..., Expr]:
159104
def func(df: DataFrame, *args: Any, **kwargs: Any) -> Any:
160105
parsed_args = parse_args(df, *args)
161106
parsed_kwargs = parse_kwargs(df, **kwargs)
162107
return getattr(self(df), attr)(*parsed_args, **parsed_kwargs)
163108

164109
return lambda *args, **kwargs: Expr(lambda df: func(df, *args, **kwargs))
165110

111+
# Namespaces
112+
@property
113+
def dt(self) -> NamespaceExpr:
114+
return NamespaceExpr(self, "dt")
115+
116+
@property
117+
def str(self) -> NamespaceExpr:
118+
return NamespaceExpr(self, "str")
119+
120+
@property
121+
def cat(self) -> NamespaceExpr:
122+
return NamespaceExpr(self, "cat")
123+
124+
@property
125+
def list(self) -> NamespaceExpr:
126+
return NamespaceExpr(self, "list")
127+
128+
@property
129+
def sparse(self) -> NamespaceExpr:
130+
return NamespaceExpr(self, "sparse")
131+
132+
@property
133+
def struct(self) -> NamespaceExpr:
134+
return NamespaceExpr(self, "struct")
135+
166136

167137
class NamespaceExpr:
168138
def __init__(self, func: Callable[[DataFrame], Any], namespace: str) -> None:

0 commit comments

Comments
 (0)