Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package python-narwhals for openSUSE:Factory
checked in at 2026-03-17 19:04:35
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-narwhals (Old)
and /work/SRC/openSUSE:Factory/.python-narwhals.new.8177 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-narwhals"
Tue Mar 17 19:04:35 2026 rev:7 rq:1339439 version:2.18.0
Changes:
--------
--- /work/SRC/openSUSE:Factory/python-narwhals/python-narwhals.changes
2026-03-09 16:31:52.227573347 +0100
+++
/work/SRC/openSUSE:Factory/.python-narwhals.new.8177/python-narwhals.changes
2026-03-17 19:06:16.741101340 +0100
@@ -1,0 +2,10 @@
+Mon Mar 16 21:25:30 UTC 2026 - Dirk Müller <[email protected]>
+
+- update to 2.18.0:
+ * tests: Remove xfail for SQLFrame `Expr.skew`
+ * Update marimo downstream CI to use uv instead of hatch
+ * fix: pyarrow when/then with nulls
+ * fix: Enable `Expr.replace_strict` for SQLFrame backend
+ * chore: Update end year in LICENSE.md
+
+-------------------------------------------------------------------
Old:
----
narwhals-2.17.0.tar.gz
New:
----
narwhals-2.18.0.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-narwhals.spec ++++++
--- /var/tmp/diff_new_pack.QHaThg/_old 2026-03-17 19:06:17.333125875 +0100
+++ /var/tmp/diff_new_pack.QHaThg/_new 2026-03-17 19:06:17.337126041 +0100
@@ -17,7 +17,7 @@
Name: python-narwhals
-Version: 2.17.0
+Version: 2.18.0
Release: 0
Summary: Extremely lightweight compatibility layer between dataframe
libraries
License: MIT
++++++ narwhals-2.17.0.tar.gz -> narwhals-2.18.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/narwhals-2.17.0/LICENSE.md
new/narwhals-2.18.0/LICENSE.md
--- old/narwhals-2.17.0/LICENSE.md 2020-02-02 01:00:00.000000000 +0100
+++ new/narwhals-2.18.0/LICENSE.md 2020-02-02 01:00:00.000000000 +0100
@@ -1,6 +1,6 @@
MIT License
-Copyright (c) 2024, Marco Gorelli
+Copyright (c) 2024 to present, Marco Gorelli
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/narwhals-2.17.0/PKG-INFO new/narwhals-2.18.0/PKG-INFO
--- old/narwhals-2.17.0/PKG-INFO 2020-02-02 01:00:00.000000000 +0100
+++ new/narwhals-2.18.0/PKG-INFO 2020-02-02 01:00:00.000000000 +0100
@@ -1,6 +1,6 @@
Metadata-Version: 2.4
Name: narwhals
-Version: 2.17.0
+Version: 2.18.0
Summary: Extremely lightweight compatibility layer between dataframe libraries
Project-URL: Homepage, https://github.com/narwhals-dev/narwhals
Project-URL: Documentation, https://narwhals-dev.github.io/narwhals/
@@ -9,7 +9,7 @@
Author-email: Marco Gorelli <[email protected]>
License: MIT License
- Copyright (c) 2024, Marco Gorelli
+ Copyright (c) 2024 to present, Marco Gorelli
Permission is hereby granted, free of charge, to any person obtaining
a copy
of this software and associated documentation files (the "Software"),
to deal
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/narwhals-2.17.0/narwhals/_arrow/namespace.py
new/narwhals-2.18.0/narwhals/_arrow/namespace.py
--- old/narwhals-2.17.0/narwhals/_arrow/namespace.py 2020-02-02
01:00:00.000000000 +0100
+++ new/narwhals-2.18.0/narwhals/_arrow/namespace.py 2020-02-02
01:00:00.000000000 +0100
@@ -252,4 +252,4 @@
otherwise: ChunkedArrayAny | None = None,
) -> ChunkedArrayAny:
otherwise = pa.nulls(len(when), then.type) if otherwise is None else
otherwise
- return pc.if_else(when, then, otherwise)
+ return pc.if_else(when.fill_null(pa.scalar(False)), then, otherwise)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/narwhals-2.17.0/narwhals/_spark_like/expr.py
new/narwhals-2.18.0/narwhals/_spark_like/expr.py
--- old/narwhals-2.17.0/narwhals/_spark_like/expr.py 2020-02-02
01:00:00.000000000 +0100
+++ new/narwhals-2.18.0/narwhals/_spark_like/expr.py 2020-02-02
01:00:00.000000000 +0100
@@ -360,7 +360,7 @@
assert value is not None # noqa: S101
return self._with_elementwise(_fill_constant, value=value)
- def replace_strict( # pragma: no cover
+ def replace_strict(
self,
default: SparkLikeExpr | NoDefault,
old: Sequence[Any],
@@ -372,8 +372,7 @@
msg = "`replace_strict` requires an explicit value for `default`
for any spark-like backend."
raise ValueError(msg)
- if self._implementation is not Implementation.PYSPARK:
- # Issue tracker: https://github.com/eakmanrq/sqlframe/issues/545
+ if self._implementation is Implementation.PYSPARK_CONNECT:
msg = f"`replace_strict` is not (yet) implemented for
{self._implementation}."
raise NotImplementedError(msg)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/narwhals-2.17.0/pyproject.toml
new/narwhals-2.18.0/pyproject.toml
--- old/narwhals-2.17.0/pyproject.toml 2020-02-02 01:00:00.000000000 +0100
+++ new/narwhals-2.18.0/pyproject.toml 2020-02-02 01:00:00.000000000 +0100
@@ -5,7 +5,7 @@
[project]
name = "narwhals"
-version = "2.17.0"
+version = "2.18.0"
dependencies = []
requires-python = ">=3.9"
authors = [
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/narwhals-2.17.0/tests/expr_and_series/replace_strict_test.py
new/narwhals-2.18.0/tests/expr_and_series/replace_strict_test.py
--- old/narwhals-2.17.0/tests/expr_and_series/replace_strict_test.py
2020-02-02 01:00:00.000000000 +0100
+++ new/narwhals-2.18.0/tests/expr_and_series/replace_strict_test.py
2020-02-02 01:00:00.000000000 +0100
@@ -22,10 +22,6 @@
polars_lt_v1 = POLARS_VERSION < (1, 0, 0)
skip_reason = "replace_strict only available after 1.0"
pl_skip_reason = "replace_strict only available after 1.0"
-sqlframe_xfail_reason = (
- "AttributeError: module 'sqlframe.duckdb.functions' has no attribute
'map_keys'.\n"
- "Issue tracker: https://github.com/eakmanrq/sqlframe/issues/545"
-)
def xfail_if_no_default(constructor: Constructor, request:
pytest.FixtureRequest) -> None:
@@ -144,9 +140,6 @@
if "polars" in str(constructor) and polars_lt_v1:
pytest.skip(reason=pl_skip_reason)
- if "sqlframe" in str(constructor):
- request.applymarker(pytest.mark.xfail(reason=sqlframe_xfail_reason))
-
df = nw.from_native(constructor({"a": [1, 2, 3, 4]}))
result = df.select(
nw.col("a").replace_strict(
@@ -180,9 +173,6 @@
if "polars" in str(constructor) and polars_lt_v1:
pytest.skip(reason=pl_skip_reason)
- if "sqlframe" in str(constructor):
- request.applymarker(pytest.mark.xfail(reason=sqlframe_xfail_reason))
-
df = nw.from_native(constructor({"a": [1, 2, None, 4]}))
result = df.select(
nw.col("a").replace_strict([1, 2], [10, 20], default=99,
return_dtype=nw.Int64)
@@ -198,9 +188,6 @@
if "polars" in str(constructor) and polars_lt_v1:
pytest.skip(reason=pl_skip_reason)
- if "sqlframe" in str(constructor):
- request.applymarker(pytest.mark.xfail(reason=sqlframe_xfail_reason))
-
df = nw.from_native(constructor({"a": [1, 2, 3, 4]}))
result = df.select(
nw.col("a").replace_strict(
@@ -218,9 +205,6 @@
if "polars" in str(constructor) and polars_lt_v1:
pytest.skip(reason=pl_skip_reason)
- if "sqlframe" in str(constructor):
- request.applymarker(pytest.mark.xfail(reason=sqlframe_xfail_reason))
-
data = {"a": [1, 2, 3, 4], "b": ["beluga", "narwhal", "orca", "vaquita"]}
df = nw.from_native(constructor(data))
result = df.select(
@@ -254,9 +238,6 @@
if "polars" in str(constructor) and polars_lt_v1:
pytest.skip(reason=pl_skip_reason)
- if "sqlframe" in str(constructor):
- request.applymarker(pytest.mark.xfail(reason=sqlframe_xfail_reason))
-
data = {"a": [1, 2]}
df = nw.from_native(constructor(data))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/narwhals-2.17.0/tests/expr_and_series/skew_test.py
new/narwhals-2.18.0/tests/expr_and_series/skew_test.py
--- old/narwhals-2.17.0/tests/expr_and_series/skew_test.py 2020-02-02
01:00:00.000000000 +0100
+++ new/narwhals-2.18.0/tests/expr_and_series/skew_test.py 2020-02-02
01:00:00.000000000 +0100
@@ -51,10 +51,6 @@
# Can not infer schema from empty dataset.
pytest.skip()
- if "sqlframe" in str(constructor):
- # https://github.com/eakmanrq/sqlframe/issues/522
- request.applymarker(pytest.mark.xfail)
-
result = nw.from_native(constructor({"a":
data})).select(nw.col("a").skew())
assert_equal_data(result, {"a": [expected]})
result = nw.from_native(constructor({"a":
data})).with_columns(nw.col("a").skew())
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/narwhals-2.17.0/tests/expr_and_series/when_test.py
new/narwhals-2.18.0/tests/expr_and_series/when_test.py
--- old/narwhals-2.17.0/tests/expr_and_series/when_test.py 2020-02-02
01:00:00.000000000 +0100
+++ new/narwhals-2.18.0/tests/expr_and_series/when_test.py 2020-02-02
01:00:00.000000000 +0100
@@ -227,3 +227,13 @@
result = df.with_columns(nw.when(nw.col("a") ==
1).then(nw.lit(1)).alias("new_col"))
expected: dict[str, Any] = {"a": [], "new_col": []}
assert_equal_data(result, expected)
+
+
+def test_when_chain_with_nulls(constructor: Constructor) -> None:
+ df = nw.from_native(constructor({"a": [1, None, 3, None, 5]}))
+
+ result = df.select(nw.when(nw.col("a") ==
1).then(10).otherwise(99).alias("result"))
+
+ # Null values don't match any condition, so they get otherwise value
+ expected = {"result": [10, 99, 99, 99, 99]}
+ assert_equal_data(result, expected)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/narwhals-2.17.0/tests/frame/join_test.py
new/narwhals-2.18.0/tests/frame/join_test.py
--- old/narwhals-2.17.0/tests/frame/join_test.py 2020-02-02
01:00:00.000000000 +0100
+++ new/narwhals-2.18.0/tests/frame/join_test.py 2020-02-02
01:00:00.000000000 +0100
@@ -785,11 +785,7 @@
from pandas.errors import MergeError
exception = MergeError
- elif "sqlframe" in str(constructor):
- import duckdb
-
- exception = duckdb.BinderException
- elif "pyspark" in str(constructor):
+ elif "pyspark" in str(constructor) and "sqlframe" not in str(constructor):
from pyspark.errors import AnalysisException
exception = AnalysisException