Skip to content

Commit 0b32cae

Browse files
committed
add handling for special case where np datetime contained in Python list gets converted to integer
1 parent 11d50b0 commit 0b32cae

File tree

1 file changed

+17
-2
lines changed

1 file changed

+17
-2
lines changed

_plotly_utils/basevalidators.py

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,21 @@ def fullmatch(regex, string, flags=0):
2222
return re.match("(?:" + regex_string + r")\Z", string, flags=flags)
2323

2424

25+
def to_non_numpy_type(np, v):
26+
"""
27+
Convert a numpy scalar value to a native Python type.
28+
Calling .item() on a datetime64[ns] value returns an integer, since
29+
Python datetimes only support microsecond precision. So we cast
30+
datetime64[ns] to datetime64[us] to ensure it remains a datetime.
31+
32+
Should only be used in contexts where we already know `np` is defined
33+
"""
34+
if hasattr(v, "dtype") and v.dtype == np.dtype("datetime64[ns]"):
35+
return v.astype("datetime64[us]").item()
36+
else:
37+
return v.item()
38+
39+
2540
# Utility functions
2641
# -----------------
2742
def to_scalar_or_list(v):
@@ -35,12 +50,12 @@ def to_scalar_or_list(v):
3550
np = get_module("numpy", should_load=False)
3651
pd = get_module("pandas", should_load=False)
3752
if np and np.isscalar(v) and hasattr(v, "item"):
38-
return v.item()
53+
return to_non_numpy_type(np, v)
3954
if isinstance(v, (list, tuple)):
4055
return [to_scalar_or_list(e) for e in v]
4156
elif np and isinstance(v, np.ndarray):
4257
if v.ndim == 0:
43-
return v.item()
58+
return to_non_numpy_type(np, v)
4459
return [to_scalar_or_list(e) for e in v]
4560
elif pd and isinstance(v, (pd.Series, pd.Index)):
4661
return [to_scalar_or_list(e) for e in v]

0 commit comments

Comments
 (0)