import glob
import importlib
import importlib.util
+import locale
import logging.handlers
import nntplib
import os
"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_strfptime",
"ignore_warnings",
# sys
"is_jython", "is_android", "check_impl_detail", "unix_shell",
msg = "Requires functional symlink implementation"
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:
"""Creates a symlink for the current Python executable"""
def __init__(self, link=None):
import os
import sys
from test import support
+from test.support import skip_if_buggy_ucrt_strfptime
from datetime import date as datetime_date
import _strptime
"%s does not have re characters escaped properly" %
pattern_string)
+ @skip_if_buggy_ucrt_strfptime
def test_compile(self):
# Check that compiled regex is correct
found = self.time_re.compile(r"%A").match(self.locale_time.f_weekday[6])
_strptime._strptime("-01:3030", "%z")
self.assertEqual("Inconsistent use of : in -01:3030", str(err.exception))
+ @skip_if_buggy_ucrt_strfptime
def test_timezone(self):
# Test timezone directives.
# When gmtime() is used with %Z, entire result of strftime() is empty.
def setUp(self):
self.time_tuple = time.gmtime()
+ @skip_if_buggy_ucrt_strfptime
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"
"Calculation of tm_yday failed; %s != %s" %
(result.tm_yday, self.time_tuple.tm_yday))
+ @skip_if_buggy_ucrt_strfptime
def test_gregorian_calculation(self):
# Test that Gregorian date can be calculated from Julian day
format_string = "%Y %H %M %S %w %j %Z"
self.time_tuple.tm_year, self.time_tuple.tm_mon,
self.time_tuple.tm_mday))
+ @skip_if_buggy_ucrt_strfptime
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"
except ImportError:
_testcapi = None
+from test.support import skip_if_buggy_ucrt_strfptime
# Max year is only limited by the size of C int.
SIZEOF_INT = sysconfig.get_config_var('SIZEOF_INT') or 4
result = time.strftime("%Y %m %d %H %M %S %w %j", (2000,)+(0,)*8)
self.assertEqual(expected, result)
+ @skip_if_buggy_ucrt_strfptime
def test_strptime(self):
# Should be able to go round-trip from strftime to strptime without
# raising an exception.
class TestPytime(unittest.TestCase):
+ @skip_if_buggy_ucrt_strfptime
@unittest.skipUnless(time._STRUCT_TM_ITEMS == 11, "needs tm_zone support")
def test_localtime_timezone(self):