]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-126947: Typechecking for _pydatetime.timedelta.__new__ arguments (#126949)
authorBeomsoo Kim <beoms424@gmail.com>
Tue, 19 Nov 2024 19:40:52 +0000 (04:40 +0900)
committerGitHub <noreply@github.com>
Tue, 19 Nov 2024 19:40:52 +0000 (22:40 +0300)
Co-authored-by: sobolevn <mail@sobolevn.me>
Co-authored-by: Peter Bierma <zintensitydev@gmail.com>
Lib/_pydatetime.py
Lib/test/datetimetester.py
Misc/NEWS.d/next/Library/2024-11-18-19-03-46.gh-issue-126947.NiDYUe.rst [new file with mode: 0644]

index 78e03e328967402b271974171f726e1c1770c038..ed01670cfece432792d1ca697de76904a2e3ca65 100644 (file)
@@ -651,7 +651,19 @@ class timedelta:
         # 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.
index dbe25ef57dea83bf40099213b4c7bcb2a1c518cc..25a3015c4e19ce840c54c2cbbc408f6b3c008130 100644 (file)
@@ -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 @@ class TestTimeDelta(HarmlessMixedComparison, unittest.TestCase):
         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
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 (file)
index 0000000..29ba4f2
--- /dev/null
@@ -0,0 +1,2 @@
+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.