Skip to content

Commit e999a77

Browse files
authored
Harden serialization of temporal numpy types (#1261)
1 parent 023f012 commit e999a77

File tree

1 file changed

+18
-11
lines changed

1 file changed

+18
-11
lines changed

src/neo4j/_codec/hydration/v1/temporal.py

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -216,16 +216,16 @@ def dehydrate_np_datetime(value):
216216
"""
217217
if np.isnat(value):
218218
return None
219-
year = value.astype("datetime64[Y]").astype(int) + 1970
219+
year = value.astype("datetime64[Y]").astype(np.int64) + 1970
220220
if not 0 < year <= 9999:
221221
# while we could encode years outside the range, they would fail
222222
# when retrieved from the database.
223223
raise ValueError(
224224
f"Year out of range ({MIN_YEAR:d}..{MAX_YEAR:d}) found {year}"
225225
)
226-
seconds = value.astype(np.dtype("datetime64[s]")).astype(int)
226+
seconds = value.astype(np.dtype("datetime64[s]")).astype(np.int64)
227227
nanoseconds = (
228-
value.astype(np.dtype("datetime64[ns]")).astype(int)
228+
value.astype(np.dtype("datetime64[ns]")).astype(np.int64)
229229
% _NANO_SECONDS
230230
)
231231
return Structure(b"d", seconds, nanoseconds)
@@ -299,6 +299,7 @@ def dehydrate_timedelta(value):
299299

300300

301301
if np is not None:
302+
_NUMPY_DURATION_NS_FALLBACK = object()
302303
_NUMPY_DURATION_UNITS = {
303304
"Y": "years",
304305
"M": "months",
@@ -310,6 +311,9 @@ def dehydrate_timedelta(value):
310311
"ms": "milliseconds",
311312
"us": "microseconds",
312313
"ns": "nanoseconds",
314+
"ps": _NUMPY_DURATION_NS_FALLBACK,
315+
"fs": _NUMPY_DURATION_NS_FALLBACK,
316+
"as": _NUMPY_DURATION_NS_FALLBACK,
313317
}
314318

315319
def dehydrate_np_timedelta(value):
@@ -323,14 +327,17 @@ def dehydrate_np_timedelta(value):
323327
if np.isnat(value):
324328
return None
325329
unit, step_size = np.datetime_data(value)
326-
numer = int(value.astype(int))
327-
# raise RuntimeError((type(numer), type(step_size)))
328-
kwarg = _NUMPY_DURATION_UNITS.get(unit)
329-
if kwarg is not None:
330-
return dehydrate_duration(Duration(**{kwarg: numer * step_size}))
331-
return dehydrate_duration(
332-
Duration(nanoseconds=value.astype("timedelta64[ns]").astype(int))
333-
)
330+
numer = int(value.astype(np.int64))
331+
try:
332+
kwarg = _NUMPY_DURATION_UNITS[unit]
333+
except KeyError:
334+
raise TypeError(
335+
f"Unsupported numpy.timedelta64 unit: {unit!r}"
336+
) from None
337+
if kwarg is _NUMPY_DURATION_NS_FALLBACK:
338+
nanoseconds = value.astype("timedelta64[ns]").astype(np.int64)
339+
return dehydrate_duration(Duration(nanoseconds=nanoseconds))
340+
return dehydrate_duration(Duration(**{kwarg: numer * step_size}))
334341

335342

336343
if pd is not None:

0 commit comments

Comments
 (0)