2323from pandas ._libs .missing import (
2424 NA ,
2525 NAType ,
26+ checknull ,
2627)
2728from pandas ._libs .tslibs import (
2829 NaT ,
@@ -556,6 +557,13 @@ def ensure_dtype_can_hold_na(dtype: DtypeObj) -> DtypeObj:
556557 return dtype
557558
558559
560+ _canonical_nans = {
561+ np .datetime64 : np .datetime64 ("NaT" , "ns" ),
562+ np .timedelta64 : np .timedelta64 ("NaT" , "ns" ),
563+ type (np .nan ): np .nan ,
564+ }
565+
566+
559567def maybe_promote (dtype : np .dtype , fill_value = np .nan ):
560568 """
561569 Find the minimal dtype that can hold both the given dtype and fill_value.
@@ -577,18 +585,29 @@ def maybe_promote(dtype: np.dtype, fill_value=np.nan):
577585 ValueError
578586 If fill_value is a non-scalar and dtype is not object.
579587 """
588+ orig = fill_value
589+ if checknull (fill_value ):
590+ # https://github.com/pandas-dev/pandas/pull/39692#issuecomment-1441051740
591+ # avoid cache misses with NaN/NaT values that are not singletons
592+ fill_value = _canonical_nans .get (type (fill_value ), fill_value )
593+
580594 # for performance, we are using a cached version of the actual implementation
581595 # of the function in _maybe_promote. However, this doesn't always work (in case
582596 # of non-hashable arguments), so we fallback to the actual implementation if needed
583597 try :
584598 # error: Argument 3 to "__call__" of "_lru_cache_wrapper" has incompatible type
585599 # "Type[Any]"; expected "Hashable" [arg-type]
586- return _maybe_promote_cached (
600+ dtype , fill_value = _maybe_promote_cached (
587601 dtype , fill_value , type (fill_value ) # type: ignore[arg-type]
588602 )
589603 except TypeError :
590604 # if fill_value is not hashable (required for caching)
591- return _maybe_promote (dtype , fill_value )
605+ dtype , fill_value = _maybe_promote (dtype , fill_value )
606+
607+ if dtype == _dtype_obj and orig is not None :
608+ # GH#51592 restore our potentially non-canonical fill_value
609+ fill_value = orig
610+ return dtype , fill_value
592611
593612
594613@functools .lru_cache (maxsize = 128 )
0 commit comments