Skip to content
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 validation is stricter in 3.6.1 than previous versions #74107

Closed
m-parry mannequin opened this issue Mar 27, 2017 · 10 comments
Closed

datetime validation is stricter in 3.6.1 than previous versions #74107

m-parry mannequin opened this issue Mar 27, 2017 · 10 comments
Labels
stdlib Python modules in the Lib dir type-bug An unexpected behavior, bug, or error

Comments

@m-parry
Copy link
Mannequin

m-parry mannequin commented Mar 27, 2017

BPO 29921
Nosy @abalkin, @vstinner, @ned-deily

Note: 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:

assignee = None
closed_at = <Date 2017-03-28.13:09:58.622>
created_at = <Date 2017-03-27.13:48:47.436>
labels = ['invalid', 'type-bug', 'library']
title = 'datetime validation is stricter in 3.6.1 than previous versions'
updated_at = <Date 2021-09-23.10:04:34.229>
user = 'https://bugs.python.org/m-parry'

bugs.python.org fields:

activity = <Date 2021-09-23.10:04:34.229>
actor = 'Patrick Decat'
assignee = 'none'
closed = True
closed_date = <Date 2017-03-28.13:09:58.622>
closer = 'vstinner'
components = ['Library (Lib)']
creation = <Date 2017-03-27.13:48:47.436>
creator = 'm-parry'
dependencies = []
files = []
hgrepos = []
issue_num = 29921
keywords = []
message_count = 10.0
messages = ['290609', '290646', '290647', '290688', '290698', '290699', '290707', '290709', '290721', '402486']
nosy_count = 5.0
nosy_names = ['belopolsky', 'vstinner', 'ned.deily', 'm-parry', 'Patrick Decat']
pr_nums = []
priority = 'normal'
resolution = 'not a bug'
stage = 'resolved'
status = 'closed'
superseder = None
type = 'behavior'
url = 'https://bugs.python.org/issue29921'
versions = ['Python 3.6']

@m-parry
Copy link
Mannequin Author

m-parry mannequin commented Mar 27, 2017

The change in issue bpo-29100 - intended AFAICS simply to fix a regression in 3.6 - seems to have made datetime validation via certain code paths stricter than it was in 2.7 or 3.5. I think it's the case that some routes via the C API now reject out of range values that were previously permitted. Even if this previous behaviour was incorrect, was it intentional to alter that in a maintenance release?

Here's a quick example using pywin32:

---

import getpass, sspi, sspicon, win32security
client_name = getpass.getuser()
auth_info = (client_name, 'wherever.com', None)
pkg_info = win32security.QuerySecurityPackageInfo('Kerberos')
win32security.AcquireCredentialsHandle(
client_name, pkg_info['Name'],
sspicon.SECPKG_CRED_OUTBOUND,
None, auth_info)

ValueError: year 30828 is out of range

---

Of course, this is probably a mishandling of the 'never expires' value returned by the Windows API in this case, and indeed I have also created a pywin32 ticket. However, I'm guessing that the linked issue wasn't supposed to break such code.

@m-parry m-parry mannequin added stdlib Python modules in the Lib dir type-bug An unexpected behavior, bug, or error labels Mar 27, 2017
@vstinner
Copy link
Member

The change in issue bpo-29100 - intended AFAICS simply to fix a regression in 3.6 - seems to have made datetime validation via certain code paths stricter than it was in 2.7 or 3.5.

What do you mean by "stricter than 2.7 & 3.5"? The year 30828 was never valid.

Python 2.7 and 3.5:

>>> datetime.datetime(30828, 1, 1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: year is out of range
>>> datetime.datetime.fromtimestamp(2**37)
datetime.datetime(6325, 4, 8, 17, 4, 32)
>>> datetime.datetime.fromtimestamp(2**38)
Traceback (most recent call last):
  ...
ValueError: year is out of range

Python 3.6.1 should only be stricter than Python 3.6.0.

@vstinner
Copy link
Member

The range of valid timestamp is the same since the module was added to Python 2.3:

>>> datetime.datetime.min
datetime.datetime(1, 1, 1, 0, 0)
>>> datetime.datetime.max
datetime.datetime(9999, 12, 31, 23, 59, 59, 999999)

https://docs.python.org/2/library/datetime.html#datetime.datetime.max
https://docs.python.org/dev/library/datetime.html#datetime.datetime.max

@m-parry
Copy link
Mannequin Author

m-parry mannequin commented Mar 28, 2017

From my opening comment (with new emphasis):

"I think it's the case that **some routes via the C API** now reject out of range values that were previously permitted."

The pywin32 repro I gave above eventually calls PyDateTimeAPI->DateTime_FromDateAndTime():

http://pywin32.hg.sourceforge.net/hgweb/pywin32/pywin32/file/85c1c99b1cb8/win32/src/PyTime.cpp#l980

AFAICT, under Python < 3.6.1 such out of range values were tolerated there. Under Python 2.7, for example, the datetime that results from this call is somewhere in 1899.

I am not claiming that these invalid values should be tolerated forever more, or that this was ever the correct behaviour, but I would have expected a backwards incompatible change like this to happen in, say, Python 3.7, rather than a maintenance release. (Particularly when it breaks a library that's practically standard on Windows.)

@vstinner
Copy link
Member

2017-03-28 10:17 GMT+02:00 m-parry <report@bugs.python.org>:

"I think it's the case that **some routes via the C API** now reject out of range values that were previously permitted."

The pywin32 repro I gave above eventually calls PyDateTimeAPI->DateTime_FromDateAndTime():

http://pywin32.hg.sourceforge.net/hgweb/pywin32/pywin32/file/85c1c99b1cb8/win32/src/PyTime.cpp#l980

You can please identify which C function is called and dump which
parameters are passed to the function?

@m-parry
Copy link
Mannequin Author

m-parry mannequin commented Mar 28, 2017

That's just a Python C API call. It looks like it eventually resolves to new_datetime_ex(30828, 9, 13, 3, 48, 5, 480000, Py_None, PyDateTime_DateTimeType).

We also have some internal code that sees a similar problem from calling PyTime_FromTime(), that was similarly affected by this change. In one example, that appears to resolve to new_time_ex(24, 0, 0, 0, Py_None, PyDateTime_TimeType). Again, under <3.6.1, that was accepted. (And again, I am making no argument about the validity of this code, just with regards to backwards compatibility.)

@vstinner
Copy link
Member

Again, under <3.6.1, that was accepted. (And again, I am making no argument about the validity of this code, just with regards to backwards compatibility.)

You are right that I modified the C API of datetime in Python 3.6.1 to make it stricter and reject invalid dates.

I disagree that the "backward incompatibility" part: I consider that it's a bugfix, and not a behaviour change.

The datetime module was enhanced in Python 3.6 with the PEP-495 to handle better DST changes: a new "fold" attribute was added. Computing this attribute requires to handle valid dates in the [datetime.datetime.min; datetime.datetime.max] range. Otherwise, you get strange errors like OverflowError: see issue bpo-29100.

If Python older than 3.6.1 allowed creating invalid dates, it was a bug, and now this bug can lead to new bugs because of the implementation of the PEP-495.

Please fix you code. I now close this issue as NOTABUG. Stricter input validation was a deliberate choice.

@m-parry
Copy link
Mannequin Author

m-parry mannequin commented Mar 28, 2017

pywin32 is not my code. It is a ubiquitous Python library on Windows that cannot be used under Python 3.6.1.

@ned-deily
Copy link
Member

FTR, there is now a pywin32 issue (opened by the OP) on this: https://sourceforge.net/p/pywin32/bugs/748/

@PatrickDecat
Copy link
Mannequin

PatrickDecat mannequin commented Sep 23, 2021

pywin32 project has moved from sourceforge to github.

https://sourceforge.net/p/pywin32/bugs/748/ is now at mhammond/pywin32#748

pywin32 issue is supposed to be resolved since pywin32 b222

See:

mhammond/pywin32#748 (comment)

mhammond/pywin32@0720265

https://github.com/mhammond/pywin32/blob/b222/CHANGES.txt#L24-L26

@ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
stdlib Python modules in the Lib dir type-bug An unexpected behavior, bug, or error
Projects
None yet
Development

No branches or pull requests

2 participants