Skip to content

bpo-37552 strptime/strftime return invalid results with UCRT version 17763.615 #14460

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

Merged
merged 8 commits into from
Jul 18, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
refactor skips
  • Loading branch information
Paul Monson committed Jul 17, 2019
commit 6cfcddb3c8fbd5e046ee2d3f7cf6d8fe4a1d06d1
24 changes: 23 additions & 1 deletion Lib/test/support/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import importlib
import importlib.util
import io
import locale
import logging.handlers
import nntplib
import os
Expand Down Expand Up @@ -93,7 +94,7 @@
"bigmemtest", "bigaddrspacetest", "cpython_only", "get_attribute",
"requires_IEEE_754", "skip_unless_xattr", "requires_zlib",
"anticipate_failure", "load_package_tests", "detect_api_mismatch",
"check__all__", "skip_unless_bind_unix_socket",
"check__all__", "skip_unless_bind_unix_socket", "skip_if_buggy_ucrt"
"ignore_warnings",
# sys
"is_jython", "is_android", "check_impl_detail", "unix_shell",
Expand Down Expand Up @@ -2500,6 +2501,27 @@ def skip_unless_symlink(test):
msg = "Requires functional symlink implementation"
return test if ok else unittest.skip(msg)(test)

_buggy_ucrt = None
def skip_if_buggy_ucrt(test):
Copy link
Member

Choose a reason for hiding this comment

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

Since this now lives in test.support, it might be worthwhile to mention 'time' in the name (skip_if_buggy_ucrt_strfptime or similar).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I added strftime/strptime to the skip message and skip decorator name

"""
Skip decorator for tests that use buggy strptime/strftime

If the UCRT bugs are present time.localtime().tm_zone will be
an empty string, otherwise we assume the UCRT bugs are fixed

See bpo-37552 [Windows] strptime/strftime return invalid
results with UCRT version 17763.615
"""
global _buggy_ucrt
Copy link
Member

Choose a reason for hiding this comment

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

This is not a particularly expensive check, right? Why cache it instead of checking each time?

Copy link
Member

Choose a reason for hiding this comment

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

The caching is simple and easy to follow; I'd rather keep it than assume it's not worthwhile :)

if _buggy_ucrt is None:
if(sys.platform == 'win32' and
locale.getdefaultlocale()[1] == 'cp65001' and
time.localtime().tm_zone == ''):
_buggy_ucrt = True
else:
_buggy_ucrt = False
return unittest.skip("buggy MSVC UCRT")(test) if _buggy_ucrt else test

_can_xattr = None
def can_xattr():
global _can_xattr
Expand Down
21 changes: 6 additions & 15 deletions Lib/test/test_strptime.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import os
import sys
from test import support
from test.support import skip_if_buggy_ucrt
from datetime import date as datetime_date

import _strptime
Expand Down Expand Up @@ -135,9 +136,7 @@ def test_pattern_escaping(self):
"%s does not have re characters escaped properly" %
pattern_string)

# bpo-37552 [Windows] strptime/strftime return invalid results with UCRT version 17763.615
@unittest.skipIf(sys.platform == 'win32' and locale.getdefaultlocale()[1] == 'cp65001',
'issue in MSVC UCRT')
@skip_if_buggy_ucrt
def test_compile(self):
# Check that compiled regex is correct
found = self.time_re.compile(r"%A").match(self.locale_time.f_weekday[6])
Expand Down Expand Up @@ -368,9 +367,7 @@ def test_bad_offset(self):
_strptime._strptime("-01:3030", "%z")
self.assertEqual("Inconsistent use of : in -01:3030", str(err.exception))

# bpo-37552 [Windows] strptime/strftime return invalid results with UCRT version 17763.615
@unittest.skipIf(sys.platform == 'win32' and locale.getdefaultlocale()[1] == 'cp65001',
'issue in MSVC UCRT')
@skip_if_buggy_ucrt
def test_timezone(self):
# Test timezone directives.
# When gmtime() is used with %Z, entire result of strftime() is empty.
Expand Down Expand Up @@ -495,9 +492,7 @@ class CalculationTests(unittest.TestCase):
def setUp(self):
self.time_tuple = time.gmtime()

# bpo-37552 [Windows] strptime/strftime return invalid results with UCRT version 17763.615
@unittest.skipIf(sys.platform == 'win32' and locale.getdefaultlocale()[1] == 'cp65001',
'issue in MSVC UCRT')
@skip_if_buggy_ucrt
def test_julian_calculation(self):
# Make sure that when Julian is missing that it is calculated
format_string = "%Y %m %d %H %M %S %w %Z"
Expand All @@ -507,9 +502,7 @@ def test_julian_calculation(self):
"Calculation of tm_yday failed; %s != %s" %
(result.tm_yday, self.time_tuple.tm_yday))

# bpo-37552 [Windows] strptime/strftime return invalid results with UCRT version 17763.615
@unittest.skipIf(sys.platform == 'win32' and locale.getdefaultlocale()[1] == 'cp65001',
'issue in MSVC UCRT')
@skip_if_buggy_ucrt
def test_gregorian_calculation(self):
# Test that Gregorian date can be calculated from Julian day
format_string = "%Y %H %M %S %w %j %Z"
Expand All @@ -524,9 +517,7 @@ def test_gregorian_calculation(self):
self.time_tuple.tm_year, self.time_tuple.tm_mon,
self.time_tuple.tm_mday))

# bpo-37552 [Windows] strptime/strftime return invalid results with UCRT version 17763.615
@unittest.skipIf(sys.platform == 'win32' and locale.getdefaultlocale()[1] == 'cp65001',
'issue in MSVC UCRT')
@skip_if_buggy_ucrt
def test_day_of_week_calculation(self):
# Test that the day of the week is calculated as needed
format_string = "%Y %m %d %H %S %j %Z"
Expand Down
9 changes: 3 additions & 6 deletions Lib/test/test_time.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
except ImportError:
_testcapi = None

from test.support import skip_if_buggy_ucrt

# Max year is only limited by the size of C int.
SIZEOF_INT = sysconfig.get_config_var('SIZEOF_INT') or 4
Expand Down Expand Up @@ -250,9 +251,7 @@ def test_default_values_for_zero(self):
result = time.strftime("%Y %m %d %H %M %S %w %j", (2000,)+(0,)*8)
self.assertEqual(expected, result)

# bpo-37552 [Windows] strptime/strftime return invalid results with UCRT version 17763.615
@unittest.skipIf(sys.platform == 'win32' and locale.getdefaultlocale()[1] == 'cp65001',
'issue in MSVC UCRT')
@skip_if_buggy_ucrt
def test_strptime(self):
# Should be able to go round-trip from strftime to strptime without
# raising an exception.
Expand Down Expand Up @@ -675,9 +674,7 @@ class TestStrftime4dyear(_TestStrftimeYear, _Test4dYear, unittest.TestCase):


class TestPytime(unittest.TestCase):
# bpo-37552 [Windows] strptime/strftime return invalid results with UCRT version 17763.615
@unittest.skipIf(sys.platform == 'win32' and locale.getdefaultlocale()[1] == 'cp65001',
'issue in MSVC UCRT')
@skip_if_buggy_ucrt
@unittest.skipUnless(time._STRUCT_TM_ITEMS == 11, "needs tm_zone support")
def test_localtime_timezone(self):

Expand Down
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy