99
1010from pandas ._libs import NaT , lib , tslib , tslibs
1111import pandas ._libs .internals as libinternals
12- from pandas ._libs .tslibs import Timedelta , conversion , is_null_datetimelike
12+ from pandas ._libs .tslibs import Timedelta , conversion
13+ from pandas ._libs .tslibs .timezones import tz_compare
1314from pandas .util ._validators import validate_bool_kwarg
1415
1516from pandas .core .dtypes .cast import (
6061 ABCPandasArray ,
6162 ABCSeries ,
6263)
63- from pandas .core .dtypes .missing import _isna_compat , array_equivalent , isna , notna
64+ from pandas .core .dtypes .missing import (
65+ _isna_compat ,
66+ array_equivalent ,
67+ is_valid_nat_for_dtype ,
68+ isna ,
69+ notna ,
70+ )
6471
6572import pandas .core .algorithms as algos
6673from pandas .core .arrays import (
@@ -2248,14 +2255,17 @@ def _astype(self, dtype, **kwargs):
22482255 def _can_hold_element (self , element ):
22492256 tipo = maybe_infer_dtype_type (element )
22502257 if tipo is not None :
2251- return tipo == _NS_DTYPE or tipo == np .int64
2258+ return is_dtype_equal (tipo , self .dtype )
2259+ elif element is NaT :
2260+ return True
22522261 elif isinstance (element , datetime ):
2262+ if self .is_datetimetz :
2263+ return tz_compare (element .tzinfo , self .dtype .tz )
22532264 return element .tzinfo is None
22542265 elif is_integer (element ):
22552266 return element == tslibs .iNaT
22562267
2257- # TODO: shouldnt we exclude timedelta64("NaT")? See GH#27297
2258- return isna (element )
2268+ return is_valid_nat_for_dtype (element , self .dtype )
22592269
22602270 def _coerce_values (self , values ):
22612271 return values .view ("i8" )
@@ -2275,8 +2285,10 @@ def _try_coerce_args(self, other):
22752285 -------
22762286 base-type other
22772287 """
2278- if is_null_datetimelike (other ):
2288+ if is_valid_nat_for_dtype (other , self . dtype ):
22792289 other = tslibs .iNaT
2290+ elif is_integer (other ) and other == tslibs .iNaT :
2291+ pass
22802292 elif isinstance (other , (datetime , np .datetime64 , date )):
22812293 other = self ._box_func (other )
22822294 if getattr (other , "tz" ) is not None :
@@ -2359,6 +2371,8 @@ class DatetimeTZBlock(ExtensionBlock, DatetimeBlock):
23592371 is_datetimetz = True
23602372 is_extension = True
23612373
2374+ _can_hold_element = DatetimeBlock ._can_hold_element
2375+
23622376 @property
23632377 def _holder (self ):
23642378 return DatetimeArray
@@ -2465,8 +2479,10 @@ def _try_coerce_args(self, other):
24652479 # add the tz back
24662480 other = self ._holder (other , dtype = self .dtype )
24672481
2468- elif is_null_datetimelike (other ):
2482+ elif is_valid_nat_for_dtype (other , self . dtype ):
24692483 other = tslibs .iNaT
2484+ elif is_integer (other ) and other == tslibs .iNaT :
2485+ pass
24702486 elif isinstance (other , self ._holder ):
24712487 if other .tz != self .values .tz :
24722488 raise ValueError ("incompatible or non tz-aware value" )
@@ -2606,10 +2622,16 @@ def _box_func(self):
26062622 def _can_hold_element (self , element ):
26072623 tipo = maybe_infer_dtype_type (element )
26082624 if tipo is not None :
2625+ # TODO: remove the np.int64 support once coerce_values and
2626+ # _try_coerce_args both coerce to m8[ns] and not i8.
26092627 return issubclass (tipo .type , (np .timedelta64 , np .int64 ))
26102628 elif element is NaT :
26112629 return True
2612- return is_integer (element ) or isinstance (element , (timedelta , np .timedelta64 ))
2630+ elif isinstance (element , (timedelta , np .timedelta64 )):
2631+ return True
2632+ elif is_integer (element ):
2633+ return element == tslibs .iNaT
2634+ return is_valid_nat_for_dtype (element , self .dtype )
26132635
26142636 def fillna (self , value , ** kwargs ):
26152637
@@ -2645,8 +2667,10 @@ def _try_coerce_args(self, other):
26452667 base-type other
26462668 """
26472669
2648- if is_null_datetimelike (other ):
2670+ if is_valid_nat_for_dtype (other , self . dtype ):
26492671 other = tslibs .iNaT
2672+ elif is_integer (other ) and other == tslibs .iNaT :
2673+ pass
26502674 elif isinstance (other , (timedelta , np .timedelta64 )):
26512675 other = Timedelta (other ).value
26522676 elif hasattr (other , "dtype" ) and is_timedelta64_dtype (other ):
0 commit comments