This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: timedelta subtraction glitch on big timedelta values
Type: behavior Stage: resolved
Components: Extension Modules, Library (Lib) Versions: Python 3.2, Python 3.3, Python 2.7
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: belopolsky Nosy List: SilentGhost, belopolsky, enrico, gkcn, mark.dickinson, python-dev
Priority: normal Keywords: patch

Created on 2011-03-16 18:32 by enrico, last changed 2022-04-11 14:57 by admin. This issue is now closed.

Files
File name Uploaded Description Edit
issue11576.diff belopolsky, 2011-04-05 17:39 review
Messages (7)
msg131155 - (view) Author: Enrico Zini (enrico) Date: 2011-03-16 18:32
Hello,

I was testing edge case behaviour of some code of mine and stumbled into this unexpected domain error from timedelta:

  >>> from datetime import *
  >>> timedelta(999999999, 86399, 999999) - timedelta(999999999, 86399, 999998)
  Traceback (most recent call last):
    File "<stdin>", line 1, in ?
  OverflowError: days=-1000000000; must have magnitude <= 999999999
  >>>

The expected result is of course timedelta(0, 0, 1):

  >>> timedelta(999999999, 86399, 999998) + timedelta(0, 0, 1)
  datetime.timedelta(999999999, 86399, 999999)

Both time deltas are within the range documented in
/usr/share/doc/python-doc/html/lib/datetime-timedelta.html

I could reproduce it on 2.6.6 and 3.1.3. I don't have access to other python versions.


Ciao,

Enrico


Note: I reported it 4 years ago in the Debian BTS (http://bugs.debian.org/408872) but I noticed now that the Debian maintainer doesn't seem to have bothered forwarding it here :(
msg131156 - (view) Author: SilentGhost (SilentGhost) * (Python triager) Date: 2011-03-16 18:38
To emphasize that it's only days parameter that is overflowing here is another case:

>>> timedelta(999999999, 1, 1) - timedelta(999999999, 0, 0)
datetime.timedelta(0, 1, 1)
>>> timedelta(999999999, 1, 1) - timedelta(999999999, 1, 0)
Traceback (most recent call last):
  File "<pyshell#18>", line 1, in <module>
    timedelta(999999999, 1, 1) - timedelta(999999999, 1, 0)
OverflowError: days=-1000000000; must have magnitude <= 999999999
msg131157 - (view) Author: SilentGhost (SilentGhost) * (Python triager) Date: 2011-03-16 18:55
What happens is the second value is negated (__neg__) which causes it to become less than timedelta.min and that is causing OverflowError.
msg133054 - (view) Author: Alexander Belopolsky (belopolsky) * (Python committer) Date: 2011-04-05 17:39
> What happens is the second value is negated (__neg__)
> which causes it to become less than timedelta.min and
> that is causing OverflowError.

Yes, and running the test case without C acceleration makes this obvious:

>>> import sys
>>> sys.modules['_datetime'] = None
>>> from datetime import *
>>> timedelta(999999999, 86399, 999999) - timedelta(999999999, 86399, 999998)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "Lib/datetime.py", line 488, in __sub__
    return self + -other
  File "Lib/datetime.py", line 501, in __neg__
    -self._microseconds)
  File "Lib/datetime.py", line 426, in __new__
    raise OverflowError("timedelta # of days is too large: %d" % d)
OverflowError: timedelta # of days is too large: -1000000000

Attached patch fixes the issue.  I would like to think some more about C int overflow before committing.
msg133103 - (view) Author: Roundup Robot (python-dev) (Python triager) Date: 2011-04-06 00:44
New changeset 76180cc853b6 by Alexander Belopolsky in branch '3.2':
Issue #11576: Fixed timedelta subtraction glitch on big timedelta values
http://hg.python.org/cpython/rev/76180cc853b6

New changeset d492915cf76d by Alexander Belopolsky in branch 'default':
Issue #11576: Fixed timedelta subtraction glitch on big timedelta values
http://hg.python.org/cpython/rev/d492915cf76d
msg133105 - (view) Author: Roundup Robot (python-dev) (Python triager) Date: 2011-04-06 02:14
New changeset 202a9feb1fd6 by Alexander Belopolsky in branch '2.7':
Issue #11576: Fixed timedelta subtraction glitch on big timedelta values
http://hg.python.org/cpython/rev/202a9feb1fd6
msg142960 - (view) Author: Gökcen Eraslan (gkcn) * Date: 2011-08-25 07:25
I can still reproduce that error with Python 2.7.2:

Python 2.7.1 (r271:86832, Apr 27 2011, 15:42:42) 
[GCC 4.5.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from datetime import *
>>> timedelta(999999999, 86399, 999999) - timedelta(999999999, 86399, 999998)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OverflowError: days=-1000000000; must have magnitude <= 999999999
>>> 

and I see that patch is applied in 2.7.2.
History
Date User Action Args
2022-04-11 14:57:14adminsetgithub: 55785
2011-08-25 07:25:22gkcnsetnosy: + gkcn
messages: + msg142960
2011-04-06 02:16:58belopolskysetstatus: open -> closed
stage: patch review -> resolved
resolution: fixed
components: + Extension Modules
versions: - Python 2.6, Python 2.5, Python 3.1
2011-04-06 02:14:28python-devsetmessages: + msg133105
2011-04-06 00:44:01python-devsetnosy: + python-dev
messages: + msg133103
2011-04-05 17:39:40belopolskysetfiles: + issue11576.diff

assignee: belopolsky

keywords: + patch
nosy: + mark.dickinson
messages: + msg133054
stage: patch review
2011-03-16 18:55:50SilentGhostsetnosy: + belopolsky
messages: + msg131157
components: + Library (Lib)
2011-03-16 18:38:30SilentGhostsetnosy: + SilentGhost

messages: + msg131156
versions: + Python 3.2, Python 3.3
2011-03-16 18:32:53enricocreate