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