On 29/06/17 19:00, eryk sun wrote: > On Thu, Jun 29, 2017 at 6:50 AM, Steven D'Aprano <st...@pearwood.info> wrote: >> try: >> something >> except: >> exc_type, exc, tb = sys.exc_info() >> print(traceback.extract_tb(tb)) >> raise >> >> Why does it return the exception type separately from the exception, when >> the type can be derived by calling `type(exc)`? > > I think normally it is redundant. While the type and value do have to > be tracked separately for the thread's hot exception state (i.e. > curexc_type, curexc_value, curexc_traceback), sys.exc_info() returns a > caught exception (i.e. exc_type, exc_value, exc_traceback), which is > normalized by PyErr_NormalizeException. > > In CPython you can trivially force the exception value to be None by > calling PyErr_SetExcInfo. For example: > > import sys > import ctypes > > PyErr_SetExcInfo = ctypes.pythonapi.PyErr_SetExcInfo > PyErr_SetExcInfo.restype = None > PyErr_SetExcInfo.argtypes = (ctypes.py_object,) * 3 > > PyErr_SetExcInfo(TypeError, None, None) > > >>> sys.exc_info() > (<class 'TypeError'>, None, None) > > Of course this is a silly example, because C. >
This is doubly silly, as since 1.5 the stdlib documentation has stated that the value "is always a class instance if the exception type is a class object" (... the formulation was changed in py3) -- https://mail.python.org/mailman/listinfo/python-list