@@ -17,6 +17,10 @@ cnp.import_array()
17
17
from pandas._libs cimport util
18
18
from pandas._libs.hashtable cimport HashTable
19
19
from pandas._libs.tslibs.nattype cimport c_NaT as NaT
20
+ from pandas._libs.tslibs.np_datetime cimport (
21
+ NPY_DATETIMEUNIT,
22
+ get_unit_from_dtype,
23
+ )
20
24
from pandas._libs.tslibs.period cimport is_period_object
21
25
from pandas._libs.tslibs.timedeltas cimport _Timedelta
22
26
from pandas._libs.tslibs.timestamps cimport _Timestamp
@@ -485,17 +489,35 @@ cdef class ObjectEngine(IndexEngine):
485
489
486
490
cdef class DatetimeEngine(Int64Engine):
487
491
492
+ cdef:
493
+ NPY_DATETIMEUNIT reso
494
+
495
+ def __init__ (self , ndarray values ):
496
+ super ().__init__(values.view(" i8" ))
497
+ self .reso = get_unit_from_dtype(values.dtype)
498
+
488
499
cdef int64_t _unbox_scalar(self , scalar) except ? - 1 :
489
500
# NB: caller is responsible for ensuring tzawareness compat
490
501
# before we get here
491
- if not (isinstance (scalar, _Timestamp) or scalar is NaT):
492
- raise TypeError (scalar)
493
- return scalar.value
502
+ if scalar is NaT:
503
+ return NaT.value
504
+ elif isinstance (scalar, _Timestamp):
505
+ if scalar._reso == self .reso:
506
+ return scalar.value
507
+ else :
508
+ # Note: caller is responsible for catching potential ValueError
509
+ # from _as_reso
510
+ return (< _Timestamp> scalar)._as_reso(self .reso, round_ok = False ).value
511
+ raise TypeError (scalar)
494
512
495
513
def __contains__ (self , val: object ) -> bool:
496
514
# We assume before we get here:
497
515
# - val is hashable
498
- self._unbox_scalar(val )
516
+ try:
517
+ self._unbox_scalar(val )
518
+ except ValueError:
519
+ return False
520
+
499
521
try:
500
522
self.get_loc(val )
501
523
return True
@@ -517,8 +539,8 @@ cdef class DatetimeEngine(Int64Engine):
517
539
518
540
try :
519
541
conv = self ._unbox_scalar(val)
520
- except TypeError :
521
- raise KeyError (val)
542
+ except ( TypeError , ValueError ) as err :
543
+ raise KeyError (val) from err
522
544
523
545
# Welcome to the spaghetti factory
524
546
if self .over_size_threshold and self .is_monotonic_increasing:
@@ -545,9 +567,16 @@ cdef class DatetimeEngine(Int64Engine):
545
567
cdef class TimedeltaEngine(DatetimeEngine):
546
568
547
569
cdef int64_t _unbox_scalar(self , scalar) except ? - 1 :
548
- if not (isinstance (scalar, _Timedelta) or scalar is NaT):
549
- raise TypeError (scalar)
550
- return scalar.value
570
+ if scalar is NaT:
571
+ return NaT.value
572
+ elif isinstance (scalar, _Timedelta):
573
+ if scalar._reso == self .reso:
574
+ return scalar.value
575
+ else :
576
+ # Note: caller is responsible for catching potential ValueError
577
+ # from _as_reso
578
+ return (< _Timedelta> scalar)._as_reso(self .reso, round_ok = False ).value
579
+ raise TypeError (scalar)
551
580
552
581
553
582
cdef class PeriodEngine(Int64Engine):
0 commit comments