a-hirota
## Environment cudf 26.06.01 (pandas 2.3.3), cudf 26.08.01 (pandas 3.0.6). Reproduces on both. ## Reproducer ```python import cudf import pandas as pd for vals in (["x", None], ["x", "y", None], ["x", None, None], [None, None, "z"], ["x", None, "z"]): c = cudf.Series(vals, dtype="str").str.cat(sep="|") p = pd.Series(vals).str.cat(sep="|") print(f"{str(vals):<22} cudf={c!r:<10} pandas={p!r}") ``` ## Actual ``` ['x', None] cudf='x|' pandas='x' ['x', 'y', None] cudf='x|y|' pandas='x|y' ['x', None, None] cudf='x|' pandas='x' [None, None, 'z'] cudf='z' pandas='z' ['x', None, 'z'] cudf='x|z' pandas='x|z' ``` ## Expected ``` ['x', None] cudf='x' ['x', 'y', None] cudf='x|y' ['x', None, None] cudf='x' ``` With `na_rep=None`, null elements are skipped, so the separator that would precede a skipped element should be skipped as well — which is what cudf already does for leading and interior nulls. ## Scope Exactly one trailing separator is emitted regardless of how many trailing nulls there are, and the full separator is emitted for multi-character separators (`sep="<>"` gives `'x<>'`). Passing `na_rep=` gives the correct result (`["x", None]` with `na_rep="-"` gives `'x|-'`). Present at the column level: ```python cudf.Series(["x", None], dtype="str")._column.join_strings("|", None).to_arrow().to_pylist() # ['x|'] ```