diff --git a/CHANGELOG.md b/CHANGELOG.md index 7854479..cc25e22 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ - Read `symbols` registered in RDS objects. - Fixed an issue with S4 classes not properly saved as RDS files. - Implement `save_rds` generic for sparse matrix formats (csc, csr and coo). +- Implement `save_rds` for NumPy scalars. ## Version 0.9.0 - 0.9.1 diff --git a/src/rds2py/save_atomic.py b/src/rds2py/save_atomic.py index 1ecd09b..5f0379f 100644 --- a/src/rds2py/save_atomic.py +++ b/src/rds2py/save_atomic.py @@ -26,6 +26,11 @@ def _save_rds_primitives(x, path: Optional[str] = None): return x +@save_rds.register(np.generic) +def _save_rds_numpy_scalars(x: np.generic, path: Optional[str] = None): + return save_rds(x.item(), path=path) + + @save_rds.register(BooleanList) def _save_rds_booleanlist(x: BooleanList, path: Optional[str] = None): from .lib_rds_parser import write_rds as _write_rds_native diff --git a/tests/test_atomics.py b/tests/test_atomics.py index a4a31c2..57d9176 100644 --- a/tests/test_atomics.py +++ b/tests/test_atomics.py @@ -119,3 +119,32 @@ def test_save_names_directly(): finally: if os.path.exists(path): os.unlink(path) + + +def test_save_numpy_scalars(): + import numpy as np + from rds2py import save_rds + + # Test integer scalar + i_scalar = np.int32(42) + res_i = save_rds(i_scalar) + assert isinstance(res_i, int) + assert res_i == 42 + + # Test float scalar + f_scalar = np.float64(3.14) + res_f = save_rds(f_scalar) + assert isinstance(res_f, float) + assert res_f == 3.14 + + # Test bool scalar + b_scalar = np.bool_(True) + res_b = save_rds(b_scalar) + assert isinstance(res_b, bool) + assert res_b is True + + # Test string scalar + s_scalar = np.str_("hello") + res_s = save_rds(s_scalar) + assert isinstance(res_s, str) + assert res_s == "hello"