Skip to content

Commit 0a13e4f

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

File tree

1 file changed

+16
-2
lines changed

1 file changed

+16
-2
lines changed

_plotly_utils/basevalidators.py

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,20 @@ 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+
return v.item()
37+
38+
2539
# Utility functions
2640
# -----------------
2741
def to_scalar_or_list(v):
@@ -35,12 +49,12 @@ def to_scalar_or_list(v):
3549
np = get_module("numpy", should_load=False)
3650
pd = get_module("pandas", should_load=False)
3751
if np and np.isscalar(v) and hasattr(v, "item"):
38-
return v.item()
52+
return to_non_numpy_type(np, v)
3953
if isinstance(v, (list, tuple)):
4054
return [to_scalar_or_list(e) for e in v]
4155
elif np and isinstance(v, np.ndarray):
4256
if v.ndim == 0:
43-
return v.item()
57+
return to_non_numpy_type(np, v)
4458
return [to_scalar_or_list(e) for e in v]
4559
elif pd and isinstance(v, (pd.Series, pd.Index)):
4660
return [to_scalar_or_list(e) for e in v]

0 commit comments

Comments
 (0)