bpo-37552: Skip failing tests in strptime/strftime with UCRT version 17763.615 (#14460)
A bug in MSVC UCRT version 17763.615 (which has been fixed in newer versions) is causing test failures in some strptime/strftime tests when the default code page is c65001. This change selectively skips the tests affected by this.
This commit is contained in:
parent
1b38922434
commit
9cd39b16e2
|
@ -14,6 +14,7 @@ import gc
|
||||||
import glob
|
import glob
|
||||||
import importlib
|
import importlib
|
||||||
import importlib.util
|
import importlib.util
|
||||||
|
import locale
|
||||||
import logging.handlers
|
import logging.handlers
|
||||||
import nntplib
|
import nntplib
|
||||||
import os
|
import os
|
||||||
|
@ -92,7 +93,7 @@ __all__ = [
|
||||||
"bigmemtest", "bigaddrspacetest", "cpython_only", "get_attribute",
|
"bigmemtest", "bigaddrspacetest", "cpython_only", "get_attribute",
|
||||||
"requires_IEEE_754", "skip_unless_xattr", "requires_zlib",
|
"requires_IEEE_754", "skip_unless_xattr", "requires_zlib",
|
||||||
"anticipate_failure", "load_package_tests", "detect_api_mismatch",
|
"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_strfptime",
|
||||||
"ignore_warnings",
|
"ignore_warnings",
|
||||||
# sys
|
# sys
|
||||||
"is_jython", "is_android", "check_impl_detail", "unix_shell",
|
"is_jython", "is_android", "check_impl_detail", "unix_shell",
|
||||||
|
@ -2501,6 +2502,27 @@ def skip_unless_symlink(test):
|
||||||
msg = "Requires functional symlink implementation"
|
msg = "Requires functional symlink implementation"
|
||||||
return test if ok else unittest.skip(msg)(test)
|
return test if ok else unittest.skip(msg)(test)
|
||||||
|
|
||||||
|
_buggy_ucrt = None
|
||||||
|
def skip_if_buggy_ucrt_strfptime(test):
|
||||||
|
"""
|
||||||
|
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
|
||||||
|
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 strptime/strftime")(test) if _buggy_ucrt else test
|
||||||
|
|
||||||
class PythonSymlink:
|
class PythonSymlink:
|
||||||
"""Creates a symlink for the current Python executable"""
|
"""Creates a symlink for the current Python executable"""
|
||||||
def __init__(self, link=None):
|
def __init__(self, link=None):
|
||||||
|
|
|
@ -7,6 +7,7 @@ import re
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
from test import support
|
from test import support
|
||||||
|
from test.support import skip_if_buggy_ucrt_strfptime
|
||||||
from datetime import date as datetime_date
|
from datetime import date as datetime_date
|
||||||
|
|
||||||
import _strptime
|
import _strptime
|
||||||
|
@ -135,6 +136,7 @@ class TimeRETests(unittest.TestCase):
|
||||||
"%s does not have re characters escaped properly" %
|
"%s does not have re characters escaped properly" %
|
||||||
pattern_string)
|
pattern_string)
|
||||||
|
|
||||||
|
@skip_if_buggy_ucrt_strfptime
|
||||||
def test_compile(self):
|
def test_compile(self):
|
||||||
# Check that compiled regex is correct
|
# Check that compiled regex is correct
|
||||||
found = self.time_re.compile(r"%A").match(self.locale_time.f_weekday[6])
|
found = self.time_re.compile(r"%A").match(self.locale_time.f_weekday[6])
|
||||||
|
@ -365,6 +367,7 @@ class StrptimeTests(unittest.TestCase):
|
||||||
_strptime._strptime("-01:3030", "%z")
|
_strptime._strptime("-01:3030", "%z")
|
||||||
self.assertEqual("Inconsistent use of : in -01:3030", str(err.exception))
|
self.assertEqual("Inconsistent use of : in -01:3030", str(err.exception))
|
||||||
|
|
||||||
|
@skip_if_buggy_ucrt_strfptime
|
||||||
def test_timezone(self):
|
def test_timezone(self):
|
||||||
# Test timezone directives.
|
# Test timezone directives.
|
||||||
# When gmtime() is used with %Z, entire result of strftime() is empty.
|
# When gmtime() is used with %Z, entire result of strftime() is empty.
|
||||||
|
@ -489,6 +492,7 @@ class CalculationTests(unittest.TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.time_tuple = time.gmtime()
|
self.time_tuple = time.gmtime()
|
||||||
|
|
||||||
|
@skip_if_buggy_ucrt_strfptime
|
||||||
def test_julian_calculation(self):
|
def test_julian_calculation(self):
|
||||||
# Make sure that when Julian is missing that it is calculated
|
# Make sure that when Julian is missing that it is calculated
|
||||||
format_string = "%Y %m %d %H %M %S %w %Z"
|
format_string = "%Y %m %d %H %M %S %w %Z"
|
||||||
|
@ -498,6 +502,7 @@ class CalculationTests(unittest.TestCase):
|
||||||
"Calculation of tm_yday failed; %s != %s" %
|
"Calculation of tm_yday failed; %s != %s" %
|
||||||
(result.tm_yday, self.time_tuple.tm_yday))
|
(result.tm_yday, self.time_tuple.tm_yday))
|
||||||
|
|
||||||
|
@skip_if_buggy_ucrt_strfptime
|
||||||
def test_gregorian_calculation(self):
|
def test_gregorian_calculation(self):
|
||||||
# Test that Gregorian date can be calculated from Julian day
|
# Test that Gregorian date can be calculated from Julian day
|
||||||
format_string = "%Y %H %M %S %w %j %Z"
|
format_string = "%Y %H %M %S %w %j %Z"
|
||||||
|
@ -512,6 +517,7 @@ class CalculationTests(unittest.TestCase):
|
||||||
self.time_tuple.tm_year, self.time_tuple.tm_mon,
|
self.time_tuple.tm_year, self.time_tuple.tm_mon,
|
||||||
self.time_tuple.tm_mday))
|
self.time_tuple.tm_mday))
|
||||||
|
|
||||||
|
@skip_if_buggy_ucrt_strfptime
|
||||||
def test_day_of_week_calculation(self):
|
def test_day_of_week_calculation(self):
|
||||||
# Test that the day of the week is calculated as needed
|
# Test that the day of the week is calculated as needed
|
||||||
format_string = "%Y %m %d %H %S %j %Z"
|
format_string = "%Y %m %d %H %S %j %Z"
|
||||||
|
|
|
@ -14,6 +14,7 @@ try:
|
||||||
except ImportError:
|
except ImportError:
|
||||||
_testcapi = None
|
_testcapi = None
|
||||||
|
|
||||||
|
from test.support import skip_if_buggy_ucrt_strfptime
|
||||||
|
|
||||||
# Max year is only limited by the size of C int.
|
# Max year is only limited by the size of C int.
|
||||||
SIZEOF_INT = sysconfig.get_config_var('SIZEOF_INT') or 4
|
SIZEOF_INT = sysconfig.get_config_var('SIZEOF_INT') or 4
|
||||||
|
@ -250,6 +251,7 @@ class TimeTestCase(unittest.TestCase):
|
||||||
result = time.strftime("%Y %m %d %H %M %S %w %j", (2000,)+(0,)*8)
|
result = time.strftime("%Y %m %d %H %M %S %w %j", (2000,)+(0,)*8)
|
||||||
self.assertEqual(expected, result)
|
self.assertEqual(expected, result)
|
||||||
|
|
||||||
|
@skip_if_buggy_ucrt_strfptime
|
||||||
def test_strptime(self):
|
def test_strptime(self):
|
||||||
# Should be able to go round-trip from strftime to strptime without
|
# Should be able to go round-trip from strftime to strptime without
|
||||||
# raising an exception.
|
# raising an exception.
|
||||||
|
@ -672,6 +674,7 @@ class TestStrftime4dyear(_TestStrftimeYear, _Test4dYear, unittest.TestCase):
|
||||||
|
|
||||||
|
|
||||||
class TestPytime(unittest.TestCase):
|
class TestPytime(unittest.TestCase):
|
||||||
|
@skip_if_buggy_ucrt_strfptime
|
||||||
@unittest.skipUnless(time._STRUCT_TM_ITEMS == 11, "needs tm_zone support")
|
@unittest.skipUnless(time._STRUCT_TM_ITEMS == 11, "needs tm_zone support")
|
||||||
def test_localtime_timezone(self):
|
def test_localtime_timezone(self):
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue