10
10
11
11
import numpy as np
12
12
13
- from pandas ._libs import internals as libinternals
13
+ from pandas ._libs import (
14
+ NaT ,
15
+ internals as libinternals ,
16
+ )
17
+ from pandas ._libs .missing import NA
14
18
from pandas ._typing import (
15
19
ArrayLike ,
16
20
DtypeObj ,
28
32
is_1d_only_ea_obj ,
29
33
is_datetime64tz_dtype ,
30
34
is_dtype_equal ,
31
- is_extension_array_dtype ,
35
+ needs_i8_conversion ,
32
36
)
33
37
from pandas .core .dtypes .concat import (
34
38
cast_to_common_type ,
@@ -374,13 +378,20 @@ def _is_valid_na_for(self, dtype: DtypeObj) -> bool:
374
378
values = self .block .values
375
379
return all (is_valid_na_for_dtype (x , dtype ) for x in values .ravel (order = "K" ))
376
380
377
- if self . dtype . kind == dtype . kind == "M" and not is_dtype_equal (
378
- self .dtype , dtype
379
- ):
381
+ na_value = self . block . fill_value
382
+ if na_value is NaT and not is_dtype_equal ( self .dtype , dtype ):
383
+ # e.g. we are dt64 and other is td64
380
384
# fill_values match but we should not cast self.block.values to dtype
385
+ # TODO: this will need updating if we ever have non-nano dt64/td64
381
386
return False
382
387
383
- na_value = self .block .fill_value
388
+ if na_value is NA and needs_i8_conversion (dtype ):
389
+ # FIXME: kludge; test_append_empty_frame_with_timedelta64ns_nat
390
+ # e.g. self.dtype == "Int64" and dtype is td64, we dont want
391
+ # to consider these as matching
392
+ return False
393
+
394
+ # TODO: better to use can_hold_element?
384
395
return is_valid_na_for_dtype (na_value , dtype )
385
396
386
397
@cache_readonly
@@ -426,9 +437,6 @@ def get_reindexed_values(self, empty_dtype: DtypeObj, upcasted_na) -> ArrayLike:
426
437
i8values = np .full (self .shape , fill_value .value )
427
438
return DatetimeArray (i8values , dtype = empty_dtype )
428
439
429
- elif is_extension_array_dtype (blk_dtype ):
430
- pass
431
-
432
440
elif is_1d_only_ea_dtype (empty_dtype ):
433
441
empty_dtype = cast (ExtensionDtype , empty_dtype )
434
442
cls = empty_dtype .construct_array_type ()
@@ -440,11 +448,16 @@ def get_reindexed_values(self, empty_dtype: DtypeObj, upcasted_na) -> ArrayLike:
440
448
return missing_arr .take (
441
449
empty_arr , allow_fill = True , fill_value = fill_value
442
450
)
451
+ elif isinstance (empty_dtype , ExtensionDtype ):
452
+ # TODO: no tests get here, a handful would if we disabled
453
+ # the dt64tz special-case above (which is faster)
454
+ cls = empty_dtype .construct_array_type ()
455
+ missing_arr = cls ._empty (shape = self .shape , dtype = empty_dtype )
456
+ missing_arr [:] = fill_value
457
+ return missing_arr
443
458
else :
444
459
# NB: we should never get here with empty_dtype integer or bool;
445
460
# if we did, the missing_arr.fill would cast to gibberish
446
- empty_dtype = cast (np .dtype , empty_dtype )
447
-
448
461
missing_arr = np .empty (self .shape , dtype = empty_dtype )
449
462
missing_arr .fill (fill_value )
450
463
return missing_arr
0 commit comments