From da253e17ac728a55a0c0a1bdb3059924a35a925c Mon Sep 17 00:00:00 2001 From: Beomsoo Kim Date: Mon, 18 Nov 2024 17:37:46 +0900 Subject: [PATCH 1/5] Add typecheck in _pydatetime.timedelta so that same format error is raised as in _datetime.timedelta --- Lib/_pydatetime.py | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/Lib/_pydatetime.py b/Lib/_pydatetime.py index 78e03e32896740..ed01670cfece43 100644 --- a/Lib/_pydatetime.py +++ b/Lib/_pydatetime.py @@ -651,7 +651,19 @@ def __new__(cls, days=0, seconds=0, microseconds=0, # guide the C implementation; it's way more convoluted than speed- # ignoring auto-overflow-to-long idiomatic Python could be. - # XXX Check that all inputs are ints or floats. + for name, value in ( + ("days", days), + ("seconds", seconds), + ("microseconds", microseconds), + ("milliseconds", milliseconds), + ("minutes", minutes), + ("hours", hours), + ("weeks", weeks) + ): + if not isinstance(value, (int, float)): + raise TypeError( + f"unsupported type for timedelta {name} component: {type(value).__name__}" + ) # Final values, all integer. # s and us fit in 32-bit signed ints; d isn't bounded. From 68aa4a7be860a1996c6ffaff3730cd9068dabfcc Mon Sep 17 00:00:00 2001 From: Beomsoo Kim Date: Mon, 18 Nov 2024 17:38:29 +0900 Subject: [PATCH 2/5] Add relevant tests for the new typecheck in datetime module --- Lib/test/datetimetester.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Lib/test/datetimetester.py b/Lib/test/datetimetester.py index dbe25ef57dea83..25a3015c4e19ce 100644 --- a/Lib/test/datetimetester.py +++ b/Lib/test/datetimetester.py @@ -510,6 +510,7 @@ class TestTimeDelta(HarmlessMixedComparison, unittest.TestCase): def test_constructor(self): eq = self.assertEqual + ra = self.assertRaises td = timedelta # Check keyword args to constructor @@ -533,6 +534,15 @@ def test_constructor(self): eq(td(seconds=0.001), td(milliseconds=1)) eq(td(milliseconds=0.001), td(microseconds=1)) + # Check type of args to constructor + ra(TypeError, lambda: td(weeks='1')) + ra(TypeError, lambda: td(days='1')) + ra(TypeError, lambda: td(hours='1')) + ra(TypeError, lambda: td(minutes='1')) + ra(TypeError, lambda: td(seconds='1')) + ra(TypeError, lambda: td(milliseconds='1')) + ra(TypeError, lambda: td(microseconds='1')) + def test_computations(self): eq = self.assertEqual td = timedelta From fc501ff09cd3829f7d18d0706aae80790d85fde1 Mon Sep 17 00:00:00 2001 From: Beomsoo Kim Date: Mon, 18 Nov 2024 19:03:50 +0900 Subject: [PATCH 3/5] Add a NEWS entry --- .../next/Library/2024-11-18-19-03-46.gh-issue-126947.NiDYUe.rst | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2024-11-18-19-03-46.gh-issue-126947.NiDYUe.rst diff --git a/Misc/NEWS.d/next/Library/2024-11-18-19-03-46.gh-issue-126947.NiDYUe.rst b/Misc/NEWS.d/next/Library/2024-11-18-19-03-46.gh-issue-126947.NiDYUe.rst new file mode 100644 index 00000000000000..ea86bf6c0e0e8b --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-11-18-19-03-46.gh-issue-126947.NiDYUe.rst @@ -0,0 +1,2 @@ +Add typechecking for _pydatetime.timedelta.__new__ arguments so that python +implementation is in line with C implementation From 0b257d2a10750bb5b4fd53fa0bf70512ba990006 Mon Sep 17 00:00:00 2001 From: Beomsoo Kim Date: Mon, 18 Nov 2024 19:47:16 +0900 Subject: [PATCH 4/5] Update Misc/NEWS.d/next/Library/2024-11-18-19-03-46.gh-issue-126947.NiDYUe.rst Co-authored-by: sobolevn --- .../Library/2024-11-18-19-03-46.gh-issue-126947.NiDYUe.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Misc/NEWS.d/next/Library/2024-11-18-19-03-46.gh-issue-126947.NiDYUe.rst b/Misc/NEWS.d/next/Library/2024-11-18-19-03-46.gh-issue-126947.NiDYUe.rst index ea86bf6c0e0e8b..23f393873f6728 100644 --- a/Misc/NEWS.d/next/Library/2024-11-18-19-03-46.gh-issue-126947.NiDYUe.rst +++ b/Misc/NEWS.d/next/Library/2024-11-18-19-03-46.gh-issue-126947.NiDYUe.rst @@ -1,2 +1,2 @@ -Add typechecking for _pydatetime.timedelta.__new__ arguments so that python -implementation is in line with C implementation +Raise :exc:`TypeError` in :meth:`!_pydatetime.timedelta.__new__` arguments are not :class:`int` or :class:`float`, so that python +implementation is in line with C implementation. From 9bc13a1d391f1f0ed3b59f725e138e41f4c22174 Mon Sep 17 00:00:00 2001 From: Beomsoo Kim Date: Tue, 19 Nov 2024 09:03:18 +0900 Subject: [PATCH 5/5] Update 2024-11-18-19-03-46.gh-issue-126947.NiDYUe.rst Co-authored-by: Peter Bierma --- .../Library/2024-11-18-19-03-46.gh-issue-126947.NiDYUe.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Misc/NEWS.d/next/Library/2024-11-18-19-03-46.gh-issue-126947.NiDYUe.rst b/Misc/NEWS.d/next/Library/2024-11-18-19-03-46.gh-issue-126947.NiDYUe.rst index 23f393873f6728..29ba4f21454fe1 100644 --- a/Misc/NEWS.d/next/Library/2024-11-18-19-03-46.gh-issue-126947.NiDYUe.rst +++ b/Misc/NEWS.d/next/Library/2024-11-18-19-03-46.gh-issue-126947.NiDYUe.rst @@ -1,2 +1,2 @@ -Raise :exc:`TypeError` in :meth:`!_pydatetime.timedelta.__new__` arguments are not :class:`int` or :class:`float`, so that python -implementation is in line with C implementation. +Raise :exc:`TypeError` in :meth:`!_pydatetime.timedelta.__new__` if the passed arguments are not :class:`int` or :class:`float`, so that the Python +implementation is in line with the C implementation.