99 Any ,
1010)
1111
12+ from pandas .core .dtypes .common import is_scalar
13+
1214from pandas .core .series import Series
1315
1416if 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
167137class NamespaceExpr :
168138 def __init__ (self , func : Callable [[DataFrame ], Any ], namespace : str ) -> None :
0 commit comments