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

bpo-35317: Fix mktime() error in test_email #10721

Merged
merged 1 commit into from
Nov 27, 2018
Merged

bpo-35317: Fix mktime() error in test_email #10721

merged 1 commit into from
Nov 27, 2018

Conversation

vstinner
Copy link
Member

@vstinner vstinner commented Nov 26, 2018

Fix mktime() overflow error in test_email: run
test_localtime_daylight_true_dst_true() and
test_localtime_daylight_false_dst_true() with a specific timezone.

https://bugs.python.org/issue35317

Fix mktime() overflow error in test_email: run
test_localtime_daylight_true_dst_true() and
test_localtime_daylight_false_dst_true() with a specific timezone.
@vstinner vstinner requested a review from a team as a code owner November 26, 2018 15:55
@bedevere-bot bedevere-bot added tests Tests in the Lib/test dir awaiting merge labels Nov 26, 2018
@vstinner
Copy link
Member Author

I tested manually the fix on FreeBSD 12.0-RC2 and Fedora Rawhide with TZ=UTC: the change fix test_email.

@vstinner
Copy link
Member Author

@bitdancer, @abalkin, @pganssle: Would you mind to review this change?

@hroncok
Copy link
Contributor

hroncok commented Nov 26, 2018

This will still blow up outside of test environment, when I have UTC timezone:

>>> t0 = datetime.datetime(2012, 8, 12, 1, 1)
>>> t1 = utils.localtime(t0, isdst=1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib64/python3.7/email/utils.py", line 361, in localtime
    seconds = time.mktime(tm)
OverflowError: mktime argument out of range

Shouldn't the exception be nicer? E.g.: ValueError: You cannot have DST when you have UTC timezone.

@vstinner
Copy link
Member Author

This will still blow up outside of test environment, when I have UTC timezone: (...)

That's expected. Python exposes the behavior of the OS.

The PR only fix test_email, it doesn't touch time nor datetime modules.

@pganssle
Copy link
Member

Hm, I was not aware of this email.utils.localtime. It seems like a bad idea to have added this function in the first place, but probably the tests for it should be pinning to a specific time zone if they implicitly rely on that time zone's behavior.

@@ -75,13 +75,15 @@ def test_localtime_daylight_false_dst_false(self):
t2 = utils.localtime(t1)
self.assertEqual(t1, t2)

@test.support.run_with_tz('Europe/Minsk')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This feels like an odd choice of test time zone, but the choice is essentially arbitrary, so I have no real problem with it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess it's copied from other tests at the bottom fo the file.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I reused a timezone which is already used in other tests, so I don't have to pick a different timezone ;-)

Copy link
Member

@pganssle pganssle left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minsk is an odd choice to pin this test on, but as long as the test is specifically pointing at some time in the past I think it is pretty safe to leave it in Europe/Minsk, since it is not likely that DST will be found to have not been in effect on this particular date.

@vstinner
Copy link
Member Author

Hm, I was not aware of this email.utils.localtime. It seems like a bad idea to have added this function in the first place, but probably the tests for it should be pinning to a specific time zone if they implicitly rely on that time zone's behavior.

Sorry, I don't know the origin of this helper and I don't know the function. Feel free to propose an enhancement :-)

I only care of fixing the test ;-)

@vstinner
Copy link
Member Author

Shouldn't the exception be nicer? E.g.: ValueError: You cannot have DST when you have UTC timezone.

Python is a thin wrapper to the C function mktime() which only sets errno to EOVERFLOW on error: "The result cannot be represented". The function doesn't tell where the error comes from.

@pganssle
Copy link
Member

@vstinner Yes, hopefully we can get a "local time" tzinfo singleton in Python 3.8 or 3.9 and this function can either be deprecated or turned into a wrapper for return dt.astimezone(LOCAL_TIME_ZONE)

@vstinner
Copy link
Member Author

@vstinner Yes, hopefully we can get a "local time" tzinfo singleton in Python 3.8 or 3.9 and this function can either be deprecated or turned into a wrapper for return dt.astimezone(LOCAL_TIME_ZONE)

Adding a "local timezone" feature directly to datetime would be great, but I have no idea how to do that :-)

@pganssle
Copy link
Member

pganssle commented Nov 26, 2018

@vstinner @hroncok I agree with Miro that OverflowError is not the right exception to raise there, it's quite opaque. I also think it's a different bug than "this specific test fails if you run it in the wrong locale".

Maybe we can open up a new bug on the issue tracker (if one doesn't exist) to address the exception raised in UTC.

I'm pretty confident that at the very least email.utils.localtime should not throw OverflowError for any valid datetime in any real time zone, regardless of whether time.mktime may occasionally throw OverflowError.

I recommend a new PR for a new issue that starts by adding a new test that is effectively the same as the one that throws an error, but pins the time zone to 'UTC' instead. Note that that tests something different from this test - if I understand this correctly, this test is checking that is_dst works correctly when the date given is already DST. That test would be meaningless or have a very different meaning when applied to UTC.

@vstinner vstinner merged commit cfaafda into python:master Nov 27, 2018
@miss-islington
Copy link
Contributor

Thanks @vstinner for the PR 🌮🎉.. I'm working now to backport this PR to: 3.6, 3.7.
🐍🍒⛏🤖

miss-islington pushed a commit to miss-islington/cpython that referenced this pull request Nov 27, 2018
Fix mktime() overflow error in test_email: run
test_localtime_daylight_true_dst_true() and
test_localtime_daylight_false_dst_true() with a specific timezone.
(cherry picked from commit cfaafda)

Co-authored-by: Victor Stinner <vstinner@redhat.com>
@bedevere-bot
Copy link

GH-10741 is a backport of this pull request to the 3.7 branch.

@bedevere-bot
Copy link

GH-10742 is a backport of this pull request to the 3.6 branch.

@vstinner vstinner deleted the test_email_dst branch November 27, 2018 11:41
miss-islington pushed a commit to miss-islington/cpython that referenced this pull request Nov 27, 2018
Fix mktime() overflow error in test_email: run
test_localtime_daylight_true_dst_true() and
test_localtime_daylight_false_dst_true() with a specific timezone.
(cherry picked from commit cfaafda)

Co-authored-by: Victor Stinner <vstinner@redhat.com>
miss-islington added a commit that referenced this pull request Nov 27, 2018
Fix mktime() overflow error in test_email: run
test_localtime_daylight_true_dst_true() and
test_localtime_daylight_false_dst_true() with a specific timezone.
(cherry picked from commit cfaafda)

Co-authored-by: Victor Stinner <vstinner@redhat.com>
miss-islington added a commit that referenced this pull request Nov 27, 2018
Fix mktime() overflow error in test_email: run
test_localtime_daylight_true_dst_true() and
test_localtime_daylight_false_dst_true() with a specific timezone.
(cherry picked from commit cfaafda)

Co-authored-by: Victor Stinner <vstinner@redhat.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
tests Tests in the Lib/test dir
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants