Description
When running dsdiff against a malformed or empty CSV file (e.g., a file containing only headers or single-line unexpected characters that result in 0 valid data rows), the program crashes with a ZeroDivisionError: float division by zero.
Steps to Reproduce
- Create a CSV file with no actual data rows (or malformed layout resulting in 0 row count).
- Run
dsdiff diff baseline.csv malformed.csv (or vice versa).
Traceback
...\src\dsdiff\drift.py:32 in _normalize
return np.full(counts.shape, 1.0 / counts.size)
ZeroDivisionError: float division by zero
Root Cause Analysis
In dsdiff/drift.py, the _normalize function checks total <= 0 and executes a uniform fallback:
if total <= 0:
# Uniform fallback keeps PSI finite when a side is empty.
return np.full(counts.shape, 1.0 / counts.size)
However, if the dataset has 0 data rows, counts.size also evaluates to 0. This results in 1.0 / 0, causing a ZeroDivisionError and crashing the program.
Suggested Fix
We might want to safely intercept when counts.size == 0 inside _normalize, or validate the dataset row count earlier during the file-loading/profiling stage to provide a cleaner error message to users.
Description
When running
dsdiffagainst a malformed or empty CSV file (e.g., a file containing only headers or single-line unexpected characters that result in 0 valid data rows), the program crashes with aZeroDivisionError: float division by zero.Steps to Reproduce
dsdiff diff baseline.csv malformed.csv(or vice versa).Traceback
Root Cause Analysis
In dsdiff/drift.py, the _normalize function checks total <= 0 and executes a uniform fallback:
However, if the dataset has 0 data rows, counts.size also evaluates to 0. This results in 1.0 / 0, causing a ZeroDivisionError and crashing the program.
Suggested Fix
We might want to safely intercept when
counts.size == 0inside_normalize, or validate the dataset row count earlier during the file-loading/profiling stage to provide a cleaner error message to users.