From cb0523e67c1ad82213edaecb0e27d72f1759d02e Mon Sep 17 00:00:00 2001 From: Rohit Mediratta Date: Sun, 1 Nov 2015 01:02:39 -0700 Subject: [PATCH 01/25] Increased test coverage of calendar module --- Lib/test/test_calendar.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_calendar.py b/Lib/test/test_calendar.py index f76cbc9472a6e8..e60326e292f30a 100644 --- a/Lib/test/test_calendar.py +++ b/Lib/test/test_calendar.py @@ -546,17 +546,20 @@ def test_locale_calendars(self): # (it is still not thread-safe though) old_october = calendar.TextCalendar().formatmonthname(2010, 10, 10) try: - cal = calendar.LocaleTextCalendar(locale='') + cal = calendar.LocaleTextCalendar(locale=None) local_weekday = cal.formatweekday(1, 10) + local_weekday_abbr = cal.formatweekday(1, 3) local_month = cal.formatmonthname(2010, 10, 10) except locale.Error: # cannot set the system default locale -- skip rest of test raise unittest.SkipTest('cannot set the system default locale') self.assertIsInstance(local_weekday, str) + self.assertIsInstance(local_weekday_abbr, str) self.assertIsInstance(local_month, str) self.assertEqual(len(local_weekday), 10) + self.assertEqual(len(local_weekday_abbr), 3) self.assertGreaterEqual(len(local_month), 10) - cal = calendar.LocaleHTMLCalendar(locale='') + cal = calendar.LocaleHTMLCalendar(locale=None) local_weekday = cal.formatweekday(1) local_month = cal.formatmonthname(2010, 10) self.assertIsInstance(local_weekday, str) From 78935daf5a83fc96c1cba9dbd4f2b76165c74149 Mon Sep 17 00:00:00 2001 From: Bart Skowron Date: Mon, 6 Jun 2022 23:24:26 +0200 Subject: [PATCH 02/25] gh-69714: Restore the test thrown out by cb0523e67c --- Lib/test/test_calendar.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/Lib/test/test_calendar.py b/Lib/test/test_calendar.py index e60326e292f30a..07126a2bf4deb3 100644 --- a/Lib/test/test_calendar.py +++ b/Lib/test/test_calendar.py @@ -559,11 +559,27 @@ def test_locale_calendars(self): self.assertEqual(len(local_weekday), 10) self.assertEqual(len(local_weekday_abbr), 3) self.assertGreaterEqual(len(local_month), 10) + + cal = calendar.LocaleTextCalendar(locale='') + local_weekday = cal.formatweekday(1, 10) + local_month = cal.formatmonthname(2010, 10, 10) + self.assertIsInstance(local_weekday, str) + self.assertIsInstance(local_month, str) + self.assertEqual(len(local_weekday), 10) + self.assertGreaterEqual(len(local_month), 10) + cal = calendar.LocaleHTMLCalendar(locale=None) local_weekday = cal.formatweekday(1) local_month = cal.formatmonthname(2010, 10) self.assertIsInstance(local_weekday, str) self.assertIsInstance(local_month, str) + + cal = calendar.LocaleHTMLCalendar(locale='') + local_weekday = cal.formatweekday(1) + local_month = cal.formatmonthname(2010, 10) + self.assertIsInstance(local_weekday, str) + self.assertIsInstance(local_month, str) + new_october = calendar.TextCalendar().formatmonthname(2010, 10, 10) self.assertEqual(old_october, new_october) From 0dd6321fea80e87931064e0e8521dd79822efc9a Mon Sep 17 00:00:00 2001 From: Bart Skowron Date: Mon, 6 Jun 2022 23:33:12 +0200 Subject: [PATCH 03/25] gh-69714: Increase test coverage for `calendar.Locale{Text|HTML}Calendar(locale='')` --- Lib/test/test_calendar.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Lib/test/test_calendar.py b/Lib/test/test_calendar.py index 07126a2bf4deb3..60c76e9307e584 100644 --- a/Lib/test/test_calendar.py +++ b/Lib/test/test_calendar.py @@ -562,10 +562,13 @@ def test_locale_calendars(self): cal = calendar.LocaleTextCalendar(locale='') local_weekday = cal.formatweekday(1, 10) + local_weekday_abbr = cal.formatweekday(1, 3) local_month = cal.formatmonthname(2010, 10, 10) self.assertIsInstance(local_weekday, str) + self.assertIsInstance(local_weekday_abbr, str) self.assertIsInstance(local_month, str) self.assertEqual(len(local_weekday), 10) + self.assertEqual(len(local_weekday_abbr), 3) self.assertGreaterEqual(len(local_month), 10) cal = calendar.LocaleHTMLCalendar(locale=None) From 69c8f4fdbcb453ddbac0779a9287c23cd86df885 Mon Sep 17 00:00:00 2001 From: Bart Skowron Date: Tue, 7 Jun 2022 02:24:14 +0200 Subject: [PATCH 04/25] gh-69714: Add missing test cases for custom locale in `calendar.Locale{Text|HTML}Calendar` There are 3 paths to use `locale` argument in `calendar.Locale{Text|HTML}Calendar.__init__(..., locale=None)`: (1) `locale=None` -- denotes the "default locale"[1] (2) `locale=""` -- denotes the native environment (3) `locale=other_valid_locale` -- denotes a custom locale So far case (2) is covered and case (1) is in 78935daf5a (same branch). This commit adds a remaining case (3). [1] In the current implementation, this translates into the following approach: GET current locale IF current locale == "C" THEN SET current locale TO "" GET current locale ENDIF --- Lib/test/test_calendar.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/Lib/test/test_calendar.py b/Lib/test/test_calendar.py index 60c76e9307e584..8068607e0164e8 100644 --- a/Lib/test/test_calendar.py +++ b/Lib/test/test_calendar.py @@ -571,6 +571,17 @@ def test_locale_calendars(self): self.assertEqual(len(local_weekday_abbr), 3) self.assertGreaterEqual(len(local_month), 10) + cal = calendar.LocaleTextCalendar(locale='C') + local_weekday = cal.formatweekday(1, 10) + local_weekday_abbr = cal.formatweekday(1, 3) + local_month = cal.formatmonthname(2010, 10, 10) + self.assertIsInstance(local_weekday, str) + self.assertIsInstance(local_weekday_abbr, str) + self.assertIsInstance(local_month, str) + self.assertEqual(len(local_weekday), 10) + self.assertEqual(len(local_weekday_abbr), 3) + self.assertGreaterEqual(len(local_month), 10) + cal = calendar.LocaleHTMLCalendar(locale=None) local_weekday = cal.formatweekday(1) local_month = cal.formatmonthname(2010, 10) @@ -583,6 +594,12 @@ def test_locale_calendars(self): self.assertIsInstance(local_weekday, str) self.assertIsInstance(local_month, str) + cal = calendar.LocaleHTMLCalendar(locale='C') + local_weekday = cal.formatweekday(1) + local_month = cal.formatmonthname(2010, 10) + self.assertIsInstance(local_weekday, str) + self.assertIsInstance(local_month, str) + new_october = calendar.TextCalendar().formatmonthname(2010, 10, 10) self.assertEqual(old_october, new_october) From a96786cc1fe9de9f051884ed66e75b87c7fde1ba Mon Sep 17 00:00:00 2001 From: Bart Skowron Date: Tue, 7 Jun 2022 02:25:01 +0200 Subject: [PATCH 05/25] gh-69714: Remove unreachable code (and increase test coverage) This condition cannot be true. `_locale.setlocale()` from the C module raises `locale.Error` instead of returning `None` for `different_locale.__enter__` (where `self.oldlocale` is set). --- Lib/calendar.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/Lib/calendar.py b/Lib/calendar.py index 657396439c91fc..cb49aa976ec06e 100644 --- a/Lib/calendar.py +++ b/Lib/calendar.py @@ -555,8 +555,6 @@ def __enter__(self): _locale.setlocale(_locale.LC_TIME, self.locale) def __exit__(self, *args): - if self.oldlocale is None: - return _locale.setlocale(_locale.LC_TIME, self.oldlocale) From 636b4e155b4c8e5e2a0ab03c8fd3cf51a9cdb75d Mon Sep 17 00:00:00 2001 From: Bart Skowron Date: Thu, 9 Jun 2022 02:16:43 +0200 Subject: [PATCH 06/25] gh-69714: Increase CLI tests coverage --- Lib/calendar.py | 6 +- Lib/test/test_calendar.py | 151 +++++++++++++++++++++++++++----------- 2 files changed, 110 insertions(+), 47 deletions(-) diff --git a/Lib/calendar.py b/Lib/calendar.py index cb49aa976ec06e..3edb578d560dc7 100644 --- a/Lib/calendar.py +++ b/Lib/calendar.py @@ -658,7 +658,7 @@ def timegm(tuple): return seconds -def main(args): +def main(args=None): import argparse parser = argparse.ArgumentParser() textgroup = parser.add_argument_group('text only arguments') @@ -715,7 +715,7 @@ def main(args): help="month number (1-12, text only)" ) - options = parser.parse_args(args[1:]) + options = parser.parse_args(args) if options.locale and not options.encoding: parser.error("if --locale is specified --encoding is required") @@ -763,4 +763,4 @@ def main(args): if __name__ == "__main__": - main(sys.argv) + main() diff --git a/Lib/test/test_calendar.py b/Lib/test/test_calendar.py index 8068607e0164e8..47df030814552b 100644 --- a/Lib/test/test_calendar.py +++ b/Lib/test/test_calendar.py @@ -3,11 +3,13 @@ from test import support from test.support.script_helper import assert_python_ok, assert_python_failure -import time -import locale -import sys +import contextlib import datetime +import io +import locale import os +import sys +import time # From https://en.wikipedia.org/wiki/Leap_year_starting_on_Saturday result_0_02_text = """\ @@ -861,20 +863,71 @@ def conv(s): return s.replace('\n', os.linesep).encode() class CommandLineTestCase(unittest.TestCase): - def run_ok(self, *args): + def setUp(self): + self.runners = [self.run_cli_ok, self.run_cmd_ok] + + @contextlib.contextmanager + def captured_stdout_with_buffer(self): + orig_stdout = sys.stdout + buffer = io.BytesIO() + sys.stdout = io.TextIOWrapper(buffer) + try: + yield sys.stdout + finally: + sys.stdout.flush() + sys.stdout.buffer.seek(0, 0) + sys.stdout = orig_stdout + + @contextlib.contextmanager + def captured_stderr_with_buffer(self): + orig_stderr = sys.stderr + buffer = io.BytesIO() + sys.stderr = io.TextIOWrapper(buffer) + try: + yield sys.stderr + finally: + sys.stderr.flush() + sys.stderr.buffer.seek(0, 0) + sys.stderr= orig_stderr + + def run_cli_ok(self, *args): + with self.captured_stdout_with_buffer() as stdout: + calendar.main(args) + return stdout.buffer.read() + + def run_cmd_ok(self, *args): return assert_python_ok('-m', 'calendar', *args)[1] - def assertFailure(self, *args): + def assertCLIFails(self, *args): + with self.captured_stderr_with_buffer() as stderr: + self.assertRaises(SystemExit, calendar.main, args) + stderr = stderr.buffer.read() + self.assertIn(b'usage:', stderr) + return stderr + + def assertCmdFails(self, *args): rc, stdout, stderr = assert_python_failure('-m', 'calendar', *args) self.assertIn(b'usage:', stderr) self.assertEqual(rc, 2) + return rc, stdout, stderr + + def assertFailure(self, *args): + self.assertCLIFails(*args) + self.assertCmdFails(*args) def test_help(self): - stdout = self.run_ok('-h') + stdout = self.run_cmd_ok('-h') self.assertIn(b'usage:', stdout) self.assertIn(b'calendar.py', stdout) self.assertIn(b'--help', stdout) + # special case: stdout but sys.exit() + with self.captured_stdout_with_buffer() as output: + self.assertRaises(SystemExit, calendar.main, ['-h']) + output = output.buffer.read() + self.assertIn(b'usage:', output) + self.assertIn(b'--help', output) + def test_illegal_arguments(self): self.assertFailure('-z') self.assertFailure('spam') @@ -882,25 +935,29 @@ def test_illegal_arguments(self): self.assertFailure('-t', 'html', '2004', '1') def test_output_current_year(self): - stdout = self.run_ok() - year = datetime.datetime.now().year - self.assertIn((' %s' % year).encode(), stdout) - self.assertIn(b'January', stdout) - self.assertIn(b'Mo Tu We Th Fr Sa Su', stdout) + for run in self.runners: + output = run() + year = datetime.datetime.now().year + self.assertIn(conv(' %s' % year), output) + self.assertIn(b'January', output) + self.assertIn(b'Mo Tu We Th Fr Sa Su', output) def test_output_year(self): - stdout = self.run_ok('2004') - self.assertEqual(stdout, conv(result_2004_text)) + for run in self.runners: + output = run('2004') + self.assertEqual(output, conv(result_2004_text)) def test_output_month(self): - stdout = self.run_ok('2004', '1') - self.assertEqual(stdout, conv(result_2004_01_text)) + for run in self.runners: + output = run('2004', '1') + self.assertEqual(output, conv(result_2004_01_text)) def test_option_encoding(self): self.assertFailure('-e') self.assertFailure('--encoding') - stdout = self.run_ok('--encoding', 'utf-16-le', '2004') - self.assertEqual(stdout, result_2004_text.encode('utf-16-le')) + for run in self.runners: + output = run('--encoding', 'utf-16-le', '2004') + self.assertEqual(output, result_2004_text.encode('utf-16-le')) def test_option_locale(self): self.assertFailure('-L') @@ -918,66 +975,72 @@ def test_option_locale(self): locale.setlocale(locale.LC_TIME, oldlocale) except (locale.Error, ValueError): self.skipTest('cannot set the system default locale') - stdout = self.run_ok('--locale', lang, '--encoding', enc, '2004') - self.assertIn('2004'.encode(enc), stdout) + for run in self.runners: + output = run('--locale', lang, '--encoding', enc, '2004') + self.assertIn('2004'.encode(enc), output) def test_option_width(self): self.assertFailure('-w') self.assertFailure('--width') self.assertFailure('-w', 'spam') - stdout = self.run_ok('--width', '3', '2004') - self.assertIn(b'Mon Tue Wed Thu Fri Sat Sun', stdout) + for run in self.runners: + output = run('--width', '3', '2004') + self.assertIn(b'Mon Tue Wed Thu Fri Sat Sun', output) def test_option_lines(self): self.assertFailure('-l') self.assertFailure('--lines') self.assertFailure('-l', 'spam') - stdout = self.run_ok('--lines', '2', '2004') - self.assertIn(conv('December\n\nMo Tu We'), stdout) + for run in self.runners: + output = run('--lines', '2', '2004') + self.assertIn(conv('December\n\nMo Tu We'), output) def test_option_spacing(self): self.assertFailure('-s') self.assertFailure('--spacing') self.assertFailure('-s', 'spam') - stdout = self.run_ok('--spacing', '8', '2004') - self.assertIn(b'Su Mo', stdout) + for run in self.runners: + output = run('--spacing', '8', '2004') + self.assertIn(b'Su Mo', output) def test_option_months(self): self.assertFailure('-m') self.assertFailure('--month') self.assertFailure('-m', 'spam') - stdout = self.run_ok('--months', '1', '2004') - self.assertIn(conv('\nMo Tu We Th Fr Sa Su\n'), stdout) + for run in self.runners: + output = run('--months', '1', '2004') + self.assertIn(conv('\nMo Tu We Th Fr Sa Su\n'), output) def test_option_type(self): self.assertFailure('-t') self.assertFailure('--type') self.assertFailure('-t', 'spam') - stdout = self.run_ok('--type', 'text', '2004') - self.assertEqual(stdout, conv(result_2004_text)) - stdout = self.run_ok('--type', 'html', '2004') - self.assertEqual(stdout[:6], b'Calendar for 2004', stdout) + for run in self.runners: + output = run('--type', 'text', '2004') + self.assertEqual(output, conv(result_2004_text)) + output = run('--type', 'html', '2004') + self.assertEqual(output[:6], b'Calendar for 2004', output) def test_html_output_current_year(self): - stdout = self.run_ok('--type', 'html') - year = datetime.datetime.now().year - self.assertIn(('Calendar for %s' % year).encode(), - stdout) - self.assertIn(b'January', - stdout) + for run in self.runners: + output = run('--type', 'html') + year = datetime.datetime.now().year + self.assertIn(('Calendar for %s' % year).encode(), output) + self.assertIn(b'January', output) def test_html_output_year_encoding(self): - stdout = self.run_ok('-t', 'html', '--encoding', 'ascii', '2004') - self.assertEqual(stdout, - result_2004_html.format(**default_format).encode('ascii')) + for run in self.runners: + output = run('-t', 'html', '--encoding', 'ascii', '2004') + self.assertEqual(output, result_2004_html.format(**default_format).encode('ascii')) def test_html_output_year_css(self): self.assertFailure('-t', 'html', '-c') self.assertFailure('-t', 'html', '--css') - stdout = self.run_ok('-t', 'html', '--css', 'custom.css', '2004') - self.assertIn(b'', stdout) + for run in self.runners: + output = run('-t', 'html', '--css', 'custom.css', '2004') + self.assertIn(b'', output) class MiscTestCase(unittest.TestCase): From 238c5271226f500b4b395dfcd8d05aa998870390 Mon Sep 17 00:00:00 2001 From: Bart Skowron Date: Thu, 9 Jun 2022 02:17:45 +0200 Subject: [PATCH 07/25] gh-69714: Add more test cases to `calendar` cmdline --- Lib/test/test_calendar.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Lib/test/test_calendar.py b/Lib/test/test_calendar.py index 47df030814552b..5df66f505e81ea 100644 --- a/Lib/test/test_calendar.py +++ b/Lib/test/test_calendar.py @@ -934,6 +934,15 @@ def test_illegal_arguments(self): self.assertFailure('2004', 'spam') self.assertFailure('-t', 'html', '2004', '1') + def test_too_many_arguments(self): + stderr = self.assertCmdFails('--type', 'html', '2004', '5')[2] + self.assertIn(b'error', stderr) + self.assertIn(b'incorrect number of arguments', stderr) + + stderr = self.assertCLIFails('--type', 'html', '2004', '5') + self.assertIn(b'error', stderr) + self.assertIn(b'incorrect number of arguments', stderr) + def test_output_current_year(self): for run in self.runners: output = run() From b850c92c01ea8c4922494d6e93f48f9092af8f17 Mon Sep 17 00:00:00 2001 From: Bart Skowron Date: Thu, 9 Jun 2022 02:20:47 +0200 Subject: [PATCH 08/25] gh-69714: Increase test coverage for `calendar` cmdline --- Lib/test/test_calendar.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_calendar.py b/Lib/test/test_calendar.py index 5df66f505e81ea..39b47e6fa39ca8 100644 --- a/Lib/test/test_calendar.py +++ b/Lib/test/test_calendar.py @@ -985,8 +985,11 @@ def test_option_locale(self): except (locale.Error, ValueError): self.skipTest('cannot set the system default locale') for run in self.runners: - output = run('--locale', lang, '--encoding', enc, '2004') - self.assertIn('2004'.encode(enc), output) + for type in ('text', 'html'): + output = run( + '--type', type, '--locale', lang, '--encoding', enc, '2004' + ) + self.assertIn('2004'.encode(enc), output) def test_option_width(self): self.assertFailure('-w') From ab069a4a857a182a87fa9ad9b3c893b48ce16ce8 Mon Sep 17 00:00:00 2001 From: Jessica McKellar Date: Sun, 27 Apr 2014 13:28:25 -0700 Subject: [PATCH 09/25] gh-57539: Add tests for `LocaleTextCalendar.formatweekday` This patch has already been applied to `main` branch (via gh-93468), but with wrong copyright. After merging this commit to `main`, git `Author` metadata will be updated to the original author. --- Lib/test/test_calendar.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Lib/test/test_calendar.py b/Lib/test/test_calendar.py index 39b47e6fa39ca8..b7cbe740119cad 100644 --- a/Lib/test/test_calendar.py +++ b/Lib/test/test_calendar.py @@ -605,6 +605,16 @@ def test_locale_calendars(self): new_october = calendar.TextCalendar().formatmonthname(2010, 10, 10) self.assertEqual(old_october, new_october) + def test_locale_calendar_formatweekday(self): + # formatweekday uses different day names based on the available width. + cal = calendar.LocaleTextCalendar(locale='en_US') + # For short widths, a centered, abbreviated name is used. + self.assertEqual(cal.formatweekday(0, 5), " Mon ") + # For really short widths, even the abbreviated name is truncated. + self.assertEqual(cal.formatweekday(0, 2), "Mo") + # For long widths, the full day name is used. + self.assertEqual(cal.formatweekday(0, 10), " Monday ") + def test_locale_html_calendar_custom_css_class_month_name(self): try: cal = calendar.LocaleHTMLCalendar(locale='') From f1febfc7aa7c3414641d0b2f37824e7de8025e10 Mon Sep 17 00:00:00 2001 From: Bart Skowron Date: Thu, 9 Jun 2022 18:52:22 +0200 Subject: [PATCH 10/25] gh-69714: Increase test coverage for `LocaleTextCalendar.formatmonthname` --- Lib/test/test_calendar.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/Lib/test/test_calendar.py b/Lib/test/test_calendar.py index b7cbe740119cad..117e27265fe872 100644 --- a/Lib/test/test_calendar.py +++ b/Lib/test/test_calendar.py @@ -615,6 +615,20 @@ def test_locale_calendar_formatweekday(self): # For long widths, the full day name is used. self.assertEqual(cal.formatweekday(0, 10), " Monday ") + def test_locale_calendar_formatmonthname(self): + try: + # formatmonthname uses the same month names regardless of the width argument. + cal = calendar.LocaleTextCalendar(locale='en_US') + except locale.Error: + # cannot set the system default locale -- skip rest of test + raise unittest.SkipTest('cannot set the en_US locale') + # For too short widths, a full name (with year) is used. + self.assertEqual(cal.formatmonthname(2022, 6, 2, withyear=False), "June") + self.assertEqual(cal.formatmonthname(2022, 6, 2, withyear=True), "June 2022") + # For long widths, a centered name is used. + self.assertEqual(cal.formatmonthname(2022, 6, 10, withyear=False), " June ") + self.assertEqual(cal.formatmonthname(2022, 6, 15, withyear=True), " June 2022 ") + def test_locale_html_calendar_custom_css_class_month_name(self): try: cal = calendar.LocaleHTMLCalendar(locale='') From 827e664571e84723e0e2caa8b9f5498ec2aebe4d Mon Sep 17 00:00:00 2001 From: Bart Skowron Date: Thu, 9 Jun 2022 20:43:13 +0200 Subject: [PATCH 11/25] Remove comment Co-authored-by: Adam Turner <9087854+AA-Turner@users.noreply.github.com> --- Lib/test/test_calendar.py | 1 - 1 file changed, 1 deletion(-) diff --git a/Lib/test/test_calendar.py b/Lib/test/test_calendar.py index 34c48116d0ecf1..03e365b4465078 100644 --- a/Lib/test/test_calendar.py +++ b/Lib/test/test_calendar.py @@ -623,7 +623,6 @@ def test_locale_calendar_formatmonthname(self): # formatmonthname uses the same month names regardless of the width argument. cal = calendar.LocaleTextCalendar(locale='en_US') except locale.Error: - # cannot set the system default locale -- skip rest of test raise unittest.SkipTest('cannot set the en_US locale') # For too short widths, a full name (with year) is used. self.assertEqual(cal.formatmonthname(2022, 6, 2, withyear=False), "June") From d28e2e4b0a1218444e30d3cf9d36e891608e576c Mon Sep 17 00:00:00 2001 From: Bart Skowron Date: Thu, 9 Jun 2022 21:24:32 +0200 Subject: [PATCH 12/25] gh-69714: Reorder locale in the test case --- Lib/test/test_calendar.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Lib/test/test_calendar.py b/Lib/test/test_calendar.py index 03e365b4465078..d64d9d94909892 100644 --- a/Lib/test/test_calendar.py +++ b/Lib/test/test_calendar.py @@ -548,7 +548,7 @@ def test_locale_calendars(self): # (it is still not thread-safe though) old_october = calendar.TextCalendar().formatmonthname(2010, 10, 10) try: - cal = calendar.LocaleTextCalendar(locale=None) + cal = calendar.LocaleTextCalendar(locale='') local_weekday = cal.formatweekday(1, 10) local_weekday_abbr = cal.formatweekday(1, 3) local_month = cal.formatmonthname(2010, 10, 10) @@ -562,7 +562,7 @@ def test_locale_calendars(self): self.assertEqual(len(local_weekday_abbr), 3) self.assertGreaterEqual(len(local_month), 10) - cal = calendar.LocaleTextCalendar(locale='') + cal = calendar.LocaleTextCalendar(locale=None) local_weekday = cal.formatweekday(1, 10) local_weekday_abbr = cal.formatweekday(1, 3) local_month = cal.formatmonthname(2010, 10, 10) @@ -584,13 +584,13 @@ def test_locale_calendars(self): self.assertEqual(len(local_weekday_abbr), 3) self.assertGreaterEqual(len(local_month), 10) - cal = calendar.LocaleHTMLCalendar(locale=None) + cal = calendar.LocaleHTMLCalendar(locale='') local_weekday = cal.formatweekday(1) local_month = cal.formatmonthname(2010, 10) self.assertIsInstance(local_weekday, str) self.assertIsInstance(local_month, str) - cal = calendar.LocaleHTMLCalendar(locale='') + cal = calendar.LocaleHTMLCalendar(locale=None) local_weekday = cal.formatweekday(1) local_month = cal.formatmonthname(2010, 10) self.assertIsInstance(local_weekday, str) From bbdc3930678c1c22d8c9ed8e365f180d47e566a1 Mon Sep 17 00:00:00 2001 From: Bart Skowron Date: Thu, 9 Jun 2022 21:25:51 +0200 Subject: [PATCH 13/25] gh-69714: Extract test case --- Lib/test/test_calendar.py | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/Lib/test/test_calendar.py b/Lib/test/test_calendar.py index d64d9d94909892..fb384fc0c78b77 100644 --- a/Lib/test/test_calendar.py +++ b/Lib/test/test_calendar.py @@ -544,9 +544,6 @@ def test_months(self): self.assertEqual(value[::-1], list(reversed(value))) def test_locale_calendars(self): - # ensure that Locale{Text,HTML}Calendar resets the locale properly - # (it is still not thread-safe though) - old_october = calendar.TextCalendar().formatmonthname(2010, 10, 10) try: cal = calendar.LocaleTextCalendar(locale='') local_weekday = cal.formatweekday(1, 10) @@ -602,6 +599,31 @@ def test_locale_calendars(self): self.assertIsInstance(local_weekday, str) self.assertIsInstance(local_month, str) + def test_locale_calendars_reset_locale_properly(self): + # ensure that Locale{Text,HTML}Calendar resets the locale properly + # (it is still not thread-safe though) + old_october = calendar.TextCalendar().formatmonthname(2010, 10, 10) + try: + cal = calendar.LocaleTextCalendar(locale='') + local_weekday = cal.formatweekday(1, 10) + local_weekday_abbr = cal.formatweekday(1, 3) + local_month = cal.formatmonthname(2010, 10, 10) + except locale.Error: + # cannot set the system default locale -- skip rest of test + raise unittest.SkipTest('cannot set the system default locale') + self.assertIsInstance(local_weekday, str) + self.assertIsInstance(local_weekday_abbr, str) + self.assertIsInstance(local_month, str) + self.assertEqual(len(local_weekday), 10) + self.assertEqual(len(local_weekday_abbr), 3) + self.assertGreaterEqual(len(local_month), 10) + + cal = calendar.LocaleHTMLCalendar(locale='') + local_weekday = cal.formatweekday(1) + local_month = cal.formatmonthname(2010, 10) + self.assertIsInstance(local_weekday, str) + self.assertIsInstance(local_month, str) + new_october = calendar.TextCalendar().formatmonthname(2010, 10, 10) self.assertEqual(old_october, new_october) From 8914cdca8dfeda9cf5f8f66dadb413cc46178a73 Mon Sep 17 00:00:00 2001 From: Bart Skowron Date: Thu, 9 Jun 2022 21:29:21 +0200 Subject: [PATCH 14/25] Update ACKS --- Misc/ACKS | 1 + 1 file changed, 1 insertion(+) diff --git a/Misc/ACKS b/Misc/ACKS index c3a4f9b9dededd..510bb19b51e5b7 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -1664,6 +1664,7 @@ Ngalim Siregar Kragen Sitaker Kaartic Sivaraam Stanisław Skonieczny +Bart Skowron Roman Skurikhin Ville Skyttä Michael Sloan From 68adf694380b4f7b94a65019483e870057774200 Mon Sep 17 00:00:00 2001 From: Bart Skowron Date: Thu, 9 Jun 2022 21:37:36 +0200 Subject: [PATCH 15/25] Add NEWS entry --- .../next/Tests/2022-06-09-21-27-38.gh-issue-69714.49tyHW.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Tests/2022-06-09-21-27-38.gh-issue-69714.49tyHW.rst diff --git a/Misc/NEWS.d/next/Tests/2022-06-09-21-27-38.gh-issue-69714.49tyHW.rst b/Misc/NEWS.d/next/Tests/2022-06-09-21-27-38.gh-issue-69714.49tyHW.rst new file mode 100644 index 00000000000000..e28b94a171c40e --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2022-06-09-21-27-38.gh-issue-69714.49tyHW.rst @@ -0,0 +1 @@ +Add additional tests to :mod:`calendar` to achieve full test coverage. From 40e0da34fdc0a7a3484039fd37ae0e0d68d157c1 Mon Sep 17 00:00:00 2001 From: Bart Skowron Date: Thu, 9 Jun 2022 22:43:40 +0200 Subject: [PATCH 16/25] Revert "gh-69714: Remove unreachable code (and increase test coverage)" This reverts commit a96786cc1fe9de9f051884ed66e75b87c7fde1ba. --- Lib/calendar.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Lib/calendar.py b/Lib/calendar.py index 3edb578d560dc7..3d9261b4480d49 100644 --- a/Lib/calendar.py +++ b/Lib/calendar.py @@ -555,6 +555,8 @@ def __enter__(self): _locale.setlocale(_locale.LC_TIME, self.locale) def __exit__(self, *args): + if self.oldlocale is None: + return _locale.setlocale(_locale.LC_TIME, self.oldlocale) From 2b6f1f9b2d8cf8d2c2054a7d69b95f04efa2cbd0 Mon Sep 17 00:00:00 2001 From: Bart Skowron Date: Fri, 10 Jun 2022 01:01:59 +0200 Subject: [PATCH 17/25] Expand the try clause to calls to `LocaleTextCalendar.formatmonthname()`. This method temporarily changes the current locale to the given locale, so `_locale.setlocale()` may raise `local.Error`. --- Lib/test/test_calendar.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Lib/test/test_calendar.py b/Lib/test/test_calendar.py index fb384fc0c78b77..d912944c700e77 100644 --- a/Lib/test/test_calendar.py +++ b/Lib/test/test_calendar.py @@ -644,14 +644,14 @@ def test_locale_calendar_formatmonthname(self): try: # formatmonthname uses the same month names regardless of the width argument. cal = calendar.LocaleTextCalendar(locale='en_US') + # For too short widths, a full name (with year) is used. + self.assertEqual(cal.formatmonthname(2022, 6, 2, withyear=False), "June") + self.assertEqual(cal.formatmonthname(2022, 6, 2, withyear=True), "June 2022") + # For long widths, a centered name is used. + self.assertEqual(cal.formatmonthname(2022, 6, 10, withyear=False), " June ") + self.assertEqual(cal.formatmonthname(2022, 6, 15, withyear=True), " June 2022 ") except locale.Error: raise unittest.SkipTest('cannot set the en_US locale') - # For too short widths, a full name (with year) is used. - self.assertEqual(cal.formatmonthname(2022, 6, 2, withyear=False), "June") - self.assertEqual(cal.formatmonthname(2022, 6, 2, withyear=True), "June 2022") - # For long widths, a centered name is used. - self.assertEqual(cal.formatmonthname(2022, 6, 10, withyear=False), " June ") - self.assertEqual(cal.formatmonthname(2022, 6, 15, withyear=True), " June 2022 ") def test_locale_html_calendar_custom_css_class_month_name(self): try: From 64cb0290d84c8bf7eea1223677fc367855ffbd78 Mon Sep 17 00:00:00 2001 From: Bart Skowron Date: Fri, 10 Jun 2022 01:42:16 +0200 Subject: [PATCH 18/25] Revert "Revert "gh-69714: Remove unreachable code (and increase test coverage)"" This reverts commit 40e0da34fdc0a7a3484039fd37ae0e0d68d157c1. So it brings back commit a96786cc1fe9de9f051884ed66e75b87c7fde1ba. --- Lib/calendar.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/Lib/calendar.py b/Lib/calendar.py index 3d9261b4480d49..3edb578d560dc7 100644 --- a/Lib/calendar.py +++ b/Lib/calendar.py @@ -555,8 +555,6 @@ def __enter__(self): _locale.setlocale(_locale.LC_TIME, self.locale) def __exit__(self, *args): - if self.oldlocale is None: - return _locale.setlocale(_locale.LC_TIME, self.oldlocale) From 2b2c8ef502f129b8ac8785118cec64df28f952de Mon Sep 17 00:00:00 2001 From: Bart Skowron Date: Fri, 10 Jun 2022 02:15:33 +0200 Subject: [PATCH 19/25] Add missing whitespace --- Lib/test/test_calendar.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/test/test_calendar.py b/Lib/test/test_calendar.py index d912944c700e77..358a8192121ee7 100644 --- a/Lib/test/test_calendar.py +++ b/Lib/test/test_calendar.py @@ -936,7 +936,7 @@ def captured_stderr_with_buffer(self): finally: sys.stderr.flush() sys.stderr.buffer.seek(0, 0) - sys.stderr= orig_stderr + sys.stderr = orig_stderr def run_cli_ok(self, *args): with self.captured_stdout_with_buffer() as stdout: From 8b7bc065ef7864ca417d6accd51296c5935317d5 Mon Sep 17 00:00:00 2001 From: Bart Skowron Date: Sat, 11 Jun 2022 19:26:16 +0200 Subject: [PATCH 20/25] gh-69714: Move the validation to the beginning of the function No need to process the function. This also helps in supporting CLI testing. --- Lib/calendar.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Lib/calendar.py b/Lib/calendar.py index 3edb578d560dc7..961a062fae4ccd 100644 --- a/Lib/calendar.py +++ b/Lib/calendar.py @@ -724,6 +724,9 @@ def main(args=None): locale = options.locale, options.encoding if options.type == "html": + if options.month: + parser.error("incorrect number of arguments") + sys.exit(1) if options.locale: cal = LocaleHTMLCalendar(locale=locale) else: @@ -735,11 +738,8 @@ def main(args=None): write = sys.stdout.buffer.write if options.year is None: write(cal.formatyearpage(datetime.date.today().year, **optdict)) - elif options.month is None: - write(cal.formatyearpage(options.year, **optdict)) else: - parser.error("incorrect number of arguments") - sys.exit(1) + write(cal.formatyearpage(options.year, **optdict)) else: if options.locale: cal = LocaleTextCalendar(locale=locale) From de21a518f308d6ca588a90eb82f6aa3bfbc8842e Mon Sep 17 00:00:00 2001 From: Bart Skowron Date: Sat, 11 Jun 2022 19:44:25 +0200 Subject: [PATCH 21/25] gh-69714: Increase test coverage for illegal arguments --- Lib/test/test_calendar.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Lib/test/test_calendar.py b/Lib/test/test_calendar.py index 358a8192121ee7..89cd5e5d7e2087 100644 --- a/Lib/test/test_calendar.py +++ b/Lib/test/test_calendar.py @@ -980,6 +980,9 @@ def test_illegal_arguments(self): self.assertFailure('-z') self.assertFailure('spam') self.assertFailure('2004', 'spam') + self.assertFailure('2004', '1', 'spam') + self.assertFailure('2004', '1', '1') + self.assertFailure('2004', '1', '1', 'spam') self.assertFailure('-t', 'html', '2004', '1') def test_too_many_arguments(self): From ab5a508488b663df7f16e20a93d537c929f90095 Mon Sep 17 00:00:00 2001 From: Bart Skowron Date: Sat, 11 Jun 2022 19:46:31 +0200 Subject: [PATCH 22/25] Revert "gh-69714: Add more test cases to `calendar` cmdline" These tests are now part of `test_illegal_arguments`. This reverts commit 238c5271226f500b4b395dfcd8d05aa998870390. --- Lib/test/test_calendar.py | 9 --------- 1 file changed, 9 deletions(-) diff --git a/Lib/test/test_calendar.py b/Lib/test/test_calendar.py index 89cd5e5d7e2087..38db9a4b5b3045 100644 --- a/Lib/test/test_calendar.py +++ b/Lib/test/test_calendar.py @@ -985,15 +985,6 @@ def test_illegal_arguments(self): self.assertFailure('2004', '1', '1', 'spam') self.assertFailure('-t', 'html', '2004', '1') - def test_too_many_arguments(self): - stderr = self.assertCmdFails('--type', 'html', '2004', '5')[2] - self.assertIn(b'error', stderr) - self.assertIn(b'incorrect number of arguments', stderr) - - stderr = self.assertCLIFails('--type', 'html', '2004', '5') - self.assertIn(b'error', stderr) - self.assertIn(b'incorrect number of arguments', stderr) - def test_output_current_year(self): for run in self.runners: output = run() From 1558845bc8754563be88733af52584033a548226 Mon Sep 17 00:00:00 2001 From: Bart Skowron Date: Sat, 11 Jun 2022 19:49:36 +0200 Subject: [PATCH 23/25] Clean up redundant arguments --- Lib/test/test_calendar.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_calendar.py b/Lib/test/test_calendar.py index 38db9a4b5b3045..44a7575f1dcad9 100644 --- a/Lib/test/test_calendar.py +++ b/Lib/test/test_calendar.py @@ -923,7 +923,7 @@ def captured_stdout_with_buffer(self): yield sys.stdout finally: sys.stdout.flush() - sys.stdout.buffer.seek(0, 0) + sys.stdout.buffer.seek(0) sys.stdout = orig_stdout @contextlib.contextmanager @@ -935,7 +935,7 @@ def captured_stderr_with_buffer(self): yield sys.stderr finally: sys.stderr.flush() - sys.stderr.buffer.seek(0, 0) + sys.stderr.buffer.seek(0) sys.stderr = orig_stderr def run_cli_ok(self, *args): From 0aa0caf8b8e67de0f3e222c697f4cd06c3061974 Mon Sep 17 00:00:00 2001 From: Bart Skowron Date: Sat, 11 Jun 2022 20:28:14 +0200 Subject: [PATCH 24/25] gh-69417: Include cases with odd widths in `formatmonthname` --- Lib/test/test_calendar.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Lib/test/test_calendar.py b/Lib/test/test_calendar.py index 44a7575f1dcad9..d30941c9d45160 100644 --- a/Lib/test/test_calendar.py +++ b/Lib/test/test_calendar.py @@ -647,6 +647,8 @@ def test_locale_calendar_formatmonthname(self): # For too short widths, a full name (with year) is used. self.assertEqual(cal.formatmonthname(2022, 6, 2, withyear=False), "June") self.assertEqual(cal.formatmonthname(2022, 6, 2, withyear=True), "June 2022") + self.assertEqual(cal.formatmonthname(2022, 6, 3, withyear=False), "June") + self.assertEqual(cal.formatmonthname(2022, 6, 3, withyear=True), "June 2022") # For long widths, a centered name is used. self.assertEqual(cal.formatmonthname(2022, 6, 10, withyear=False), " June ") self.assertEqual(cal.formatmonthname(2022, 6, 15, withyear=True), " June 2022 ") From e73fc9ea14f59b594922b006ccd58d01094ccdec Mon Sep 17 00:00:00 2001 From: Bart Skowron Date: Sat, 11 Jun 2022 20:39:20 +0200 Subject: [PATCH 25/25] gh-69714: Split tests for LocaleTextCalendar and LocaleHTMLCalendar --- Lib/test/test_calendar.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/Lib/test/test_calendar.py b/Lib/test/test_calendar.py index d30941c9d45160..d6ca1775a2721b 100644 --- a/Lib/test/test_calendar.py +++ b/Lib/test/test_calendar.py @@ -543,7 +543,7 @@ def test_months(self): # verify it "acts like a sequence" in two forms of iteration self.assertEqual(value[::-1], list(reversed(value))) - def test_locale_calendars(self): + def test_locale_text_calendar(self): try: cal = calendar.LocaleTextCalendar(locale='') local_weekday = cal.formatweekday(1, 10) @@ -581,9 +581,14 @@ def test_locale_calendars(self): self.assertEqual(len(local_weekday_abbr), 3) self.assertGreaterEqual(len(local_month), 10) - cal = calendar.LocaleHTMLCalendar(locale='') - local_weekday = cal.formatweekday(1) - local_month = cal.formatmonthname(2010, 10) + def test_locale_html_calendar(self): + try: + cal = calendar.LocaleHTMLCalendar(locale='') + local_weekday = cal.formatweekday(1) + local_month = cal.formatmonthname(2010, 10) + except locale.Error: + # cannot set the system default locale -- skip rest of test + raise unittest.SkipTest('cannot set the system default locale') self.assertIsInstance(local_weekday, str) self.assertIsInstance(local_month, str)