1414from narwhals ._plan .window import Over
1515from narwhals .dtypes import DType
1616from narwhals .utils import Version
17+ from narwhals .utils import _hasattr_static
1718from narwhals .utils import flatten
1819
1920if TYPE_CHECKING :
2930# Entirely ignoring namespace + function binding
3031class DummyExpr :
3132 _ir : ExprIR
33+ _version : t .ClassVar [Version ] = Version .MAIN
3234
3335 def __repr__ (self ) -> str :
34- return f"Narwhals DummyExpr:\n { self ._ir !r} "
36+ return f"Narwhals DummyExpr ( { self . version . name . lower () } ) :\n { self ._ir !r} "
3537
3638 @classmethod
3739 def _from_ir (cls , ir : ExprIR , / ) -> Self :
3840 obj = cls .__new__ (cls )
3941 obj ._ir = ir
4042 return obj
4143
44+ @property
45+ def version (self ) -> Version :
46+ return self ._version
47+
4248 def alias (self , name : str ) -> Self :
4349 return self ._from_ir (expr .Alias (expr = self ._ir , name = name ))
4450
4551 def cast (self , dtype : DType | type [DType ]) -> Self :
46- dtype = dtype if isinstance (dtype , DType ) else Version . MAIN .dtypes .Unknown ()
52+ dtype = dtype if isinstance (dtype , DType ) else self . version .dtypes .Unknown ()
4753 return self ._from_ir (expr .Cast (expr = self ._ir , dtype = dtype ))
4854
4955 def count (self ) -> Self :
@@ -92,7 +98,7 @@ def over(
9298 order_by : DummyExpr | t .Iterable [DummyExpr ] | None = None ,
9399 descending : bool = False ,
94100 nulls_last : bool = False ,
95- ) -> DummyExpr :
101+ ) -> Self :
96102 order : tuple [Seq [ExprIR ], SortOptions ] | None = None
97103 partition = tuple (expr ._ir for expr in flatten (partition_by ))
98104 if not (partition ) and order_by is None :
@@ -102,7 +108,7 @@ def over(
102108 by = tuple (expr ._ir for expr in flatten ([order_by ]))
103109 options = SortOptions (descending = descending , nulls_last = nulls_last )
104110 order = by , options
105- return Over ().to_window_expr (self ._ir , partition , order ). to_narwhals ( )
111+ return self . _from_ir ( Over ().to_window_expr (self ._ir , partition , order ))
106112
107113 def sort_by (
108114 self ,
@@ -121,78 +127,98 @@ def sort_by(
121127 options = SortMultipleOptions (descending = desc , nulls_last = nulls )
122128 return self ._from_ir (expr .SortBy (expr = self ._ir , by = sort_by , options = options ))
123129
124- def __eq__ (self , other : DummyExpr ) -> DummyExpr : # type: ignore[override]
130+ def __eq__ (self , other : DummyExpr ) -> Self : # type: ignore[override]
125131 op = ops .Eq ()
126- return op .to_binary_expr (self ._ir , other ._ir ). to_narwhals ( )
132+ return self . _from_ir ( op .to_binary_expr (self ._ir , other ._ir ))
127133
128- def __ne__ (self , other : DummyExpr ) -> DummyExpr : # type: ignore[override]
134+ def __ne__ (self , other : DummyExpr ) -> Self : # type: ignore[override]
129135 op = ops .NotEq ()
130- return op .to_binary_expr (self ._ir , other ._ir ). to_narwhals ( )
136+ return self . _from_ir ( op .to_binary_expr (self ._ir , other ._ir ))
131137
132- def __lt__ (self , other : DummyExpr ) -> DummyExpr :
138+ def __lt__ (self , other : DummyExpr ) -> Self :
133139 op = ops .Lt ()
134- return op .to_binary_expr (self ._ir , other ._ir ). to_narwhals ( )
140+ return self . _from_ir ( op .to_binary_expr (self ._ir , other ._ir ))
135141
136- def __le__ (self , other : DummyExpr ) -> DummyExpr :
142+ def __le__ (self , other : DummyExpr ) -> Self :
137143 op = ops .LtEq ()
138- return op .to_binary_expr (self ._ir , other ._ir ). to_narwhals ( )
144+ return self . _from_ir ( op .to_binary_expr (self ._ir , other ._ir ))
139145
140- def __gt__ (self , other : DummyExpr ) -> DummyExpr :
146+ def __gt__ (self , other : DummyExpr ) -> Self :
141147 op = ops .Gt ()
142- return op .to_binary_expr (self ._ir , other ._ir ). to_narwhals ( )
148+ return self . _from_ir ( op .to_binary_expr (self ._ir , other ._ir ))
143149
144- def __ge__ (self , other : DummyExpr ) -> DummyExpr :
150+ def __ge__ (self , other : DummyExpr ) -> Self :
145151 op = ops .GtEq ()
146- return op .to_binary_expr (self ._ir , other ._ir ). to_narwhals ( )
152+ return self . _from_ir ( op .to_binary_expr (self ._ir , other ._ir ))
147153
148- def __add__ (self , other : DummyExpr ) -> DummyExpr :
154+ def __add__ (self , other : DummyExpr ) -> Self :
149155 op = ops .Add ()
150- return op .to_binary_expr (self ._ir , other ._ir ). to_narwhals ( )
156+ return self . _from_ir ( op .to_binary_expr (self ._ir , other ._ir ))
151157
152- def __sub__ (self , other : DummyExpr ) -> DummyExpr :
158+ def __sub__ (self , other : DummyExpr ) -> Self :
153159 op = ops .Sub ()
154- return op .to_binary_expr (self ._ir , other ._ir ). to_narwhals ( )
160+ return self . _from_ir ( op .to_binary_expr (self ._ir , other ._ir ))
155161
156- def __mul__ (self , other : DummyExpr ) -> DummyExpr :
162+ def __mul__ (self , other : DummyExpr ) -> Self :
157163 op = ops .Multiply ()
158- return op .to_binary_expr (self ._ir , other ._ir ). to_narwhals ( )
164+ return self . _from_ir ( op .to_binary_expr (self ._ir , other ._ir ))
159165
160- def __truediv__ (self , other : DummyExpr ) -> DummyExpr :
166+ def __truediv__ (self , other : DummyExpr ) -> Self :
161167 op = ops .TrueDivide ()
162- return op .to_binary_expr (self ._ir , other ._ir ). to_narwhals ( )
168+ return self . _from_ir ( op .to_binary_expr (self ._ir , other ._ir ))
163169
164- def __floordiv__ (self , other : DummyExpr ) -> DummyExpr :
170+ def __floordiv__ (self , other : DummyExpr ) -> Self :
165171 op = ops .FloorDivide ()
166- return op .to_binary_expr (self ._ir , other ._ir ). to_narwhals ( )
172+ return self . _from_ir ( op .to_binary_expr (self ._ir , other ._ir ))
167173
168- def __mod__ (self , other : DummyExpr ) -> DummyExpr :
174+ def __mod__ (self , other : DummyExpr ) -> Self :
169175 op = ops .Modulus ()
170- return op .to_binary_expr (self ._ir , other ._ir ). to_narwhals ( )
176+ return self . _from_ir ( op .to_binary_expr (self ._ir , other ._ir ))
171177
172- def __and__ (self , other : DummyExpr ) -> DummyExpr :
178+ def __and__ (self , other : DummyExpr ) -> Self :
173179 op = ops .And ()
174- return op .to_binary_expr (self ._ir , other ._ir ). to_narwhals ( )
180+ return self . _from_ir ( op .to_binary_expr (self ._ir , other ._ir ))
175181
176- def __or__ (self , other : DummyExpr ) -> DummyExpr :
182+ def __or__ (self , other : DummyExpr ) -> Self :
177183 op = ops .Or ()
178- return op .to_binary_expr (self ._ir , other ._ir ).to_narwhals ()
184+ return self ._from_ir (op .to_binary_expr (self ._ir , other ._ir ))
185+
186+ def __invert__ (self ) -> Self :
187+ return self ._from_ir (boolean .Not ().to_function_expr (self ._ir ))
188+
179189
180- def __invert__ ( self ) -> DummyExpr :
181- return boolean . Not (). to_function_expr ( self . _ir ). to_narwhals ()
190+ class DummyExprV1 ( DummyExpr ) :
191+ _version : t . ClassVar [ Version ] = Version . V1
182192
183193
184194class DummyCompliantExpr :
185195 _ir : ExprIR
196+ _version : Version
197+
198+ @property
199+ def version (self ) -> Version :
200+ return self ._version
186201
187202 @classmethod
188- def _from_ir (cls , ir : ExprIR , / ) -> Self :
203+ def _from_ir (cls , ir : ExprIR , / , version : Version ) -> Self :
189204 obj = cls .__new__ (cls )
190205 obj ._ir = ir
206+ obj ._version = version
191207 return obj
192208
209+ def to_narwhals (self ) -> DummyExpr :
210+ if self .version is Version .MAIN :
211+ return DummyExpr ._from_ir (self ._ir )
212+ return DummyExprV1 ._from_ir (self ._ir )
213+
193214
194215class DummySeries :
195216 _compliant : DummyCompliantSeries
217+ _version : t .ClassVar [Version ] = Version .MAIN
218+
219+ @property
220+ def version (self ) -> Version :
221+ return self ._version
196222
197223 @property
198224 def dtype (self ) -> DType :
@@ -205,31 +231,38 @@ def name(self) -> str:
205231 @classmethod
206232 def from_native (cls , native : NativeSeries , / ) -> Self :
207233 obj = cls .__new__ (cls )
208- obj ._compliant = DummyCompliantSeries .from_native (native )
234+ obj ._compliant = DummyCompliantSeries .from_native (native , cls . _version )
209235 return obj
210236
211237
238+ class DummySeriesV1 (DummySeries ):
239+ _version : t .ClassVar [Version ] = Version .V1
240+
241+
212242class DummyCompliantSeries :
213243 _native : NativeSeries
214244 _name : str
245+ _version : Version
246+
247+ @property
248+ def version (self ) -> Version :
249+ return self ._version
215250
216251 @property
217252 def dtype (self ) -> DType :
218- return Version . MAIN .dtypes .Float64 ()
253+ return self . version .dtypes .Float64 ()
219254
220255 @property
221256 def name (self ) -> str :
222257 return self ._name
223258
224259 @classmethod
225- def from_native (cls , native : NativeSeries , / ) -> Self :
226- from narwhals .utils import _hasattr_static
227-
260+ def from_native (cls , native : NativeSeries , / , version : Version ) -> Self :
228261 name : str = "<PLACEHOLDER>"
229-
230262 if _hasattr_static (native , "name" ):
231263 name = getattr (native , "name" , name )
232264 obj = cls .__new__ (cls )
233265 obj ._native = native
234266 obj ._name = name
267+ obj ._version = version
235268 return obj
0 commit comments