From 528fdd663f4fcb52f48b965ba5e8a4b07d66d98f Mon Sep 17 00:00:00 2001 From: Justin Baum Date: Sat, 28 Nov 2020 17:35:21 -0500 Subject: [PATCH 01/10] Add ignore_case flag to doc-test --- Lib/doctest.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/Lib/doctest.py b/Lib/doctest.py index 5bb35c9715d1e9..18de02c3fc1f4b 100644 --- a/Lib/doctest.py +++ b/Lib/doctest.py @@ -63,6 +63,7 @@ def _test(): 'REPORT_ONLY_FIRST_FAILURE', 'REPORTING_FLAGS', 'FAIL_FAST', + 'IGNORE_CASE', # 1. Utility Functions # 2. Example & DocTest 'Example', @@ -139,13 +140,15 @@ def register_optionflag(name): ELLIPSIS = register_optionflag('ELLIPSIS') SKIP = register_optionflag('SKIP') IGNORE_EXCEPTION_DETAIL = register_optionflag('IGNORE_EXCEPTION_DETAIL') +IGNORE_CASE = register_optionflag('IGNORE_CASE') COMPARISON_FLAGS = (DONT_ACCEPT_TRUE_FOR_1 | DONT_ACCEPT_BLANKLINE | NORMALIZE_WHITESPACE | ELLIPSIS | SKIP | - IGNORE_EXCEPTION_DETAIL) + IGNORE_EXCEPTION_DETAIL | + IGNORE_CASE) REPORT_UDIFF = register_optionflag('REPORT_UDIFF') REPORT_CDIFF = register_optionflag('REPORT_CDIFF') @@ -1607,6 +1610,12 @@ def check_output(self, want, got, optionflags): if got == want: return True + # Ignore case if flag + # Lowercase got and want + if (optionflags & IGNORE_CASE): + got = got.lower() + want = want.lower() + # The values True and False replaced 1 and 0 as the return # value for boolean comparisons in Python 2.3. if not (optionflags & DONT_ACCEPT_TRUE_FOR_1): From 99a79ea76c8915be57f1b7eb7453970e540b6ba7 Mon Sep 17 00:00:00 2001 From: Justin Baum Date: Sat, 28 Nov 2020 19:26:42 -0500 Subject: [PATCH 02/10] add a test --- Lib/test/test_doctest.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Lib/test/test_doctest.py b/Lib/test/test_doctest.py index bff20f9cac9c98..55e093d0bf692b 100644 --- a/Lib/test/test_doctest.py +++ b/Lib/test/test_doctest.py @@ -1314,6 +1314,12 @@ def optionflags(): r""" ... # doctest: +NORMALIZE_WHITESPACE [0, 1, ..., 18, 19] +The IGNORE_CASE flag causes the test runner to ignore case when +matching the expected output to the actual output + >>> print("Hello World") # doctest: +IGNORE_CASE + hello world + + The SKIP flag causes an example to be skipped entirely. I.e., the example is not run. It can be useful in contexts where doctest examples serve as both documentation and test cases, and an example From 539dc014851b79c23781a4e2f4b43a2a5d6317e9 Mon Sep 17 00:00:00 2001 From: "blurb-it[bot]" <43283697+blurb-it[bot]@users.noreply.github.com> Date: Sun, 29 Nov 2020 00:38:32 +0000 Subject: [PATCH 03/10] =?UTF-8?q?=F0=9F=93=9C=F0=9F=A4=96=20Added=20by=20b?= =?UTF-8?q?lurb=5Fit.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../NEWS.d/next/Library/2020-11-29-00-38-32.bpo-13337.rSk6U7.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Library/2020-11-29-00-38-32.bpo-13337.rSk6U7.rst diff --git a/Misc/NEWS.d/next/Library/2020-11-29-00-38-32.bpo-13337.rSk6U7.rst b/Misc/NEWS.d/next/Library/2020-11-29-00-38-32.bpo-13337.rSk6U7.rst new file mode 100644 index 00000000000000..2c32587b6d735e --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-11-29-00-38-32.bpo-13337.rSk6U7.rst @@ -0,0 +1 @@ +Adds an `ignore_case` flag to the `doctest` library. \ No newline at end of file From 1109111cc6486c09f9b83c488b6cb29551df020e Mon Sep 17 00:00:00 2001 From: Justin Baum Date: Sat, 28 Nov 2020 19:45:33 -0500 Subject: [PATCH 04/10] Fix whitespace --- Lib/test/test_doctest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/test/test_doctest.py b/Lib/test/test_doctest.py index 55e093d0bf692b..728c31a50868fc 100644 --- a/Lib/test/test_doctest.py +++ b/Lib/test/test_doctest.py @@ -1318,7 +1318,7 @@ def optionflags(): r""" matching the expected output to the actual output >>> print("Hello World") # doctest: +IGNORE_CASE hello world - + The SKIP flag causes an example to be skipped entirely. I.e., the example is not run. It can be useful in contexts where doctest From e7a82e8db84ea1c1566b0a63fccc1896540de3e9 Mon Sep 17 00:00:00 2001 From: Justin Baum Date: Sat, 28 Nov 2020 20:02:50 -0500 Subject: [PATCH 05/10] Add edge case as issue laid out --- Lib/doctest.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Lib/doctest.py b/Lib/doctest.py index 18de02c3fc1f4b..fdfccc4408aa0f 100644 --- a/Lib/doctest.py +++ b/Lib/doctest.py @@ -1612,16 +1612,20 @@ def check_output(self, want, got, optionflags): # Ignore case if flag # Lowercase got and want + true_line = "True\n" + false_line = "False\n" if (optionflags & IGNORE_CASE): got = got.lower() want = want.lower() + true_line = "true\n" + false_line = "false\n" # The values True and False replaced 1 and 0 as the return # value for boolean comparisons in Python 2.3. if not (optionflags & DONT_ACCEPT_TRUE_FOR_1): - if (got,want) == ("True\n", "1\n"): + if (got, want) == (true_line, "1\n"): return True - if (got,want) == ("False\n", "0\n"): + if (got, want) == (false_line, "0\n"): return True # can be used as a special sequence to signify a From e48d79027b6641327969cb95e3203e70c11a7ea5 Mon Sep 17 00:00:00 2001 From: Justin Baum Date: Sun, 29 Nov 2020 16:31:52 -0500 Subject: [PATCH 06/10] lower -> casefold --- Lib/doctest.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/doctest.py b/Lib/doctest.py index fdfccc4408aa0f..3894e26f3dcdc4 100644 --- a/Lib/doctest.py +++ b/Lib/doctest.py @@ -1615,8 +1615,8 @@ def check_output(self, want, got, optionflags): true_line = "True\n" false_line = "False\n" if (optionflags & IGNORE_CASE): - got = got.lower() - want = want.lower() + got = got.casefold() + want = want.casefold() true_line = "true\n" false_line = "false\n" From 23ece35eb2086cb77b9c6ad6d4efda6adce3d4e1 Mon Sep 17 00:00:00 2001 From: Justin Baum Date: Mon, 30 Nov 2020 11:59:01 -0500 Subject: [PATCH 07/10] Add NAN test cases --- Lib/test/test_doctest.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_doctest.py b/Lib/test/test_doctest.py index 728c31a50868fc..a8302d1dd3a018 100644 --- a/Lib/test/test_doctest.py +++ b/Lib/test/test_doctest.py @@ -1315,10 +1315,24 @@ def optionflags(): r""" [0, 1, ..., 18, 19] The IGNORE_CASE flag causes the test runner to ignore case when -matching the expected output to the actual output +matching the expected output to the actual output, >>> print("Hello World") # doctest: +IGNORE_CASE hello world +It can resolve the issues with POSIX and Windows NAN and other types. +On Windows this should fail without the flag. + >>> float("NaN") # doctest: +IGNORE_CASE + nan + +On POSIX this should fail. + >>> float("NaN") # doctest: +IGNORE_CASE + NaN + + >>> float("nan") # doctest: +IGNORE_CASE + nan + >>> float("nan") # doctest: +IGNORE_CASE + NaN + The SKIP flag causes an example to be skipped entirely. I.e., the example is not run. It can be useful in contexts where doctest From 851846511f6411945e6ba3edf437fdb7bd9fc5f2 Mon Sep 17 00:00:00 2001 From: Justin Baum Date: Mon, 30 Nov 2020 12:01:34 -0500 Subject: [PATCH 08/10] Mistype , -> . --- Lib/test/test_doctest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/test/test_doctest.py b/Lib/test/test_doctest.py index a8302d1dd3a018..e8acafd9e144fc 100644 --- a/Lib/test/test_doctest.py +++ b/Lib/test/test_doctest.py @@ -1315,7 +1315,7 @@ def optionflags(): r""" [0, 1, ..., 18, 19] The IGNORE_CASE flag causes the test runner to ignore case when -matching the expected output to the actual output, +matching the expected output to the actual output. >>> print("Hello World") # doctest: +IGNORE_CASE hello world From 12af0d6162c35f46fbe80cc95d5f0fa98a78e45c Mon Sep 17 00:00:00 2001 From: Justin Baum Date: Mon, 1 Sep 2025 23:27:14 -0400 Subject: [PATCH 09/10] add review address --- Lib/test/test_doctest/test_doctest.py | 16 ++++++++-------- .../2020-11-29-00-38-32.bpo-13337.rSk6U7.rst | 1 - .../2025-09-02-03-18-00.bpo-13337.rSk6U7.rst | 1 + 3 files changed, 9 insertions(+), 9 deletions(-) delete mode 100644 Misc/NEWS.d/next/Library/2020-11-29-00-38-32.bpo-13337.rSk6U7.rst create mode 100644 Misc/NEWS.d/next/Library/2025-09-02-03-18-00.bpo-13337.rSk6U7.rst diff --git a/Lib/test/test_doctest/test_doctest.py b/Lib/test/test_doctest/test_doctest.py index 5ff66fa6f4f6e5..f567746b8091d3 100644 --- a/Lib/test/test_doctest/test_doctest.py +++ b/Lib/test/test_doctest/test_doctest.py @@ -1449,22 +1449,22 @@ def optionflags(): r""" The IGNORE_CASE flag causes the test runner to ignore case when matching the expected output to the actual output. - >>> print("Hello World") # doctest: +IGNORE_CASE + + >>> print("HeLlO WoRlD") # doctest: +IGNORE_CASE hello world It can resolve the issues with POSIX and Windows NAN and other types. On Windows this should fail without the flag. + >>> float("NaN") # doctest: +IGNORE_CASE nan -On POSIX this should fail. - >>> float("NaN") # doctest: +IGNORE_CASE - NaN +It also works with boolean values. - >>> float("nan") # doctest: +IGNORE_CASE - nan - >>> float("nan") # doctest: +IGNORE_CASE - NaN + >>> print("tRuE") # doctest: +IGNORE_CASE + 1 + >>> print("FaLsE") # doctest: +IGNORE_CASE + 0 The SKIP flag causes an example to be skipped entirely. I.e., the diff --git a/Misc/NEWS.d/next/Library/2020-11-29-00-38-32.bpo-13337.rSk6U7.rst b/Misc/NEWS.d/next/Library/2020-11-29-00-38-32.bpo-13337.rSk6U7.rst deleted file mode 100644 index 2c32587b6d735e..00000000000000 --- a/Misc/NEWS.d/next/Library/2020-11-29-00-38-32.bpo-13337.rSk6U7.rst +++ /dev/null @@ -1 +0,0 @@ -Adds an `ignore_case` flag to the `doctest` library. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2025-09-02-03-18-00.bpo-13337.rSk6U7.rst b/Misc/NEWS.d/next/Library/2025-09-02-03-18-00.bpo-13337.rSk6U7.rst new file mode 100644 index 00000000000000..9318663c869257 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-09-02-03-18-00.bpo-13337.rSk6U7.rst @@ -0,0 +1 @@ +Adds the :const:`~doctest.IGNORE_CASE` flag to the :mod:`doctest` module. Patch by Justin Baum. From 1cfe3c32fa138c0cc869dabf1ead4c41b9225e19 Mon Sep 17 00:00:00 2001 From: Justin Baum Date: Mon, 1 Sep 2025 23:34:57 -0400 Subject: [PATCH 10/10] const -> flag --- .../next/Library/2025-09-02-03-18-00.bpo-13337.rSk6U7.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/Library/2025-09-02-03-18-00.bpo-13337.rSk6U7.rst b/Misc/NEWS.d/next/Library/2025-09-02-03-18-00.bpo-13337.rSk6U7.rst index 9318663c869257..e4356aacd307ff 100644 --- a/Misc/NEWS.d/next/Library/2025-09-02-03-18-00.bpo-13337.rSk6U7.rst +++ b/Misc/NEWS.d/next/Library/2025-09-02-03-18-00.bpo-13337.rSk6U7.rst @@ -1 +1 @@ -Adds the :const:`~doctest.IGNORE_CASE` flag to the :mod:`doctest` module. Patch by Justin Baum. +Adds the :flag:`~doctest.IGNORE_CASE` flag to the :mod:`doctest` module. Patch by Justin Baum.