8000 DEP: Deprecate 'generic' unit in np.timedelta64 and np.datetime64 by riku-sakamoto · Pull Request #29619 · numpy/numpy · GitHub
[go: up one dir, main page]

Skip to content

Conversation

@riku-sakamoto
Copy link
Contributor
@riku-sakamoto riku-sakamoto commented Aug 23, 2025

(Updated from previous PR description.)

This PR deprecates the generic unit in np.timedelta64 and np.datetime64. Using this unit can lead to unexpected behavior in some cases (see #28287 for details). Using generic unit now raises a DeprecationWarning FutureWarning.

  • Allowed behavior (no warning):
import numpy as np

np.timedelta64(10, 's')  # seconds
np.timedelta64("NaT", "ns") # NaT is not allowed with generic either
  • Deprecated behavior (raises FutureWarning):
import numpy as np

np.timedelta64(10)  # generic unit
np.timedellta64("NaT") # NaT with generic unit
np.timedelta64(10, 's') + 5 # adding integer to timedelta with generic unit
np.datetime64('2020-01-01') + 2

Changes

Main

  • Raise DeprecationWarning FutureWarning when np.timedelta64 or np.datetime64 is constructed with the generic unit.
  • Add tests to ensure the warning is raised in relevant scenarios.
  • Add Release notes

Test

Test updates fall into three categories.

  • Suppressing the warning in tests where the generic unit seems to be used intentionally. (with pytest.warns(DeprecationWarning))

  • Adding tests to check generic unit's behavior. Some tests uses generic timedelta in pytest.mark.parametrize. In such cases, the warnings cannot be suppressed with pytest.mark.filterwarnings. Instead, this PR add additional tests to check only generic unit's behavior.

  • Modifying tests to use an explicit unit instead of generic.

Future Work

These works are not included in this PR and I am planning to do them in future PRs. But, if you think they should be included in this PR, please let me know. I am happy to do so.

  • NaT is allowed with generic unit. We may want to disallow this in future.

  • np.timedelta64() creates a generic timedelta with value 0. We may want to change this to create a timedelta with an explicit unit (e.g., np.timedelta64(0, 's')) instead.

    • This may requires to seek consensus.
  • np.ones_like now raises FutureWarning when the input array is of timedelta type.

    • It seems that we should set 1 value with specific unit.
  • np.all_close now raises FutureWarning when the input arrays are of datetime or timedelta type.

    • atol is not allowed to be timedelta64 because it is supposed to be printed with g format. ("{atol:g}" in the code.)

@riku-sakamoto riku-sakamoto marked this pull request as ready for review August 23, 2025 10:30
pytest.ini Outdated
# Ignore DeprecationWarning from typing.mypy_plugin
ignore:`numpy.typing.mypy_plugin` is deprecated:DeprecationWarning
# Ignore Runtime Warning from datetime by calculating unitless value and unitful value
ignore:Casting from unitless timedelta to unitful timedelta is ambiguous.:RuntimeWarning
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe that if we do this, we'd likely want at least one test case that actually makes sure that the warning is issued.

I see locally that there are 18 failures if this is removed though, and we wouldn't want 18 checks for the warning. Still, it might be nice if we could suppress most of them but enforce at least one of them.

That said, the discussion in the matching issue suggests that the decision here may be tricky, so it may be best to wait for some design feedback first before making changes.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tylerjereddy

Thank you for the feedback!
I agree that adding a test case to check this warning makes sense.
As you suggested, I’ll wait for the design feedback before making the change.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to the issue discussion and the triage meeting, deprecation of the np.generic unit has been decided. I have updated the test implementation as you suggested.

I would appreciate it if you could take a look.

@charris charris added the 56 - Needs Release Note. Needs an entry in doc/release/upcoming_changes label Sep 1, 2025
@charris
Copy link
Member
charris commented Sep 1, 2025

Needs a release note.

@riku-sakamoto riku-sakamoto force-pushed the enhancement/raise_warning_when_generic_unit_casting branch 2 times, most recently from 7b3b00a to 902f4ac Compare September 7, 2025 11:42
@riku-sakamoto riku-sakamoto force-pushed the enhancement/raise_warning_when_generic_unit_casting branch 2 times, most recently from 93ae278 to 9e14d71 Compare September 7, 2025 21:28
@riku-sakamoto riku-sakamoto changed the title ENH: Raise RuntimeWarning when casting from a unitless np.timedelta64 to unitful one. DEP: Deprecate 'generic' unit in np.timedelta64 and np.datetime64 8000 Sep 7, 2025
@riku-sakamoto
Copy link
Contributor Author
riku-sakamoto commented Sep 24, 2025

Needs a release note.

@charris
I've added the release note. Thank you for the review!

@seberg
Copy link
Member
seberg commented Oct 15, 2025

@jbrockmendel I wonder if you have thoughts on this. I think the idea now was to deprecate any unitless scalars except for NaT (I suppose 0 may be another plausible exception).

The hope would be that we may still need NaT as a unitless scalar, but overall try to make it hard or impossible to work with this.

I think the scalar trick may well be good. But we may need some deeper stuff to really disable this fully. Since I think you can still cast from int (or view), etc.

(But maybe it can be a follow-up too, I am mostly curious if it seems safe to remove almost all unitless datetimes from a pandas perspective.)

@jbrockmendel
Copy link
Contributor

I am mostly curious if it seems safe to remove almost all unitless datetimes from a pandas perspective

That won't cause us any problems, might even allow us to clean up some checking-for-it code.

sys.path.append(str(build_dir))


@pytest.mark.filterwarnings("ignore::FutureWarning")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rather than a general filter, could you assert that the warning is raised when expected

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the comment! I've updated the test to assert that the warning is raised when expected.

pytest.mark.filterwarnings is now used only in numpy/typing/tests/test_typing.py to avoid failures when this test loads a Python script file that uses the generic unit. I can update it further if needed.

# # m8 generic units
# (np.timedelta64(1890),
# np.timedelta64(31),
# 60),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a test in test_deprecations that asserts that these calls now warn?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes! I've implemented it as test_generic_timedelta_floor_divide in test_datetime.py.

def test_raise_warning_for_timedelta_with_generic_unit(self, value: int):
msg = "Using 'generic' unit for NumPy timedelta is deprecated"
with pytest.warns(FutureWarning, match=msg):
_ = np.timedelta64(value)
Copy link
Member
@mattip mattip Oct 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this test these tests should be moved to test_deprecations

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've moved the relevant tests to test_deprecations.py.

@riku-sakamoto riku-sakamoto force-pushed the enhancement/raise_warning_when_generic_unit_casting branch 3 times, most recently from 91b812e to acbcdf2 Compare October 31, 2025 19:11
@riku-sakamoto
Copy link
Contributor Author
riku-sakamoto commented Oct 31, 2025

It seems that some CI jobs are failing (especially those related to Python 3.11). I’m investigating it now.

Update: I've resolved them.

@riku-sakamoto riku-sakamoto force-pushed the enhancement/raise_warning_when_generic_unit_casting branch 5 times, most recently from 2a42032 to c943f3a Compare November 2, 2025 06:08
@seberg seberg modified the milestone: 2.4.0 release Nov 4, 2025
@riku-sakamoto
Copy link
Contributor Author

@seberg
It sounds like pandas is fine with removing all unitless timedeltas.
In that case, should we also emit a warning when NaT is created in a unitless form, so that we can deprecate it as well in the future?

C3F7
@seberg
Copy link
Member
seberg commented Nov 20, 2025

@riku-sakamoto yes, since pandas is likely fine, I think we can give it a shot. But we need to wait another few weeks until branching unfortunatley.
(And actually if we merge it just after branching, it'll confuse a bit of downstream also, because they may think this is included in the pre-release when it's not. But maybe possible to try anyway.)

@riku-sakamoto
Copy link
Contributor Author

@seberg
Thanks for the explanation! That makes sense.
I’ll continue working on the PR, and I’ll hold off on merging until the timing is clearer.

…4` to unitful one.

This is a temporary solution to handle numpy#28287.
Rasing `RuntimeWarning` encourages users to pay attention to the behavior.
….datetime64`

The ``generic`` unit in `numpy.timedelta64` and `numpy.datetime64` is now
deprecated. Using it will raise a ``FutureWarning``. (See numpy#28287)
* Asserting warnings with the warns function¶
* Some tests are moved to `test_deprecations.py`
@riku-sakamoto riku-sakamoto force-pushed the enhancement/raise_warning_when_generic_unit_casting branch from c943f3a to b9853f7 Compare November 27, 2025 17:31
@charris charris added this to the 2.5.0 Release milestone Nov 27, 2025
@riku-sakamoto riku-sakamoto force-pushed the enhancement/raise_warning_when_generic_unit_casting branch from b9853f7 to 8f1daf2 Compare November 27, 2025 19:17
@riku-sakamoto
Copy link
Contributor Author

@seberg I've updated the PR to raise a warning for unitless NaT. Please let me know if you have any further suggestions. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

07 - Deprecation 56 - Needs Release Note. Needs an entry in doc/release/upcoming_changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants

0