44
44
from narwhals .group_by import GroupBy
45
45
from narwhals .group_by import LazyGroupBy
46
46
from narwhals .series import Series
47
+ from narwhals .typing import IntoCompliantExpr
47
48
from narwhals .typing import IntoDataFrame
48
49
from narwhals .typing import IntoExpr
49
50
from narwhals .typing import IntoFrame
@@ -70,28 +71,29 @@ def __narwhals_namespace__(self: Self) -> Any:
70
71
def _from_compliant_dataframe (self : Self , df : Any ) -> Self :
71
72
# construct, preserving properties
72
73
return self .__class__ ( # type: ignore[call-arg]
73
- df ,
74
- level = self ._level ,
74
+ df , level = self ._level
75
75
)
76
76
77
77
def _flatten_parse_col_names_into_expr_and_extract (
78
78
self , * exprs : IntoExpr | Any , ** named_exprs : IntoExpr | Any
79
- ) -> Any :
79
+ ) -> tuple [ tuple [ IntoCompliantExpr [ Any ]], dict [ str , IntoCompliantExpr [ Any ]]] :
80
80
"""Process `args` and `kwargs`, extracting underlying objects as we go, interpreting strings as column names."""
81
81
plx = self .__narwhals_namespace__ ()
82
- exprs = tuple (
82
+ compliant_exprs = tuple (
83
83
plx .col (expr ) if isinstance (expr , str ) else self ._extract_compliant (expr )
84
84
for expr in flatten (exprs )
85
85
)
86
- named_exprs = {
86
+ compliant_named_exprs = {
87
87
key : plx .col (value )
88
88
if isinstance (value , str )
89
89
else self ._extract_compliant (value )
90
90
for key , value in named_exprs .items ()
91
91
}
92
- return exprs , named_exprs
92
+ return compliant_exprs , compliant_named_exprs
93
93
94
- def _flatten_and_extract (self : Self , * args : Any , ** kwargs : Any ) -> Any :
94
+ def _flatten_and_extract (
95
+ self : Self , * args : Any , ** kwargs : Any
96
+ ) -> tuple [tuple [IntoCompliantExpr [Any ]], dict [str , IntoCompliantExpr [Any ]]]:
95
97
"""Process `args` and `kwargs`, extracting underlying objects as we go."""
96
98
args = [self ._extract_compliant (v ) for v in flatten (args )] # type: ignore[assignment]
97
99
kwargs = {k : self ._extract_compliant (v ) for k , v in kwargs .items ()}
@@ -136,35 +138,35 @@ def columns(self: Self) -> list[str]:
136
138
def with_columns (
137
139
self : Self , * exprs : IntoExpr | Iterable [IntoExpr ], ** named_exprs : IntoExpr
138
140
) -> Self :
139
- exprs , named_exprs = self . _flatten_parse_col_names_into_expr_and_extract (
140
- * exprs , ** named_exprs
141
+ compliant_exprs , compliant_named_exprs = (
142
+ self . _flatten_parse_col_names_into_expr_and_extract ( * exprs , ** named_exprs )
141
143
)
142
144
return self ._from_compliant_dataframe (
143
- self ._compliant_frame .with_columns (* exprs , ** named_exprs ),
145
+ self ._compliant_frame .with_columns (* compliant_exprs , ** compliant_named_exprs ),
144
146
)
145
147
146
148
def select (
147
149
self : Self ,
148
150
* exprs : IntoExpr | Iterable [IntoExpr ],
149
151
** named_exprs : IntoExpr ,
150
152
) -> Self :
151
- flat_exprs = list (flatten (exprs ))
152
- if flat_exprs and all (isinstance (x , str ) for x in flat_exprs ) and not named_exprs :
153
+ exprs = tuple (flatten (exprs ))
154
+ if exprs and all (isinstance (x , str ) for x in exprs ) and not named_exprs :
153
155
# fast path!
154
156
try :
155
157
return self ._from_compliant_dataframe (
156
- self ._compliant_frame .simple_select (* flat_exprs ),
158
+ self ._compliant_frame .simple_select (* exprs ),
157
159
)
158
160
except Exception as e :
159
161
# Column not found is the only thing that can realistically be raised here.
160
162
msg = f"{ e !s} \n \n Hint: Did you mean one of these columns: { self .columns } ?"
161
163
raise ColumnNotFoundError (msg ) from e
162
164
163
- flat_exprs , named_exprs = self . _flatten_parse_col_names_into_expr_and_extract (
164
- * flat_exprs , ** named_exprs
165
+ compliant_exprs , compliant_named_exprs = (
166
+ self . _flatten_parse_col_names_into_expr_and_extract ( * exprs , ** named_exprs )
165
167
)
166
168
return self ._from_compliant_dataframe (
167
- self ._compliant_frame .select (* flat_exprs , ** named_exprs ),
169
+ self ._compliant_frame .select (* compliant_exprs , ** compliant_named_exprs ),
168
170
)
169
171
170
172
def rename (self : Self , mapping : dict [str , str ]) -> Self :
0 commit comments