You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
pandas keys several khash tables on a bare `const char *`, which hashes to
the first NUL and compares with strcmp, so any string containing an embedded
NUL is truncated for both hashing and comparison. Distinct values that share
a prefix up to their first NUL therefore collapse into one.
Key those tables on an explicit (pointer, length) pair instead. The hash is
X31 over exactly `len` bytes -- bit-identical to `__ac_X31_hash_string` for
NUL-free input, so bucket distribution is unchanged -- and equality is a
length check plus a byte comparison. `PyUnicode_AsUTF8AndSize` and
`_token_len` supply the length, so no path pays an extra strlen.
This fixes `unique`, `factorize`, `Series.unique`, `Index.unique` and
`groupby` on object dtype, plus `read_csv`'s `dtype=object` interning and
`dtype="category"` conversion.
The na_values/true_values/false_values hashsets change key type but still
derive their length with strlen, so NA handling is unchanged here; giving
them an explicit length changes user-visible NA semantics and is left to a
follow-up.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: doc/source/whatsnew/v3.1.0.rst
+2Lines changed: 2 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -410,6 +410,7 @@ Strings
410
410
- Bug in :meth:`Series.str.rsplit` and :meth:`Index.str.rsplit` silently accepting a compiled regex and returning incorrect results (:issue:`29633`)
411
411
- Bug in :meth:`Series.str.split` with :class:`ArrowDtype` ``string`` not inferring regex for multi-character patterns when ``regex=None``, causing the pattern to be treated as a literal instead of a regular expression (:issue:`58321`)
412
412
- Bug in :meth:`Series.unique`, :meth:`Index.unique` and :func:`factorize` on object dtype returning incorrect results when the values were not UTF-8 encodable, e.g. lone surrogates (:issue:`34550`)
413
+
- Bug in :meth:`Series.unique`, :meth:`Index.unique`, :func:`factorize` and ``groupby`` on object dtype collapsing distinct strings that are identical up to an embedded NUL byte, e.g. ``""`` and ``"\x00"``, into a single value (:issue:`34551`)
413
414
414
415
Interval
415
416
^^^^^^^^
@@ -496,6 +497,7 @@ I/O
496
497
- Fixed bug in :func:`read_csv` with ``engine="pyarrow"`` where passing tuples in ``names`` produced flat columns instead of :class:`MultiIndex` columns as with the other engines (:issue:`65862`)
497
498
- Fixed bug in :func:`read_csv` with the ``c`` engine where a quoted field containing an embedded NUL byte was silently truncated at the NUL under the default string dtype or ``dtype_backend="pyarrow"`` (:issue:`66415`)
498
499
- Fixed bug in :func:`read_csv` with the ``c`` engine where an embedded ``\r`` followed by a space in an unquoted field could cause an infinite re-parsing loop, producing spurious rows or a buffer overflow (:issue:`51141`)
500
+
- Fixed bug in :func:`read_csv` with the ``c`` engine where two fields differing only after an embedded NUL byte were read as the same value with ``dtype=object`` or ``dtype="category"`` (:issue:`19886`)
499
501
- Fixed bug in :func:`read_excel` where usage of ``skiprows`` could lead to an infinite loop (:issue:`64027`)
500
502
- Fixed bug in :func:`read_excel` with the ``openpyxl`` engine where reading a sheet set its ``max_row`` and ``max_column`` to ``None`` on the workbook exposed through ``ExcelFile.book`` (:issue:`63010`)
501
503
- Fixed bug in :func:`read_sas` where ``encoding="infer"`` raised ``LookupError: unknown encoding: infer`` instead of falling back to latin-1, for SAS7BDAT files recording an encoding pandas does not recognize and for XPORT files, which record no encoding at all (:issue:`66470`)
0 commit comments