mirror of
https://github.com/python/cpython.git
synced 2025-09-22 16:33:26 +00:00
gh-53203: Improve tests for strptime() (GH-125090)
Run them with different locales and different date and time. Add the @run_with_locales() decorator to run the test with multiple locales. Improve the run_with_locale() context manager/decorator -- it now catches only expected exceptions and reports the test as skipped if no appropriate locale is available.
This commit is contained in:
parent
7c4b6a68f2
commit
19984fe024
10 changed files with 198 additions and 83 deletions
|
@ -26,7 +26,7 @@ except ImportError:
|
||||||
from test import support
|
from test import support
|
||||||
from test.support import os_helper
|
from test.support import os_helper
|
||||||
from test.support import (
|
from test.support import (
|
||||||
TestFailed, run_with_locale, no_tracing,
|
TestFailed, run_with_locales, no_tracing,
|
||||||
_2G, _4G, bigmemtest
|
_2G, _4G, bigmemtest
|
||||||
)
|
)
|
||||||
from test.support.import_helper import forget
|
from test.support.import_helper import forget
|
||||||
|
@ -2895,7 +2895,7 @@ class AbstractPickleTests:
|
||||||
got = self.loads(pickle)
|
got = self.loads(pickle)
|
||||||
self.assert_is_copy(value, got)
|
self.assert_is_copy(value, got)
|
||||||
|
|
||||||
@run_with_locale('LC_ALL', 'de_DE', 'fr_FR')
|
@run_with_locales('LC_ALL', 'de_DE', 'fr_FR', '')
|
||||||
def test_float_format(self):
|
def test_float_format(self):
|
||||||
# make sure that floats are formatted locale independent with proto 0
|
# make sure that floats are formatted locale independent with proto 0
|
||||||
self.assertEqual(self.dumps(1.2, 0)[0:3], b'F1.')
|
self.assertEqual(self.dumps(1.2, 0)[0:3], b'F1.')
|
||||||
|
|
|
@ -930,8 +930,8 @@ def check_sizeof(test, o, size):
|
||||||
test.assertEqual(result, size, msg)
|
test.assertEqual(result, size, msg)
|
||||||
|
|
||||||
#=======================================================================
|
#=======================================================================
|
||||||
# Decorator for running a function in a different locale, correctly resetting
|
# Decorator/context manager for running a code in a different locale,
|
||||||
# it afterwards.
|
# correctly resetting it afterwards.
|
||||||
|
|
||||||
@contextlib.contextmanager
|
@contextlib.contextmanager
|
||||||
def run_with_locale(catstr, *locales):
|
def run_with_locale(catstr, *locales):
|
||||||
|
@ -942,16 +942,21 @@ def run_with_locale(catstr, *locales):
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
# if the test author gives us an invalid category string
|
# if the test author gives us an invalid category string
|
||||||
raise
|
raise
|
||||||
except:
|
except Exception:
|
||||||
# cannot retrieve original locale, so do nothing
|
# cannot retrieve original locale, so do nothing
|
||||||
locale = orig_locale = None
|
locale = orig_locale = None
|
||||||
|
if '' not in locales:
|
||||||
|
raise unittest.SkipTest('no locales')
|
||||||
else:
|
else:
|
||||||
for loc in locales:
|
for loc in locales:
|
||||||
try:
|
try:
|
||||||
locale.setlocale(category, loc)
|
locale.setlocale(category, loc)
|
||||||
break
|
break
|
||||||
except:
|
except locale.Error:
|
||||||
pass
|
pass
|
||||||
|
else:
|
||||||
|
if '' not in locales:
|
||||||
|
raise unittest.SkipTest(f'no locales {locales}')
|
||||||
|
|
||||||
try:
|
try:
|
||||||
yield
|
yield
|
||||||
|
@ -959,6 +964,46 @@ def run_with_locale(catstr, *locales):
|
||||||
if locale and orig_locale:
|
if locale and orig_locale:
|
||||||
locale.setlocale(category, orig_locale)
|
locale.setlocale(category, orig_locale)
|
||||||
|
|
||||||
|
#=======================================================================
|
||||||
|
# Decorator for running a function in multiple locales (if they are
|
||||||
|
# availasble) and resetting the original locale afterwards.
|
||||||
|
|
||||||
|
def run_with_locales(catstr, *locales):
|
||||||
|
def deco(func):
|
||||||
|
@functools.wraps(func)
|
||||||
|
def wrapper(self, /, *args, **kwargs):
|
||||||
|
dry_run = '' in locales
|
||||||
|
try:
|
||||||
|
import locale
|
||||||
|
category = getattr(locale, catstr)
|
||||||
|
orig_locale = locale.setlocale(category)
|
||||||
|
except AttributeError:
|
||||||
|
# if the test author gives us an invalid category string
|
||||||
|
raise
|
||||||
|
except Exception:
|
||||||
|
# cannot retrieve original locale, so do nothing
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
for loc in locales:
|
||||||
|
with self.subTest(locale=loc):
|
||||||
|
try:
|
||||||
|
locale.setlocale(category, loc)
|
||||||
|
except locale.Error:
|
||||||
|
self.skipTest(f'no locale {loc!r}')
|
||||||
|
else:
|
||||||
|
dry_run = False
|
||||||
|
func(self, *args, **kwargs)
|
||||||
|
finally:
|
||||||
|
locale.setlocale(category, orig_locale)
|
||||||
|
if dry_run:
|
||||||
|
# no locales available, so just run the test
|
||||||
|
# with the current locale
|
||||||
|
with self.subTest(locale=None):
|
||||||
|
func(self, *args, **kwargs)
|
||||||
|
return wrapper
|
||||||
|
return deco
|
||||||
|
|
||||||
#=======================================================================
|
#=======================================================================
|
||||||
# Decorator for running a function in a specific timezone, correctly
|
# Decorator for running a function in a specific timezone, correctly
|
||||||
# resetting it afterwards.
|
# resetting it afterwards.
|
||||||
|
|
|
@ -2,7 +2,6 @@ import codecs
|
||||||
import contextlib
|
import contextlib
|
||||||
import copy
|
import copy
|
||||||
import io
|
import io
|
||||||
import locale
|
|
||||||
import pickle
|
import pickle
|
||||||
import sys
|
import sys
|
||||||
import unittest
|
import unittest
|
||||||
|
@ -1812,16 +1811,10 @@ class CodecsModuleTest(unittest.TestCase):
|
||||||
self.assertRaises(TypeError, codecs.getwriter)
|
self.assertRaises(TypeError, codecs.getwriter)
|
||||||
self.assertRaises(LookupError, codecs.getwriter, "__spam__")
|
self.assertRaises(LookupError, codecs.getwriter, "__spam__")
|
||||||
|
|
||||||
|
@support.run_with_locale('LC_CTYPE', 'tr_TR')
|
||||||
def test_lookup_issue1813(self):
|
def test_lookup_issue1813(self):
|
||||||
# Issue #1813: under Turkish locales, lookup of some codecs failed
|
# Issue #1813: under Turkish locales, lookup of some codecs failed
|
||||||
# because 'I' is lowercased as "ı" (dotless i)
|
# because 'I' is lowercased as "ı" (dotless i)
|
||||||
oldlocale = locale.setlocale(locale.LC_CTYPE)
|
|
||||||
self.addCleanup(locale.setlocale, locale.LC_CTYPE, oldlocale)
|
|
||||||
try:
|
|
||||||
locale.setlocale(locale.LC_CTYPE, 'tr_TR')
|
|
||||||
except locale.Error:
|
|
||||||
# Unsupported locale on this system
|
|
||||||
self.skipTest('test needs Turkish locale')
|
|
||||||
c = codecs.lookup('ASCII')
|
c = codecs.lookup('ASCII')
|
||||||
self.assertEqual(c.name, 'ascii')
|
self.assertEqual(c.name, 'ascii')
|
||||||
|
|
||||||
|
|
|
@ -1253,7 +1253,7 @@ class FormatTest:
|
||||||
self.assertRaises(ValueError, format, h, '10Nf')
|
self.assertRaises(ValueError, format, h, '10Nf')
|
||||||
self.assertRaises(ValueError, format, h, 'Nx')
|
self.assertRaises(ValueError, format, h, 'Nx')
|
||||||
|
|
||||||
@run_with_locale('LC_ALL', 'ps_AF')
|
@run_with_locale('LC_ALL', 'ps_AF', '')
|
||||||
def test_wide_char_separator_decimal_point(self):
|
def test_wide_char_separator_decimal_point(self):
|
||||||
# locale with wide char separator and decimal point
|
# locale with wide char separator and decimal point
|
||||||
Decimal = self.decimal.Decimal
|
Decimal = self.decimal.Decimal
|
||||||
|
|
|
@ -175,7 +175,7 @@ class GeneralFloatCases(unittest.TestCase):
|
||||||
# non-UTF-8 byte string
|
# non-UTF-8 byte string
|
||||||
check(b'123\xa0')
|
check(b'123\xa0')
|
||||||
|
|
||||||
@support.run_with_locale('LC_NUMERIC', 'fr_FR', 'de_DE')
|
@support.run_with_locale('LC_NUMERIC', 'fr_FR', 'de_DE', '')
|
||||||
def test_float_with_comma(self):
|
def test_float_with_comma(self):
|
||||||
# set locale to something that doesn't use '.' for the decimal point
|
# set locale to something that doesn't use '.' for the decimal point
|
||||||
# float must not accept the locale specific decimal point but
|
# float must not accept the locale specific decimal point but
|
||||||
|
|
|
@ -57,7 +57,7 @@ class TestImaplib(unittest.TestCase):
|
||||||
timezone(timedelta(0, 2 * 60 * 60))),
|
timezone(timedelta(0, 2 * 60 * 60))),
|
||||||
'"18-May-2033 05:33:20 +0200"']
|
'"18-May-2033 05:33:20 +0200"']
|
||||||
|
|
||||||
@run_with_locale('LC_ALL', 'de_DE', 'fr_FR')
|
@run_with_locale('LC_ALL', 'de_DE', 'fr_FR', '')
|
||||||
# DST rules included to work around quirk where the Gnu C library may not
|
# DST rules included to work around quirk where the Gnu C library may not
|
||||||
# otherwise restore the previous time zone
|
# otherwise restore the previous time zone
|
||||||
@run_with_tz('STD-1DST,M3.2.0,M11.1.0')
|
@run_with_tz('STD-1DST,M3.2.0,M11.1.0')
|
||||||
|
|
|
@ -1665,7 +1665,7 @@ class StrTest(string_tests.StringLikeTest,
|
||||||
self.assertIn('str', exc)
|
self.assertIn('str', exc)
|
||||||
self.assertIn('tuple', exc)
|
self.assertIn('tuple', exc)
|
||||||
|
|
||||||
@support.run_with_locale('LC_ALL', 'de_DE', 'fr_FR')
|
@support.run_with_locale('LC_ALL', 'de_DE', 'fr_FR', '')
|
||||||
def test_format_float(self):
|
def test_format_float(self):
|
||||||
# should not format with a comma, but always with C locale
|
# should not format with a comma, but always with C locale
|
||||||
self.assertEqual('1.0', '%.1f' % 1.0)
|
self.assertEqual('1.0', '%.1f' % 1.0)
|
||||||
|
|
|
@ -7,7 +7,8 @@ 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, warnings_helper
|
from test.support import warnings_helper
|
||||||
|
from test.support import skip_if_buggy_ucrt_strfptime, run_with_locales
|
||||||
from datetime import date as datetime_date
|
from datetime import date as datetime_date
|
||||||
|
|
||||||
import _strptime
|
import _strptime
|
||||||
|
@ -207,8 +208,8 @@ class StrptimeTests(unittest.TestCase):
|
||||||
"""Tests for _strptime.strptime."""
|
"""Tests for _strptime.strptime."""
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
"""Create testing time tuple."""
|
"""Create testing time tuples."""
|
||||||
self.time_tuple = time.gmtime()
|
self.time_tuple = time.localtime()
|
||||||
|
|
||||||
def test_ValueError(self):
|
def test_ValueError(self):
|
||||||
# Make sure ValueError is raised when match fails or format is bad
|
# Make sure ValueError is raised when match fails or format is bad
|
||||||
|
@ -289,54 +290,67 @@ class StrptimeTests(unittest.TestCase):
|
||||||
# Check ValueError is raised when there is unconverted data
|
# Check ValueError is raised when there is unconverted data
|
||||||
self.assertRaises(ValueError, _strptime._strptime_time, "10 12", "%m")
|
self.assertRaises(ValueError, _strptime._strptime_time, "10 12", "%m")
|
||||||
|
|
||||||
def helper(self, directive, position):
|
def roundtrip(self, fmt, position, time_tuple=None):
|
||||||
"""Helper fxn in testing."""
|
"""Helper fxn in testing."""
|
||||||
fmt = "%d %Y" if directive == 'd' else "%" + directive
|
if time_tuple is None:
|
||||||
strf_output = time.strftime(fmt, self.time_tuple)
|
time_tuple = self.time_tuple
|
||||||
|
strf_output = time.strftime(fmt, time_tuple)
|
||||||
strp_output = _strptime._strptime_time(strf_output, fmt)
|
strp_output = _strptime._strptime_time(strf_output, fmt)
|
||||||
self.assertTrue(strp_output[position] == self.time_tuple[position],
|
self.assertEqual(strp_output[position], time_tuple[position],
|
||||||
"testing of '%s' directive failed; '%s' -> %s != %s" %
|
"testing of %r format failed; %r -> %r != %r" %
|
||||||
(directive, strf_output, strp_output[position],
|
(fmt, strf_output, strp_output[position],
|
||||||
self.time_tuple[position]))
|
time_tuple[position]))
|
||||||
|
if support.verbose >= 3:
|
||||||
|
print("testing of %r format: %r -> %r" %
|
||||||
|
(fmt, strf_output, strp_output[position]))
|
||||||
|
|
||||||
def test_year(self):
|
def test_year(self):
|
||||||
# Test that the year is handled properly
|
# Test that the year is handled properly
|
||||||
for directive in ('y', 'Y'):
|
self.roundtrip('%Y', 0)
|
||||||
self.helper(directive, 0)
|
self.roundtrip('%y', 0)
|
||||||
|
self.roundtrip('%Y', 0, (1900, 1, 1, 0, 0, 0, 0, 1, 0))
|
||||||
|
|
||||||
# Must also make sure %y values are correct for bounds set by Open Group
|
# Must also make sure %y values are correct for bounds set by Open Group
|
||||||
for century, bounds in ((1900, ('69', '99')), (2000, ('00', '68'))):
|
strptime = _strptime._strptime_time
|
||||||
for bound in bounds:
|
self.assertEqual(strptime('00', '%y')[0], 2000)
|
||||||
strp_output = _strptime._strptime_time(bound, '%y')
|
self.assertEqual(strptime('68', '%y')[0], 2068)
|
||||||
expected_result = century + int(bound)
|
self.assertEqual(strptime('69', '%y')[0], 1969)
|
||||||
self.assertTrue(strp_output[0] == expected_result,
|
self.assertEqual(strptime('99', '%y')[0], 1999)
|
||||||
"'y' test failed; passed in '%s' "
|
|
||||||
"and returned '%s'" % (bound, strp_output[0]))
|
|
||||||
|
|
||||||
def test_month(self):
|
def test_month(self):
|
||||||
# Test for month directives
|
# Test for month directives
|
||||||
for directive in ('B', 'b', 'm'):
|
self.roundtrip('%m', 1)
|
||||||
self.helper(directive, 1)
|
|
||||||
|
@run_with_locales('LC_TIME', 'C', 'en_US', 'fr_FR', 'de_DE', 'ja_JP', 'he_IL', '')
|
||||||
|
def test_month_locale(self):
|
||||||
|
# Test for month directives
|
||||||
|
self.roundtrip('%B', 1)
|
||||||
|
self.roundtrip('%b', 1)
|
||||||
|
for m in range(1, 13):
|
||||||
|
self.roundtrip('%B', 1, (1900, m, 1, 0, 0, 0, 0, 1, 0))
|
||||||
|
self.roundtrip('%b', 1, (1900, m, 1, 0, 0, 0, 0, 1, 0))
|
||||||
|
|
||||||
def test_day(self):
|
def test_day(self):
|
||||||
# Test for day directives
|
# Test for day directives
|
||||||
self.helper('d', 2)
|
self.roundtrip('%d %Y', 2)
|
||||||
|
|
||||||
def test_hour(self):
|
def test_hour(self):
|
||||||
# Test hour directives
|
# Test hour directives
|
||||||
self.helper('H', 3)
|
self.roundtrip('%H', 3)
|
||||||
strf_output = time.strftime("%I %p", self.time_tuple)
|
|
||||||
strp_output = _strptime._strptime_time(strf_output, "%I %p")
|
# NB: Only works on locales with AM/PM
|
||||||
self.assertTrue(strp_output[3] == self.time_tuple[3],
|
@run_with_locales('LC_TIME', 'C', 'en_US', 'ja_JP')
|
||||||
"testing of '%%I %%p' directive failed; '%s' -> %s != %s" %
|
def test_hour_locale(self):
|
||||||
(strf_output, strp_output[3], self.time_tuple[3]))
|
# Test hour directives
|
||||||
|
self.roundtrip('%I %p', 3)
|
||||||
|
|
||||||
def test_minute(self):
|
def test_minute(self):
|
||||||
# Test minute directives
|
# Test minute directives
|
||||||
self.helper('M', 4)
|
self.roundtrip('%M', 4)
|
||||||
|
|
||||||
def test_second(self):
|
def test_second(self):
|
||||||
# Test second directives
|
# Test second directives
|
||||||
self.helper('S', 5)
|
self.roundtrip('%S', 5)
|
||||||
|
|
||||||
def test_fraction(self):
|
def test_fraction(self):
|
||||||
# Test microseconds
|
# Test microseconds
|
||||||
|
@ -347,12 +361,18 @@ class StrptimeTests(unittest.TestCase):
|
||||||
|
|
||||||
def test_weekday(self):
|
def test_weekday(self):
|
||||||
# Test weekday directives
|
# Test weekday directives
|
||||||
for directive in ('A', 'a', 'w', 'u'):
|
self.roundtrip('%w', 6)
|
||||||
self.helper(directive,6)
|
self.roundtrip('%u', 6)
|
||||||
|
|
||||||
|
@run_with_locales('LC_TIME', 'C', 'en_US', 'fr_FR', 'de_DE', 'ja_JP', '')
|
||||||
|
def test_weekday_locale(self):
|
||||||
|
# Test weekday directives
|
||||||
|
self.roundtrip('%A', 6)
|
||||||
|
self.roundtrip('%a', 6)
|
||||||
|
|
||||||
def test_julian(self):
|
def test_julian(self):
|
||||||
# Test julian directives
|
# Test julian directives
|
||||||
self.helper('j', 7)
|
self.roundtrip('%j', 7)
|
||||||
|
|
||||||
def test_offset(self):
|
def test_offset(self):
|
||||||
one_hour = 60 * 60
|
one_hour = 60 * 60
|
||||||
|
@ -449,20 +469,96 @@ class StrptimeTests(unittest.TestCase):
|
||||||
"time.daylight set to %s and passing in %s" %
|
"time.daylight set to %s and passing in %s" %
|
||||||
(time.tzname, tz_value, time.daylight, tz_name))
|
(time.tzname, tz_value, time.daylight, tz_name))
|
||||||
|
|
||||||
def test_date_time(self):
|
# NB: Does not roundtrip in some locales due to the ambiguity of
|
||||||
|
# the date and time representation (bugs in locales?):
|
||||||
|
# * Seconds are not included: bem_ZM, bokmal, ff_SN, nb_NO, nn_NO,
|
||||||
|
# no_NO, norwegian, nynorsk.
|
||||||
|
# * Hours are in 12-hour notation without AM/PM indication: hy_AM,
|
||||||
|
# id_ID, ms_MY.
|
||||||
|
# * Year is not included: ha_NG.
|
||||||
|
# * Use non-Gregorian calendar: lo_LA, thai, th_TH.
|
||||||
|
#
|
||||||
|
# BUG: Generates invalid regexp for br_FR, csb_PL, Arabic.
|
||||||
|
# BUG: Generates regexp that does not match the current date and time
|
||||||
|
# for fa_IR, gez_ER, gez_ET, lzh_TW, my_MM, or_IN, shn_MM, yo_NG.
|
||||||
|
# BUG: Generates regexp that does not match the current date and time
|
||||||
|
# for fa_IR, gez_ER, gez_ET, lzh_TW, my_MM, or_IN, shn_MM, yo_NG,
|
||||||
|
# fr_FR, ja_JP, he_IL, ko_KR, zh_CN, etc.
|
||||||
|
@run_with_locales('LC_TIME', 'C', 'en_US', 'de_DE',
|
||||||
|
'eu_ES', 'mfe_MU')
|
||||||
|
def test_date_time_locale(self):
|
||||||
# Test %c directive
|
# Test %c directive
|
||||||
for position in range(6):
|
now = time.time()
|
||||||
self.helper('c', position)
|
self.roundtrip('%c', slice(0, 6), time.localtime(now))
|
||||||
|
# 1 hour 20 minutes 30 seconds ago
|
||||||
|
self.roundtrip('%c', slice(0, 6), time.localtime(now - 4830))
|
||||||
|
# 12 hours ago
|
||||||
|
self.roundtrip('%c', slice(0, 6), time.localtime(now - 12*3600))
|
||||||
|
# different days of the week
|
||||||
|
for i in range(1, 7):
|
||||||
|
self.roundtrip('%c', slice(0, 6), time.localtime(now - i*24*3600))
|
||||||
|
# different months
|
||||||
|
for i in range(1, 12):
|
||||||
|
self.roundtrip('%c', slice(0, 6), time.localtime(now - i*30*24*3600))
|
||||||
|
# different year
|
||||||
|
self.roundtrip('%c', slice(0, 6), time.localtime(now - 366*24*3600))
|
||||||
|
|
||||||
def test_date(self):
|
# NB: Dates before 1969 do not roundtrip on some locales:
|
||||||
|
# bo_CN, bo_IN, dz_BT, eu_ES, eu_FR.
|
||||||
|
@run_with_locales('LC_TIME', 'C', 'en_US', 'de_DE', 'ja_JP')
|
||||||
|
def test_date_time_locale2(self):
|
||||||
|
# Test %c directive
|
||||||
|
self.roundtrip('%c', slice(0, 6), (1900, 1, 1, 0, 0, 0, 0, 1, 0))
|
||||||
|
|
||||||
|
# NB: Does not roundtrip because use non-Gregorian calendar:
|
||||||
|
# lo_LA, thai, th_TH.
|
||||||
|
# BUG: Generates regexp that does not match the current date
|
||||||
|
# for az_IR, fa_IR, lzh_TW, my_MM, or_IN, shn_MM,
|
||||||
|
# Arabic, ja_JP, ko_KR, zh_CN, etc.
|
||||||
|
@run_with_locales('LC_TIME', 'C', 'en_US', 'fr_FR', 'de_DE',
|
||||||
|
'he_IL', 'eu_ES')
|
||||||
|
def test_date_locale(self):
|
||||||
# Test %x directive
|
# Test %x directive
|
||||||
for position in range(0,3):
|
now = time.time()
|
||||||
self.helper('x', position)
|
self.roundtrip('%x', slice(0, 3), time.localtime(now))
|
||||||
|
# different days of the week
|
||||||
|
for i in range(1, 7):
|
||||||
|
self.roundtrip('%x', slice(0, 3), time.localtime(now - i*24*3600))
|
||||||
|
# different months
|
||||||
|
for i in range(1, 12):
|
||||||
|
self.roundtrip('%x', slice(0, 3), time.localtime(now - i*30*24*3600))
|
||||||
|
# different year
|
||||||
|
self.roundtrip('%x', slice(0, 3), time.localtime(now - 366*24*3600))
|
||||||
|
|
||||||
def test_time(self):
|
# NB: Dates before 1969 do not roundtrip on many locales, including C.
|
||||||
|
@unittest.skipIf(
|
||||||
|
support.is_emscripten or support.is_wasi,
|
||||||
|
"musl libc issue on Emscripten, bpo-46390"
|
||||||
|
)
|
||||||
|
@run_with_locales('LC_TIME', 'en_US', 'fr_FR', 'de_DE', 'ja_JP')
|
||||||
|
def test_date_locale2(self):
|
||||||
|
# Test %x directive
|
||||||
|
self.roundtrip('%x', slice(0, 3), (1900, 1, 1, 0, 0, 0, 0, 1, 0))
|
||||||
|
|
||||||
|
# NB: Does not roundtrip in some locales due to the ambiguity of
|
||||||
|
# the time representation (bugs in locales?):
|
||||||
|
# * Seconds are not included: bokmal, ff_SN, nb_NO, nn_NO, no_NO,
|
||||||
|
# norwegian, nynorsk.
|
||||||
|
# * Hours are in 12-hour notation without AM/PM indication: hy_AM,
|
||||||
|
# ms_MY, sm_WS.
|
||||||
|
# BUG: Generates regexp that does not match the current time for
|
||||||
|
# aa_DJ, aa_ER, aa_ET, am_ET, az_IR, byn_ER, fa_IR, gez_ER, gez_ET,
|
||||||
|
# lzh_TW, my_MM, om_ET, om_KE, or_IN, shn_MM, sid_ET, so_DJ, so_ET,
|
||||||
|
# so_SO, ti_ER, ti_ET, tig_ER, wal_ET.
|
||||||
|
@run_with_locales('LC_TIME', 'C', 'en_US', 'fr_FR', 'de_DE', 'ja_JP')
|
||||||
|
def test_time_locale(self):
|
||||||
# Test %X directive
|
# Test %X directive
|
||||||
for position in range(3,6):
|
now = time.time()
|
||||||
self.helper('X', position)
|
self.roundtrip('%X', slice(3, 6), time.localtime(now))
|
||||||
|
# 1 hour 20 minutes 30 seconds ago
|
||||||
|
self.roundtrip('%X', slice(3, 6), time.localtime(now - 4830))
|
||||||
|
# 12 hours ago
|
||||||
|
self.roundtrip('%X', slice(3, 6), time.localtime(now - 12*3600))
|
||||||
|
|
||||||
def test_percent(self):
|
def test_percent(self):
|
||||||
# Make sure % signs are handled properly
|
# Make sure % signs are handled properly
|
||||||
|
@ -714,12 +810,7 @@ class CacheTests(unittest.TestCase):
|
||||||
|
|
||||||
def test_TimeRE_recreation_locale(self):
|
def test_TimeRE_recreation_locale(self):
|
||||||
# The TimeRE instance should be recreated upon changing the locale.
|
# The TimeRE instance should be recreated upon changing the locale.
|
||||||
locale_info = locale.getlocale(locale.LC_TIME)
|
with support.run_with_locale('LC_TIME', 'en_US.UTF8'):
|
||||||
try:
|
|
||||||
locale.setlocale(locale.LC_TIME, ('en_US', 'UTF8'))
|
|
||||||
except locale.Error:
|
|
||||||
self.skipTest('test needs en_US.UTF8 locale')
|
|
||||||
try:
|
|
||||||
_strptime._strptime_time('10 2004', '%d %Y')
|
_strptime._strptime_time('10 2004', '%d %Y')
|
||||||
# Get id of current cache object.
|
# Get id of current cache object.
|
||||||
first_time_re = _strptime._TimeRE_cache
|
first_time_re = _strptime._TimeRE_cache
|
||||||
|
@ -736,10 +827,6 @@ class CacheTests(unittest.TestCase):
|
||||||
# to the resetting to the original locale.
|
# to the resetting to the original locale.
|
||||||
except locale.Error:
|
except locale.Error:
|
||||||
self.skipTest('test needs de_DE.UTF8 locale')
|
self.skipTest('test needs de_DE.UTF8 locale')
|
||||||
# Make sure we don't trample on the locale setting once we leave the
|
|
||||||
# test.
|
|
||||||
finally:
|
|
||||||
locale.setlocale(locale.LC_TIME, locale_info)
|
|
||||||
|
|
||||||
@support.run_with_tz('STD-1DST,M4.1.0,M10.1.0')
|
@support.run_with_tz('STD-1DST,M4.1.0,M10.1.0')
|
||||||
def test_TimeRE_recreation_timezone(self):
|
def test_TimeRE_recreation_timezone(self):
|
||||||
|
|
|
@ -2,7 +2,6 @@ from test import support
|
||||||
from test.support import warnings_helper
|
from test.support import warnings_helper
|
||||||
import decimal
|
import decimal
|
||||||
import enum
|
import enum
|
||||||
import locale
|
|
||||||
import math
|
import math
|
||||||
import platform
|
import platform
|
||||||
import sys
|
import sys
|
||||||
|
@ -600,17 +599,8 @@ class TimeTestCase(unittest.TestCase):
|
||||||
|
|
||||||
|
|
||||||
class TestLocale(unittest.TestCase):
|
class TestLocale(unittest.TestCase):
|
||||||
def setUp(self):
|
@support.run_with_locale('LC_ALL', 'fr_FR', '')
|
||||||
self.oldloc = locale.setlocale(locale.LC_ALL)
|
|
||||||
|
|
||||||
def tearDown(self):
|
|
||||||
locale.setlocale(locale.LC_ALL, self.oldloc)
|
|
||||||
|
|
||||||
def test_bug_3061(self):
|
def test_bug_3061(self):
|
||||||
try:
|
|
||||||
tmp = locale.setlocale(locale.LC_ALL, "fr_FR")
|
|
||||||
except locale.Error:
|
|
||||||
self.skipTest('could not set locale.LC_ALL to fr_FR')
|
|
||||||
# This should not cause an exception
|
# This should not cause an exception
|
||||||
time.strftime("%B", (2009,2,1,0,0,0,0,0,0))
|
time.strftime("%B", (2009,2,1,0,0,0,0,0,0))
|
||||||
|
|
||||||
|
|
|
@ -398,7 +398,7 @@ class TypesTests(unittest.TestCase):
|
||||||
test(123456, "1=20", '11111111111111123456')
|
test(123456, "1=20", '11111111111111123456')
|
||||||
test(123456, "*=20", '**************123456')
|
test(123456, "*=20", '**************123456')
|
||||||
|
|
||||||
@run_with_locale('LC_NUMERIC', 'en_US.UTF8')
|
@run_with_locale('LC_NUMERIC', 'en_US.UTF8', '')
|
||||||
def test_float__format__locale(self):
|
def test_float__format__locale(self):
|
||||||
# test locale support for __format__ code 'n'
|
# test locale support for __format__ code 'n'
|
||||||
|
|
||||||
|
@ -407,7 +407,7 @@ class TypesTests(unittest.TestCase):
|
||||||
self.assertEqual(locale.format_string('%g', x, grouping=True), format(x, 'n'))
|
self.assertEqual(locale.format_string('%g', x, grouping=True), format(x, 'n'))
|
||||||
self.assertEqual(locale.format_string('%.10g', x, grouping=True), format(x, '.10n'))
|
self.assertEqual(locale.format_string('%.10g', x, grouping=True), format(x, '.10n'))
|
||||||
|
|
||||||
@run_with_locale('LC_NUMERIC', 'en_US.UTF8')
|
@run_with_locale('LC_NUMERIC', 'en_US.UTF8', '')
|
||||||
def test_int__format__locale(self):
|
def test_int__format__locale(self):
|
||||||
# test locale support for __format__ code 'n' for integers
|
# test locale support for __format__ code 'n' for integers
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue