Skip to content

ENH: add timedelta64 support boolean division and floor - #32555

Merged
ngoldbaum merged 11 commits into
numpy:mainfrom
mhafizazh:timedelta64-div-boolean
Sep 9, 2026
Merged

ngoldbaum merged 11 commits into
numpy:mainfrom
mhafizazh:timedelta64-div-boolean

Conversation

@mhafizazh

@mhafizazh mhafizazh commented Sep 9, 2026 •

Copy link
Copy Markdown
Contributor

PR summary

This PR based on issue #18445. Initially timedelta64 only accept int##, if timedelta64 is divided by boolean value such as

m = np.array([1], dtype="timedelta64[s]")
b = np.array([True])

output:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
numpy._core._exceptions._UFuncBinaryResolutionError: ufunc 'divide' cannot use operands with types dtype('<m8[s]') and dtype('bool')

I added condition in ufunct_type_resolution.c so PyUFunc_DivisionTypeResolver() bool i s upcast to int64 (true=1, False=0).

new output:

>>> import numpy as np
>>> m = np.array([1], dtype="timedelta64[s]")
>>> b = np.array([True])
>>> m/b
array([1], dtype='timedelta64[s]')

First time committer introduction

I'm new contributors and I joined previous community meeting maybe 1-2 month ago, and suggested to take a look at the old issues and see if the bug still exist. I want to contribute to NumPy to challenge myself to contribute large repository and I use NumPy almost everyday for my internship too.

AI Disclosure

I used opencode to help draft both the code fix, and the test. I reviewed, wrote, and ran the test with myself.

@ngoldbaum

ngoldbaum commented Sep 9, 2026 •

Copy link
Copy Markdown
Member

Nice minimal fix. The test failures in the CI run are unrelated breakage on canonical's infrastructure.

This needs a release note. I also think this impacts the type stubs (cc @jorenham). It's probably also worth adding test cases for numpy booleans (numpy.True_ is not the same thing as True).

@jorenham

jorenham commented Sep 9, 2026

Copy link
Copy Markdown
Member

This needs a release note. I also think this impacts the type stubs (cc @jorenham). It's probably also worth adding test cases for numpy booleans (numpy.True_ is not the same thing as True).

Right now the stubs already accept builtins.bool as a direct consequence of bool being a subtype of int. If numpy.bool_ is now also accepted, then the corresponding overloads should indeed be updated to also accept bool_:

numpy/numpy/__init__.pyi

Lines 12881 to 12916 in 88ddb98

@overload
def __truediv__(self, b: timedelta64, /) -> float64: ...
@overload
def __truediv__(self: timedelta64[dt.timedelta], b: dt.timedelta, /) -> float: ...
@overload
def __truediv__(self: timedelta64[Never], b: float | floating | integer, /) -> timedelta64: ...
@overload
def __truediv__[AnyItemT: (dt.timedelta, int, None)](
self: timedelta64[AnyItemT], b: int | integer, /
) -> timedelta64[AnyItemT]: ...
@overload
def __truediv__[AnyItemT: (dt.timedelta, int, None)](
self: timedelta64[AnyItemT], b: float | floating, /
) -> timedelta64[AnyItemT | None]: ...
@overload
def __truediv__(self, b: float | floating | integer, /) -> timedelta64: ...
@overload
def __rtruediv__(self, a: timedelta64, /) -> float64: ...
@overload
def __rtruediv__(self: timedelta64[dt.timedelta], a: dt.timedelta, /) -> float: ...
@overload
def __floordiv__(self, b: timedelta64, /) -> int64: ...
@overload
def __floordiv__(self: timedelta64[dt.timedelta], b: dt.timedelta, /) -> int: ...
@overload
def __floordiv__(self: timedelta64[Never], b: float | floating | integer, /) -> timedelta64: ...
@overload
def __floordiv__[AnyItemT: (dt.timedelta, int, None)](
self: timedelta64[AnyItemT], b: int | integer, /
) -> timedelta64[AnyItemT]: ...
@overload
def __floordiv__[AnyItemT: (dt.timedelta, int, None)](
self: timedelta64[AnyItemT], b: float | floating, /
) -> timedelta64[AnyItemT | None]: ...

@jorenham jorenham added the 56 - Needs Release Note. Needs an entry in doc/release/upcoming_changes label Sep 9, 2026
@mhafizazh mhafizazh changed the title fixing so timedelta64 support boolean division and floor BUG: fixing so timedelta64 support boolean division and floor Sep 9, 2026
@mhafizazh

Copy link
Copy Markdown
Contributor Author

@ngoldbaum thanks for your feedback. I just added release note.

Comment thread numpy/_core/tests/test_datetime.py Resolved
@ngoldbaum ngoldbaum added 01 - Enhancement and removed 56 - Needs Release Note. Needs an entry in doc/release/upcoming_changes labels Sep 9, 2026
@ngoldbaum ngoldbaum changed the title BUG: fixing so timedelta64 support boolean division and floor ENH: add timedelta64 support boolean division and floor Sep 9, 2026
@ngoldbaum ngoldbaum added this to the 2.6.0 Release milestone Sep 9, 2026

@ngoldbaum ngoldbaum left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks! Someone else will need to give this a look and merge it but this looks good to me.

@ngoldbaum ngoldbaum left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Oh sorry, I missed that you still need to update the type stubs. Joren can probably help if you get stuck there.

@mhafizazh
mhafizazh requested a review from ngoldbaum September 9, 2026 21:02
@jorenham
jorenham self-requested a review September 9, 2026 21:03

@jorenham jorenham left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Stub changes look good.

I have some minor suggestions to simplify things a bit, because these unions now coincide with the existing _FloatLike_co and _IntLike_co type aliases:

type _IntLike_co = int | np.integer | np.bool
type _FloatLike_co = float | np.floating | np.integer | np.bool

Comment thread numpy/__init__.pyi Resolved
Comment thread numpy/__init__.pyi Resolved
Comment thread numpy/__init__.pyi Resolved
Comment thread numpy/__init__.pyi Resolved
Comment thread numpy/__init__.pyi Resolved
mhafizazh and others added 5 commits September 9, 2026 15:25
Co-authored-by: Joren Hammudoglu <[email protected]>
Co-authored-by: Joren Hammudoglu <[email protected]>
Co-authored-by: Joren Hammudoglu <[email protected]>
Co-authored-by: Joren Hammudoglu <[email protected]>
Co-authored-by: Joren Hammudoglu <[email protected]>
@mhafizazh

Copy link
Copy Markdown
Contributor Author

Stub changes look good.

I have some minor suggestions to simplify things a bit, because these unions now coincide with the existing _FloatLike_co and _IntLike_co type aliases:

type _IntLike_co = int | np.integer | np.bool
type _FloatLike_co = float | np.floating | np.integer | np.bool

I see. It looks much cleaner now. Thank you!

Comment thread numpy/__init__.pyi Resolved
Co-authored-by: Joren Hammudoglu <[email protected]>
@ngoldbaum
ngoldbaum merged commit ee2a62a into numpy:main Sep 9, 2026
93 checks passed
@ngoldbaum

Copy link
Copy Markdown
Member

Thank you!

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants