@@ -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# -----------------
2741def 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