From 84ea60fed628d6da06897544afed7e505b30aba6 Mon Sep 17 00:00:00 2001 From: MarcoGorelli <> Date: Wed, 18 Jan 2023 11:41:04 +0000 Subject: [PATCH 01/17] wip --- pandas/_libs/tslibs/nattype.pyx | 2 +- pandas/_libs/tslibs/offsets.pyx | 4 +-- pandas/_libs/tslibs/timedeltas.pyx | 54 +++++++++++++++--------------- pandas/_libs/tslibs/timestamps.pxd | 2 +- pandas/_libs/tslibs/timestamps.pyx | 50 ++++++++++++++------------- 5 files changed, 58 insertions(+), 54 deletions(-) diff --git a/pandas/_libs/tslibs/nattype.pyx b/pandas/_libs/tslibs/nattype.pyx index 9407f57a282bf..370d7598e55fb 100644 --- a/pandas/_libs/tslibs/nattype.pyx +++ b/pandas/_libs/tslibs/nattype.pyx @@ -357,7 +357,7 @@ class NaTType(_NaT): cdef _NaT base base = _NaT.__new__(cls, 1, 1, 1) - base.value = NPY_NAT + base.value= NPY_NAT return base diff --git a/pandas/_libs/tslibs/offsets.pyx b/pandas/_libs/tslibs/offsets.pyx index 17d4e0dd3234b..237cb256aef93 100644 --- a/pandas/_libs/tslibs/offsets.pyx +++ b/pandas/_libs/tslibs/offsets.pyx @@ -3469,7 +3469,7 @@ cdef class FY5253Quarter(FY5253Mixin): else: tdelta = Timedelta(0) - # Note: we always have tdelta.value >= 0 + # Note: we always have tdelta._value>= 0 return start, num_qtrs, tdelta @apply_wraps @@ -3481,7 +3481,7 @@ cdef class FY5253Quarter(FY5253Mixin): prev_year_end, num_qtrs, tdelta = self._rollback_to_year(other) res = prev_year_end n += num_qtrs - if self.n <= 0 and tdelta.value > 0: + if self.n <= 0 and tdelta._value > 0: n += 1 # Possible speedup by handling years first. diff --git a/pandas/_libs/tslibs/timedeltas.pyx b/pandas/_libs/tslibs/timedeltas.pyx index 8f9dd1fe02c19..a4e9dca800b79 100644 --- a/pandas/_libs/tslibs/timedeltas.pyx +++ b/pandas/_libs/tslibs/timedeltas.pyx @@ -243,7 +243,7 @@ cpdef int64_t delta_to_nanoseconds( in_reso = delta._creso elif isinstance(delta, _Timedelta): - n = delta.value + n = delta._value in_reso = delta._creso elif is_timedelta64_object(delta): @@ -342,7 +342,7 @@ cdef convert_to_timedelta64(object ts, str unit): if ts._creso != NPY_FR_ns: ts = ts.as_unit("ns").asm8 else: - ts = np.timedelta64(ts.value, "ns") + ts = np.timedelta64(ts._value, "ns") elif is_timedelta64_object(ts): ts = ensure_td64ns(ts) elif is_integer_object(ts): @@ -741,7 +741,7 @@ cdef bint _validate_ops_compat(other): def _op_unary_method(func, name): def f(self): - new_value = func(self.value) + new_value = func(self._value) return _timedelta_from_value_and_reso(Timedelta, new_value, self._creso) f.__name__ = name return f @@ -799,7 +799,7 @@ def _binary_op_method_timedeltalike(op, name): elif self._creso > other._creso: other = (<_Timedelta>other)._as_creso(self._creso, round_ok=True) - res = op(self.value, other.value) + res = op(self._value, other._value) if res == NPY_NAT: # e.g. test_implementation_limits # TODO: more generally could do an overflowcheck in op? @@ -969,7 +969,7 @@ cdef _timedelta_from_value_and_reso(cls, int64_t value, NPY_DATETIMEUNIT reso): "Only resolutions 's', 'ms', 'us', 'ns' are supported." ) - td_base.value = value + td_base._value= value td_base._is_populated = 0 td_base._creso = reso return td_base @@ -1093,7 +1093,7 @@ cdef class _Timedelta(timedelta): # if td1 and td2 have different _resos. timedelta64 also has this # non-invariant behavior. # see GH#44504 - return hash(self.value) + return hash(self._value) elif self._is_in_pytimedelta_bounds() and ( self._creso == NPY_FR_ns or self._creso == NPY_DATETIMEUNIT.NPY_FR_us ): @@ -1112,7 +1112,7 @@ cdef class _Timedelta(timedelta): obj = (<_Timedelta>self)._as_creso((self._creso + 1)) except OverflowError: # Doesn't fit, so we're off the hook - return hash(self.value) + return hash(self._value) else: return hash(obj) @@ -1148,7 +1148,7 @@ cdef class _Timedelta(timedelta): return NotImplemented if self._creso == ots._creso: - return cmp_scalar(self.value, ots.value, op) + return cmp_scalar(self._value, ots._value, op) return self._compare_mismatched_resos(ots, op) # TODO: re-use/share with Timestamp @@ -1159,13 +1159,13 @@ cdef class _Timedelta(timedelta): npy_datetimestruct dts_other # dispatch to the datetimestruct utils instead of writing new ones! - pandas_datetime_to_datetimestruct(self.value, self._creso, &dts_self) - pandas_datetime_to_datetimestruct(other.value, other._creso, &dts_other) + pandas_datetime_to_datetimestruct(self._value, self._creso, &dts_self) + pandas_datetime_to_datetimestruct(other._value, other._creso, &dts_other) return cmp_dtstructs(&dts_self, &dts_other, op) cdef bint _has_ns(self): if self._creso == NPY_FR_ns: - return self.value % 1000 != 0 + return self._value % 1000 != 0 elif self._creso < NPY_FR_ns: # i.e. seconds, millisecond, microsecond return False @@ -1189,7 +1189,7 @@ cdef class _Timedelta(timedelta): cdef: pandas_timedeltastruct tds - pandas_timedelta_to_timedeltastruct(self.value, self._creso, &tds) + pandas_timedelta_to_timedeltastruct(self._value, self._creso, &tds) self._d = tds.days self._h = tds.hrs self._m = tds.min @@ -1222,7 +1222,7 @@ cdef class _Timedelta(timedelta): Any nanosecond resolution will be lost. """ if self._creso == NPY_FR_ns: - return timedelta(microseconds=int(self.value) / 1000) + return timedelta(microseconds=int(self._value) / 1000) # TODO(@WillAyd): is this the right way to use components? self._ensure_components() @@ -1238,7 +1238,7 @@ cdef class _Timedelta(timedelta): str abbrev = npy_unit_to_abbrev(self._creso) # TODO: way to create a np.timedelta64 obj with the reso directly # instead of having to get the abbrev? - return np.timedelta64(self.value, abbrev) + return np.timedelta64(self._value, abbrev) def to_numpy(self, dtype=None, copy=False) -> np.timedelta64: """ @@ -1271,7 +1271,7 @@ cdef class _Timedelta(timedelta): dtype : str or dtype The dtype to view the underlying data as. """ - return np.timedelta64(self.value).view(dtype) + return np.timedelta64(self._value).view(dtype) @property def components(self): @@ -1470,7 +1470,7 @@ cdef class _Timedelta(timedelta): return self._repr_base(format="long") def __bool__(self) -> bool: - return self.value != 0 + return self._value!= 0 def isoformat(self) -> str: """ @@ -1556,7 +1556,7 @@ cdef class _Timedelta(timedelta): return self try: - value = convert_reso(self.value, self._creso, reso, round_ok=round_ok) + value = convert_reso(self._value, self._creso, reso, round_ok=round_ok) except OverflowError as err: unit = npy_unit_to_abbrev(reso) raise OutOfBoundsTimedelta( @@ -1771,11 +1771,11 @@ class Timedelta(_Timedelta): reso = NPY_FR_ns else: value, reso = state - self.value = value + self._value= value self._creso = reso def __reduce__(self): - object_state = self.value, self._creso + object_state = self._value, self._creso return (_timedelta_unpickle, object_state) @cython.cdivision(True) @@ -1789,7 +1789,7 @@ class Timedelta(_Timedelta): to_offset(freq).nanos # raises on non-fixed freq unit = delta_to_nanoseconds(to_offset(freq), self._creso) - arr = np.array([self.value], dtype="i8") + arr = np.array([self._value], dtype="i8") result = round_nsint64(arr, mode, unit)[0] return Timedelta._from_value_and_reso(result, self._creso) @@ -1855,7 +1855,7 @@ class Timedelta(_Timedelta): return _timedelta_from_value_and_reso( Timedelta, - (other * self.value), + (other * self._value), reso=self._creso, ) @@ -1878,14 +1878,14 @@ class Timedelta(_Timedelta): return np.nan if other._creso != self._creso: self, other = self._maybe_cast_to_matching_resos(other) - return self.value / float(other.value) + return self._value/ float(other._value) elif is_integer_object(other) or is_float_object(other): # integers or floats if util.is_nan(other): return NaT return Timedelta._from_value_and_reso( - (self.value / other), self._creso + (self._value/ other), self._creso ) elif is_array(other): @@ -1905,7 +1905,7 @@ class Timedelta(_Timedelta): return np.nan if self._creso != other._creso: self, other = self._maybe_cast_to_matching_resos(other) - return float(other.value) / self.value + return float(other._value) / self._value elif is_array(other): if other.ndim == 0: @@ -1933,12 +1933,12 @@ class Timedelta(_Timedelta): return np.nan if self._creso != other._creso: self, other = self._maybe_cast_to_matching_resos(other) - return self.value // other.value + return self._value// other._value elif is_integer_object(other) or is_float_object(other): if util.is_nan(other): return NaT - return type(self)._from_value_and_reso(self.value // other, self._creso) + return type(self)._from_value_and_reso(self._value// other, self._creso) elif is_array(other): if other.ndim == 0: @@ -1982,7 +1982,7 @@ class Timedelta(_Timedelta): return np.nan if self._creso != other._creso: self, other = self._maybe_cast_to_matching_resos(other) - return other.value // self.value + return other._value// self._value elif is_array(other): if other.ndim == 0: diff --git a/pandas/_libs/tslibs/timestamps.pxd b/pandas/_libs/tslibs/timestamps.pxd index 1b87d2ba4eb25..26018cd904249 100644 --- a/pandas/_libs/tslibs/timestamps.pxd +++ b/pandas/_libs/tslibs/timestamps.pxd @@ -21,7 +21,7 @@ cdef _Timestamp create_timestamp_from_ts(int64_t value, cdef class _Timestamp(ABCTimestamp): cdef readonly: - int64_t value, nanosecond, year + int64_t _value, nanosecond, year NPY_DATETIMEUNIT _creso cdef bint _get_start_end_field(self, str field, freq) diff --git a/pandas/_libs/tslibs/timestamps.pyx b/pandas/_libs/tslibs/timestamps.pyx index c1aef2e5115ac..b602caba3e069 100644 --- a/pandas/_libs/tslibs/timestamps.pyx +++ b/pandas/_libs/tslibs/timestamps.pyx @@ -154,7 +154,7 @@ cdef _Timestamp create_timestamp_from_ts( dts.day, dts.hour, dts.min, dts.sec, dts.us, tz, fold=fold) - ts_base.value = value + ts_base._value = value ts_base.year = dts.year ts_base.nanosecond = dts.ps // 1000 ts_base._creso = reso @@ -232,6 +232,10 @@ cdef class _Timestamp(ABCTimestamp): max = MinMaxReso("max") resolution = MinMaxReso("resolution") # GH#21336, GH#21365 + @property + def value(self) -> int: + return convert_reso(self._value, self._creso, NPY_FR_ns, False) + @property def unit(self) -> str: """ @@ -282,10 +286,10 @@ cdef class _Timestamp(ABCTimestamp): def __hash__(_Timestamp self): if self.nanosecond: - return hash(self.value) + return hash(self._value) if not (1 <= self.year <= 9999): # out of bounds for pydatetime - return hash(self.value) + return hash(self._value) if self.fold: return datetime.__hash__(self.replace(fold=0)) return datetime.__hash__(self) @@ -357,7 +361,7 @@ cdef class _Timestamp(ABCTimestamp): "Cannot compare tz-naive and tz-aware timestamps" ) if self._creso == ots._creso: - return cmp_scalar(self.value, ots.value, op) + return cmp_scalar(self._value, ots._value, op) return self._compare_mismatched_resos(ots, op) # TODO: copied from Timedelta; try to de-duplicate @@ -368,8 +372,8 @@ cdef class _Timestamp(ABCTimestamp): npy_datetimestruct dts_other # dispatch to the datetimestruct utils instead of writing new ones! - pandas_datetime_to_datetimestruct(self.value, self._creso, &dts_self) - pandas_datetime_to_datetimestruct(other.value, other._creso, &dts_other) + pandas_datetime_to_datetimestruct(self._value, self._creso, &dts_self) + pandas_datetime_to_datetimestruct(other._value, other._creso, &dts_other) return cmp_dtstructs(&dts_self, &dts_other, op) cdef bint _compare_outside_nanorange(_Timestamp self, datetime other, @@ -414,16 +418,16 @@ cdef class _Timestamp(ABCTimestamp): elif self._creso > other._creso: other = (<_Timedelta>other)._as_creso(self._creso, round_ok=True) - nanos = other.value + nanos = other._value try: - new_value = self.value + nanos + new_value = self._value+ nanos result = type(self)._from_value_and_reso( new_value, reso=self._creso, tz=self.tzinfo ) except OverflowError as err: # TODO: don't hard-code nanosecond here - new_value = int(self.value) + int(nanos) + new_value = int(self._value) + int(nanos) raise OutOfBoundsDatetime( f"Out of bounds nanosecond timestamp: {new_value}" ) from err @@ -505,7 +509,7 @@ cdef class _Timestamp(ABCTimestamp): # scalar Timestamp/datetime - Timestamp/datetime -> yields a # Timedelta try: - res_value = self.value - other.value + res_value = self._value- other._value return Timedelta._from_value_and_reso(res_value, self._creso) except (OverflowError, OutOfBoundsDatetime, OutOfBoundsTimedelta) as err: if isinstance(other, _Timestamp): @@ -551,7 +555,7 @@ cdef class _Timestamp(ABCTimestamp): pydatetime_to_dtstruct(self, &dts) val = npy_datetimestruct_to_datetime(self._creso, &dts) + self.nanosecond else: - val = self.value + val = self._value return val @cython.boundscheck(False) @@ -891,7 +895,7 @@ cdef class _Timestamp(ABCTimestamp): return self.__reduce__() def __setstate__(self, state): - self.value = state[0] + self._value= state[0] self.tzinfo = state[2] if len(state) == 3: @@ -903,7 +907,7 @@ cdef class _Timestamp(ABCTimestamp): self._creso = reso def __reduce__(self): - object_state = self.value, None, self.tzinfo, self._creso + object_state = self._value, None, self.tzinfo, self._creso return (_unpickle_timestamp, object_state) # ----------------------------------------------------------------- @@ -1030,7 +1034,7 @@ cdef class _Timestamp(ABCTimestamp): return self try: - value = convert_reso(self.value, self._creso, creso, round_ok=round_ok) + value = convert_reso(self._value, self._creso, creso, round_ok=round_ok) except OverflowError as err: unit = npy_unit_to_abbrev(creso) raise OutOfBoundsDatetime( @@ -1090,7 +1094,7 @@ cdef class _Timestamp(ABCTimestamp): denom = periods_per_second(self._creso) - return round(self.value / denom, 6) + return round(self._value/ denom, 6) cpdef datetime to_pydatetime(_Timestamp self, bint warn=True): """ @@ -1123,7 +1127,7 @@ cdef class _Timestamp(ABCTimestamp): """ # TODO: find a way to construct dt64 directly from _reso abbrev = npy_unit_to_abbrev(self._creso) - return np.datetime64(self.value, abbrev) + return np.datetime64(self._value, abbrev) def to_numpy(self, dtype=None, copy=False) -> np.datetime64: """ @@ -1618,9 +1622,9 @@ class Timestamp(_Timestamp): # TODO: problem if nanos==0 if self.tz is not None: - value = self.tz_localize(None).value + value = self.tz_localize(None)._value else: - value = self.value + value = self._value value = np.array([value], dtype=np.int64) @@ -2016,13 +2020,13 @@ default 'raise' tz = maybe_get_tz(tz) if not isinstance(ambiguous, str): ambiguous = [ambiguous] - value = tz_localize_to_utc_single(self.value, tz, + value = tz_localize_to_utc_single(self._value, tz, ambiguous=ambiguous, nonexistent=nonexistent, creso=self._creso) elif tz is None: # reset tz - value = tz_convert_from_utc_single(self.value, self.tz, creso=self._creso) + value = tz_convert_from_utc_single(self._value, self.tz, creso=self._creso) else: raise TypeError( @@ -2082,7 +2086,7 @@ default 'raise' else: # Same UTC timestamp, different time zone tz = maybe_get_tz(tz) - out = type(self)._from_value_and_reso(self.value, reso=self._creso, tz=tz) + out = type(self)._from_value_and_reso(self._value, reso=self._creso, tz=tz) return out astimezone = tz_convert @@ -2154,7 +2158,7 @@ default 'raise' # set to naive if needed tzobj = self.tzinfo - value = self.value + value = self._value # GH 37610. Preserve fold when replacing. if fold is None: @@ -2215,7 +2219,7 @@ default 'raise' ts_input, tzobj, nanos=dts.ps // 1000, reso=self._creso ) return create_timestamp_from_ts( - ts.value, dts, tzobj, fold, reso=self._creso + ts._value, dts, tzobj, fold, reso=self._creso ) def to_julian_date(self) -> np.float64: From 540113ac435cbe8bcb47d164d289841da2831cb2 Mon Sep 17 00:00:00 2001 From: MarcoGorelli <> Date: Wed, 18 Jan 2023 12:09:53 +0000 Subject: [PATCH 02/17] wip --- pandas/_libs/tslib.pyx | 2 +- pandas/_libs/tslibs/conversion.pyx | 2 +- pandas/_libs/tslibs/nattype.pxd | 2 +- pandas/_libs/tslibs/nattype.pyx | 2 +- pandas/_libs/tslibs/strptime.pyx | 8 ++++---- pandas/_libs/tslibs/timedeltas.pxd | 2 +- pandas/_libs/tslibs/timestamps.pyx | 3 ++- pandas/core/arrays/_ranges.py | 6 +++--- pandas/core/arrays/datetimelike.py | 4 ++-- pandas/core/arrays/datetimes.py | 8 ++++---- pandas/core/arrays/period.py | 2 +- pandas/core/arrays/timedeltas.py | 4 ++-- pandas/core/dtypes/cast.py | 2 +- pandas/core/tools/datetimes.py | 4 ++-- pandas/tests/arrays/test_datetimelike.py | 12 ++++++------ pandas/tests/indexes/datetimes/test_constructors.py | 6 +++--- pandas/tests/series/test_constructors.py | 2 +- pandas/tests/tools/test_to_datetime.py | 12 ++++++------ pandas/tests/tslibs/test_timezones.py | 2 +- 19 files changed, 43 insertions(+), 42 deletions(-) diff --git a/pandas/_libs/tslib.pyx b/pandas/_libs/tslib.pyx index 5f7fb05876b35..06a25c59a3fa9 100644 --- a/pandas/_libs/tslib.pyx +++ b/pandas/_libs/tslib.pyx @@ -770,7 +770,7 @@ def array_to_datetime_with_tz(ndarray values, tzinfo tz): # datetime64, tznaive pydatetime, int, float ts = ts.tz_localize(tz) ts = ts.as_unit("ns") - ival = ts.value + ival = ts._value # Analogous to: result[i] = ival (cnp.PyArray_MultiIter_DATA(mi, 0))[0] = ival diff --git a/pandas/_libs/tslibs/conversion.pyx b/pandas/_libs/tslibs/conversion.pyx index d862b5bb606cc..e3b333b54ba1d 100644 --- a/pandas/_libs/tslibs/conversion.pyx +++ b/pandas/_libs/tslibs/conversion.pyx @@ -767,7 +767,7 @@ cdef int64_t parse_pydatetime( result = _ts.value else: if isinstance(val, _Timestamp): - result = val.as_unit("ns").value + result = val.as_unit("ns")._value else: result = pydatetime_to_dt64(val, dts) check_dts_bounds(dts) diff --git a/pandas/_libs/tslibs/nattype.pxd b/pandas/_libs/tslibs/nattype.pxd index e878fa7629f25..32705aa633135 100644 --- a/pandas/_libs/tslibs/nattype.pxd +++ b/pandas/_libs/tslibs/nattype.pxd @@ -8,7 +8,7 @@ cdef set c_nat_strings cdef class _NaT(datetime): cdef readonly: - int64_t value + int64_t _value cdef _NaT c_NaT diff --git a/pandas/_libs/tslibs/nattype.pyx b/pandas/_libs/tslibs/nattype.pyx index 370d7598e55fb..88b7707c4fb53 100644 --- a/pandas/_libs/tslibs/nattype.pyx +++ b/pandas/_libs/tslibs/nattype.pyx @@ -357,7 +357,7 @@ class NaTType(_NaT): cdef _NaT base base = _NaT.__new__(cls, 1, 1, 1) - base.value= NPY_NAT + base._value= NPY_NAT return base diff --git a/pandas/_libs/tslibs/strptime.pyx b/pandas/_libs/tslibs/strptime.pyx index 3ca87f8680b53..bb06c65597987 100644 --- a/pandas/_libs/tslibs/strptime.pyx +++ b/pandas/_libs/tslibs/strptime.pyx @@ -113,14 +113,14 @@ cdef bint parse_today_now(str val, int64_t* iresult, bint utc): # microsecond resolution if val == "now": if utc: - iresult[0] = Timestamp.utcnow().value * 1000 + iresult[0] = Timestamp.utcnow()._value * 1000 else: # GH#18705 make sure to_datetime("now") matches Timestamp("now") # Note using Timestamp.now() is faster than Timestamp("now") - iresult[0] = Timestamp.now().value * 1000 + iresult[0] = Timestamp.now()._value * 1000 return True elif val == "today": - iresult[0] = Timestamp.today().value * 1000 + iresult[0] = Timestamp.today()._value * 1000 return True return False @@ -284,7 +284,7 @@ def array_strptime( utc, ) if isinstance(val, _Timestamp): - iresult[i] = val.tz_localize(None).as_unit("ns").value + iresult[i] = val.tz_localize(None).as_unit("ns")._value else: iresult[i] = pydatetime_to_dt64(val.replace(tzinfo=None), &dts) check_dts_bounds(&dts) diff --git a/pandas/_libs/tslibs/timedeltas.pxd b/pandas/_libs/tslibs/timedeltas.pxd index 3f37ef7eb1e3f..f072fb8196214 100644 --- a/pandas/_libs/tslibs/timedeltas.pxd +++ b/pandas/_libs/tslibs/timedeltas.pxd @@ -15,7 +15,7 @@ cdef object ensure_td64ns(object ts) cdef class _Timedelta(timedelta): cdef readonly: - int64_t value # nanoseconds + int64_t _value # nanoseconds bint _is_populated # are my components populated int64_t _d, _h, _m, _s, _ms, _us, _ns NPY_DATETIMEUNIT _creso diff --git a/pandas/_libs/tslibs/timestamps.pyx b/pandas/_libs/tslibs/timestamps.pyx index b602caba3e069..02bf03c4a6d24 100644 --- a/pandas/_libs/tslibs/timestamps.pyx +++ b/pandas/_libs/tslibs/timestamps.pyx @@ -234,6 +234,7 @@ cdef class _Timestamp(ABCTimestamp): @property def value(self) -> int: + 1/0 return convert_reso(self._value, self._creso, NPY_FR_ns, False) @property @@ -2219,7 +2220,7 @@ default 'raise' ts_input, tzobj, nanos=dts.ps // 1000, reso=self._creso ) return create_timestamp_from_ts( - ts._value, dts, tzobj, fold, reso=self._creso + ts.value, dts, tzobj, fold, reso=self._creso ) def to_julian_date(self) -> np.float64: diff --git a/pandas/core/arrays/_ranges.py b/pandas/core/arrays/_ranges.py index baf8470a866ff..c93fc94685358 100644 --- a/pandas/core/arrays/_ranges.py +++ b/pandas/core/arrays/_ranges.py @@ -46,8 +46,8 @@ def generate_regular_range( ndarray[np.int64] Representing the given resolution. """ - istart = start.value if start is not None else None - iend = end.value if end is not None else None + istart = start._value if start is not None else None + iend = end._value if end is not None else None freq.nanos # raises if non-fixed frequency td = Timedelta(freq) try: @@ -59,7 +59,7 @@ def generate_regular_range( f"freq={freq} is incompatible with unit={unit}. " "Use a lower freq or a higher unit instead." ) from err - stride = int(td.value) + stride = int(td._value) if periods is None and istart is not None and iend is not None: b = istart diff --git a/pandas/core/arrays/datetimelike.py b/pandas/core/arrays/datetimelike.py index 816d8abec1428..f59f8ac245c33 100644 --- a/pandas/core/arrays/datetimelike.py +++ b/pandas/core/arrays/datetimelike.py @@ -176,7 +176,7 @@ def new_meth(self, *args, **kwargs): if result is NaT: return NaT elif isinstance(result, Timestamp): - return self._box_func(result.value) + return self._box_func(result._value) res_i8 = result.view("i8") return self._from_backing_data(res_i8) @@ -1003,7 +1003,7 @@ def _get_i8_values_and_mask( i8values = other.ordinal mask = None elif isinstance(other, (Timestamp, Timedelta)): - i8values = other.value + i8values = other._value mask = None else: # PeriodArray, DatetimeArray, TimedeltaArray diff --git a/pandas/core/arrays/datetimes.py b/pandas/core/arrays/datetimes.py index 53d02e92946d9..3efaa070b2fe8 100644 --- a/pandas/core/arrays/datetimes.py +++ b/pandas/core/arrays/datetimes.py @@ -446,7 +446,7 @@ def _generate_range( # type: ignore[override] xdr = _generate_range( start=start, end=end, periods=periods, offset=freq, unit=unit ) - i8values = np.array([x.value for x in xdr], dtype=np.int64) + i8values = np.array([x._value for x in xdr], dtype=np.int64) endpoint_tz = start.tz if start is not None else end.tz @@ -488,8 +488,8 @@ def _generate_range( # type: ignore[override] if not left_inclusive and not right_inclusive: i8values = i8values[1:-1] else: - start_i8 = Timestamp(start).value - end_i8 = Timestamp(end).value + start_i8 = Timestamp(start)._value + end_i8 = Timestamp(end)._value if not left_inclusive or not right_inclusive: if not left_inclusive and len(i8values) and i8values[0] == start_i8: i8values = i8values[1:] @@ -508,7 +508,7 @@ def _unbox_scalar(self, value) -> np.datetime64: raise ValueError("'value' should be a Timestamp.") self._check_compatible_with(value) if value is NaT: - return np.datetime64(value.value, self.unit) + return np.datetime64(value._value, self.unit) else: return value.as_unit(self.unit).asm8 diff --git a/pandas/core/arrays/period.py b/pandas/core/arrays/period.py index e6682b0dea814..da1c94101b785 100644 --- a/pandas/core/arrays/period.py +++ b/pandas/core/arrays/period.py @@ -331,7 +331,7 @@ def _unbox_scalar( # type: ignore[override] ) -> np.int64: if value is NaT: # error: Item "Period" of "Union[Period, NaTType]" has no attribute "value" - return np.int64(value.value) # type: ignore[union-attr] + return np.int64(value._value) # type: ignore[union-attr] elif isinstance(value, self._scalar_type): self._check_compatible_with(value) return np.int64(value.ordinal) diff --git a/pandas/core/arrays/timedeltas.py b/pandas/core/arrays/timedeltas.py index 1371472af34f8..66026661cff0e 100644 --- a/pandas/core/arrays/timedeltas.py +++ b/pandas/core/arrays/timedeltas.py @@ -151,7 +151,7 @@ def _scalar_type(self) -> type[Timedelta]: def _box_func(self, x: np.timedelta64) -> Timedelta | NaTType: y = x.view("i8") - if y == NaT.value: + if y == NaT._value: return NaT return Timedelta._from_value_and_reso(y, reso=self._creso) @@ -316,7 +316,7 @@ def _unbox_scalar(self, value) -> np.timedelta64: raise ValueError("'value' should be a Timedelta.") self._check_compatible_with(value) if value is NaT: - return np.timedelta64(value.value, "ns") + return np.timedelta64(value._value, "ns") else: return value.as_unit(self.unit).asm8 diff --git a/pandas/core/dtypes/cast.py b/pandas/core/dtypes/cast.py index 3be89f6da2bd8..f0b309638321c 100644 --- a/pandas/core/dtypes/cast.py +++ b/pandas/core/dtypes/cast.py @@ -814,7 +814,7 @@ def infer_dtype_from_scalar(val, pandas_dtype: bool = False) -> tuple[DtypeObj, dtype = _dtype_obj else: dtype = np.dtype("m8[ns]") - val = np.timedelta64(val.value, "ns") + val = np.timedelta64(val._value, "ns") elif is_bool(val): dtype = np.dtype(np.bool_) diff --git a/pandas/core/tools/datetimes.py b/pandas/core/tools/datetimes.py index eaa7339f3747a..14a09ff5ff4e9 100644 --- a/pandas/core/tools/datetimes.py +++ b/pandas/core/tools/datetimes.py @@ -520,8 +520,8 @@ def _to_datetime_with_unit(arg, unit, name, utc: bool, errors: str) -> Index: fvalues = iresult.astype("f8") * mult - if (fvalues < Timestamp.min.value).any() or ( - fvalues > Timestamp.max.value + if (fvalues < Timestamp.min._value).any() or ( + fvalues > Timestamp.max._value ).any(): if errors != "raise": arg = arg.astype(object) diff --git a/pandas/tests/arrays/test_datetimelike.py b/pandas/tests/arrays/test_datetimelike.py index f80051fb187ba..362abee1d482a 100644 --- a/pandas/tests/arrays/test_datetimelike.py +++ b/pandas/tests/arrays/test_datetimelike.py @@ -339,7 +339,7 @@ def test_searchsorted_castable_strings(self, arr1d, box, string_storage): def test_getitem_near_implementation_bounds(self): # We only check tz-naive for DTA bc the bounds are slightly different # for other tzs - i8vals = np.asarray([NaT.value + n for n in range(1, 5)], dtype="i8") + i8vals = np.asarray([NaT._value + n for n in range(1, 5)], dtype="i8") arr = self.array_cls(i8vals, freq="ns") arr[0] # should not raise OutOfBoundsDatetime @@ -815,7 +815,7 @@ def test_take_fill_valid(self, arr1d, fixed_now_ts): # Timestamp with mismatched tz-awareness arr.take([-1, 1], allow_fill=True, fill_value=now) - value = NaT.value + value = NaT._value msg = f"value should be a '{arr1d._scalar_type.__name__}' or 'NaT'. Got" with pytest.raises(TypeError, match=msg): # require NaT, not iNaT, as it could be confused with an integer @@ -1038,7 +1038,7 @@ def test_astype_object(self, arr1d): def test_take_fill_valid(self, arr1d): arr = arr1d - value = NaT.value + value = NaT._value msg = f"value should be a '{arr1d._scalar_type.__name__}' or 'NaT'. Got" with pytest.raises(TypeError, match=msg): # require NaT, not iNaT, as it could be confused with an integer @@ -1181,15 +1181,15 @@ def test_casting_nat_setitem_array(arr, casting_nats): [ ( TimedeltaIndex(["1 Day", "3 Hours", "NaT"])._data, - (np.datetime64("NaT", "ns"), NaT.value), + (np.datetime64("NaT", "ns"), NaT._value), ), ( pd.date_range("2000-01-01", periods=3, freq="D")._data, - (np.timedelta64("NaT", "ns"), NaT.value), + (np.timedelta64("NaT", "ns"), NaT._value), ), ( pd.period_range("2000-01-01", periods=3, freq="D")._data, - (np.datetime64("NaT", "ns"), np.timedelta64("NaT", "ns"), NaT.value), + (np.datetime64("NaT", "ns"), np.timedelta64("NaT", "ns"), NaT._value), ), ], ids=lambda x: type(x).__name__, diff --git a/pandas/tests/indexes/datetimes/test_constructors.py b/pandas/tests/indexes/datetimes/test_constructors.py index e1ada9f10c261..4c8d22b8f9384 100644 --- a/pandas/tests/indexes/datetimes/test_constructors.py +++ b/pandas/tests/indexes/datetimes/test_constructors.py @@ -73,7 +73,7 @@ def test_freq_validation_with_nat(self, dt_cls): with pytest.raises(ValueError, match=msg): dt_cls([pd.NaT, Timestamp("2011-01-01")], freq="D") with pytest.raises(ValueError, match=msg): - dt_cls([pd.NaT, Timestamp("2011-01-01").value], freq="D") + dt_cls([pd.NaT, Timestamp("2011-01-01")._value], freq="D") # TODO: better place for tests shared by DTI/TDI? @pytest.mark.parametrize( @@ -805,7 +805,7 @@ def test_constructor_timestamp_near_dst(self): def test_constructor_with_int_tz(self, klass, box, tz, dtype): # GH 20997, 20964 ts = Timestamp("2018-01-01", tz=tz).as_unit("ns") - result = klass(box([ts.value]), dtype=dtype) + result = klass(box([ts._value]), dtype=dtype) expected = klass([ts]) assert result == expected @@ -1200,6 +1200,6 @@ def test_timestamp_constructor_adjust_value_for_fold(tz, ts_input, fold, value_o # Check that we adjust value for fold correctly # based on timestamps since utc ts = Timestamp(ts_input, tz=tz, fold=fold) - result = ts.value + result = ts._value expected = value_out assert result == expected diff --git a/pandas/tests/series/test_constructors.py b/pandas/tests/series/test_constructors.py index f89ecfecedbed..e0d5684fdc447 100644 --- a/pandas/tests/series/test_constructors.py +++ b/pandas/tests/series/test_constructors.py @@ -901,7 +901,7 @@ def test_constructor_datelike_coercion2(self): def test_constructor_mixed_int_and_timestamp(self, frame_or_series): # specifically Timestamp with nanos, not datetimes - objs = [Timestamp(9), 10, NaT.value] + objs = [Timestamp(9), 10, NaT._value] result = frame_or_series(objs, dtype="M8[ns]") expected = frame_or_series([Timestamp(9), Timestamp(10), NaT]) diff --git a/pandas/tests/tools/test_to_datetime.py b/pandas/tests/tools/test_to_datetime.py index fcbe33a555f4f..7f6b4780ea7ed 100644 --- a/pandas/tests/tools/test_to_datetime.py +++ b/pandas/tests/tools/test_to_datetime.py @@ -945,8 +945,8 @@ def test_to_datetime_now(self): # These should all be equal with infinite perf; this gives # a generous margin of 10 seconds - assert abs(pdnow.value - now.value) < 1e10 - assert abs(pdnow2.value - now.value) < 1e10 + assert abs(pdnow._value - now._value) < 1e10 + assert abs(pdnow2._value - now._value) < 1e10 assert pdnow.tzinfo is None assert pdnow2.tzinfo is None @@ -970,10 +970,10 @@ def test_to_datetime_today(self, tz): # These should all be equal with infinite perf; this gives # a generous margin of 10 seconds - assert abs(pdtoday.normalize().value - nptoday) < 1e10 - assert abs(pdtoday2.normalize().value - nptoday) < 1e10 - assert abs(pdtoday.value - tstoday.value) < 1e10 - assert abs(pdtoday.value - tstoday2.value) < 1e10 + assert abs(pdtoday.normalize()._value - nptoday) < 1e10 + assert abs(pdtoday2.normalize()._value - nptoday) < 1e10 + assert abs(pdtoday._value - tstoday._value) < 1e10 + assert abs(pdtoday._value - tstoday2._value) < 1e10 assert pdtoday.tzinfo is None assert pdtoday2.tzinfo is None diff --git a/pandas/tests/tslibs/test_timezones.py b/pandas/tests/tslibs/test_timezones.py index 386b89fa03471..28e4889983fb9 100644 --- a/pandas/tests/tslibs/test_timezones.py +++ b/pandas/tests/tslibs/test_timezones.py @@ -57,7 +57,7 @@ def test_tzlocal_offset(): offset = dateutil.tz.tzlocal().utcoffset(datetime(2011, 1, 1)) offset = offset.total_seconds() - assert ts.value + offset == Timestamp("2011-01-01").value + assert ts._value + offset == Timestamp("2011-01-01")._value def test_tzlocal_is_not_utc(): From 82da04f9596ca11fcd9968e3d1c55fad37e9eed4 Mon Sep 17 00:00:00 2001 From: MarcoGorelli <> Date: Wed, 18 Jan 2023 13:13:06 +0000 Subject: [PATCH 03/17] fixup test collection --- pandas/core/arrays/datetimes.py | 4 ++-- pandas/tests/dtypes/test_missing.py | 4 ++-- pandas/tests/indexes/test_engines.py | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/pandas/core/arrays/datetimes.py b/pandas/core/arrays/datetimes.py index 3efaa070b2fe8..bc311e176218b 100644 --- a/pandas/core/arrays/datetimes.py +++ b/pandas/core/arrays/datetimes.py @@ -476,8 +476,8 @@ def _generate_range( # type: ignore[override] # representable with doubles, so we limit the range that we # pass to np.linspace as much as possible i8values = ( - np.linspace(0, end.value - start.value, periods, dtype="int64") - + start.value + np.linspace(0, end._value - start._value, periods, dtype="int64") + + start._value ) if i8values.dtype != "i8": # 2022-01-09 I (brock) am not sure if it is possible for this diff --git a/pandas/tests/dtypes/test_missing.py b/pandas/tests/dtypes/test_missing.py index b9aa84aefd2cb..b62d3c96cd137 100644 --- a/pandas/tests/dtypes/test_missing.py +++ b/pandas/tests/dtypes/test_missing.py @@ -801,8 +801,8 @@ def test_empty_like(self): int_na_vals = [ # Values that match iNaT, which we treat as null in specific cases - np.int64(NaT.value), - int(NaT.value), + np.int64(NaT._value), + int(NaT._value), ] sometimes_na_vals = [Decimal("NaN")] diff --git a/pandas/tests/indexes/test_engines.py b/pandas/tests/indexes/test_engines.py index 02d8c5b2a6a22..a4b7ce6822b80 100644 --- a/pandas/tests/indexes/test_engines.py +++ b/pandas/tests/indexes/test_engines.py @@ -32,7 +32,7 @@ class TestDatetimeEngine: "scalar", [ pd.Timedelta(pd.Timestamp("2016-01-01").asm8.view("m8[ns]")), - pd.Timestamp("2016-01-01").value, + pd.Timestamp("2016-01-01")._value, pd.Timestamp("2016-01-01").to_pydatetime(), pd.Timestamp("2016-01-01").to_datetime64(), ], @@ -58,7 +58,7 @@ class TestTimedeltaEngine: "scalar", [ pd.Timestamp(pd.Timedelta(days=42).asm8.view("datetime64[ns]")), - pd.Timedelta(days=42).value, + pd.Timedelta(days=42)._value, pd.Timedelta(days=42).to_pytimedelta(), pd.Timedelta(days=42).to_timedelta64(), ], From c026a4f1179047768fa616edd870c0f687a2292a Mon Sep 17 00:00:00 2001 From: MarcoGorelli <> Date: Wed, 18 Jan 2023 13:16:13 +0000 Subject: [PATCH 04/17] divide by zero to debug LOL --- pandas/_libs/tslibs/timedeltas.pyx | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pandas/_libs/tslibs/timedeltas.pyx b/pandas/_libs/tslibs/timedeltas.pyx index a4e9dca800b79..e2d0e4649fb71 100644 --- a/pandas/_libs/tslibs/timedeltas.pyx +++ b/pandas/_libs/tslibs/timedeltas.pyx @@ -1020,6 +1020,11 @@ cdef class _Timedelta(timedelta): max = MinMaxReso("max") resolution = MinMaxReso("resolution") + @property + def value(self): + 1/0 + pass + @property def _unit(self) -> str: """ From 378dbef2527ae09c09968356087a9198120eef34 Mon Sep 17 00:00:00 2001 From: MarcoGorelli <> Date: Wed, 18 Jan 2023 17:46:56 +0000 Subject: [PATCH 05/17] wip --- pandas/_libs/index.pyx | 18 +++-- pandas/core/arrays/timedeltas.py | 2 +- pandas/core/indexes/datetimelike.py | 4 +- pandas/core/resample.py | 32 ++++----- pandas/core/reshape/merge.py | 2 +- pandas/tests/arithmetic/test_datetime64.py | 18 ++--- pandas/tests/arithmetic/test_timedelta64.py | 4 +- pandas/tests/arrays/test_datetimes.py | 2 +- .../tests/frame/methods/test_sort_values.py | 2 +- pandas/tests/groupby/test_function.py | 2 +- .../indexes/datetimes/test_date_range.py | 2 +- .../tests/indexes/datetimes/test_indexing.py | 2 +- .../tests/indexes/datetimes/test_timezones.py | 2 +- pandas/tests/indexes/datetimes/test_unique.py | 2 +- pandas/tests/indexes/period/test_indexing.py | 2 +- .../tests/indexes/timedeltas/test_indexing.py | 2 +- pandas/tests/indexing/test_loc.py | 4 +- pandas/tests/scalar/test_nat.py | 2 +- .../scalar/timedelta/test_constructors.py | 32 ++++----- .../tests/scalar/timedelta/test_timedelta.py | 68 +++++++++---------- .../tests/scalar/timestamp/test_timestamp.py | 4 +- pandas/tests/series/indexing/test_setitem.py | 2 +- pandas/tests/series/methods/test_fillna.py | 4 +- pandas/tests/series/test_repr.py | 2 +- pandas/tests/tools/test_to_timedelta.py | 2 +- 25 files changed, 111 insertions(+), 107 deletions(-) diff --git a/pandas/_libs/index.pyx b/pandas/_libs/index.pyx index 9e2adee407b1a..ed46029b08bfd 100644 --- a/pandas/_libs/index.pyx +++ b/pandas/_libs/index.pyx @@ -503,14 +503,16 @@ cdef class DatetimeEngine(Int64Engine): # NB: caller is responsible for ensuring tzawareness compat # before we get here if scalar is NaT: - return NaT.value + return NaT._value elif isinstance(scalar, _Timestamp): if scalar._creso == self._creso: - return scalar.value + return scalar._value else: # Note: caller is responsible for catching potential ValueError # from _as_creso - return (<_Timestamp>scalar)._as_creso(self._creso, round_ok=False).value + return ( + (<_Timestamp>scalar)._as_creso(self._creso, round_ok=False)._value + ) raise TypeError(scalar) def __contains__(self, val: object) -> bool: @@ -571,14 +573,16 @@ cdef class TimedeltaEngine(DatetimeEngine): cdef int64_t _unbox_scalar(self, scalar) except? -1: if scalar is NaT: - return NaT.value + return NaT._value elif isinstance(scalar, _Timedelta): if scalar._creso == self._creso: - return scalar.value + return scalar._value else: # Note: caller is responsible for catching potential ValueError # from _as_creso - return (<_Timedelta>scalar)._as_creso(self._creso, round_ok=False).value + return ( + (<_Timedelta>scalar)._as_creso(self._creso, round_ok=False)._value + ) raise TypeError(scalar) @@ -586,7 +590,7 @@ cdef class PeriodEngine(Int64Engine): cdef int64_t _unbox_scalar(self, scalar) except? -1: if scalar is NaT: - return scalar.value + return scalar._value if is_period_object(scalar): # NB: we assume that we have the correct freq here. return scalar.ordinal diff --git a/pandas/core/arrays/timedeltas.py b/pandas/core/arrays/timedeltas.py index 66026661cff0e..ce9d9b53af62b 100644 --- a/pandas/core/arrays/timedeltas.py +++ b/pandas/core/arrays/timedeltas.py @@ -298,7 +298,7 @@ def _generate_range( # type: ignore[override] if freq is not None: index = generate_regular_range(start, end, periods, freq, unit=unit) else: - index = np.linspace(start.value, end.value, periods).astype("i8") + index = np.linspace(start._value, end._value, periods).astype("i8") if not left_closed: index = index[1:] diff --git a/pandas/core/indexes/datetimelike.py b/pandas/core/indexes/datetimelike.py index ea0c93e75f496..c5739ad150c8d 100644 --- a/pandas/core/indexes/datetimelike.py +++ b/pandas/core/indexes/datetimelike.py @@ -469,8 +469,8 @@ def _as_range_index(self) -> RangeIndex: # Convert our i8 representations to RangeIndex # Caller is responsible for checking isinstance(self.freq, Tick) freq = cast(Tick, self.freq) - tick = freq.delta.value - rng = range(self[0].value, self[-1].value + tick, tick) + tick = freq.delta._value + rng = range(self[0]._value, self[-1]._value + tick, tick) return RangeIndex(rng) def _can_range_setop(self, other): diff --git a/pandas/core/resample.py b/pandas/core/resample.py index 3c26299c93b70..cf4cd09757ec4 100644 --- a/pandas/core/resample.py +++ b/pandas/core/resample.py @@ -2089,19 +2089,19 @@ def _adjust_dates_anchored( origin_nanos = 0 # origin == "epoch" if origin == "start_day": - origin_nanos = first.normalize().value + origin_nanos = first.normalize()._value elif origin == "start": - origin_nanos = first.value + origin_nanos = first._value elif isinstance(origin, Timestamp): - origin_nanos = origin.as_unit("ns").value + origin_nanos = origin.as_unit("ns")._value elif origin in ["end", "end_day"]: origin_last = last if origin == "end" else last.ceil("D") - sub_freq_times = (origin_last.value - first.value) // freq.nanos + sub_freq_times = (origin_last._value - first._value) // freq.nanos if closed == "left": sub_freq_times += 1 first = origin_last - sub_freq_times * freq - origin_nanos = first.value - origin_nanos += offset.value if offset else 0 + origin_nanos = first._value + origin_nanos += offset._value if offset else 0 # GH 10117 & GH 19375. If first and last contain timezone information, # Perform the calculation in UTC in order to avoid localizing on an @@ -2113,34 +2113,34 @@ def _adjust_dates_anchored( if last_tzinfo is not None: last = last.tz_convert("UTC") - foffset = (first.value - origin_nanos) % freq.nanos - loffset = (last.value - origin_nanos) % freq.nanos + foffset = (first._value - origin_nanos) % freq.nanos + loffset = (last._value - origin_nanos) % freq.nanos if closed == "right": if foffset > 0: # roll back - fresult_int = first.value - foffset + fresult_int = first._value - foffset else: - fresult_int = first.value - freq.nanos + fresult_int = first._value - freq.nanos if loffset > 0: # roll forward - lresult_int = last.value + (freq.nanos - loffset) + lresult_int = last._value + (freq.nanos - loffset) else: # already the end of the road - lresult_int = last.value + lresult_int = last._value else: # closed == 'left' if foffset > 0: - fresult_int = first.value - foffset + fresult_int = first._value - foffset else: # start of the road - fresult_int = first.value + fresult_int = first._value if loffset > 0: # roll forward - lresult_int = last.value + (freq.nanos - loffset) + lresult_int = last._value + (freq.nanos - loffset) else: - lresult_int = last.value + freq.nanos + lresult_int = last._value + freq.nanos fresult = Timestamp(fresult_int) lresult = Timestamp(lresult_int) if first_tzinfo is not None: diff --git a/pandas/core/reshape/merge.py b/pandas/core/reshape/merge.py index 8d009d25a66ba..2ff04354e7b4b 100644 --- a/pandas/core/reshape/merge.py +++ b/pandas/core/reshape/merge.py @@ -2113,7 +2113,7 @@ def injection(obj): right_values = right_values.view("i8") if tolerance is not None: tolerance = Timedelta(tolerance) - tolerance = tolerance.value + tolerance = tolerance._value # a "by" parameter requires special handling if self.left_by is not None: diff --git a/pandas/tests/arithmetic/test_datetime64.py b/pandas/tests/arithmetic/test_datetime64.py index 2b5eb8b261af3..8dce4cfcf16b3 100644 --- a/pandas/tests/arithmetic/test_datetime64.py +++ b/pandas/tests/arithmetic/test_datetime64.py @@ -1720,15 +1720,15 @@ def test_datetimeindex_sub_timestamp_overflow(self): with pytest.raises(OverflowError, match=msg): dtimax - variant - expected = Timestamp.max.value - tspos.value + expected = Timestamp.max._value - tspos._value for variant in ts_pos_variants: res = dtimax - variant - assert res[1].value == expected + assert res[1]._value == expected - expected = Timestamp.min.value - tsneg.value + expected = Timestamp.min._value - tsneg._value for variant in ts_neg_variants: res = dtimin - variant - assert res[1].value == expected + assert res[1]._value == expected for variant in ts_pos_variants: with pytest.raises(OverflowError, match=msg): @@ -1743,13 +1743,13 @@ def test_datetimeindex_sub_datetimeindex_overflow(self): ts_pos = pd.to_datetime(["1980-01-01", "1980-01-01"]) # General tests - expected = Timestamp.max.value - ts_pos[1].value + expected = Timestamp.max._value - ts_pos[1]._value result = dtimax - ts_pos - assert result[1].value == expected + assert result[1]._value == expected - expected = Timestamp.min.value - ts_neg[1].value + expected = Timestamp.min._value - ts_neg[1]._value result = dtimin - ts_neg - assert result[1].value == expected + assert result[1]._value == expected msg = "Overflow in int64 addition" with pytest.raises(OverflowError, match=msg): dtimax - ts_neg @@ -2443,4 +2443,4 @@ def test_dt64arr_addsub_object_dtype_2d(): result2 = dta - dta.astype(object) assert result2.shape == (4, 1) - assert all(td.value == 0 for td in result2.ravel()) + assert all(td._value == 0 for td in result2.ravel()) diff --git a/pandas/tests/arithmetic/test_timedelta64.py b/pandas/tests/arithmetic/test_timedelta64.py index 6570b0e04514e..fa3e2f3871c2e 100644 --- a/pandas/tests/arithmetic/test_timedelta64.py +++ b/pandas/tests/arithmetic/test_timedelta64.py @@ -692,7 +692,7 @@ def test_tdi_add_overflow(self): with pytest.raises(OutOfBoundsDatetime, match="10155196800000000000"): Timestamp("2000") + pd.to_timedelta(106580, "D") - _NaT = NaT.value + 1 + _NaT = NaT._value + 1 msg = "Overflow in int64 addition" with pytest.raises(OverflowError, match=msg): pd.to_timedelta([106580], "D") + Timestamp("2000") @@ -756,7 +756,7 @@ def test_timedelta_ops_with_missing_values(self): # supported GH#29794 DataFrame([NaT]).apply(pd.to_timedelta) # TODO: belongs elsewhere? - dfn = DataFrame([NaT.value]).apply(pd.to_timedelta) + dfn = DataFrame([NaT._value]).apply(pd.to_timedelta) scalar1 = pd.to_timedelta("00:00:01") scalar2 = pd.to_timedelta("00:00:02") diff --git a/pandas/tests/arrays/test_datetimes.py b/pandas/tests/arrays/test_datetimes.py index fb5627b68abff..38e659a658d07 100644 --- a/pandas/tests/arrays/test_datetimes.py +++ b/pandas/tests/arrays/test_datetimes.py @@ -132,7 +132,7 @@ def test_iter(self, dta): expected = dta[0] assert type(res) is pd.Timestamp - assert res.value == expected.value + assert res._value == expected._value assert res._creso == expected._creso assert res == expected diff --git a/pandas/tests/frame/methods/test_sort_values.py b/pandas/tests/frame/methods/test_sort_values.py index 43fcb25d122fb..026c3ae7011a0 100644 --- a/pandas/tests/frame/methods/test_sort_values.py +++ b/pandas/tests/frame/methods/test_sort_values.py @@ -355,7 +355,7 @@ def test_sort_values_nat_values_in_int_column(self): # cause was that the int64 value NaT was considered as "na". Which is # only correct for datetime64 columns. - int_values = (2, int(NaT.value)) + int_values = (2, int(NaT._value)) float_values = (2.0, -1.797693e308) df = DataFrame( diff --git a/pandas/tests/groupby/test_function.py b/pandas/tests/groupby/test_function.py index 1e16e353cc1a4..0a3506966e11c 100644 --- a/pandas/tests/groupby/test_function.py +++ b/pandas/tests/groupby/test_function.py @@ -925,7 +925,7 @@ def test_cummax(dtypes_for_minmax): def test_cummax_i8_at_implementation_bound(): # the minimum value used to be treated as NPY_NAT+1 instead of NPY_NAT # for int64 dtype GH#46382 - ser = Series([pd.NaT.value + n for n in range(5)]) + ser = Series([pd.NaT._value + n for n in range(5)]) df = DataFrame({"A": 1, "B": ser, "C": ser.view("M8[ns]")}) gb = df.groupby("A") diff --git a/pandas/tests/indexes/datetimes/test_date_range.py b/pandas/tests/indexes/datetimes/test_date_range.py index 11bc785c66b70..7be4d12c26e87 100644 --- a/pandas/tests/indexes/datetimes/test_date_range.py +++ b/pandas/tests/indexes/datetimes/test_date_range.py @@ -1236,7 +1236,7 @@ def test_date_range_freq_lower_than_endpoints(self): # but we can losslessly cast to "us" dti = date_range(start, end, periods=2, unit="us") rng = np.array( - [start.as_unit("us").value, end.as_unit("us").value], dtype=np.int64 + [start.as_unit("us")._value, end.as_unit("us")._value], dtype=np.int64 ) expected = DatetimeIndex(rng.view("M8[us]")) tm.assert_index_equal(dti, expected) diff --git a/pandas/tests/indexes/datetimes/test_indexing.py b/pandas/tests/indexes/datetimes/test_indexing.py index 04d1d8204a346..ecdea9ea25c9d 100644 --- a/pandas/tests/indexes/datetimes/test_indexing.py +++ b/pandas/tests/indexes/datetimes/test_indexing.py @@ -175,7 +175,7 @@ def test_where_invalid_dtypes(self): tm.assert_index_equal(result, expected) result = dti.where(mask, i2.asi8) - expected = Index([pd.NaT.value, pd.NaT.value] + tail, dtype=object) + expected = Index([pd.NaT._value, pd.NaT._value] + tail, dtype=object) assert isinstance(expected[0], int) tm.assert_index_equal(result, expected) diff --git a/pandas/tests/indexes/datetimes/test_timezones.py b/pandas/tests/indexes/datetimes/test_timezones.py index 65207a4d7a60f..05700841de7e1 100644 --- a/pandas/tests/indexes/datetimes/test_timezones.py +++ b/pandas/tests/indexes/datetimes/test_timezones.py @@ -1138,7 +1138,7 @@ def test_dti_convert_tz_aware_datetime_datetime(self, tz): assert timezones.tz_compare(result.tz, tz) converted = to_datetime(dates_aware, utc=True) - ex_vals = np.array([Timestamp(x).as_unit("ns").value for x in dates_aware]) + ex_vals = np.array([Timestamp(x).as_unit("ns")._value for x in dates_aware]) tm.assert_numpy_array_equal(converted.asi8, ex_vals) assert converted.tz is timezone.utc diff --git a/pandas/tests/indexes/datetimes/test_unique.py b/pandas/tests/indexes/datetimes/test_unique.py index 68ac770f612e6..c18bd99b67000 100644 --- a/pandas/tests/indexes/datetimes/test_unique.py +++ b/pandas/tests/indexes/datetimes/test_unique.py @@ -55,7 +55,7 @@ def test_index_unique(rand_series_with_duplicate_datetimeindex): def test_index_unique2(): # NaT, note this is excluded - arr = [1370745748 + t for t in range(20)] + [NaT.value] + arr = [1370745748 + t for t in range(20)] + [NaT._value] idx = DatetimeIndex(arr * 3) tm.assert_index_equal(idx.unique(), DatetimeIndex(arr)) assert idx.nunique() == 20 diff --git a/pandas/tests/indexes/period/test_indexing.py b/pandas/tests/indexes/period/test_indexing.py index 2db1e8c72a87c..228fd2829c5d9 100644 --- a/pandas/tests/indexes/period/test_indexing.py +++ b/pandas/tests/indexes/period/test_indexing.py @@ -570,7 +570,7 @@ def test_where_invalid_dtypes(self): mask = notna(i2) result = pi.where(mask, i2.asi8) - expected = pd.Index([NaT.value, NaT.value] + tail, dtype=object) + expected = pd.Index([NaT._value, NaT._value] + tail, dtype=object) assert isinstance(expected[0], int) tm.assert_index_equal(result, expected) diff --git a/pandas/tests/indexes/timedeltas/test_indexing.py b/pandas/tests/indexes/timedeltas/test_indexing.py index cc166f9f32a34..2d2711520d44f 100644 --- a/pandas/tests/indexes/timedeltas/test_indexing.py +++ b/pandas/tests/indexes/timedeltas/test_indexing.py @@ -144,7 +144,7 @@ def test_where_invalid_dtypes(self, fixed_now_ts): i2 = Index([NaT, NaT] + tail) mask = notna(i2) - expected = Index([NaT.value, NaT.value] + tail, dtype=object, name="idx") + expected = Index([NaT._value, NaT._value] + tail, dtype=object, name="idx") assert isinstance(expected[0], int) result = tdi.where(mask, i2.asi8) tm.assert_index_equal(result, expected) diff --git a/pandas/tests/indexing/test_loc.py b/pandas/tests/indexing/test_loc.py index 5445053027940..9306cbb80e886 100644 --- a/pandas/tests/indexing/test_loc.py +++ b/pandas/tests/indexing/test_loc.py @@ -2563,9 +2563,9 @@ def test_loc_setitem_mask_td64_series_value(self): df_copy = df.copy() ser = Series([td1]) - expected = df["col"].iloc[1].value + expected = df["col"].iloc[1]._value df.loc[[True, False]] = ser - result = df["col"].iloc[1].value + result = df["col"].iloc[1]._value assert expected == result tm.assert_frame_equal(df, df_copy) diff --git a/pandas/tests/scalar/test_nat.py b/pandas/tests/scalar/test_nat.py index e310506935729..3192baacb4ef4 100644 --- a/pandas/tests/scalar/test_nat.py +++ b/pandas/tests/scalar/test_nat.py @@ -110,7 +110,7 @@ def test_equality(klass, value, request): pytest.mark.xfail(reason="Period cannot parse empty string") ) - assert klass(value).value == iNaT + assert klass(value)._value == iNaT @pytest.mark.parametrize("klass", [Timestamp, Timedelta]) diff --git a/pandas/tests/scalar/timedelta/test_constructors.py b/pandas/tests/scalar/timedelta/test_constructors.py index e4120478370d1..bdd9b2ab1dfd8 100644 --- a/pandas/tests/scalar/timedelta/test_constructors.py +++ b/pandas/tests/scalar/timedelta/test_constructors.py @@ -44,7 +44,7 @@ def test_from_td64_retain_resolution(): obj = np.timedelta64(12345, "ms") td = Timedelta(obj) - assert td.value == obj.view("i8") + assert td._value == obj.view("i8") assert td._creso == NpyDatetimeUnit.NPY_FR_ms.value # Case where we cast to nearest-supported reso @@ -95,22 +95,22 @@ def test_from_tick_reso(): def test_construction(): expected = np.timedelta64(10, "D").astype("m8[ns]").view("i8") - assert Timedelta(10, unit="d").value == expected - assert Timedelta(10.0, unit="d").value == expected - assert Timedelta("10 days").value == expected - assert Timedelta(days=10).value == expected - assert Timedelta(days=10.0).value == expected + assert Timedelta(10, unit="d")._value == expected + assert Timedelta(10.0, unit="d")._value == expected + assert Timedelta("10 days")._value == expected + assert Timedelta(days=10)._value == expected + assert Timedelta(days=10.0)._value == expected expected += np.timedelta64(10, "s").astype("m8[ns]").view("i8") - assert Timedelta("10 days 00:00:10").value == expected - assert Timedelta(days=10, seconds=10).value == expected - assert Timedelta(days=10, milliseconds=10 * 1000).value == expected - assert Timedelta(days=10, microseconds=10 * 1000 * 1000).value == expected + assert Timedelta("10 days 00:00:10")._value == expected + assert Timedelta(days=10, seconds=10)._value == expected + assert Timedelta(days=10, milliseconds=10 * 1000)._value == expected + assert Timedelta(days=10, microseconds=10 * 1000 * 1000)._value == expected # rounding cases - assert Timedelta(82739999850000).value == 82739999850000 + assert Timedelta(82739999850000)._value == 82739999850000 assert "0 days 22:58:59.999850" in str(Timedelta(82739999850000)) - assert Timedelta(123072001000000).value == 123072001000000 + assert Timedelta(123072001000000)._value == 123072001000000 assert "1 days 10:11:12.001" in str(Timedelta(123072001000000)) # string conversion with/without leading zero @@ -200,7 +200,7 @@ def test_construction(): expected = np.timedelta64(10, "s").astype("m8[ns]").view("i8") + np.timedelta64( 500, "ms" ).astype("m8[ns]").view("i8") - assert Timedelta(10.5, unit="s").value == expected + assert Timedelta(10.5, unit="s")._value == expected # offset assert to_timedelta(offsets.Hour(2)) == Timedelta(hours=2) @@ -239,7 +239,7 @@ def test_td_construction_with_np_dtypes(npdtype, item): # GH#8757: test construction with np dtypes pykwarg, npkwarg = item expected = np.timedelta64(1, npkwarg).astype("m8[ns]").view("i8") - assert Timedelta(**{pykwarg: npdtype(1)}).value == expected + assert Timedelta(**{pykwarg: npdtype(1)})._value == expected @pytest.mark.parametrize( @@ -261,7 +261,7 @@ def test_td_construction_with_np_dtypes(npdtype, item): def test_td_from_repr_roundtrip(val): # round-trip both for string and value td = Timedelta(val) - assert Timedelta(td.value) == td + assert Timedelta(td._value) == td assert Timedelta(str(td)) == td assert Timedelta(td._repr_base(format="all")) == td @@ -270,7 +270,7 @@ def test_td_from_repr_roundtrip(val): def test_overflow_on_construction(): # GH#3374 - value = Timedelta("1day").value * 20169940 + value = Timedelta("1day")._value * 20169940 msg = "Cannot cast 1742682816000000000000 from ns to 'ns' without overflow" with pytest.raises(OutOfBoundsTimedelta, match=msg): Timedelta(value) diff --git a/pandas/tests/scalar/timedelta/test_timedelta.py b/pandas/tests/scalar/timedelta/test_timedelta.py index 924f756edb233..d92d290d33816 100644 --- a/pandas/tests/scalar/timedelta/test_timedelta.py +++ b/pandas/tests/scalar/timedelta/test_timedelta.py @@ -32,41 +32,41 @@ def test_as_unit(self): assert td.as_unit("ns") is td res = td.as_unit("us") - assert res.value == td.value // 1000 - assert res._creso == NpyDatetimeUnit.NPY_FR_us.value + assert res._value == td._value // 1000 + assert res._creso == NpyDatetimeUnit.NPY_FR_us._value rt = res.as_unit("ns") - assert rt.value == td.value + assert rt._value == td._value assert rt._creso == td._creso res = td.as_unit("ms") - assert res.value == td.value // 1_000_000 - assert res._creso == NpyDatetimeUnit.NPY_FR_ms.value + assert res._value == td._value // 1_000_000 + assert res._creso == NpyDatetimeUnit.NPY_FR_ms._value rt = res.as_unit("ns") - assert rt.value == td.value + assert rt._value == td._value assert rt._creso == td._creso res = td.as_unit("s") - assert res.value == td.value // 1_000_000_000 + assert res._value == td._value // 1_000_000_000 assert res._creso == NpyDatetimeUnit.NPY_FR_s.value rt = res.as_unit("ns") - assert rt.value == td.value + assert rt._value == td._value assert rt._creso == td._creso def test_as_unit_overflows(self): # microsecond that would be just out of bounds for nano us = 9223372800000000 - td = Timedelta._from_value_and_reso(us, NpyDatetimeUnit.NPY_FR_us.value) + td = Timedelta._from_value_and_reso(us, NpyDatetimeUnit.NPY_FR_us._value) msg = "Cannot cast 106752 days 00:00:00 to unit='ns' without overflow" with pytest.raises(OutOfBoundsTimedelta, match=msg): td.as_unit("ns") res = td.as_unit("ms") - assert res.value == us // 1000 - assert res._creso == NpyDatetimeUnit.NPY_FR_ms.value + assert res._value == us // 1000 + assert res._creso == NpyDatetimeUnit.NPY_FR_ms._value def test_as_unit_rounding(self): td = Timedelta(microseconds=1500) @@ -75,8 +75,8 @@ def test_as_unit_rounding(self): expected = Timedelta(milliseconds=1) assert res == expected - assert res._creso == NpyDatetimeUnit.NPY_FR_ms.value - assert res.value == 1 + assert res._creso == NpyDatetimeUnit.NPY_FR_ms._value + assert res._value == 1 with pytest.raises(ValueError, match="Cannot losslessly convert units"): td.as_unit("ms", round_ok=False) @@ -85,13 +85,13 @@ def test_as_unit_non_nano(self): # case where we are going neither to nor from nano td = Timedelta(days=1).as_unit("ms") assert td.days == 1 - assert td.value == 86_400_000 + assert td._value == 86_400_000 assert td.components.days == 1 assert td._d == 1 assert td.total_seconds() == 86400 res = td.as_unit("us") - assert res.value == 86_400_000_000 + assert res._value == 86_400_000_000 assert res.components.days == 1 assert res.components.hours == 0 assert res._d == 1 @@ -108,7 +108,7 @@ def unit_str(self, request): def unit(self, unit_str): # 7, 8, 9 correspond to second, millisecond, and microsecond, respectively attr = f"NPY_FR_{unit_str}" - return getattr(NpyDatetimeUnit, attr).value + return getattr(NpyDatetimeUnit, attr)._value @pytest.fixture def val(self, unit): @@ -129,7 +129,7 @@ def td(self, unit, val): def test_from_value_and_reso(self, unit, val): # Just checking that the fixture is giving us what we asked for td = Timedelta._from_value_and_reso(val, unit) - assert td.value == val + assert td._value == val assert td._creso == unit assert td.days == 106752 @@ -148,7 +148,7 @@ def test_mul_preserves_reso(self, td, unit): # The td fixture should always be far from the implementation # bound, so doubling does not risk overflow. res = td * 2 - assert res.value == td.value * 2 + assert res._value == td._value * 2 assert res._creso == unit def test_cmp_cross_reso(self, td): @@ -169,7 +169,7 @@ def test_to_timedelta64(self, td, unit): for res in [td.to_timedelta64(), td.to_numpy(), td.asm8]: assert isinstance(res, np.timedelta64) - assert res.view("i8") == td.value + assert res.view("i8") == td._value if unit == NpyDatetimeUnit.NPY_FR_s.value: assert res.dtype == "m8[s]" elif unit == NpyDatetimeUnit.NPY_FR_ms.value: @@ -181,7 +181,7 @@ def test_truediv_timedeltalike(self, td): assert td / td == 1 assert (2.5 * td) / td == 2.5 - other = Timedelta(td.value) + other = Timedelta(td._value) msg = "Cannot cast 106752 days 00:00:00 to unit='ns' without overflow." with pytest.raises(OutOfBoundsTimedelta, match=msg): td / other @@ -206,18 +206,18 @@ def test_truediv_numeric(self, td): assert td / np.nan is NaT res = td / 2 - assert res.value == td.value / 2 + assert res._value == td._value / 2 assert res._creso == td._creso res = td / 2.0 - assert res.value == td.value / 2 + assert res._value == td._value / 2 assert res._creso == td._creso def test_floordiv_timedeltalike(self, td): assert td // td == 1 assert (2.5 * td) // td == 2 - other = Timedelta(td.value) + other = Timedelta(td._value) msg = "Cannot cast 106752 days 00:00:00 to unit='ns' without overflow" with pytest.raises(OutOfBoundsTimedelta, match=msg): td // other @@ -240,21 +240,21 @@ def test_floordiv_numeric(self, td): assert td // np.nan is NaT res = td // 2 - assert res.value == td.value // 2 + assert res._value == td._value // 2 assert res._creso == td._creso res = td // 2.0 - assert res.value == td.value // 2 + assert res._value == td._value // 2 assert res._creso == td._creso assert td // np.array(np.nan) is NaT res = td // np.array(2) - assert res.value == td.value // 2 + assert res._value == td._value // 2 assert res._creso == td._creso res = td // np.array(2.0) - assert res.value == td.value // 2 + assert res._value == td._value // 2 assert res._creso == td._creso def test_addsub_mismatched_reso(self, td): @@ -293,12 +293,12 @@ def test_addsub_mismatched_reso(self, td): def test_min(self, td): assert td.min <= td assert td.min._creso == td._creso - assert td.min.value == NaT.value + 1 + assert td.min._value == NaT._value + 1 def test_max(self, td): assert td.max >= td assert td.max._creso == td._creso - assert td.max.value == np.iinfo(np.int64).max + assert td.max._value == np.iinfo(np.int64).max def test_resolution(self, td): expected = Timedelta._from_value_and_reso(1, td._creso) @@ -310,7 +310,7 @@ def test_resolution(self, td): def test_timedelta_class_min_max_resolution(): # when accessed on the class (as opposed to an instance), we default # to nanoseconds - assert Timedelta.min == Timedelta(NaT.value + 1) + assert Timedelta.min == Timedelta(NaT._value + 1) assert Timedelta.min._creso == NpyDatetimeUnit.NPY_FR_ns.value assert Timedelta.max == Timedelta(np.iinfo(np.int64).max) @@ -896,16 +896,16 @@ def test_implementation_limits(self): max_td + Timedelta(1, "ns") # Same tests using the internal nanosecond values - td = Timedelta(min_td.value - 1, "ns") + td = Timedelta(min_td._value - 1, "ns") assert td is NaT msg = "Cannot cast -9223372036854775809 from ns to 'ns' without overflow" with pytest.raises(OutOfBoundsTimedelta, match=msg): - Timedelta(min_td.value - 2, "ns") + Timedelta(min_td._value - 2, "ns") msg = "Cannot cast 9223372036854775808 from ns to 'ns' without overflow" with pytest.raises(OutOfBoundsTimedelta, match=msg): - Timedelta(max_td.value + 1, "ns") + Timedelta(max_td._value + 1, "ns") def test_total_seconds_precision(self): # GH 19458 @@ -963,5 +963,5 @@ def test_timedelta_attribute_precision(): result += td.microseconds result *= 1000 result += td.nanoseconds - expected = td.value + expected = td._value assert result == expected diff --git a/pandas/tests/scalar/timestamp/test_timestamp.py b/pandas/tests/scalar/timestamp/test_timestamp.py index 22f5286569c6e..1d96544e05d9f 100644 --- a/pandas/tests/scalar/timestamp/test_timestamp.py +++ b/pandas/tests/scalar/timestamp/test_timestamp.py @@ -983,7 +983,7 @@ def test_sub_timedelta64_mismatched_reso(self, ts_tz): def test_min(self, ts): assert ts.min <= ts assert ts.min._creso == ts._creso - assert ts.min.value == NaT.value + 1 + assert ts.min.value == NaT._value + 1 def test_max(self, ts): assert ts.max >= ts @@ -1000,7 +1000,7 @@ def test_resolution(self, ts): def test_timestamp_class_min_max_resolution(): # when accessed on the class (as opposed to an instance), we default # to nanoseconds - assert Timestamp.min == Timestamp(NaT.value + 1) + assert Timestamp.min == Timestamp(NaT._value + 1) assert Timestamp.min._creso == NpyDatetimeUnit.NPY_FR_ns.value assert Timestamp.max == Timestamp(np.iinfo(np.int64).max) diff --git a/pandas/tests/series/indexing/test_setitem.py b/pandas/tests/series/indexing/test_setitem.py index 1a52e02ee314f..3d09954ed3c0f 100644 --- a/pandas/tests/series/indexing/test_setitem.py +++ b/pandas/tests/series/indexing/test_setitem.py @@ -949,7 +949,7 @@ class TestSetitemNAPeriodDtype(SetitemCastingEquivalents): @pytest.fixture def expected(self, key): exp = Series(period_range("2000-01-01", periods=10, freq="D")) - exp._values.view("i8")[key] = NaT.value + exp._values.view("i8")[key] = NaT._value assert exp[key] is NaT or all(x is NaT for x in exp[key]) return exp diff --git a/pandas/tests/series/methods/test_fillna.py b/pandas/tests/series/methods/test_fillna.py index 9fded26c37caf..ae6622da1d407 100644 --- a/pandas/tests/series/methods/test_fillna.py +++ b/pandas/tests/series/methods/test_fillna.py @@ -26,7 +26,7 @@ class TestSeriesFillNA: def test_fillna_nat(self): - series = Series([0, 1, 2, NaT.value], dtype="M8[ns]") + series = Series([0, 1, 2, NaT._value], dtype="M8[ns]") filled = series.fillna(method="pad") filled2 = series.fillna(value=series.values[2]) @@ -44,7 +44,7 @@ def test_fillna_nat(self): tm.assert_frame_equal(filled, expected) tm.assert_frame_equal(filled2, expected) - series = Series([NaT.value, 0, 1, 2], dtype="M8[ns]") + series = Series([NaT._value, 0, 1, 2], dtype="M8[ns]") filled = series.fillna(method="bfill") filled2 = series.fillna(value=series[1]) diff --git a/pandas/tests/series/test_repr.py b/pandas/tests/series/test_repr.py index 43a6c7028883b..23de7106e08a4 100644 --- a/pandas/tests/series/test_repr.py +++ b/pandas/tests/series/test_repr.py @@ -241,7 +241,7 @@ def test_format_pre_1900_dates(self): repr(ts) def test_series_repr_nat(self): - series = Series([0, 1000, 2000, pd.NaT.value], dtype="M8[ns]") + series = Series([0, 1000, 2000, pd.NaT._value], dtype="M8[ns]") result = repr(series) expected = ( diff --git a/pandas/tests/tools/test_to_timedelta.py b/pandas/tests/tools/test_to_timedelta.py index 0ce2a424f6915..734f80d4ccdb2 100644 --- a/pandas/tests/tools/test_to_timedelta.py +++ b/pandas/tests/tools/test_to_timedelta.py @@ -73,7 +73,7 @@ def test_to_timedelta_units_dtypes(self, dtype, unit): tm.assert_index_equal(result, expected) def test_to_timedelta_oob_non_nano(self): - arr = np.array([pd.NaT.value + 1], dtype="timedelta64[m]") + arr = np.array([pd.NaT._value + 1], dtype="timedelta64[m]") msg = ( "Cannot convert -9223372036854775807 minutes to " From dd6d8b4d9fc5c8b1d88c6943a56174a9a93573f6 Mon Sep 17 00:00:00 2001 From: MarcoGorelli <> Date: Wed, 18 Jan 2023 18:20:05 +0000 Subject: [PATCH 06/17] more fixups --- .../tests/scalar/timedelta/test_timedelta.py | 28 +++---- .../tests/scalar/timestamp/test_timestamp.py | 83 ++++++++++--------- 2 files changed, 56 insertions(+), 55 deletions(-) diff --git a/pandas/tests/scalar/timedelta/test_timedelta.py b/pandas/tests/scalar/timedelta/test_timedelta.py index d92d290d33816..dc4399a4a38de 100644 --- a/pandas/tests/scalar/timedelta/test_timedelta.py +++ b/pandas/tests/scalar/timedelta/test_timedelta.py @@ -33,7 +33,7 @@ def test_as_unit(self): res = td.as_unit("us") assert res._value == td._value // 1000 - assert res._creso == NpyDatetimeUnit.NPY_FR_us._value + assert res._creso == NpyDatetimeUnit.NPY_FR_us.value rt = res.as_unit("ns") assert rt._value == td._value @@ -41,7 +41,7 @@ def test_as_unit(self): res = td.as_unit("ms") assert res._value == td._value // 1_000_000 - assert res._creso == NpyDatetimeUnit.NPY_FR_ms._value + assert res._creso == NpyDatetimeUnit.NPY_FR_ms.value rt = res.as_unit("ns") assert rt._value == td._value @@ -58,7 +58,7 @@ def test_as_unit(self): def test_as_unit_overflows(self): # microsecond that would be just out of bounds for nano us = 9223372800000000 - td = Timedelta._from_value_and_reso(us, NpyDatetimeUnit.NPY_FR_us._value) + td = Timedelta._from_value_and_reso(us, NpyDatetimeUnit.NPY_FR_us.value) msg = "Cannot cast 106752 days 00:00:00 to unit='ns' without overflow" with pytest.raises(OutOfBoundsTimedelta, match=msg): @@ -66,7 +66,7 @@ def test_as_unit_overflows(self): res = td.as_unit("ms") assert res._value == us // 1000 - assert res._creso == NpyDatetimeUnit.NPY_FR_ms._value + assert res._creso == NpyDatetimeUnit.NPY_FR_ms.value def test_as_unit_rounding(self): td = Timedelta(microseconds=1500) @@ -75,7 +75,7 @@ def test_as_unit_rounding(self): expected = Timedelta(milliseconds=1) assert res == expected - assert res._creso == NpyDatetimeUnit.NPY_FR_ms._value + assert res._creso == NpyDatetimeUnit.NPY_FR_ms.value assert res._value == 1 with pytest.raises(ValueError, match="Cannot losslessly convert units"): @@ -108,7 +108,7 @@ def unit_str(self, request): def unit(self, unit_str): # 7, 8, 9 correspond to second, millisecond, and microsecond, respectively attr = f"NPY_FR_{unit_str}" - return getattr(NpyDatetimeUnit, attr)._value + return getattr(NpyDatetimeUnit, attr).value @pytest.fixture def val(self, unit): @@ -362,9 +362,9 @@ class TestTimedeltas: def test_rounding_on_int_unit_construction(self, unit, value, expected): # GH 12690 result = Timedelta(value, unit=unit) - assert result.value == expected + assert result._value == expected result = Timedelta(str(value) + unit) - assert result.value == expected + assert result._value == expected def test_total_seconds_scalar(self): # see gh-10939 @@ -383,10 +383,10 @@ def test_conversion(self): assert td == pydt assert isinstance(pydt, timedelta) and not isinstance(pydt, Timedelta) - assert td == np.timedelta64(td.value, "ns") + assert td == np.timedelta64(td._value, "ns") td64 = td.to_timedelta64() - assert td64 == np.timedelta64(td.value, "ns") + assert td64 == np.timedelta64(td._value, "ns") assert td == td64 assert isinstance(td64, np.timedelta64) @@ -425,8 +425,8 @@ def check(value): assert abs(td) == Timedelta("13:48:48") assert str(td) == "-1 days +10:11:12" assert -td == Timedelta("0 days 13:48:48") - assert -Timedelta("-1 days, 10:11:12").value == 49728000000000 - assert Timedelta("-1 days, 10:11:12").value == -49728000000000 + assert -Timedelta("-1 days, 10:11:12")._value == 49728000000000 + assert Timedelta("-1 days, 10:11:12")._value == -49728000000000 rng = to_timedelta("-1 days, 10:11:12.100123456") assert rng.days == -1 @@ -882,8 +882,8 @@ def test_implementation_limits(self): # GH 12727 # timedelta limits correspond to int64 boundaries - assert min_td.value == iNaT + 1 - assert max_td.value == lib.i8max + assert min_td._value == iNaT + 1 + assert max_td._value == lib.i8max # Beyond lower limit, a NAT before the Overflow assert (min_td - Timedelta(1, "ns")) is NaT diff --git a/pandas/tests/scalar/timestamp/test_timestamp.py b/pandas/tests/scalar/timestamp/test_timestamp.py index 1d96544e05d9f..968ec122cde20 100644 --- a/pandas/tests/scalar/timestamp/test_timestamp.py +++ b/pandas/tests/scalar/timestamp/test_timestamp.py @@ -245,7 +245,7 @@ def test_utc_z_designator(self): def test_asm8(self): np.random.seed(7_960_929) - ns = [Timestamp.min.value, Timestamp.max.value, 1000] + ns = [Timestamp.min._value, Timestamp.max._value, 1000] for n in ns: assert ( @@ -256,7 +256,7 @@ def test_asm8(self): def test_class_ops_pytz(self): def compare(x, y): - assert int((Timestamp(x).value - Timestamp(y).value) / 1e9) == 0 + assert int((Timestamp(x)._value - Timestamp(y)._value) / 1e9) == 0 compare(Timestamp.now(), datetime.now()) compare(Timestamp.now("UTC"), datetime.now(pytz.timezone("UTC"))) @@ -291,8 +291,8 @@ def test_class_ops_dateutil(self): def compare(x, y): assert ( int( - np.round(Timestamp(x).value / 1e9) - - np.round(Timestamp(y).value / 1e9) + np.round(Timestamp(x)._value / 1e9) + - np.round(Timestamp(y)._value / 1e9) ) == 0 ) @@ -386,24 +386,24 @@ def test_roundtrip(self): # further test accessors base = Timestamp("20140101 00:00:00").as_unit("ns") - result = Timestamp(base.value + Timedelta("5ms").value) + result = Timestamp(base._value + Timedelta("5ms")._value) assert result == Timestamp(f"{base}.005000") assert result.microsecond == 5000 - result = Timestamp(base.value + Timedelta("5us").value) + result = Timestamp(base._value + Timedelta("5us")._value) assert result == Timestamp(f"{base}.000005") assert result.microsecond == 5 - result = Timestamp(base.value + Timedelta("5ns").value) + result = Timestamp(base._value + Timedelta("5ns")._value) assert result == Timestamp(f"{base}.000000005") assert result.nanosecond == 5 assert result.microsecond == 0 - result = Timestamp(base.value + Timedelta("6ms 5us").value) + result = Timestamp(base._value + Timedelta("6ms 5us")._value) assert result == Timestamp(f"{base}.006005") assert result.microsecond == 5 + 6 * 1000 - result = Timestamp(base.value + Timedelta("200ms 5us").value) + result = Timestamp(base._value + Timedelta("200ms 5us")._value) assert result == Timestamp(f"{base}.200005") assert result.microsecond == 5 + 200 * 1000 @@ -446,24 +446,24 @@ def test_nanosecond_string_parsing(self): # GH 7878 expected_repr = "2013-05-01 07:15:45.123456789" expected_value = 1_367_392_545_123_456_789 - assert ts.value == expected_value + assert ts._value == expected_value assert expected_repr in repr(ts) ts = Timestamp("2013-05-01 07:15:45.123456789+09:00", tz="Asia/Tokyo") - assert ts.value == expected_value - 9 * 3600 * 1_000_000_000 + assert ts._value == expected_value - 9 * 3600 * 1_000_000_000 assert expected_repr in repr(ts) ts = Timestamp("2013-05-01 07:15:45.123456789", tz="UTC") - assert ts.value == expected_value + assert ts._value == expected_value assert expected_repr in repr(ts) ts = Timestamp("2013-05-01 07:15:45.123456789", tz="US/Eastern") - assert ts.value == expected_value + 4 * 3600 * 1_000_000_000 + assert ts._value == expected_value + 4 * 3600 * 1_000_000_000 assert expected_repr in repr(ts) # GH 10041 ts = Timestamp("20130501T071545.123456789") - assert ts.value == expected_value + assert ts._value == expected_value assert expected_repr in repr(ts) def test_nanosecond_timestamp(self): @@ -471,33 +471,33 @@ def test_nanosecond_timestamp(self): expected = 1_293_840_000_000_000_005 t = Timestamp("2011-01-01") + offsets.Nano(5) assert repr(t) == "Timestamp('2011-01-01 00:00:00.000000005')" - assert t.value == expected + assert t._value == expected assert t.nanosecond == 5 t = Timestamp(t) assert repr(t) == "Timestamp('2011-01-01 00:00:00.000000005')" - assert t.value == expected + assert t._value == expected assert t.nanosecond == 5 t = Timestamp("2011-01-01 00:00:00.000000005") assert repr(t) == "Timestamp('2011-01-01 00:00:00.000000005')" - assert t.value == expected + assert t._value == expected assert t.nanosecond == 5 expected = 1_293_840_000_000_000_010 t = t + offsets.Nano(5) assert repr(t) == "Timestamp('2011-01-01 00:00:00.000000010')" - assert t.value == expected + assert t._value == expected assert t.nanosecond == 10 t = Timestamp(t) assert repr(t) == "Timestamp('2011-01-01 00:00:00.000000010')" - assert t.value == expected + assert t._value == expected assert t.nanosecond == 10 t = Timestamp("2011-01-01 00:00:00.000000010") assert repr(t) == "Timestamp('2011-01-01 00:00:00.000000010')" - assert t.value == expected + assert t._value == expected assert t.nanosecond == 10 @@ -534,7 +534,7 @@ def test_conversion(self): assert type(result) == type(expected) result = ts.to_datetime64() - expected = np.datetime64(ts.value, "ns") + expected = np.datetime64(ts._value, "ns") assert result == expected assert type(result) == type(expected) assert result.dtype == expected.dtype @@ -588,7 +588,8 @@ def test_to_datetime_bijective(self): pydt_max = Timestamp.max.to_pydatetime() assert ( - Timestamp(pydt_max).as_unit("ns").value / 1000 == Timestamp.max.value / 1000 + Timestamp(pydt_max).as_unit("ns")._value / 1000 + == Timestamp.max._value / 1000 ) exp_warning = None if Timestamp.min.nanosecond == 0 else UserWarning @@ -601,8 +602,8 @@ def test_to_datetime_bijective(self): assert pydt_min + tdus > Timestamp.min assert ( - Timestamp(pydt_min + tdus).as_unit("ns").value / 1000 - == Timestamp.min.value / 1000 + Timestamp(pydt_min + tdus).as_unit("ns")._value / 1000 + == Timestamp.min._value / 1000 ) def test_to_period_tz_warning(self): @@ -664,10 +665,10 @@ def ts(self, dt64): @pytest.fixture def ts_tz(self, ts, tz_aware_fixture): tz = maybe_get_tz(tz_aware_fixture) - return Timestamp._from_value_and_reso(ts.value, ts._creso, tz) + return Timestamp._from_value_and_reso(ts._value, ts._creso, tz) def test_non_nano_construction(self, dt64, ts, reso): - assert ts.value == dt64.view("i8") + assert ts._value == dt64.view("i8") if reso == "s": assert ts._creso == NpyDatetimeUnit.NPY_FR_s.value @@ -714,7 +715,7 @@ def test_month_name(self, dt64, ts): assert ts.month_name() == alt.month_name() def test_tz_convert(self, ts): - ts = Timestamp._from_value_and_reso(ts.value, ts._creso, utc) + ts = Timestamp._from_value_and_reso(ts._value, ts._creso, utc) tz = pytz.timezone("US/Pacific") result = ts.tz_convert(tz) @@ -788,7 +789,7 @@ def test_cmp_cross_reso_reversed_dt64(self): def test_pickle(self, ts, tz_aware_fixture): tz = tz_aware_fixture tz = maybe_get_tz(tz) - ts = Timestamp._from_value_and_reso(ts.value, ts._creso, tz) + ts = Timestamp._from_value_and_reso(ts._value, ts._creso, tz) rt = tm.round_trip_pickle(ts) assert rt._creso == ts._creso assert rt == ts @@ -888,12 +889,12 @@ def test_sub_datetimelike_mismatched_reso(self, ts_tz): result = ts - other assert isinstance(result, Timedelta) - assert result.value == 0 + assert result._value == 0 assert result._creso == max(ts._creso, other._creso) result = other - ts assert isinstance(result, Timedelta) - assert result.value == 0 + assert result._value == 0 assert result._creso == max(ts._creso, other._creso) if ts._creso < other._creso: @@ -983,12 +984,12 @@ def test_sub_timedelta64_mismatched_reso(self, ts_tz): def test_min(self, ts): assert ts.min <= ts assert ts.min._creso == ts._creso - assert ts.min.value == NaT._value + 1 + assert ts.min._value == NaT._value + 1 def test_max(self, ts): assert ts.max >= ts assert ts.max._creso == ts._creso - assert ts.max.value == np.iinfo(np.int64).max + assert ts.max._value == np.iinfo(np.int64).max def test_resolution(self, ts): expected = Timedelta._from_value_and_reso(1, ts._creso) @@ -1018,27 +1019,27 @@ def test_as_unit(self): assert ts.as_unit("ns") is ts res = ts.as_unit("us") - assert res.value == ts.value // 1000 + assert res._value == ts._value // 1000 assert res._creso == NpyDatetimeUnit.NPY_FR_us.value rt = res.as_unit("ns") - assert rt.value == ts.value + assert rt._value == ts._value assert rt._creso == ts._creso res = ts.as_unit("ms") - assert res.value == ts.value // 1_000_000 + assert res._value == ts._value // 1_000_000 assert res._creso == NpyDatetimeUnit.NPY_FR_ms.value rt = res.as_unit("ns") - assert rt.value == ts.value + assert rt._value == ts._value assert rt._creso == ts._creso res = ts.as_unit("s") - assert res.value == ts.value // 1_000_000_000 + assert res._value == ts._value // 1_000_000_000 assert res._creso == NpyDatetimeUnit.NPY_FR_s.value rt = res.as_unit("ns") - assert rt.value == ts.value + assert rt._value == ts._value assert rt._creso == ts._creso def test_as_unit_overflows(self): @@ -1051,7 +1052,7 @@ def test_as_unit_overflows(self): ts.as_unit("ns") res = ts.as_unit("ms") - assert res.value == us // 1000 + assert res._value == us // 1000 assert res._creso == NpyDatetimeUnit.NPY_FR_ms.value def test_as_unit_rounding(self): @@ -1062,7 +1063,7 @@ def test_as_unit_rounding(self): assert res == expected assert res._creso == NpyDatetimeUnit.NPY_FR_ms.value - assert res.value == 1 + assert res._value == 1 with pytest.raises(ValueError, match="Cannot losslessly convert units"): ts.as_unit("ms", round_ok=False) @@ -1076,7 +1077,7 @@ def test_as_unit_non_nano(self): assert ts.hour == ts.minute == ts.second == ts.microsecond == ts.nanosecond == 0 res = ts.as_unit("s") - assert res.value == 24 * 3600 + assert res._value == 24 * 3600 assert res.year == 1970 assert res.month == 1 assert res.day == 2 From af97b06a2f98f7dd48ce01b009b4c59bf334a0b6 Mon Sep 17 00:00:00 2001 From: MarcoGorelli <> Date: Wed, 18 Jan 2023 18:26:07 +0000 Subject: [PATCH 07/17] fixup test unary ops --- .../tests/scalar/timestamp/test_unary_ops.py | 42 +++++++++---------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/pandas/tests/scalar/timestamp/test_unary_ops.py b/pandas/tests/scalar/timestamp/test_unary_ops.py index f87922336b714..62bfede7f4261 100644 --- a/pandas/tests/scalar/timestamp/test_unary_ops.py +++ b/pandas/tests/scalar/timestamp/test_unary_ops.py @@ -268,21 +268,21 @@ def test_round_int64(self, timestamp, freq): # test floor result = dt.floor(freq) - assert result.value % unit == 0, f"floor not a {freq} multiple" - assert 0 <= dt.value - result.value < unit, "floor error" + assert result._value % unit == 0, f"floor not a {freq} multiple" + assert 0 <= dt._value - result._value < unit, "floor error" # test ceil result = dt.ceil(freq) - assert result.value % unit == 0, f"ceil not a {freq} multiple" - assert 0 <= result.value - dt.value < unit, "ceil error" + assert result._value % unit == 0, f"ceil not a {freq} multiple" + assert 0 <= result._value - dt._value < unit, "ceil error" # test round result = dt.round(freq) - assert result.value % unit == 0, f"round not a {freq} multiple" - assert abs(result.value - dt.value) <= unit // 2, "round error" - if unit % 2 == 0 and abs(result.value - dt.value) == unit // 2: + assert result._value % unit == 0, f"round not a {freq} multiple" + assert abs(result._value - dt._value) <= unit // 2, "round error" + if unit % 2 == 0 and abs(result._value - dt._value) == unit // 2: # round half to even - assert result.value // unit % 2 == 0, "round half to even error" + assert result._value // unit % 2 == 0, "round half to even error" def test_round_implementation_bounds(self): # See also: analogous test for Timedelta @@ -315,7 +315,7 @@ def test_round_sanity(self, val, method): def checker(res, ts, nanos): if method is Timestamp.round: - diff = np.abs((res - ts).value) + diff = np.abs((res - ts)._value) assert diff <= nanos / 2 elif method is Timestamp.floor: assert res <= ts @@ -326,38 +326,38 @@ def checker(res, ts, nanos): res = method(ts, "us") nanos = 1000 - assert np.abs((res - ts).value) < nanos - assert res.value % nanos == 0 + assert np.abs((res - ts)._value) < nanos + assert res._value % nanos == 0 checker(res, ts, nanos) res = method(ts, "ms") nanos = 1_000_000 - assert np.abs((res - ts).value) < nanos - assert res.value % nanos == 0 + assert np.abs((res - ts)._value) < nanos + assert res._value % nanos == 0 checker(res, ts, nanos) res = method(ts, "s") nanos = 1_000_000_000 - assert np.abs((res - ts).value) < nanos - assert res.value % nanos == 0 + assert np.abs((res - ts)._value) < nanos + assert res._value % nanos == 0 checker(res, ts, nanos) res = method(ts, "min") nanos = 60 * 1_000_000_000 - assert np.abs((res - ts).value) < nanos - assert res.value % nanos == 0 + assert np.abs((res - ts)._value) < nanos + assert res._value % nanos == 0 checker(res, ts, nanos) res = method(ts, "h") nanos = 60 * 60 * 1_000_000_000 - assert np.abs((res - ts).value) < nanos - assert res.value % nanos == 0 + assert np.abs((res - ts)._value) < nanos + assert res._value % nanos == 0 checker(res, ts, nanos) res = method(ts, "D") nanos = 24 * 60 * 60 * 1_000_000_000 - assert np.abs((res - ts).value) < nanos - assert res.value % nanos == 0 + assert np.abs((res - ts)._value) < nanos + assert res._value % nanos == 0 checker(res, ts, nanos) # -------------------------------------------------------------- From aeb49d75fd210ca0c023c46b6f8119100ef35068 Mon Sep 17 00:00:00 2001 From: MarcoGorelli <> Date: Fri, 20 Jan 2023 09:11:48 +0000 Subject: [PATCH 08/17] ewm --- pandas/core/window/ewm.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/core/window/ewm.py b/pandas/core/window/ewm.py index c0a7b2b7cc361..b61fa9a92539e 100644 --- a/pandas/core/window/ewm.py +++ b/pandas/core/window/ewm.py @@ -117,7 +117,7 @@ def _calculate_deltas( """ _times = np.asarray(times.view(np.int64), dtype=np.float64) # TODO: generalize to non-nano? - _halflife = float(Timedelta(halflife).as_unit("ns").value) + _halflife = float(Timedelta(halflife).as_unit("ns")._value) return np.diff(_times) / _halflife From 1f271ca568fcfe51f08456e8a259eebd3fcd8712 Mon Sep 17 00:00:00 2001 From: MarcoGorelli <> Date: Fri, 20 Jan 2023 09:13:19 +0000 Subject: [PATCH 09/17] test offseetes --- pandas/_libs/tslibs/offsets.pyx | 2 +- pandas/tests/tseries/offsets/test_ticks.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pandas/_libs/tslibs/offsets.pyx b/pandas/_libs/tslibs/offsets.pyx index 237cb256aef93..31e8dd9bd3d37 100644 --- a/pandas/_libs/tslibs/offsets.pyx +++ b/pandas/_libs/tslibs/offsets.pyx @@ -183,7 +183,7 @@ def apply_wraps(func): res = result.tz_localize(None) else: res = result - value = res.as_unit("ns").value + value = res.as_unit("ns")._value result = Timestamp(value + nano) if tz is not None and result.tzinfo is None: diff --git a/pandas/tests/tseries/offsets/test_ticks.py b/pandas/tests/tseries/offsets/test_ticks.py index 13619c2c0c828..69953955ebbce 100644 --- a/pandas/tests/tseries/offsets/test_ticks.py +++ b/pandas/tests/tseries/offsets/test_ticks.py @@ -257,7 +257,7 @@ def test_tick_division(cls): assert not isinstance(result, cls) assert result.delta == off.delta / 1000 - if cls._nanos_inc < Timedelta(seconds=1).value: + if cls._nanos_inc < Timedelta(seconds=1)._value: # Case where we end up with a bigger class result = off / 0.001 assert isinstance(result, offsets.Tick) From 3b9663773b334637125e40b1c0ad051b3d56abb7 Mon Sep 17 00:00:00 2001 From: MarcoGorelli <> Date: Fri, 20 Jan 2023 11:36:35 +0000 Subject: [PATCH 10/17] are we there yet? --- pandas/_libs/tslibs/timedeltas.pyx | 3 +- pandas/_libs/tslibs/timestamps.pyx | 1 - pandas/core/computation/pytables.py | 4 +- pandas/core/indexes/interval.py | 2 +- pandas/core/internals/concat.py | 2 +- .../indexes/datetimes/methods/test_astype.py | 2 +- .../tests/indexes/interval/test_interval.py | 6 +-- pandas/tests/indexing/test_datetime.py | 2 +- pandas/tests/io/json/test_pandas.py | 2 +- pandas/tests/io/json/test_ujson.py | 8 ++-- pandas/tests/io/pytables/test_timezones.py | 2 +- pandas/tests/reductions/test_reductions.py | 2 +- pandas/tests/scalar/period/test_asfreq.py | 2 +- pandas/tests/scalar/period/test_period.py | 6 +-- pandas/tests/scalar/test_nat.py | 3 +- .../tests/scalar/timedelta/test_arithmetic.py | 12 ++--- .../tests/scalar/timestamp/test_arithmetic.py | 2 +- .../scalar/timestamp/test_constructors.py | 44 +++++++++---------- .../tests/scalar/timestamp/test_timezones.py | 16 +++---- pandas/tests/series/methods/test_asof.py | 2 +- pandas/tests/series/test_missing.py | 4 +- pandas/tests/series/test_reductions.py | 2 +- pandas/tests/tools/test_to_timedelta.py | 4 +- 23 files changed, 66 insertions(+), 67 deletions(-) diff --git a/pandas/_libs/tslibs/timedeltas.pyx b/pandas/_libs/tslibs/timedeltas.pyx index e2d0e4649fb71..a281338b90327 100644 --- a/pandas/_libs/tslibs/timedeltas.pyx +++ b/pandas/_libs/tslibs/timedeltas.pyx @@ -1022,8 +1022,7 @@ cdef class _Timedelta(timedelta): @property def value(self): - 1/0 - pass + return convert_reso(self._value, self._creso, NPY_FR_ns, False) @property def _unit(self) -> str: diff --git a/pandas/_libs/tslibs/timestamps.pyx b/pandas/_libs/tslibs/timestamps.pyx index 02bf03c4a6d24..c185e89d2c7ef 100644 --- a/pandas/_libs/tslibs/timestamps.pyx +++ b/pandas/_libs/tslibs/timestamps.pyx @@ -234,7 +234,6 @@ cdef class _Timestamp(ABCTimestamp): @property def value(self) -> int: - 1/0 return convert_reso(self._value, self._creso, NPY_FR_ns, False) @property diff --git a/pandas/core/computation/pytables.py b/pandas/core/computation/pytables.py index 04a6f6c6277ee..f7d1314b12da2 100644 --- a/pandas/core/computation/pytables.py +++ b/pandas/core/computation/pytables.py @@ -218,13 +218,13 @@ def stringify(value): v = Timestamp(v).as_unit("ns") if v.tz is not None: v = v.tz_convert("UTC") - return TermValue(v, v.value, kind) + return TermValue(v, v._value, kind) elif kind in ("timedelta64", "timedelta"): if isinstance(v, str): v = Timedelta(v) else: v = Timedelta(v, unit="s") - v = v.as_unit("ns").value + v = v.as_unit("ns")._value return TermValue(int(v), v, kind) elif meta == "category": metadata = extract_array(self.metadata, extract_numpy=True) diff --git a/pandas/core/indexes/interval.py b/pandas/core/indexes/interval.py index c6bd7b8aae980..fb4e448c01cb5 100644 --- a/pandas/core/indexes/interval.py +++ b/pandas/core/indexes/interval.py @@ -546,7 +546,7 @@ def _maybe_convert_i8(self, key): if lib.is_period(key): key_i8 = key.ordinal elif isinstance(key_i8, Timestamp): - key_i8 = key_i8.value + key_i8 = key_i8._value elif isinstance(key_i8, (np.datetime64, np.timedelta64)): key_i8 = key_i8.view("i8") else: diff --git a/pandas/core/internals/concat.py b/pandas/core/internals/concat.py index d46b51a2ee954..0e1c00b8a97b7 100644 --- a/pandas/core/internals/concat.py +++ b/pandas/core/internals/concat.py @@ -524,7 +524,7 @@ def get_reindexed_values(self, empty_dtype: DtypeObj, upcasted_na) -> ArrayLike: if isinstance(empty_dtype, DatetimeTZDtype): # NB: exclude e.g. pyarrow[dt64tz] dtypes - i8values = np.full(self.shape, fill_value.value) + i8values = np.full(self.shape, fill_value._value) return DatetimeArray(i8values, dtype=empty_dtype) elif is_1d_only_ea_dtype(empty_dtype): diff --git a/pandas/tests/indexes/datetimes/methods/test_astype.py b/pandas/tests/indexes/datetimes/methods/test_astype.py index 007204fd83bd4..8cf1edf5c7bf3 100644 --- a/pandas/tests/indexes/datetimes/methods/test_astype.py +++ b/pandas/tests/indexes/datetimes/methods/test_astype.py @@ -267,7 +267,7 @@ def _check_rng(rng): ) def test_integer_index_astype_datetime(self, tz, dtype): # GH 20997, 20964, 24559 - val = [Timestamp("2018-01-01", tz=tz).as_unit("ns").value] + val = [Timestamp("2018-01-01", tz=tz).as_unit("ns")._value] result = Index(val, name="idx").astype(dtype) expected = DatetimeIndex(["2018-01-01"], tz=tz, name="idx") tm.assert_index_equal(result, expected) diff --git a/pandas/tests/indexes/interval/test_interval.py b/pandas/tests/indexes/interval/test_interval.py index a809af7e975e2..dedc3fdd00e08 100644 --- a/pandas/tests/indexes/interval/test_interval.py +++ b/pandas/tests/indexes/interval/test_interval.py @@ -378,7 +378,7 @@ def test_maybe_convert_i8(self, breaks): # interval interval = Interval(breaks[0], breaks[1]) result = index._maybe_convert_i8(interval) - expected = Interval(breaks[0].value, breaks[1].value) + expected = Interval(breaks[0]._value, breaks[1]._value) assert result == expected # datetimelike index @@ -388,7 +388,7 @@ def test_maybe_convert_i8(self, breaks): # datetimelike scalar result = index._maybe_convert_i8(breaks[0]) - expected = breaks[0].value + expected = breaks[0]._value assert result == expected # list-like of datetimelike scalars @@ -410,7 +410,7 @@ def test_maybe_convert_i8_nat(self, breaks): tm.assert_index_equal(result, expected) to_convert = to_convert.insert(0, breaks[0]) - expected = expected.insert(0, float(breaks[0].value)) + expected = expected.insert(0, float(breaks[0]._value)) result = index._maybe_convert_i8(to_convert) tm.assert_index_equal(result, expected) diff --git a/pandas/tests/indexing/test_datetime.py b/pandas/tests/indexing/test_datetime.py index dc2fe85679181..e21bc6a4850a3 100644 --- a/pandas/tests/indexing/test_datetime.py +++ b/pandas/tests/indexing/test_datetime.py @@ -16,7 +16,7 @@ class TestDatetimeIndex: def test_get_loc_naive_dti_aware_str_deprecated(self): # GH#46903 - ts = Timestamp("20130101").value + ts = Timestamp("20130101")._value dti = pd.DatetimeIndex([ts + 50 + i for i in range(100)]) ser = Series(range(100), index=dti) diff --git a/pandas/tests/io/json/test_pandas.py b/pandas/tests/io/json/test_pandas.py index 31566f67bef2c..7ef7c1acc8665 100644 --- a/pandas/tests/io/json/test_pandas.py +++ b/pandas/tests/io/json/test_pandas.py @@ -1001,7 +1001,7 @@ def test_mixed_timedelta_datetime(self): frame = DataFrame({"a": [td, ts]}, dtype=object) expected = DataFrame( - {"a": [pd.Timedelta(td).as_unit("ns").value, ts.as_unit("ns").value]} + {"a": [pd.Timedelta(td).as_unit("ns")._value, ts.as_unit("ns")._value]} ) result = read_json(frame.to_json(date_unit="ns"), dtype={"a": "int64"}) tm.assert_frame_equal(result, expected, check_index_type=False) diff --git a/pandas/tests/io/json/test_ujson.py b/pandas/tests/io/json/test_ujson.py index a5d7a16f77a72..472b08963425b 100644 --- a/pandas/tests/io/json/test_ujson.py +++ b/pandas/tests/io/json/test_ujson.py @@ -395,16 +395,16 @@ def test_datetime_units(self): stamp = Timestamp(val).as_unit("ns") roundtrip = ujson.decode(ujson.encode(val, date_unit="s")) - assert roundtrip == stamp.value // 10**9 + assert roundtrip == stamp._value // 10**9 roundtrip = ujson.decode(ujson.encode(val, date_unit="ms")) - assert roundtrip == stamp.value // 10**6 + assert roundtrip == stamp._value // 10**6 roundtrip = ujson.decode(ujson.encode(val, date_unit="us")) - assert roundtrip == stamp.value // 10**3 + assert roundtrip == stamp._value // 10**3 roundtrip = ujson.decode(ujson.encode(val, date_unit="ns")) - assert roundtrip == stamp.value + assert roundtrip == stamp._value msg = "Invalid value 'foo' for option 'date_unit'" with pytest.raises(ValueError, match=msg): diff --git a/pandas/tests/io/pytables/test_timezones.py b/pandas/tests/io/pytables/test_timezones.py index ba125ffd28581..058eaa9d0529d 100644 --- a/pandas/tests/io/pytables/test_timezones.py +++ b/pandas/tests/io/pytables/test_timezones.py @@ -159,7 +159,7 @@ def test_roundtrip_tz_aware_index(setup_path): store.put("frame", df, format="fixed") recons = store["frame"] tm.assert_frame_equal(recons, df) - assert recons.index[0].value == 946706400000000000 + assert recons.index[0]._value == 946706400000000000 def test_store_index_name_with_tz(setup_path): diff --git a/pandas/tests/reductions/test_reductions.py b/pandas/tests/reductions/test_reductions.py index d8b9082ec318a..5dcd87d520bc5 100644 --- a/pandas/tests/reductions/test_reductions.py +++ b/pandas/tests/reductions/test_reductions.py @@ -63,7 +63,7 @@ def test_ops(self, opname, obj): if getattr(obj, "tz", None) is not None: # We need to de-localize before comparing to the numpy-produced result expected = expected.astype("M8[ns]").astype("int64") - assert result.value == expected + assert result._value == expected else: assert result == expected diff --git a/pandas/tests/scalar/period/test_asfreq.py b/pandas/tests/scalar/period/test_asfreq.py index 386ab4150c6ff..e652c63d46f18 100644 --- a/pandas/tests/scalar/period/test_asfreq.py +++ b/pandas/tests/scalar/period/test_asfreq.py @@ -668,7 +668,7 @@ def test_conv_microsecond(self): start = per.start_time expected = Timestamp("2020-01-30 15:57:27.576166") assert start == expected - assert start.value == per.ordinal * 1000 + assert start._value == per.ordinal * 1000 per2 = Period("2300-01-01", "us") msg = "2300-01-01" diff --git a/pandas/tests/scalar/period/test_period.py b/pandas/tests/scalar/period/test_period.py index 710a98ba6f005..d31653e0dba34 100644 --- a/pandas/tests/scalar/period/test_period.py +++ b/pandas/tests/scalar/period/test_period.py @@ -614,7 +614,7 @@ def test_to_timestamp(self): def _ex(p): if p.freq == "B": return p.start_time + Timedelta(days=1, nanoseconds=-1) - return Timestamp((p + p.freq).start_time.value - 1) + return Timestamp((p + p.freq).start_time._value - 1) for fcode in from_lst: p = Period("1982", freq=fcode) @@ -826,7 +826,7 @@ def test_end_time(self): p = Period("2012", freq="A") def _ex(*args): - return Timestamp(Timestamp(datetime(*args)).as_unit("ns").value - 1) + return Timestamp(Timestamp(datetime(*args)).as_unit("ns")._value - 1) xp = _ex(2013, 1, 1) assert xp == p.end_time @@ -878,7 +878,7 @@ def test_end_time_business_friday(self): def test_anchor_week_end_time(self): def _ex(*args): - return Timestamp(Timestamp(datetime(*args)).as_unit("ns").value - 1) + return Timestamp(Timestamp(datetime(*args)).as_unit("ns")._value - 1) p = Period("2013-1-1", "W-SAT") xp = _ex(2013, 1, 6) diff --git a/pandas/tests/scalar/test_nat.py b/pandas/tests/scalar/test_nat.py index 3192baacb4ef4..c1201362e3519 100644 --- a/pandas/tests/scalar/test_nat.py +++ b/pandas/tests/scalar/test_nat.py @@ -184,7 +184,7 @@ def test_nat_iso_format(get_nat): @pytest.mark.parametrize( "klass,expected", [ - (Timestamp, ["normalize", "to_julian_date", "to_period", "unit"]), + (Timestamp, ["normalize", "to_julian_date", "to_period", "unit", "value"]), ( Timedelta, [ @@ -193,6 +193,7 @@ def test_nat_iso_format(get_nat): "to_pytimedelta", "to_timedelta64", "unit", + "value", "view", ], ), diff --git a/pandas/tests/scalar/timedelta/test_arithmetic.py b/pandas/tests/scalar/timedelta/test_arithmetic.py index cbb53ed2b8e36..01ec11c306dcd 100644 --- a/pandas/tests/scalar/timedelta/test_arithmetic.py +++ b/pandas/tests/scalar/timedelta/test_arithmetic.py @@ -393,8 +393,8 @@ def test_td_mul_scalar(self, op): assert op(td, np.nan) is NaT - assert op(-1, td).value == -1 * td.value - assert op(-1.0, td).value == -1.0 * td.value + assert op(-1, td)._value == -1 * td._value + assert op(-1.0, td)._value == -1.0 * td._value msg = "unsupported operand type" with pytest.raises(TypeError, match=msg): @@ -463,11 +463,11 @@ def test_td_div_td64_non_nano(self): # truediv td = Timedelta("1 days 2 hours 3 ns") result = td / np.timedelta64(1, "D") - assert result == td.value / (86400 * 10**9) + assert result == td._value / (86400 * 10**9) result = td / np.timedelta64(1, "s") - assert result == td.value / 10**9 + assert result == td._value / 10**9 result = td / np.timedelta64(1, "ns") - assert result == td.value + assert result == td._value # floordiv td = Timedelta("1 days 2 hours 3 ns") @@ -476,7 +476,7 @@ def test_td_div_td64_non_nano(self): result = td // np.timedelta64(1, "s") assert result == 93600 result = td // np.timedelta64(1, "ns") - assert result == td.value + assert result == td._value def test_td_div_numeric_scalar(self): # GH#19738 diff --git a/pandas/tests/scalar/timestamp/test_arithmetic.py b/pandas/tests/scalar/timestamp/test_arithmetic.py index 0ad3436e55787..2dac346bc54d5 100644 --- a/pandas/tests/scalar/timestamp/test_arithmetic.py +++ b/pandas/tests/scalar/timestamp/test_arithmetic.py @@ -200,7 +200,7 @@ def test_timestamp_add_timedelta64_unit(self, other, expected_difference): now = datetime.utcnow() ts = Timestamp(now).as_unit("ns") result = ts + other - valdiff = result.value - ts.value + valdiff = result._value - ts._value assert valdiff == expected_difference ts2 = Timestamp(now) diff --git a/pandas/tests/scalar/timestamp/test_constructors.py b/pandas/tests/scalar/timestamp/test_constructors.py index 8ee92e28b78bf..10ed2e090bd77 100644 --- a/pandas/tests/scalar/timestamp/test_constructors.py +++ b/pandas/tests/scalar/timestamp/test_constructors.py @@ -133,11 +133,11 @@ def test_constructor(self): for result in [Timestamp(date_str), Timestamp(date_obj)]: result = result.as_unit("ns") # test originally written before non-nano # only with timestring - assert result.as_unit("ns").value == expected + assert result.as_unit("ns")._value == expected # re-creation shouldn't affect to internal value result = Timestamp(result) - assert result.as_unit("ns").value == expected + assert result.as_unit("ns")._value == expected # with timezone for tz, offset in timezones: @@ -146,11 +146,11 @@ def test_constructor(self): "ns" ) # test originally written before non-nano expected_tz = expected - offset * 3600 * 1_000_000_000 - assert result.as_unit("ns").value == expected_tz + assert result.as_unit("ns")._value == expected_tz # should preserve tz result = Timestamp(result) - assert result.as_unit("ns").value == expected_tz + assert result.as_unit("ns")._value == expected_tz # should convert to UTC if tz is not None: @@ -158,7 +158,7 @@ def test_constructor(self): else: result = Timestamp(result, tz="UTC") expected_utc = expected - offset * 3600 * 1_000_000_000 - assert result.as_unit("ns").value == expected_utc + assert result.as_unit("ns")._value == expected_utc def test_constructor_with_stringoffset(self): # GH 7833 @@ -190,31 +190,31 @@ def test_constructor_with_stringoffset(self): for date_str, expected in tests: for result in [Timestamp(date_str)]: # only with timestring - assert result.as_unit("ns").value == expected + assert result.as_unit("ns")._value == expected # re-creation shouldn't affect to internal value result = Timestamp(result) - assert result.as_unit("ns").value == expected + assert result.as_unit("ns")._value == expected # with timezone for tz, offset in timezones: result = Timestamp(date_str, tz=tz) expected_tz = expected - assert result.as_unit("ns").value == expected_tz + assert result.as_unit("ns")._value == expected_tz # should preserve tz result = Timestamp(result) - assert result.as_unit("ns").value == expected_tz + assert result.as_unit("ns")._value == expected_tz # should convert to UTC result = Timestamp(result).tz_convert("UTC") expected_utc = expected - assert result.as_unit("ns").value == expected_utc + assert result.as_unit("ns")._value == expected_utc # This should be 2013-11-01 05:00 in UTC # converted to Chicago tz result = Timestamp("2013-11-01 00:00:00-0500", tz="America/Chicago") - assert result.value == Timestamp("2013-11-01 05:00").value + assert result._value == Timestamp("2013-11-01 05:00")._value expected = "Timestamp('2013-11-01 00:00:00-0500', tz='America/Chicago')" assert repr(result) == expected assert result == eval(repr(result)) @@ -222,7 +222,7 @@ def test_constructor_with_stringoffset(self): # This should be 2013-11-01 05:00 in UTC # converted to Tokyo tz (+09:00) result = Timestamp("2013-11-01 00:00:00-0500", tz="Asia/Tokyo") - assert result.value == Timestamp("2013-11-01 05:00").value + assert result._value == Timestamp("2013-11-01 05:00")._value expected = "Timestamp('2013-11-01 14:00:00+0900', tz='Asia/Tokyo')" assert repr(result) == expected assert result == eval(repr(result)) @@ -231,7 +231,7 @@ def test_constructor_with_stringoffset(self): # This should be 2015-11-18 10:00 in UTC # converted to Asia/Katmandu result = Timestamp("2015-11-18 15:45:00+05:45", tz="Asia/Katmandu") - assert result.value == Timestamp("2015-11-18 10:00").value + assert result._value == Timestamp("2015-11-18 10:00")._value expected = "Timestamp('2015-11-18 15:45:00+0545', tz='Asia/Katmandu')" assert repr(result) == expected assert result == eval(repr(result)) @@ -239,7 +239,7 @@ def test_constructor_with_stringoffset(self): # This should be 2015-11-18 10:00 in UTC # converted to Asia/Kolkata result = Timestamp("2015-11-18 15:30:00+05:30", tz="Asia/Kolkata") - assert result.value == Timestamp("2015-11-18 10:00").value + assert result._value == Timestamp("2015-11-18 10:00")._value expected = "Timestamp('2015-11-18 15:30:00+0530', tz='Asia/Kolkata')" assert repr(result) == expected assert result == eval(repr(result)) @@ -464,12 +464,12 @@ def test_invalid_date_kwarg_with_string_input(self, arg): def test_out_of_bounds_integer_value(self): # GH#26651 check that we raise OutOfBoundsDatetime, not OverflowError - msg = str(Timestamp.max.value * 2) + msg = str(Timestamp.max._value * 2) with pytest.raises(OutOfBoundsDatetime, match=msg): - Timestamp(Timestamp.max.value * 2) - msg = str(Timestamp.min.value * 2) + Timestamp(Timestamp.max._value * 2) + msg = str(Timestamp.min._value * 2) with pytest.raises(OutOfBoundsDatetime, match=msg): - Timestamp(Timestamp.min.value * 2) + Timestamp(Timestamp.min._value * 2) def test_out_of_bounds_value(self): one_us = np.timedelta64(1).astype("timedelta64[us]") @@ -536,7 +536,7 @@ def test_bounds_with_different_units(self): ts = Timestamp(dt64) if unit in ["s", "ms", "us"]: # We can preserve the input unit - assert ts.value == dt64.view("i8") + assert ts._value == dt64.view("i8") else: # we chose the closest unit that we _do_ support assert ts._creso == NpyDatetimeUnit.NPY_FR_s.value @@ -697,8 +697,8 @@ def test_constructor_ambigous_dst(): # on Timestamp created from ambiguous time # doesn't change Timestamp.value ts = Timestamp(1382835600000000000, tz="dateutil/Europe/London") - expected = ts.value - result = Timestamp(ts).value + expected = ts._value + result = Timestamp(ts)._value assert result == expected @@ -711,7 +711,7 @@ def test_constructor_before_dst_switch(epoch): ts = Timestamp(epoch, tz="dateutil/America/Los_Angeles") result = ts.tz.dst(ts) expected = timedelta(seconds=0) - assert Timestamp(ts).value == epoch + assert Timestamp(ts)._value == epoch assert result == expected diff --git a/pandas/tests/scalar/timestamp/test_timezones.py b/pandas/tests/scalar/timestamp/test_timezones.py index e2df4d23bd858..820b2e17a9d3f 100644 --- a/pandas/tests/scalar/timestamp/test_timezones.py +++ b/pandas/tests/scalar/timestamp/test_timezones.py @@ -49,7 +49,7 @@ def test_tz_localize_pushes_out_of_bounds(self): f"underflows past {Timestamp.min}" ) pac = Timestamp.min.tz_localize("US/Pacific") - assert pac.value > Timestamp.min.value + assert pac._value > Timestamp.min._value pac.tz_convert("Asia/Tokyo") # tz_convert doesn't change value with pytest.raises(OutOfBoundsDatetime, match=msg): Timestamp.min.tz_localize("Asia/Tokyo") @@ -60,7 +60,7 @@ def test_tz_localize_pushes_out_of_bounds(self): f"overflows past {Timestamp.max}" ) tokyo = Timestamp.max.tz_localize("Asia/Tokyo") - assert tokyo.value < Timestamp.max.value + assert tokyo._value < Timestamp.max._value tokyo.tz_convert("US/Pacific") # tz_convert doesn't change value with pytest.raises(OutOfBoundsDatetime, match=msg): Timestamp.max.tz_localize("US/Pacific") @@ -103,7 +103,7 @@ def test_tz_localize_ambiguous(self): ts_dst = ts.tz_localize("US/Eastern", ambiguous=True) ts_no_dst = ts.tz_localize("US/Eastern", ambiguous=False) - assert ts_no_dst.value - ts_dst.value == 3600 + assert ts_no_dst._value - ts_dst._value == 3600 msg = re.escape( "'ambiguous' parameter must be one of: " "True, False, 'NaT', 'raise' (default)" @@ -189,8 +189,8 @@ def test_tz_localize_ambiguous_compat(self): dateutil_zone = "dateutil/Europe/London" result_pytz = naive.tz_localize(pytz_zone, ambiguous=False) result_dateutil = naive.tz_localize(dateutil_zone, ambiguous=False) - assert result_pytz.value == result_dateutil.value - assert result_pytz.value == 1382835600 + assert result_pytz._value == result_dateutil._value + assert result_pytz._value == 1382835600 # fixed ambiguous behavior # see gh-14621, GH#45087 @@ -201,8 +201,8 @@ def test_tz_localize_ambiguous_compat(self): # 1 hour difference result_pytz = naive.tz_localize(pytz_zone, ambiguous=True) result_dateutil = naive.tz_localize(dateutil_zone, ambiguous=True) - assert result_pytz.value == result_dateutil.value - assert result_pytz.value == 1382832000 + assert result_pytz._value == result_dateutil._value + assert result_pytz._value == 1382832000 # see gh-14621 assert str(result_pytz) == str(result_dateutil) @@ -431,7 +431,7 @@ def test_timestamp_constructor_near_dst_boundary(self): Timestamp("2017-03-26 02:00", tz="Europe/Paris") result = Timestamp("2017-03-26 02:00:00+0100", tz="Europe/Paris") - naive = Timestamp(result.as_unit("ns").value) + naive = Timestamp(result.as_unit("ns")._value) expected = naive.tz_localize("UTC").tz_convert("Europe/Paris") assert result == expected diff --git a/pandas/tests/series/methods/test_asof.py b/pandas/tests/series/methods/test_asof.py index 8cb0328eb8634..6ae978b22e24d 100644 --- a/pandas/tests/series/methods/test_asof.py +++ b/pandas/tests/series/methods/test_asof.py @@ -17,7 +17,7 @@ class TestSeriesAsof: def test_asof_nanosecond_index_access(self): - ts = Timestamp("20130101").as_unit("ns").value + ts = Timestamp("20130101").as_unit("ns")._value dti = DatetimeIndex([ts + 50 + i for i in range(100)]) ser = Series(np.random.randn(100), index=dti) diff --git a/pandas/tests/series/test_missing.py b/pandas/tests/series/test_missing.py index 3c0f962b90086..81e1e4c205cf7 100644 --- a/pandas/tests/series/test_missing.py +++ b/pandas/tests/series/test_missing.py @@ -44,7 +44,7 @@ def test_timedelta64_nan(self): td1 = td.copy() td1[0] = np.nan assert isna(td1[0]) - assert td1[0].value == iNaT + assert td1[0]._value == iNaT td1[0] = td[0] assert not isna(td1[0]) @@ -58,7 +58,7 @@ def test_timedelta64_nan(self): td1[2] = NaT assert isna(td1[2]) - assert td1[2].value == iNaT + assert td1[2]._value == iNaT td1[2] = td[2] assert not isna(td1[2]) diff --git a/pandas/tests/series/test_reductions.py b/pandas/tests/series/test_reductions.py index e9d2877148c2b..eb11b62a651cc 100644 --- a/pandas/tests/series/test_reductions.py +++ b/pandas/tests/series/test_reductions.py @@ -59,7 +59,7 @@ def test_td64_summation_overflow(): # the computation is converted to float so # might be some loss of precision - assert np.allclose(result.value / 1000, expected.value / 1000) + assert np.allclose(result._value / 1000, expected._value / 1000) # sum msg = "overflow in timedelta operation" diff --git a/pandas/tests/tools/test_to_timedelta.py b/pandas/tests/tools/test_to_timedelta.py index 734f80d4ccdb2..6be499b6dc474 100644 --- a/pandas/tests/tools/test_to_timedelta.py +++ b/pandas/tests/tools/test_to_timedelta.py @@ -218,7 +218,7 @@ def test_to_timedelta_on_missing_values(self): @pytest.mark.parametrize("val", [np.nan, pd.NaT]) def test_to_timedelta_on_missing_values_scalar(self, val): actual = to_timedelta(val) - assert actual.value == np.timedelta64("NaT").astype("int64") + assert actual._value == np.timedelta64("NaT").astype("int64") def test_to_timedelta_float(self): # https://github.com/pandas-dev/pandas/issues/25077 @@ -280,7 +280,7 @@ def test_to_timedelta_zerodim(self, fixed_now_ts): arg2 = arg.view("m8[ns]") result = to_timedelta(arg2) assert isinstance(result, pd.Timedelta) - assert result.value == dt64.view("i8") + assert result._value == dt64.view("i8") def test_to_timedelta_numeric_ea(self, any_numeric_ea_dtype): # GH#48796 From a5aa8e092adbf1f0b89a0f6f1f20a8cb6b83c89e Mon Sep 17 00:00:00 2001 From: MarcoGorelli <> Date: Tue, 24 Jan 2023 09:22:53 +0000 Subject: [PATCH 11/17] _value in ujson --- pandas/_libs/src/ujson/python/objToJSON.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pandas/_libs/src/ujson/python/objToJSON.c b/pandas/_libs/src/ujson/python/objToJSON.c index 13b96f9f8fccd..e892b50515327 100644 --- a/pandas/_libs/src/ujson/python/objToJSON.c +++ b/pandas/_libs/src/ujson/python/objToJSON.c @@ -1306,9 +1306,9 @@ char **NpyArr_encodeLabels(PyArrayObject *labels, PyObjectEncoder *enc, castfunc(dataptr, &nanosecVal, 1, NULL, NULL); } else if (PyDate_Check(item) || PyDelta_Check(item)) { is_datetimelike = 1; - if (PyObject_HasAttrString(item, "value")) { + if (PyObject_HasAttrString(item, "_value")) { // see test_date_index_and_values for case with non-nano - nanosecVal = get_long_attr(item, "value"); + nanosecVal = get_long_attr(item, "_value"); } else { if (PyDelta_Check(item)) { nanosecVal = total_seconds(item) * @@ -1554,8 +1554,8 @@ void Object_beginTypeContext(JSOBJ _obj, JSONTypeContext *tc) { } return; } else if (PyDelta_Check(obj)) { - if (PyObject_HasAttrString(obj, "value")) { - value = get_long_attr(obj, "value"); + if (PyObject_HasAttrString(obj, "_value")) { + value = get_long_attr(obj, "_value"); } else { value = total_seconds(obj) * 1000000000LL; // nanoseconds per sec } From a0cf7d42724a037b6fc6596c1fdc9ecdb68a1ebe Mon Sep 17 00:00:00 2001 From: MarcoGorelli <> Date: Tue, 24 Jan 2023 10:30:50 +0000 Subject: [PATCH 12/17] :label: typing --- pandas/_libs/tslibs/nattype.pyi | 1 + pandas/_libs/tslibs/timedeltas.pyi | 1 + pandas/_libs/tslibs/timestamps.pyi | 1 + 3 files changed, 3 insertions(+) diff --git a/pandas/_libs/tslibs/nattype.pyi b/pandas/_libs/tslibs/nattype.pyi index 72f55bb50895a..8d0a1b59db2a6 100644 --- a/pandas/_libs/tslibs/nattype.pyi +++ b/pandas/_libs/tslibs/nattype.pyi @@ -19,6 +19,7 @@ class _NatComparison: class NaTType: value: np.int64 + _value: np.int64 @property def asm8(self) -> np.datetime64: ... def to_datetime64(self) -> np.datetime64: ... diff --git a/pandas/_libs/tslibs/timedeltas.pyi b/pandas/_libs/tslibs/timedeltas.pyi index c9904e4592329..d67a330e0b0c2 100644 --- a/pandas/_libs/tslibs/timedeltas.pyi +++ b/pandas/_libs/tslibs/timedeltas.pyi @@ -89,6 +89,7 @@ class Timedelta(timedelta): max: ClassVar[Timedelta] resolution: ClassVar[Timedelta] value: int # np.int64 + _value: int # np.int64 # error: "__new__" must return a class instance (got "Union[Timestamp, NaTType]") def __new__( # type: ignore[misc] cls: type[_S], diff --git a/pandas/_libs/tslibs/timestamps.pyi b/pandas/_libs/tslibs/timestamps.pyi index e6a36b69a8d47..a0e2b8df780c6 100644 --- a/pandas/_libs/tslibs/timestamps.pyi +++ b/pandas/_libs/tslibs/timestamps.pyi @@ -33,6 +33,7 @@ class Timestamp(datetime): resolution: ClassVar[Timedelta] value: int # np.int64 + _value: int # np.int64 # error: "__new__" must return a class instance (got "Union[Timestamp, NaTType]") def __new__( # type: ignore[misc] cls: type[_DatetimeT], From db72dd7ad50a666f796d4368cf58ae8b1d4396c5 Mon Sep 17 00:00:00 2001 From: MarcoGorelli <> Date: Wed, 1 Feb 2023 19:19:47 +0000 Subject: [PATCH 13/17] wip --- pandas/_libs/tslibs/timedeltas.pyx | 9 ++++++++- pandas/_libs/tslibs/timestamps.pyx | 9 ++++++++- .../scalar/timestamp/test_constructors.py | 20 +++++++++++++++++++ 3 files changed, 36 insertions(+), 2 deletions(-) diff --git a/pandas/_libs/tslibs/timedeltas.pyx b/pandas/_libs/tslibs/timedeltas.pyx index 9342946f0b3c6..6b1e6319404c1 100644 --- a/pandas/_libs/tslibs/timedeltas.pyx +++ b/pandas/_libs/tslibs/timedeltas.pyx @@ -1018,7 +1018,14 @@ cdef class _Timedelta(timedelta): @property def value(self): - return convert_reso(self._value, self._creso, NPY_FR_ns, False) + try: + return convert_reso(self._value, self._creso, NPY_FR_ns, False) + except OverflowError: + raise OverflowError( + "Cannot convert Timedelta to nanoseconds without overflow. " + "Use `.asm8.view('i8')` to cast represent timestamp in its own " + f"unit (here, {self.unit})." + ) @property def _unit(self) -> str: diff --git a/pandas/_libs/tslibs/timestamps.pyx b/pandas/_libs/tslibs/timestamps.pyx index f9f4c963229f5..903a994c7cc3c 100644 --- a/pandas/_libs/tslibs/timestamps.pyx +++ b/pandas/_libs/tslibs/timestamps.pyx @@ -234,7 +234,14 @@ cdef class _Timestamp(ABCTimestamp): @property def value(self) -> int: - return convert_reso(self._value, self._creso, NPY_FR_ns, False) + try: + return convert_reso(self._value, self._creso, NPY_FR_ns, False) + except OverflowError: + raise OverflowError( + "Cannot convert Timestamp to nanoseconds without overflow. " + "Use `.asm8.view('i8')` to cast represent timestamp in its own " + f"unit (here, {self.unit})." + ) @property def unit(self) -> str: diff --git a/pandas/tests/scalar/timestamp/test_constructors.py b/pandas/tests/scalar/timestamp/test_constructors.py index 2e30f07f7e119..db4987472dc2d 100644 --- a/pandas/tests/scalar/timestamp/test_constructors.py +++ b/pandas/tests/scalar/timestamp/test_constructors.py @@ -767,3 +767,23 @@ def test_timestamp_nano_range(nano): # GH 48255 with pytest.raises(ValueError, match="nanosecond must be in 0..999"): Timestamp(year=2022, month=1, day=1, nanosecond=nano) + + +def test_non_nano_value(): + # https://github.com/pandas-dev/pandas/issues/49076 + result = Timestamp("1800-01-01", unit="s").value + # `.value` shows nanoseconds, even though unit is 's' + assert result == -5364662400000000000 + + # out-of-nanoseconds-bounds `.value` raises informative message + msg = ( + r"Cannot convert timestamp to nanoseconds without overflow. " + r"Use `.asm8.view\('i8'\)` to cast represent timestamp in its " + r"own unit \(here, s\).$" + ) + ts = Timestamp("0300-01-01") + with pytest.raises(OverflowError, match=msg): + ts.value + # check that the suggested workaround actually works + result = ts.asm8.view("i8") + assert result == -52700112000 From 16003f97f316f56f11fbd9b349bdfc4eb25e276c Mon Sep 17 00:00:00 2001 From: MarcoGorelli <> Date: Wed, 1 Feb 2023 19:53:33 +0000 Subject: [PATCH 14/17] advise to use asm8 instead --- pandas/_libs/tslibs/timedeltas.pyx | 2 +- pandas/_libs/tslibs/timestamps.pyx | 2 +- .../scalar/timedelta/test_constructors.py | 20 +++++++++++++++++++ .../scalar/timestamp/test_constructors.py | 4 ++-- 4 files changed, 24 insertions(+), 4 deletions(-) diff --git a/pandas/_libs/tslibs/timedeltas.pyx b/pandas/_libs/tslibs/timedeltas.pyx index 6b1e6319404c1..5ecce54e01db6 100644 --- a/pandas/_libs/tslibs/timedeltas.pyx +++ b/pandas/_libs/tslibs/timedeltas.pyx @@ -1023,7 +1023,7 @@ cdef class _Timedelta(timedelta): except OverflowError: raise OverflowError( "Cannot convert Timedelta to nanoseconds without overflow. " - "Use `.asm8.view('i8')` to cast represent timestamp in its own " + "Use `.asm8.view('i8')` to cast represent Timedelta in its own " f"unit (here, {self.unit})." ) diff --git a/pandas/_libs/tslibs/timestamps.pyx b/pandas/_libs/tslibs/timestamps.pyx index 903a994c7cc3c..c4025c7e5efe7 100644 --- a/pandas/_libs/tslibs/timestamps.pyx +++ b/pandas/_libs/tslibs/timestamps.pyx @@ -239,7 +239,7 @@ cdef class _Timestamp(ABCTimestamp): except OverflowError: raise OverflowError( "Cannot convert Timestamp to nanoseconds without overflow. " - "Use `.asm8.view('i8')` to cast represent timestamp in its own " + "Use `.asm8.view('i8')` to cast represent Timestamp in its own " f"unit (here, {self.unit})." ) diff --git a/pandas/tests/scalar/timedelta/test_constructors.py b/pandas/tests/scalar/timedelta/test_constructors.py index bdd9b2ab1dfd8..ad9dd408fbeaf 100644 --- a/pandas/tests/scalar/timedelta/test_constructors.py +++ b/pandas/tests/scalar/timedelta/test_constructors.py @@ -512,3 +512,23 @@ class MyCustomTimedelta(Timedelta): td = MyCustomTimedelta("1 minute") assert isinstance(td, MyCustomTimedelta) + + +def test_non_nano_value(): + # https://github.com/pandas-dev/pandas/issues/49076 + result = Timedelta(10, unit="D").as_unit("s").value + # `.value` shows nanoseconds, even though unit is 's' + assert result == 864000000000000 + + # out-of-nanoseconds-bounds `.value` raises informative message + msg = ( + r"Cannot convert Timedelta to nanoseconds without overflow. " + r"Use `.asm8.view\('i8'\)` to cast represent Timedelta in its " + r"own unit \(here, s\).$" + ) + td = Timedelta(1_000, "D").as_unit("s") * 1_000 + with pytest.raises(OverflowError, match=msg): + td.value + # check that the suggested workaround actually works + result = td.asm8.view("i8") + assert result == 86400000000 diff --git a/pandas/tests/scalar/timestamp/test_constructors.py b/pandas/tests/scalar/timestamp/test_constructors.py index db4987472dc2d..5ea8fc53a6bab 100644 --- a/pandas/tests/scalar/timestamp/test_constructors.py +++ b/pandas/tests/scalar/timestamp/test_constructors.py @@ -777,8 +777,8 @@ def test_non_nano_value(): # out-of-nanoseconds-bounds `.value` raises informative message msg = ( - r"Cannot convert timestamp to nanoseconds without overflow. " - r"Use `.asm8.view\('i8'\)` to cast represent timestamp in its " + r"Cannot convert Timestamp to nanoseconds without overflow. " + r"Use `.asm8.view\('i8'\)` to cast represent Timestamp in its " r"own unit \(here, s\).$" ) ts = Timestamp("0300-01-01") From 2b4da6cbd77b161368d7f230171209557a322f87 Mon Sep 17 00:00:00 2001 From: MarcoGorelli <> Date: Thu, 2 Feb 2023 16:20:18 +0000 Subject: [PATCH 15/17] fix test missing --- pandas/_libs/tslibs/nattype.pyi | 3 ++- pandas/_libs/tslibs/nattype.pyx | 4 ++++ pandas/tests/scalar/test_nat.py | 3 +-- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/pandas/_libs/tslibs/nattype.pyi b/pandas/_libs/tslibs/nattype.pyi index 8d0a1b59db2a6..04f8943710416 100644 --- a/pandas/_libs/tslibs/nattype.pyi +++ b/pandas/_libs/tslibs/nattype.pyi @@ -18,9 +18,10 @@ class _NatComparison: def __call__(self, other: _NaTComparisonTypes) -> bool: ... class NaTType: - value: np.int64 _value: np.int64 @property + def value(self) -> int: ... + @property def asm8(self) -> np.datetime64: ... def to_datetime64(self) -> np.datetime64: ... def to_numpy( diff --git a/pandas/_libs/tslibs/nattype.pyx b/pandas/_libs/tslibs/nattype.pyx index 88b7707c4fb53..d9d8ce3bb16d1 100644 --- a/pandas/_libs/tslibs/nattype.pyx +++ b/pandas/_libs/tslibs/nattype.pyx @@ -361,6 +361,10 @@ class NaTType(_NaT): return base + @property + def value(self) -> int: + return self._value + def __reduce_ex__(self, protocol): # python 3.6 compat # https://bugs.python.org/issue28730 diff --git a/pandas/tests/scalar/test_nat.py b/pandas/tests/scalar/test_nat.py index c1201362e3519..3192baacb4ef4 100644 --- a/pandas/tests/scalar/test_nat.py +++ b/pandas/tests/scalar/test_nat.py @@ -184,7 +184,7 @@ def test_nat_iso_format(get_nat): @pytest.mark.parametrize( "klass,expected", [ - (Timestamp, ["normalize", "to_julian_date", "to_period", "unit", "value"]), + (Timestamp, ["normalize", "to_julian_date", "to_period", "unit"]), ( Timedelta, [ @@ -193,7 +193,6 @@ def test_nat_iso_format(get_nat): "to_pytimedelta", "to_timedelta64", "unit", - "value", "view", ], ), From 9b50ffae7b1dbf4f687425729a10a50f5432db5f Mon Sep 17 00:00:00 2001 From: MarcoGorelli <> Date: Mon, 6 Feb 2023 13:39:33 +0000 Subject: [PATCH 16/17] make value property --- pandas/_libs/tslibs/timestamps.pyi | 3 ++- pandas/core/dtypes/cast.py | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/pandas/_libs/tslibs/timestamps.pyi b/pandas/_libs/tslibs/timestamps.pyi index a0e2b8df780c6..26b0c9170aaa0 100644 --- a/pandas/_libs/tslibs/timestamps.pyi +++ b/pandas/_libs/tslibs/timestamps.pyi @@ -32,7 +32,6 @@ class Timestamp(datetime): max: ClassVar[Timestamp] resolution: ClassVar[Timedelta] - value: int # np.int64 _value: int # np.int64 # error: "__new__" must return a class instance (got "Union[Timestamp, NaTType]") def __new__( # type: ignore[misc] @@ -57,6 +56,8 @@ class Timestamp(datetime): cls, value: int, reso: int, tz: _tzinfo | None ) -> Timestamp: ... @property + def value(self) -> int: ... # np.int64 + @property def year(self) -> int: ... @property def month(self) -> int: ... diff --git a/pandas/core/dtypes/cast.py b/pandas/core/dtypes/cast.py index f0b309638321c..3be89f6da2bd8 100644 --- a/pandas/core/dtypes/cast.py +++ b/pandas/core/dtypes/cast.py @@ -814,7 +814,7 @@ def infer_dtype_from_scalar(val, pandas_dtype: bool = False) -> tuple[DtypeObj, dtype = _dtype_obj else: dtype = np.dtype("m8[ns]") - val = np.timedelta64(val._value, "ns") + val = np.timedelta64(val.value, "ns") elif is_bool(val): dtype = np.dtype(np.bool_) From 79b3f13e6e2b8d370014659ab014318d3597efa7 Mon Sep 17 00:00:00 2001 From: MarcoGorelli <> Date: Mon, 6 Feb 2023 19:55:13 +0000 Subject: [PATCH 17/17] un-xfail test --- pandas/tests/dtypes/cast/test_promote.py | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/pandas/tests/dtypes/cast/test_promote.py b/pandas/tests/dtypes/cast/test_promote.py index 4f13858b0c131..68deb0972cebb 100644 --- a/pandas/tests/dtypes/cast/test_promote.py +++ b/pandas/tests/dtypes/cast/test_promote.py @@ -430,19 +430,6 @@ def test_maybe_promote_any_with_timedelta64(any_numpy_dtype, fill_value, request expected_dtype = dtype # for timedelta dtypes, scalar values get cast to pd.Timedelta.value exp_val_for_scalar = pd.Timedelta(fill_value).to_timedelta64() - - if isinstance(fill_value, np.timedelta64) and fill_value.dtype != "m8[ns]": - mark = pytest.mark.xfail( - reason="maybe_promote not yet updated to handle non-nano " - "Timedelta scalar" - ) - request.node.add_marker(mark) - elif type(fill_value) is datetime.timedelta: - mark = pytest.mark.xfail( - reason="maybe_promote not yet updated to handle non-nano " - "Timedelta scalar" - ) - request.node.add_marker(mark) else: expected_dtype = np.dtype(object) exp_val_for_scalar = fill_value