New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
datetime.fromtimestamp() doesn't check min/max year anymore: regression of Python 3.6 #73286
Comments
In Python 3.6.0 if you give datetime.fromtimestamp a very bad value you either get a core dump or an OverflowError. The core dump occurs when no tzinfo is provided, the OverflowError occurs when a tzinfo is provided (such as tzlocal from dateutil). Attached is a minimal script to reproduce the error. Note that this behavior only occurs on certain systems. It does not happen on OSX 10.11.6, but it does happen on Ubuntu 12.04. I imagine it happens on other systems as well, but I haven't tested beyond those two. Here are the specific errors I get on Ubuntu 12.04. When no tzinfo is provided: python: /tmp/python-build.20161228223921.28011/Python-3.6.0/Modules/_datetimemodule.c:251: days_before_year: Assertion `year >= 1' failed. When a tzinfo is provided: Traceback (most recent call last):
File "test1.py", line 11, in <module>
datetime.fromtimestamp(bad_st_mtime, local_time_zone)
File "~/.pyenv/versions/venv36d/lib/python3.6/site-packages/dateutil/tz/_common.py", line 210, in fromutc
dt_wall = self._fromutc(dt)
File "~/.pyenv/versions/venv36d/lib/python3.6/site-packages/dateutil/tz/_common.py", line 195, in _fromutc
return dt + dtdst
OverflowError: date value out of range I imagine this is related to the fold changes. |
Attached datetime_check_args.patch fixes the issue: move argument checks into time(), date() and datetime() constructors of the _datetime module. The patch requires the fix of the issue bpo-29140 (time_hash bug), otherwise unit tests fail. This issue is a regression introduced the implementation of the PEP-495. In Python 3.5, datetime_from_timet_and_us() calls datetime constructor which checks argument. In Python 3.6, datetime_from_timet_and_us() calls directly new_datetime_ex2() which doesn't check arguments anymore. datetime_check_args.patch makes the _datetime module generally safer, not only for the report bug, because new_datetime_ex2() can be called by different ways, for example from the C API: "PyDateTime_CAPI". The bug always shows a major lack of unit test in datetime.datetime.fromtimestamp() on dates out of the 0001-01-01 .. 9999-12-31 range. In Python 3.6, datetime.fromtimestamp() can create invalid datetime object greater than datetime.max! $ python3.6 -c 'import datetime; print(datetime.datetime.fromtimestamp(2**38))'
10680-07-14 08:09:04 TODO: add unit tests. |
Oh, datetime.datetime.timestamp() also has a bug for values close to 0001-01-01 (year 1), at least in my timezone (CET). $ ./python -c 'import datetime; datetime.datetime.min.timestamp()'
python: /home/haypo/prog/python/default/Modules/_datetimemodule.c:251: days_before_year: Assertion `year >= 1' failed.
Aborted (core dumped) datetime_check_args.patch doesn't fix this issue. A solution is to check that year>=1 in utc_to_seconds(): + if (year < MINYEAR || year > MAXYEAR) { Maybe it would solve the following local() comment: /* XXX: add bounds checking */ |
unitttest.patch: my attempt to write an unit test, but I was bitten by the datetime.timestamp() bug. |
timestamp_limits.patch: Add many checks in the _datetime module to avoid overflows or creating a object out of the range. The patch adds unit tests. The unit test checks dates around year 1 and year 9999. I expect failures on platforms which only work well on year in the range 1970..2038. My plan is to wait for buildbot reports to check on which platforms the test fails and with which exception. Since the patch is likely to break buildbots, I will apply first to the default branch, fix it, and then backport to Python 3.6. |
The issue bpo-29346 has been marked as a duplicate of this one. |
timestamp_limits.patch is waiting for your review! This issue is a major regression of Python 3.6. I'm going to push the patch in one week if I don't get any review. |
timestamp_limits-2.patch: catch also OverflowError in unit tests, and uses a context manager rather than self.assertRaises(..., func, ...) syntax. |
New changeset 383c0238b5b0 by Victor Stinner in branch '3.6': |
I pushed timestamp_limits-2.patch. Thanks for the bug report Jordon Phillips, thanks for the review Serhiy Storshaka. |
New changeset 5b804b2fb0eaa2bacb4afcfe4cfa85b31475e87f by Victor Stinner in branch '3.6': |
New changeset 5b804b2fb0eaa2bacb4afcfe4cfa85b31475e87f by Victor Stinner in branch 'master': |
New changeset 1c6b87b07586 by Victor Stinner in branch '3.6': |
New changeset a88f9614c672c3369cf03cdf51d012a42ae5665f by Victor Stinner in branch 'master': |
New changeset 1555e7776321 by Victor Stinner in branch '3.6': |
New changeset be363764cad68ad7b608ceed837cc01c2c3b4efc by Victor Stinner in branch '3.6': |
New changeset be363764cad68ad7b608ceed837cc01c2c3b4efc by Victor Stinner in branch 'master': |
m-parry reported the issue bpo-29921 "datetime validation is stricter in 3.6.1 than previous versions". He is right, the C API of Python 3.6.1 is now stricter than Python 2.7 and 3.5. The C API doesn't allow anymore to create datetime objects outside the [datetime.datetime.min; datetime.datetime.max] range (what I would call "invalid" datetime objects). I closed the bug as NOT A BUG since I consider that it's a deliberate design choice and not a regression. |
Misc/NEWS
so that it is managed by towncrier #552Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: