23
23
from pandas ._libs .missing import (
24
24
NA ,
25
25
NAType ,
26
+ checknull ,
26
27
)
27
28
from pandas ._libs .tslibs import (
28
29
NaT ,
@@ -556,6 +557,13 @@ def ensure_dtype_can_hold_na(dtype: DtypeObj) -> DtypeObj:
556
557
return dtype
557
558
558
559
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
+
559
567
def maybe_promote (dtype : np .dtype , fill_value = np .nan ):
560
568
"""
561
569
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):
577
585
ValueError
578
586
If fill_value is a non-scalar and dtype is not object.
579
587
"""
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
+
580
594
# for performance, we are using a cached version of the actual implementation
581
595
# of the function in _maybe_promote. However, this doesn't always work (in case
582
596
# of non-hashable arguments), so we fallback to the actual implementation if needed
583
597
try :
584
598
# error: Argument 3 to "__call__" of "_lru_cache_wrapper" has incompatible type
585
599
# "Type[Any]"; expected "Hashable" [arg-type]
586
- return _maybe_promote_cached (
600
+ dtype , fill_value = _maybe_promote_cached (
587
601
dtype , fill_value , type (fill_value ) # type: ignore[arg-type]
588
602
)
589
603
except TypeError :
590
604
# 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
592
611
593
612
594
613
@functools .lru_cache (maxsize = 128 )
0 commit comments