gh-111159: Fix `doctest` output comparison for exceptions with notes (#111160)

diff --git a/Lib/doctest.py b/Lib/doctest.py
index 46b4dd6..f00d935 100644
--- a/Lib/doctest.py
+++ b/Lib/doctest.py
@@ -1393,7 +1393,20 @@ def __run(self, test, compileflags, out):
 
             # The example raised an exception:  check if it was expected.
             else:
-                exc_msg = traceback.format_exception_only(*exception[:2])[-1]
+                formatted_ex = traceback.format_exception_only(*exception[:2])
+                if issubclass(exception[0], SyntaxError):
+                    # SyntaxError / IndentationError is special:
+                    # we don't care about the carets / suggestions / etc
+                    # We only care about the error message and notes.
+                    # They start with `SyntaxError:` (or any other class name)
+                    exc_msg_index = next(
+                        index
+                        for index, line in enumerate(formatted_ex)
+                        if line.startswith(f"{exception[0].__name__}:")
+                    )
+                    formatted_ex = formatted_ex[exc_msg_index:]
+
+                exc_msg = "".join(formatted_ex)
                 if not quiet:
                     got += _exception_traceback(exception)
 
diff --git a/Lib/test/test_doctest.py b/Lib/test/test_doctest.py
index 6e12e82..6a903ed 100644
--- a/Lib/test/test_doctest.py
+++ b/Lib/test/test_doctest.py
@@ -3212,6 +3212,150 @@ def test_run_doctestsuite_multiple_times():
     """
 
 
+def test_exception_with_note(note):
+    """
+    >>> test_exception_with_note('Note')
+    Traceback (most recent call last):
+      ...
+    ValueError: Text
+    Note
+
+    >>> test_exception_with_note('Note')  # doctest: +IGNORE_EXCEPTION_DETAIL
+    Traceback (most recent call last):
+      ...
+    ValueError: Text
+    Note
+
+    >>> test_exception_with_note('''Note
+    ... multiline
+    ... example''')
+    Traceback (most recent call last):
+    ValueError: Text
+    Note
+    multiline
+    example
+
+    Different note will fail the test:
+
+    >>> def f(x):
+    ...     r'''
+    ...     >>> exc = ValueError('message')
+    ...     >>> exc.add_note('note')
+    ...     >>> raise exc
+    ...     Traceback (most recent call last):
+    ...     ValueError: message
+    ...     wrong note
+    ...     '''
+    >>> test = doctest.DocTestFinder().find(f)[0]
+    >>> doctest.DocTestRunner(verbose=False).run(test)
+    ... # doctest: +ELLIPSIS
+    **********************************************************************
+    File "...", line 5, in f
+    Failed example:
+        raise exc
+    Expected:
+        Traceback (most recent call last):
+        ValueError: message
+        wrong note
+    Got:
+        Traceback (most recent call last):
+          ...
+        ValueError: message
+        note
+    TestResults(failed=1, attempted=...)
+    """
+    exc = ValueError('Text')
+    exc.add_note(note)
+    raise exc
+
+
+def test_exception_with_multiple_notes():
+    """
+    >>> test_exception_with_multiple_notes()
+    Traceback (most recent call last):
+      ...
+    ValueError: Text
+    One
+    Two
+    """
+    exc = ValueError('Text')
+    exc.add_note('One')
+    exc.add_note('Two')
+    raise exc
+
+
+def test_syntax_error_with_note(cls, multiline=False):
+    """
+    >>> test_syntax_error_with_note(SyntaxError)
+    Traceback (most recent call last):
+      ...
+    SyntaxError: error
+    Note
+
+    >>> test_syntax_error_with_note(SyntaxError)
+    Traceback (most recent call last):
+    SyntaxError: error
+    Note
+
+    >>> test_syntax_error_with_note(SyntaxError)
+    Traceback (most recent call last):
+      ...
+      File "x.py", line 23
+        bad syntax
+    SyntaxError: error
+    Note
+
+    >>> test_syntax_error_with_note(IndentationError)
+    Traceback (most recent call last):
+      ...
+    IndentationError: error
+    Note
+
+    >>> test_syntax_error_with_note(TabError, multiline=True)
+    Traceback (most recent call last):
+      ...
+    TabError: error
+    Note
+    Line
+    """
+    exc = cls("error", ("x.py", 23, None, "bad syntax"))
+    exc.add_note('Note\nLine' if multiline else 'Note')
+    raise exc
+
+
+def test_syntax_error_with_incorrect_expected_note():
+    """
+    >>> def f(x):
+    ...     r'''
+    ...     >>> exc = SyntaxError("error", ("x.py", 23, None, "bad syntax"))
+    ...     >>> exc.add_note('note1')
+    ...     >>> exc.add_note('note2')
+    ...     >>> raise exc
+    ...     Traceback (most recent call last):
+    ...     SyntaxError: error
+    ...     wrong note
+    ...     '''
+    >>> test = doctest.DocTestFinder().find(f)[0]
+    >>> doctest.DocTestRunner(verbose=False).run(test)
+    ... # doctest: +ELLIPSIS
+    **********************************************************************
+    File "...", line 6, in f
+    Failed example:
+        raise exc
+    Expected:
+        Traceback (most recent call last):
+        SyntaxError: error
+        wrong note
+    Got:
+        Traceback (most recent call last):
+          ...
+        SyntaxError: error
+        note1
+        note2
+    TestResults(failed=1, attempted=...)
+    """
+
+
 def load_tests(loader, tests, pattern):
     tests.addTest(doctest.DocTestSuite(doctest))
     tests.addTest(doctest.DocTestSuite())
diff --git a/Misc/NEWS.d/next/Library/2023-10-21-13-57-06.gh-issue-111159.GoHp7s.rst b/Misc/NEWS.d/next/Library/2023-10-21-13-57-06.gh-issue-111159.GoHp7s.rst
new file mode 100644
index 0000000..bdec4f4
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2023-10-21-13-57-06.gh-issue-111159.GoHp7s.rst
@@ -0,0 +1 @@
+Fix :mod:`doctest` output comparison for exceptions with notes.