fix(deps): silence polars explode() empty_as_null deprecation warnings
CI / Sync project version with tag (hand-pushed tags only) (push) Skipped
CI / Publish package to Gitea package registry (push) Skipped
CI / Lint (ruff check) (push) Successful in 1m7s
CI / Format (ruff format) (push) Successful in 1m8s
CI / Type check (ty) (push) Successful in 1m12s
CI / Tests (push) Successful in 2m41s
CI / Release (bump, changelog, badges, tag) on merge to master (push) Successful in 8s

pytest emitted 113 DeprecationWarnings, all from the same source: polars
2.0 changes explode()'s default handling of empty lists from "explode to
null" to "drop the row". Every explode() call site in this repo already
follows the explode with drop_nulls() (or otherwise excludes empty
lists), so the new behavior is what we always wanted — pass
empty_as_null=False explicitly rather than suppressing the warning.

Bump the polars floor from >=1.0 to >=1.43, since the empty_as_null
kwarg doesn't exist before ~1.35.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012dE2r7cNo9Lbthh1JUW1NF
This commit is contained in:
2026-09-07 16:25:19 +02:00
co-authored by Claude Sonnet 5
parent 8cdeba088e
commit e24907862f
6 changed files with 16 additions and 12 deletions
+2 -2
View File
@@ -275,7 +275,7 @@ def prediction_secondaries(lf: pl.LazyFrame, prefix: str) -> pl.LazyFrame:
lists = [f"{col_prefix}sec_{c}_list" for c in ("E", "pdg", "dx", "dy", "dz")]
return (
lf.select("event_id", *lists)
.explode(lists)
.explode(lists, empty_as_null=False)
.drop_nulls(lists[0])
.select(
"event_id",
@@ -307,7 +307,7 @@ def paired_secondaries(lf: pl.LazyFrame) -> pl.LazyFrame:
.with_columns(pl.min_horizontal("_n_true", "_n_pred").alias("_n_paired"))
.filter(pl.col("_n_paired") > 0)
.with_columns(pl.int_ranges(0, pl.col("_n_paired")).alias("_rank"))
.explode("_rank")
.explode("_rank", empty_as_null=False)
.select(
pl.col("true_sec_pdg_list").list.get(pl.col("_rank")).cast(pl.Int64).alias("true_pdg"),
pl.col("sec_pdg_list").list.get(pl.col("_rank")).cast(pl.Int64).alias("pred_pdg"),
+2 -2
View File
@@ -230,7 +230,7 @@ def secondaries(lf: pl.LazyFrame, side: Side) -> pl.LazyFrame:
lists = ["sec_E_list", "sec_pdg_list", "sec_dx_list", "sec_dy_list", "sec_dz_list"]
return (
lf.select("event_id", *lists)
.explode(lists)
.explode(lists, empty_as_null=False)
.drop_nulls("sec_E_list")
.select(
"event_id",
@@ -268,7 +268,7 @@ def secondaries_by_step(lf: pl.LazyFrame, side: Side) -> pl.LazyFrame:
return (
lf.select("sec_pdg_list")
.with_row_index("_row")
.explode("sec_pdg_list")
.explode("sec_pdg_list", empty_as_null=False)
.drop_nulls("sec_pdg_list")
.select(pl.struct("_row").alias("step_key"), pl.col("sec_pdg_list").cast(pl.Int64).alias("pdg"))
)
+5 -1
View File
@@ -76,7 +76,11 @@ def _pooled_pdg_lazy(path: Path, has_sec_pdg_list: bool) -> pl.LazyFrame:
lf = pl.scan_parquet(path, row_index_name="__row")
parts = [lf.select(pl.col("pdg").alias("__val"), "__row")]
if has_sec_pdg_list:
parts.append(lf.select(pl.col("sec_pdg_list").alias("__val"), "__row").explode("__val").drop_nulls("__val"))
parts.append(
lf.select(pl.col("sec_pdg_list").alias("__val"), "__row")
.explode("__val", empty_as_null=False)
.drop_nulls("__val")
)
combined = pl.concat(parts)
return combined.group_by("__val").agg(pl.len().alias("__count"), pl.col("__row").min().alias("__first_row"))
+1 -1
View File
@@ -58,7 +58,7 @@ def _add_secondary_attributes(df: pl.DataFrame) -> tuple[pl.DataFrame, int]:
exploded = (
df.select(["event_id", "child_track_ids"])
.with_row_index("_step_row")
.explode("child_track_ids")
.explode("child_track_ids", empty_as_null=False)
.rename({"child_track_ids": "child_track_id"})
.drop_nulls("child_track_id")
)
+3 -3
View File
@@ -6,7 +6,7 @@ readme = "README.md"
requires-python = ">=3.12"
dependencies = [
"numpy>=1.26,<3",
"polars>=1.0,<2",
"polars>=1.43,<2",
"pyarrow>=16,<26",
"tqdm>=4.60,<5",
"typer>=0.12,<1",
@@ -43,11 +43,11 @@ wandb = [
convert = [
"uproot>=5.3,<6",
"awkward>=2.6,<3",
"polars>=1.0,<2",
"polars>=1.43,<2",
]
analysis = [
"matplotlib>=3.8,<4",
"polars>=1.0,<2",
"polars>=1.43,<2",
"ipykernel>=7.3.0",
# KIT matplotlib theme, published from git.larsbogner.de. Only the local
# `giant analyze render` step imports it; compute workers never do.
Generated
+3 -3
View File
@@ -892,9 +892,9 @@ requires-dist = [
{ name = "pandas", marker = "extra == 'dev'", specifier = ">=2.2,<4" },
{ name = "particle", specifier = ">=1.0,<2" },
{ name = "plotstyle", marker = "extra == 'analysis'", specifier = ">=1.0.0", index = "https://git.larsbogner.de/api/packages/lars/pypi/simple/" },
{ name = "polars", specifier = ">=1.0,<2" },
{ name = "polars", marker = "extra == 'analysis'", specifier = ">=1.0,<2" },
{ name = "polars", marker = "extra == 'convert'", specifier = ">=1.0,<2" },
{ name = "polars", specifier = ">=1.43,<2" },
{ name = "polars", marker = "extra == 'analysis'", specifier = ">=1.43,<2" },
{ name = "polars", marker = "extra == 'convert'", specifier = ">=1.43,<2" },
{ name = "pyarrow", specifier = ">=16,<26" },
{ name = "pytest", marker = "extra == 'dev'", specifier = ">=8,<10" },
{ name = "pytest-cov", marker = "extra == 'dev'", specifier = ">=5,<8" },