Skip to content

Commit

Permalink
gh-126947: Typechecking for _pydatetime.timedelta.__new__ arguments (#…
Browse files Browse the repository at this point in the history
…126949)

Co-authored-by: sobolevn <[email protected]>
Co-authored-by: Peter Bierma <[email protected]>
  • Loading branch information
3 people authored Nov 19, 2024
1 parent 88dc84b commit 8da9920
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 1 deletion.
14 changes: 13 additions & 1 deletion Lib/_pydatetime.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
10 changes: 10 additions & 0 deletions Lib/test/datetimetester.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
Original file line number Diff line number Diff line change
@@ -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.

0 comments on commit 8da9920

Please sign in to comment.