Skip to content

Commit 666ec37

Browse files
committed
fix: from_native updates a passed nw.DataFrame with the passed version
from_native on a narwhals.{DataFrame,Series} would always return the same object even if the DataFrame._version and the version passed into from_native disagreed. Now, if the versions mismatch we create a new narwhals object with the appropriate version. If the versions match, we short cut and return the same object.
1 parent 1a552c7 commit 666ec37

File tree

2 files changed

+42
-2
lines changed

2 files changed

+42
-2
lines changed

narwhals/translate.py

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -282,9 +282,25 @@ def _from_native_impl( # noqa: C901, PLR0911, PLR0912, PLR0915
282282

283283
# Early returns
284284
if isinstance(native_object, (DataFrame, LazyFrame)) and not series_only:
285-
return native_object
285+
if native_object._version is version:
286+
return native_object
287+
288+
real_native_object = native_object.to_native()
289+
return (
290+
version.namespace.from_native_object(real_native_object)
291+
.compliant.from_native(real_native_object)
292+
.to_narwhals()
293+
)
286294
if isinstance(native_object, Series) and (series_only or allow_series):
287-
return native_object
295+
if native_object._version is version:
296+
return native_object
297+
298+
real_native_object = native_object.to_native()
299+
return (
300+
version.namespace.from_native_object(real_native_object)
301+
.compliant.from_native(real_native_object)
302+
.to_narwhals()
303+
)
288304

289305
if series_only:
290306
if allow_series is False:

tests/translate/from_native_test.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,30 @@ def test_init_already_narwhals_unstable() -> None:
227227
assert result_s is s
228228

229229

230+
@pytest.mark.skipif(lf_pl is None, reason="polars not found")
231+
def test_init_already_narwhals_unstable_to_stable() -> None:
232+
from narwhals.stable import v1 as nw_v1
233+
234+
native = pl.DataFrame({"a": [1, 2, 3]})
235+
236+
unstable = nw.from_native(native)
237+
stablified = nw_v1.from_native(unstable)
238+
239+
assert isinstance(stablified, nw_v1.DataFrame)
240+
241+
242+
@pytest.mark.skipif(lf_pl is None, reason="polars not found")
243+
def test_init_already_narwhals_stable_to_unstable() -> None:
244+
from narwhals.stable import v1 as nw_v1
245+
246+
native = pl.DataFrame({"a": [1, 2, 3]})
247+
248+
stable_v1 = nw_v1.from_native(native)
249+
unstablified = nw.from_native(stable_v1)
250+
251+
assert isinstance(unstablified, nw.DataFrame)
252+
253+
230254
@pytest.mark.skipif(df_pd is None, reason="pandas not found")
231255
def test_series_only_dask() -> None:
232256
pytest.importorskip("dask")

0 commit comments

Comments
 (0)