Terry J. Reedy added the comment:
The print_exception API goes back to when exception values were (or at least,
could be) strings. Its doc is incomplete as to the requirements on the args
and, at least by 3.5, erroneous. To modify it, we need to understand how it
actually works now.
In 2.7, 'etype' can apparently by anything with an __str__ method. (Someone
could check the 2.7 code.) At least Exception, 'abc', and None result in
'Exception', 'abc' or 'None' leading the last line. Example:
>>> try: 1/0
except Exception as e:
tb.print_exception(None, e, None)
None: integer division or modulo by zero
By at least 3.5, the etype arg can definitely be anything, because it is
ignored. The printed exception type is already grabbed from the exception. Any
patch should not change this. Note that this 3.x change already introduced an
incompatibility. In 3.5, the above prints 'ZeroDivisionError' instead of
'None'.
This holdover line in the doc "prints the exception etype and value after the
stack trace" is wrong and should be corrected with a 'changed in 3.x' note if
done after 3.0.
In 2.7, value can at least be an exception, a string, or None (not documented).
(Ditto for checking the code.)
>>> try: 1/0
except Exception as e:
tb.print_exception(None, 'zero-divive', tb=None)
None: zero-divive
>>> try: 1/0
except Exception as e:
tb.print_exception(None, None, None)
None
In 3.?, value must be an exception instance (or compatible duck) (not
documented).
...
File "C:\Programs\Python36\lib\traceback.py", line 465, in __init__
if (exc_value and exc_value.__cause__ is not None
AttributeError: 'str' object has no attribute '__cause__'
So, more potential incompatibilities with 2.x.
In 2.7, tb is needed to supply the traceback, or to suppress it. As a separate
parameter, it allows a traceback to be modified before printing.* The option
of a modified or omitted traceback (the ultimate modification) should be kept.
*IDLE edits tracebacks before printing to delete artifacts introduced by IDLE
internals. The attempt is to print what the console interpreter would. I
don't currently know whether it replaces the original on the exception or not.
There is also a proposal for the standard interpreter to edit tracebacks after
recursion limit exceptions. So traceback editing is useful, and I see no need
to force replacement of the semi-private e.__traceback__.
My suggestions:
tb: In 3.7, in the API, change 'tb' to 'tb=True'. If tb is left True, grab it
from the exception. If tb is explicitly supplied, use it. If tb is set to
False or (for back compatibility) None, suppress it.
value: In 3.5+ document that it must be an exception.
(Optional) Change 'value' to 'exc' in the API to reflect the 3.x restriction.
Document 'value' as a deprecated synonym for keyword usage. Keep the synonym
until after 2.7.
etype: In 3.5+ document that it is an ignored dummy argument and that one can
just pass 0, '', or None.
(Optional) Deprecate the parameter and make it optional. This can be handled*
in the code and would be like range having option 'start'. This is messy but
would be temporary. Remove after 2.7.
* 1 arg = exc/value, 3 args are etype, value, tb, 2 args are exc, tb or etype,
exc depending on whether the type(first) is BaseException.
I am inclined to go with both options, but even if the 3 of us agree, I might
be inclined to post our intention on pydev.
----------
_______________________________________
Python tracker <[email protected]>
<http://bugs.python.org/issue26389>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe:
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com