From f2aa1d8dafac6cbca027983c23ccab0011945b1f Mon Sep 17 00:00:00 2001 From: Diogo Miranda Date: Mon, 1 Apr 2024 18:44:33 +0100 Subject: [PATCH 1/9] fix: replace function now also replaces unit parameter if applicable --- pandas/_libs/tslibs/timestamps.pyx | 35 ++++++++++++++++--- .../scalar/timestamp/methods/test_replace.py | 14 ++++++++ 2 files changed, 44 insertions(+), 5 deletions(-) diff --git a/pandas/_libs/tslibs/timestamps.pyx b/pandas/_libs/tslibs/timestamps.pyx index d4cd90613ca5b..72769930e69f5 100644 --- a/pandas/_libs/tslibs/timestamps.pyx +++ b/pandas/_libs/tslibs/timestamps.pyx @@ -59,6 +59,7 @@ from pandas._libs.tslibs.conversion cimport ( maybe_localize_tso, ) from pandas._libs.tslibs.dtypes cimport ( + abbrev_to_npy_unit, npy_unit_to_abbrev, npy_unit_to_attrname, periods_per_day, @@ -2439,10 +2440,12 @@ default 'raise' datetime ts_input tzinfo_type tzobj _TSObject ts + NPY_DATETIMEUNIT rep_reso # set to naive if needed tzobj = self.tzinfo value = self._value + rep_reso = self._creso # GH 37610. Preserve fold when replacing. if fold is None: @@ -2465,23 +2468,45 @@ default 'raise' return v if year is not None: + rep_reso = NPY_DATETIMEUNIT.NPY_FR_Y dts.year = validate("year", year) + rep_reso = NPY_DATETIMEUNIT.NPY_FR_Y if month is not None: + rep_reso = NPY_DATETIMEUNIT.NPY_FR_M dts.month = validate("month", month) + rep_reso = NPY_DATETIMEUNIT.NPY_FR_M if day is not None: + rep_reso = NPY_DATETIMEUNIT.NPY_FR_D dts.day = validate("day", day) + rep_reso = NPY_DATETIMEUNIT.NPY_FR_D if hour is not None: + rep_reso = NPY_DATETIMEUNIT.NPY_FR_h dts.hour = validate("hour", hour) + rep_reso = NPY_DATETIMEUNIT.NPY_FR_h if minute is not None: + rep_reso = NPY_DATETIMEUNIT.NPY_FR_m dts.min = validate("minute", minute) + rep_reso = NPY_DATETIMEUNIT.NPY_FR_m if second is not None: + rep_reso = NPY_DATETIMEUNIT.NPY_FR_s dts.sec = validate("second", second) + rep_reso = NPY_DATETIMEUNIT.NPY_FR_s if microsecond is not None: + rep_reso = NPY_DATETIMEUNIT.NPY_FR_ms dts.us = validate("microsecond", microsecond) + if microsecond > 999: + rep_reso = NPY_DATETIMEUNIT.NPY_FR_us + else: + rep_reso = NPY_DATETIMEUNIT.NPY_FR_ms if nanosecond is not None: + rep_reso = NPY_DATETIMEUNIT.NPY_FR_ns dts.ps = validate("nanosecond", nanosecond) * 1000 + rep_reso = NPY_DATETIMEUNIT.NPY_FR_ns if tzinfo is not object: tzobj = tzinfo + + if rep_reso < self._creso: + rep_reso = self._creso # reconstruct & check bounds if tzobj is None: @@ -2489,17 +2514,17 @@ default 'raise' # to datetimes outside of pydatetime range. ts = _TSObject() try: - ts.value = npy_datetimestruct_to_datetime(self._creso, &dts) + ts.value = npy_datetimestruct_to_datetime(rep_reso, &dts) except OverflowError as err: fmt = dts_to_iso_string(&dts) raise OutOfBoundsDatetime( f"Out of bounds timestamp: {fmt} with frequency '{self.unit}'" ) from err ts.dts = dts - ts.creso = self._creso + ts.creso = rep_reso ts.fold = fold return create_timestamp_from_ts( - ts.value, dts, tzobj, fold, reso=self._creso + ts.value, dts, tzobj, fold, reso=rep_reso ) elif tzobj is not None and treat_tz_as_pytz(tzobj): @@ -2518,10 +2543,10 @@ default 'raise' ts_input = datetime(**kwargs) ts = convert_datetime_to_tsobject( - ts_input, tzobj, nanos=dts.ps // 1000, reso=self._creso + ts_input, tzobj, nanos=dts.ps // 1000, reso=rep_reso ) return create_timestamp_from_ts( - ts.value, dts, tzobj, fold, reso=self._creso + ts.value, dts, tzobj, fold, reso=rep_reso ) def to_julian_date(self) -> np.float64: diff --git a/pandas/tests/scalar/timestamp/methods/test_replace.py b/pandas/tests/scalar/timestamp/methods/test_replace.py index d67de79a8dd10..e5805b387339f 100644 --- a/pandas/tests/scalar/timestamp/methods/test_replace.py +++ b/pandas/tests/scalar/timestamp/methods/test_replace.py @@ -189,3 +189,17 @@ def test_replace_preserves_fold(self, fold): ts_replaced = ts.replace(second=1) assert ts_replaced.fold == fold + + def test_replace_unit(self): + #GH#57749 + ts = Timestamp("2023-07-15 23:08:12") + ts1 = Timestamp("2023-07-15 23:08:12.134567") + ts2 = Timestamp("2023-07-15 23:08:12.134567123") + + ts = ts.replace(microsecond=ts1.microsecond) + + assert ts == ts1 + + ts = ts.replace(nanosecond=ts2.nanosecond) + + assert ts == ts2 From 97ebdc0032c7842377336a92e17c94712a42b94b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Robert?= Date: Mon, 1 Apr 2024 19:08:53 +0200 Subject: [PATCH 2/9] MNT: fix compatibility with beautifulsoup4 4.13.0b2 (#58100) --- pandas/io/html.py | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/pandas/io/html.py b/pandas/io/html.py index b4f6a5508726b..42f5266e7649b 100644 --- a/pandas/io/html.py +++ b/pandas/io/html.py @@ -584,14 +584,8 @@ class _BeautifulSoupHtml5LibFrameParser(_HtmlFrameParser): :class:`pandas.io.html._HtmlFrameParser`. """ - def __init__(self, *args, **kwargs) -> None: - super().__init__(*args, **kwargs) - from bs4 import SoupStrainer - - self._strainer = SoupStrainer("table") - def _parse_tables(self, document, match, attrs): - element_name = self._strainer.name + element_name = "table" tables = document.find_all(element_name, attrs=attrs) if not tables: raise ValueError("No tables found") From 6ed649d315937a14cb22a009f410dd7af3eca77a Mon Sep 17 00:00:00 2001 From: Jonas Bergner <44500888+bergnerjonas@users.noreply.github.com> Date: Mon, 1 Apr 2024 19:11:43 +0200 Subject: [PATCH 3/9] DOC: Fix docstring errors for pandas.DataFrame.unstack, pandas.DataFrame.value_counts and pandas.DataFrame.tz_localize (#58097) * Add results information to unstack method docstring. * Add result docstring to value_counts method. * Add See also section to DataFrame.tz_localize method. * Add See also section for unstack method of Series. * Remove methods from code check ignore list * Fix order of docstring sections. * Fix further validation errors. * Reinsert method to ignore list. --- ci/code_checks.sh | 7 ------- pandas/core/base.py | 1 + pandas/core/frame.py | 11 +++++++---- pandas/core/generic.py | 12 +++++++++--- pandas/core/series.py | 4 ++++ 5 files changed, 21 insertions(+), 14 deletions(-) diff --git a/ci/code_checks.sh b/ci/code_checks.sh index 0c4e6641444f1..a9f69ee4f6c57 100755 --- a/ci/code_checks.sh +++ b/ci/code_checks.sh @@ -127,9 +127,6 @@ if [[ -z "$CHECK" || "$CHECK" == "docstrings" ]]; then -i "pandas.DataFrame.to_period SA01" \ -i "pandas.DataFrame.to_timestamp SA01" \ -i "pandas.DataFrame.tz_convert SA01" \ - -i "pandas.DataFrame.tz_localize SA01" \ - -i "pandas.DataFrame.unstack RT03" \ - -i "pandas.DataFrame.value_counts RT03" \ -i "pandas.DataFrame.var PR01,RT03,SA01" \ -i "pandas.DataFrame.where RT03" \ -i "pandas.DatetimeIndex.ceil SA01" \ @@ -226,7 +223,6 @@ if [[ -z "$CHECK" || "$CHECK" == "docstrings" ]]; then -i "pandas.Index.to_list RT03" \ -i "pandas.Index.union PR07,RT03,SA01" \ -i "pandas.Index.unique RT03" \ - -i "pandas.Index.value_counts RT03" \ -i "pandas.Index.view GL08" \ -i "pandas.Int16Dtype SA01" \ -i "pandas.Int32Dtype SA01" \ @@ -482,10 +478,7 @@ if [[ -z "$CHECK" || "$CHECK" == "docstrings" ]]; then -i "pandas.Series.to_timestamp RT03,SA01" \ -i "pandas.Series.truediv PR07" \ -i "pandas.Series.tz_convert SA01" \ - -i "pandas.Series.tz_localize SA01" \ - -i "pandas.Series.unstack SA01" \ -i "pandas.Series.update PR07,SA01" \ - -i "pandas.Series.value_counts RT03" \ -i "pandas.Series.var PR01,RT03,SA01" \ -i "pandas.Series.where RT03" \ -i "pandas.SparseDtype SA01" \ diff --git a/pandas/core/base.py b/pandas/core/base.py index 263265701691b..f923106e967b7 100644 --- a/pandas/core/base.py +++ b/pandas/core/base.py @@ -924,6 +924,7 @@ def value_counts( Returns ------- Series + Series containing counts of unique values. See Also -------- diff --git a/pandas/core/frame.py b/pandas/core/frame.py index 50a93994dc76b..abb8d13342c9d 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -7162,7 +7162,7 @@ def value_counts( dropna: bool = True, ) -> Series: """ - Return a Series containing the frequency of each distinct row in the Dataframe. + Return a Series containing the frequency of each distinct row in the DataFrame. Parameters ---------- @@ -7175,13 +7175,14 @@ def value_counts( ascending : bool, default False Sort in ascending order. dropna : bool, default True - Don't include counts of rows that contain NA values. + Do not include counts of rows that contain NA values. .. versionadded:: 1.3.0 Returns ------- Series + Series containing the frequency of each distinct row in the DataFrame. See Also -------- @@ -7192,8 +7193,8 @@ def value_counts( The returned Series will have a MultiIndex with one level per input column but an Index (non-multi) for a single label. By default, rows that contain any NA values are omitted from the result. By default, - the resulting Series will be in descending order so that the first - element is the most frequently-occurring row. + the resulting Series will be sorted by frequencies in descending order so that + the first element is the most frequently-occurring row. Examples -------- @@ -9658,6 +9659,8 @@ def unstack( Returns ------- Series or DataFrame + If index is a MultiIndex: DataFrame with pivoted index labels as new + inner-most level column labels, else Series. See Also -------- diff --git a/pandas/core/generic.py b/pandas/core/generic.py index 858d2ba82a969..ee1ce2f817b6c 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -10485,10 +10485,10 @@ def tz_localize( nonexistent: TimeNonexistent = "raise", ) -> Self: """ - Localize tz-naive index of a Series or DataFrame to target time zone. + Localize time zone naive index of a Series or DataFrame to target time zone. This operation localizes the Index. To localize the values in a - timezone-naive Series, use :meth:`Series.dt.tz_localize`. + time zone naive Series, use :meth:`Series.dt.tz_localize`. Parameters ---------- @@ -10548,13 +10548,19 @@ def tz_localize( Returns ------- {klass} - Same type as the input. + Same type as the input, with time zone naive or aware index, depending on + ``tz``. Raises ------ TypeError If the TimeSeries is tz-aware and tz is not None. + See Also + -------- + Series.dt.tz_localize: Localize the values in a time zone naive Series. + Timestamp.tz_localize: Localize the Timestamp to a timezone. + Examples -------- Localize local times: diff --git a/pandas/core/series.py b/pandas/core/series.py index b0dc05fce7913..843788273a6ef 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -4257,6 +4257,10 @@ def unstack( DataFrame Unstacked Series. + See Also + -------- + DataFrame.unstack : Pivot the MultiIndex of a DataFrame. + Notes ----- Reference :ref:`the user guide ` for more examples. From 323bf84df6ab0df0c05fc05d5d4c049055a78eac Mon Sep 17 00:00:00 2001 From: Kamel Gazzaz <60620606+kamelCased@users.noreply.github.com> Date: Mon, 1 Apr 2024 10:19:57 -0700 Subject: [PATCH 4/9] Remove 'Not implemented for Series' from _num_doc in generic.py (#58096) Documentation fix in `generic.py` line 11715: Removed 'Not implemented for Series' in _num_doc given that `numeric_only` is now implemented for Series in all the methods min, max, mean, median, skew, kurt --- pandas/core/generic.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/core/generic.py b/pandas/core/generic.py index ee1ce2f817b6c..8a98c598324af 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -11718,7 +11718,7 @@ def last_valid_index(self) -> Hashable: skipna : bool, default True Exclude NA/null values when computing the result. numeric_only : bool, default False - Include only float, int, boolean columns. Not implemented for Series. + Include only float, int, boolean columns. {min_count}\ **kwargs From 5f75c9f4c9c2645c068431b0a0242a4d930636b3 Mon Sep 17 00:00:00 2001 From: Abdulaziz Aloqeely <52792999+Aloqeely@users.noreply.github.com> Date: Mon, 1 Apr 2024 20:27:24 +0300 Subject: [PATCH 5/9] CI: Remove deprecated methods from code_checks.sh (#58090) Remove deprecated methods from code_checks.sh Co-authored-by: Abdulaziz Aloqeely <52792999+DAzVise@users.noreply.github.com> --- ci/code_checks.sh | 3 --- 1 file changed, 3 deletions(-) diff --git a/ci/code_checks.sh b/ci/code_checks.sh index a9f69ee4f6c57..f4ea0a1e2bc28 100755 --- a/ci/code_checks.sh +++ b/ci/code_checks.sh @@ -84,7 +84,6 @@ if [[ -z "$CHECK" || "$CHECK" == "docstrings" ]]; then -i "pandas.DataFrame.assign SA01" \ -i "pandas.DataFrame.at_time PR01" \ -i "pandas.DataFrame.axes SA01" \ - -i "pandas.DataFrame.backfill PR01,SA01" \ -i "pandas.DataFrame.bfill SA01" \ -i "pandas.DataFrame.columns SA01" \ -i "pandas.DataFrame.copy SA01" \ @@ -104,7 +103,6 @@ if [[ -z "$CHECK" || "$CHECK" == "docstrings" ]]; then -i "pandas.DataFrame.mean RT03,SA01" \ -i "pandas.DataFrame.median RT03,SA01" \ -i "pandas.DataFrame.min RT03" \ - -i "pandas.DataFrame.pad PR01,SA01" \ -i "pandas.DataFrame.plot PR02,SA01" \ -i "pandas.DataFrame.pop SA01" \ -i "pandas.DataFrame.prod RT03" \ @@ -119,7 +117,6 @@ if [[ -z "$CHECK" || "$CHECK" == "docstrings" ]]; then -i "pandas.DataFrame.sparse.to_dense SA01" \ -i "pandas.DataFrame.std PR01,RT03,SA01" \ -i "pandas.DataFrame.sum RT03" \ - -i "pandas.DataFrame.swapaxes PR01,SA01" \ -i "pandas.DataFrame.swaplevel SA01" \ -i "pandas.DataFrame.to_feather SA01" \ -i "pandas.DataFrame.to_markdown SA01" \ From 0a9a50139adb8a1f29686b7220784ee4fb91e15d Mon Sep 17 00:00:00 2001 From: lamprinikourou <127689412+lamprinikourou@users.noreply.github.com> Date: Mon, 1 Apr 2024 20:32:02 +0300 Subject: [PATCH 6/9] DOC: Changed ndim to 1, modified doc as suggested. #57088 (#58091) * #57088: Changed ndim to 1, modified doc as suggested. * added tab --- pandas/core/frame.py | 4 ++-- pandas/core/generic.py | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pandas/core/frame.py b/pandas/core/frame.py index abb8d13342c9d..4715164a4208a 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -11497,7 +11497,7 @@ def any( **kwargs, ) -> Series | bool: ... - @doc(make_doc("any", ndim=2)) + @doc(make_doc("any", ndim=1)) def any( self, *, @@ -11543,7 +11543,7 @@ def all( **kwargs, ) -> Series | bool: ... - @doc(make_doc("all", ndim=2)) + @doc(make_doc("all", ndim=1)) def all( self, axis: Axis | None = 0, diff --git a/pandas/core/generic.py b/pandas/core/generic.py index 8a98c598324af..bfee4ced2b3d8 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -11887,9 +11887,9 @@ def last_valid_index(self) -> Hashable: Returns ------- -{name1} or {name2} - If level is specified, then, {name2} is returned; otherwise, {name1} - is returned. +{name2} or {name1} + If axis=None, then a scalar boolean is returned. + Otherwise a Series is returned with index matching the index argument. {see_also} {examples}""" From 96d59cdd1c052ddce1747aeb0e35b9c052410a6b Mon Sep 17 00:00:00 2001 From: Thomas Li <47963215+lithomas1@users.noreply.github.com> Date: Mon, 1 Apr 2024 13:36:41 -0400 Subject: [PATCH 7/9] BLD: Build wheels using numpy 2.0rc1 (#58087) * BLD: Build wheels using numpy 2.0rc1 * move to pyproject.toml * typo --- .circleci/config.yml | 4 ---- .github/workflows/wheels.yml | 12 ------------ pyproject.toml | 7 ++++++- 3 files changed, 6 insertions(+), 17 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index ea93575ac9430..6f134c9a7a7bd 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -72,10 +72,6 @@ jobs: no_output_timeout: 30m # Sometimes the tests won't generate any output, make sure the job doesn't get killed by that command: | pip3 install cibuildwheel==2.15.0 - # When this is a nightly wheel build, allow picking up NumPy 2.0 dev wheels: - if [[ "$IS_SCHEDULE_DISPATCH" == "true" || "$IS_PUSH" != 'true' ]]; then - export CIBW_ENVIRONMENT="PIP_EXTRA_INDEX_URL=https://pypi.anaconda.org/scientific-python-nightly-wheels/simple" - fi cibuildwheel --prerelease-pythons --output-dir wheelhouse environment: diff --git a/.github/workflows/wheels.yml b/.github/workflows/wheels.yml index 470c044d2e99e..d6cfd3b0ad257 100644 --- a/.github/workflows/wheels.yml +++ b/.github/workflows/wheels.yml @@ -148,18 +148,6 @@ jobs: CIBW_PRERELEASE_PYTHONS: True CIBW_BUILD: ${{ matrix.python[0] }}-${{ matrix.buildplat[1] }} - - name: Build nightly wheels (with NumPy pre-release) - if: ${{ (env.IS_SCHEDULE_DISPATCH == 'true' && env.IS_PUSH != 'true') }} - uses: pypa/cibuildwheel@v2.17.0 - with: - package-dir: ./dist/${{ startsWith(matrix.buildplat[1], 'macosx') && env.sdist_name || needs.build_sdist.outputs.sdist_file }} - env: - # The nightly wheels should be build witht he NumPy 2.0 pre-releases - # which requires the additional URL. - CIBW_ENVIRONMENT: PIP_EXTRA_INDEX_URL=https://pypi.anaconda.org/scientific-python-nightly-wheels/simple - CIBW_PRERELEASE_PYTHONS: True - CIBW_BUILD: ${{ matrix.python[0] }}-${{ matrix.buildplat[1] }} - - name: Set up Python uses: mamba-org/setup-micromamba@v1 with: diff --git a/pyproject.toml b/pyproject.toml index 5f5b013ca8461..259d003de92d5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -152,6 +152,9 @@ setup = ['--vsenv'] # For Windows skip = "cp36-* cp37-* cp38-* pp* *_i686 *_ppc64le *_s390x" build-verbosity = "3" environment = {LDFLAGS="-Wl,--strip-all"} +# TODO: remove this once numpy 2.0 proper releases +# and specify numpy 2.0 as a dependency in [build-system] requires in pyproject.toml +before-build = "pip install numpy==2.0.0rc1" test-requires = "hypothesis>=6.46.1 pytest>=7.3.2 pytest-xdist>=2.2.0" test-command = """ PANDAS_CI='1' python -c 'import pandas as pd; \ @@ -160,7 +163,9 @@ test-command = """ """ [tool.cibuildwheel.windows] -before-build = "pip install delvewheel" +# TODO: remove this once numpy 2.0 proper releases +# and specify numpy 2.0 as a dependency in [build-system] requires in pyproject.toml +before-build = "pip install delvewheel numpy==2.0.0rc1" repair-wheel-command = "delvewheel repair -w {dest_dir} {wheel}" [[tool.cibuildwheel.overrides]] From 63c66fed4fa57caf4a005848b87cb81e6a9c97cc Mon Sep 17 00:00:00 2001 From: Diogo Miranda Date: Mon, 1 Apr 2024 19:00:58 +0100 Subject: [PATCH 8/9] doc: added whatsnew note --- doc/source/whatsnew/v3.0.0.rst | 1 + pandas/_libs/tslibs/timestamps.pyx | 9 --------- pandas/tests/scalar/timestamp/methods/test_replace.py | 4 ---- 3 files changed, 1 insertion(+), 13 deletions(-) diff --git a/doc/source/whatsnew/v3.0.0.rst b/doc/source/whatsnew/v3.0.0.rst index 15e85d0f90c5e..1f220c51d436c 100644 --- a/doc/source/whatsnew/v3.0.0.rst +++ b/doc/source/whatsnew/v3.0.0.rst @@ -338,6 +338,7 @@ Bug fixes - Fixed bug in :meth:`Series.diff` allowing non-integer values for the ``periods`` argument. (:issue:`56607`) - Fixed bug in :meth:`Series.rank` that doesn't preserve missing values for nullable integers when ``na_option='keep'``. (:issue:`56976`) - Fixed bug in :meth:`Series.replace` and :meth:`DataFrame.replace` inconsistently replacing matching instances when ``regex=True`` and missing values are present. (:issue:`56599`) +- Fixed bug in :meth:`Timestamp.replace` which was not reflecting the resulting changes in :meth:`Timestamp.unit`. (:issue:`57749`) Categorical ^^^^^^^^^^^ diff --git a/pandas/_libs/tslibs/timestamps.pyx b/pandas/_libs/tslibs/timestamps.pyx index 72769930e69f5..1ef2a4a369160 100644 --- a/pandas/_libs/tslibs/timestamps.pyx +++ b/pandas/_libs/tslibs/timestamps.pyx @@ -59,7 +59,6 @@ from pandas._libs.tslibs.conversion cimport ( maybe_localize_tso, ) from pandas._libs.tslibs.dtypes cimport ( - abbrev_to_npy_unit, npy_unit_to_abbrev, npy_unit_to_attrname, periods_per_day, @@ -2468,38 +2467,30 @@ default 'raise' return v if year is not None: - rep_reso = NPY_DATETIMEUNIT.NPY_FR_Y dts.year = validate("year", year) rep_reso = NPY_DATETIMEUNIT.NPY_FR_Y if month is not None: - rep_reso = NPY_DATETIMEUNIT.NPY_FR_M dts.month = validate("month", month) rep_reso = NPY_DATETIMEUNIT.NPY_FR_M if day is not None: - rep_reso = NPY_DATETIMEUNIT.NPY_FR_D dts.day = validate("day", day) rep_reso = NPY_DATETIMEUNIT.NPY_FR_D if hour is not None: - rep_reso = NPY_DATETIMEUNIT.NPY_FR_h dts.hour = validate("hour", hour) rep_reso = NPY_DATETIMEUNIT.NPY_FR_h if minute is not None: - rep_reso = NPY_DATETIMEUNIT.NPY_FR_m dts.min = validate("minute", minute) rep_reso = NPY_DATETIMEUNIT.NPY_FR_m if second is not None: - rep_reso = NPY_DATETIMEUNIT.NPY_FR_s dts.sec = validate("second", second) rep_reso = NPY_DATETIMEUNIT.NPY_FR_s if microsecond is not None: - rep_reso = NPY_DATETIMEUNIT.NPY_FR_ms dts.us = validate("microsecond", microsecond) if microsecond > 999: rep_reso = NPY_DATETIMEUNIT.NPY_FR_us else: rep_reso = NPY_DATETIMEUNIT.NPY_FR_ms if nanosecond is not None: - rep_reso = NPY_DATETIMEUNIT.NPY_FR_ns dts.ps = validate("nanosecond", nanosecond) * 1000 rep_reso = NPY_DATETIMEUNIT.NPY_FR_ns if tzinfo is not object: diff --git a/pandas/tests/scalar/timestamp/methods/test_replace.py b/pandas/tests/scalar/timestamp/methods/test_replace.py index e5805b387339f..a31b23935bcd5 100644 --- a/pandas/tests/scalar/timestamp/methods/test_replace.py +++ b/pandas/tests/scalar/timestamp/methods/test_replace.py @@ -195,11 +195,7 @@ def test_replace_unit(self): ts = Timestamp("2023-07-15 23:08:12") ts1 = Timestamp("2023-07-15 23:08:12.134567") ts2 = Timestamp("2023-07-15 23:08:12.134567123") - ts = ts.replace(microsecond=ts1.microsecond) - assert ts == ts1 - ts = ts.replace(nanosecond=ts2.nanosecond) - assert ts == ts2 From 54632105aeb8f09c8e0bef29b1ecf8e82b18d9f1 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 1 Apr 2024 19:28:44 +0000 Subject: [PATCH 9/9] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- pandas/_libs/tslibs/timestamps.pyx | 2 +- pandas/tests/scalar/timestamp/methods/test_replace.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pandas/_libs/tslibs/timestamps.pyx b/pandas/_libs/tslibs/timestamps.pyx index 1ef2a4a369160..4c87132fbeeda 100644 --- a/pandas/_libs/tslibs/timestamps.pyx +++ b/pandas/_libs/tslibs/timestamps.pyx @@ -2495,7 +2495,7 @@ default 'raise' rep_reso = NPY_DATETIMEUNIT.NPY_FR_ns if tzinfo is not object: tzobj = tzinfo - + if rep_reso < self._creso: rep_reso = self._creso diff --git a/pandas/tests/scalar/timestamp/methods/test_replace.py b/pandas/tests/scalar/timestamp/methods/test_replace.py index a31b23935bcd5..70ab1a7580bda 100644 --- a/pandas/tests/scalar/timestamp/methods/test_replace.py +++ b/pandas/tests/scalar/timestamp/methods/test_replace.py @@ -191,7 +191,7 @@ def test_replace_preserves_fold(self, fold): assert ts_replaced.fold == fold def test_replace_unit(self): - #GH#57749 + # GH#57749 ts = Timestamp("2023-07-15 23:08:12") ts1 = Timestamp("2023-07-15 23:08:12.134567") ts2 = Timestamp("2023-07-15 23:08:12.134567123")