Skip to content

Test documentation for ExceptionGroup #104150

Open
@stevewanash

Description

@stevewanash

The new feature ExceptionGroup catches several exceptions at a time. It's helped me write functions that detect more than one error at a time, depending on the input. While helpful, the feature has made documentation, especially using doctest, nearly impossible. To test for exceptions, more so for Traceback stacks, before python version 3.11, the documentation only needed the traceback statement and the name of the error to test the function. Citing your own documentation it looked something like this:

"""
Traceback (most recent call last):
    ...
ValueError: detail
"""

The elipses replaces the detail within the traceback stack, and could be omitted all together, to look like this:

"""
Traceback (most recent call last):
ValueError: detail
"""

However, with ExceptionGroups now, The format of the exception doesn't allow this. An example output of an ExceptionGroup would look like this:

  + Exception Group Traceback (most recent call last):
  |   File "<stdin>", line 1, in <module>
x_divided                            
  |     raise ExceptionGroup("There were errors", errors)
  | ExceptionGroup: There were errors (3 sub-exceptions)
  +-+---------------- 1 ----------------
    | TypeError: matrix must be a matrix (list of lists) of integers/floats
    +---------------- 2 ----------------
    | TypeError: Each row of the matrix must have the same size
    +---------------- 3 ----------------
    | ZeroDivisionError: division by zero
    +------------------------------------ 

The added "+" and "|", which I assume were added for indentation purposes, make it difficult to write up test documentation for the code. Ideally, without omitting anything in the traceback stack, test documentation would look like this:

"""
Test for more than one error
>>> s([[2, 4], [6, 6, "f"]], 0)
  + Exception Group Traceback (most recent call last):
  |   File "<stdin>", line 1, in <module>
x_divided                            
  |     raise ExceptionGroup("There were errors", errors)
  | ExceptionGroup: There were errors (3 sub-exceptions)
  +-+---------------- 1 ----------------
    | TypeError: matrix must be a matrix (list of lists) of integers/floats
    +---------------- 2 ----------------
    | TypeError: Each row of the matrix must have the same size
    +---------------- 3 ----------------
    | ZeroDivisionError: division by zero
    +------------------------------------
"""

This however, would result in a failed test for the function S. The output would look like this:

Failed example:
    s([[2, 4], [6, 6, "f"]], 0)
Exception raised:
      + Exception Group Traceback (most recent call last):
      |   File "C:\Users\pc\AppData\Local\Programs\Python\Python311\Lib\doctest.py", line 1351, in __run
      |     exec(compile(example.source, filename, "single",
      |   File "<doctest 2-matrix_divided.txt[5]>", line 1, in <module>
      |     s([[2, 4], [6, 6, "f"]], 0)
      |   File "C:\Users\pc\My Github code\alx-higher_level_programming\0x07-python-test_driven_development\2-matrix_divided.py", line 35, in matrix_divided
      |     raise ExceptionGroup("There were errors", errors)
      | ExceptionGroup: There were errors (3 sub-exceptions)
      +-+---------------- 1 ----------------
        | TypeError: matrix must be a matrix (list of lists) of integers/floats
        +---------------- 2 ----------------
        | TypeError: Each row of the matrix must have the same size
        +---------------- 3 ----------------
        | ZeroDivisionError: division by zero
        +------------------------------------

I assume the reason for the test failing is the difference in the Traceback stack, but clearly from the first example, and all your previous documentation, whatever is within the traceback stack is usually ignored by python and can be replaced by an ellipses(...) or omitted entirely. This isn't the case here as removing the information within the Traceback stack, as shown below, would give the same output, a failed test:

"""
Test for more than one error
>>> s([[2, 4], [6, 6, "f"]], 0)
  + Exception Group Traceback (most recent call last):
  |       ...
  | ExceptionGroup: There were errors (3 sub-exceptions)
  +-+---------------- 1 ----------------
    | TypeError: matrix must be a matrix (list of lists) of integers/floats
    +---------------- 2 ----------------
    | TypeError: Each row of the matrix must have the same size
    +---------------- 3 ----------------
    | ZeroDivisionError: division by zero
    +------------------------------------
"""

Similarly, if I decided to ignore the "|" and "+" symbols at the beginning, and the "-" separating the errors, I would still get the same result, a failed test.

"""
Test for more than one error
>>> s([[2, 4], [6, 6, "f"]], 0)
Exception Group Traceback (most recent call last):
    ...
ExceptionGroup: There were errors (3 sub-exceptions)
      ...
  TypeError: matrix must be a matrix (list of lists) of integers/floats
      ...
  TypeError: Each row of the matrix must have the same size
      ...
  ZeroDivisionError: division by zero

"""

None of them work, and will all result in a failed test, even when I copy the output of the interpreter straight to the test documentation. This, I suppose, is due to the extra formatting when the ExceptionGroup is caught, that is the "+", "|", and "-" symbols. Doctest immediately assumes the output it gets is different from that of the test documentation, owing to the extra formatting and no provisions on how to handle it. Please fix the issue, or formulate some rules on how to write documentation when it comes to ExceptionGroups. Further clarification on the issue can be found in the link below.
https://stackoverflow.com/questions/76167508/how-do-i-write-test-documentation-for-exception-groups

I used VScode running on python version 3.11. I ran the doctest on the command prompt terminal within VScode, on a windows operating system.

Metadata

Metadata

Assignees

No one assigned

    Labels

    stdlibPython modules in the Lib dirtype-bugAn unexpected behavior, bug, or error

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions