| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -378,26 +378,41 @@ always available. | |||
| 378 | 378 | .. versionadded:: 3.8 | |
| 379 | 379 | __unraisablehook__ | |
| 380 | 380 | ||
| 381 | + | ||
| 382 | + .. function:: exception() | ||
| 383 | + | ||
| 384 | + This function returns the exception instance that is currently being | ||
| 385 | + handled. This exception is specific both to the current thread and | ||
| 386 | + to the current stack frame. If the current stack frame is not handling | ||
| 387 | + an exception, the exception is taken from the calling stack frame, or its | ||
| 388 | + caller, and so on until a stack frame is found that is handling an | ||
| 389 | + exception. Here, "handling an exception" is defined as "executing an | ||
| 390 | + except clause." For any stack frame, only the exception being currently | ||
| 391 | + handled is accessible. | ||
| 392 | + | ||
| 393 | + .. index:: object: traceback | ||
| 394 | + | ||
| 395 | + If no exception is being handled anywhere on the stack, ``None`` is | ||
| 396 | + returned. | ||
| 397 | + | ||
| 398 | + .. versionadded:: 3.11 | ||
| 399 | + | ||
| 400 | + | ||
| 381 | 401 | .. function:: exc_info() | |
| 382 | 402 | ||
| 383 | - This function returns a tuple of three values that give information about the | ||
| 384 | - exception that is currently being handled. The information returned is specific | ||
| 385 | - both to the current thread and to the current stack frame. If the current stack | ||
| 386 | - frame is not handling an exception, the information is taken from the calling | ||
| 387 | - stack frame, or its caller, and so on until a stack frame is found that is | ||
| 388 | - handling an exception. Here, "handling an exception" is defined as "executing | ||
| 389 | - an except clause." For any stack frame, only information about the exception | ||
| 390 | - being currently handled is accessible. | ||
| 403 | + This function returns the old-style representation of the handled | ||
| 404 | + exception. If an exception ``e`` is currently handled (so | ||
| 405 | + :func:`exception` would return ``e``), :func:`exc_info` returns the | ||
| 406 | + tuple ``(type(e), e, e.__traceback__)``. | ||
| 407 | + That is, a tuple containing the type of the exception (a subclass of | ||
| 408 | + :exc:`BaseException`), the exception itself, and a :ref:`traceback | ||
| 409 | + object <traceback-objects>` which typically encapsulates the call | ||
| 410 | + stack at the point where the exception last occurred. | ||
| 391 | 411 | ||
| 392 | 412 | .. index:: object: traceback | |
| 393 | 413 | ||
| 394 | - If no exception is being handled anywhere on the stack, a tuple containing | ||
| 395 | - three ``None`` values is returned. Otherwise, the values returned are | ||
| 396 | - ``(type, value, traceback)``. Their meaning is: *type* gets the type of the | ||
| 397 | - exception being handled (a subclass of :exc:`BaseException`); *value* gets | ||
| 398 | - the exception instance (an instance of the exception type); *traceback* gets | ||
| 399 | - a :ref:`traceback object <traceback-objects>` which typically encapsulates | ||
| 400 | - the call stack at the point where the exception last occurred. | ||
| 414 | + If no exception is being handled anywhere on the stack, this function | ||
| 415 | + return a tuple containing three ``None`` values. | ||
| 401 | 416 | ||
| 402 | 417 | .. versionchanged:: 3.11 | |
| 403 | 418 | The ``type`` and ``traceback`` fields are now derived from the ``value`` | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -167,7 +167,7 @@ then re-raise the exception (allowing a caller to handle the exception as well): | |||
| 167 | 167 | raise | |
| 168 | 168 | ||
| 169 | 169 | Alternatively the last except clause may omit the exception name(s), however the exception | |
| 170 | - value must then be retrieved from ``sys.exc_info()[1]``. | ||
| 170 | + value must then be retrieved with ``sys.exception()``. | ||
| 171 | 171 | ||
| 172 | 172 | The :keyword:`try` ... :keyword:`except` statement has an optional *else | |
| 173 | 173 | clause*, which, when present, must follow all *except clauses*. It is useful | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -305,6 +305,9 @@ sys | |||
| 305 | 305 | the results of subsequent calls to :func:`exc_info`. | |
| 306 | 306 | (Contributed by Irit Katriel in :issue:`45711`.) | |
| 307 | 307 | ||
| 308 | + * Add :func:`sys.exception` which returns the active exception instance | ||
| 309 | + (equivalent to ``sys.exc_info()[1]``). | ||
| 310 | + (Contributed by Irit Katriel in :issue:`46328`.) | ||
| 308 | 311 | ||
| 309 | 312 | threading | |
| 310 | 313 | --------- | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -71,6 +71,69 @@ def baddisplayhook(obj): | |||
| 71 | 71 | code = compile("42", "<string>", "single") | |
| 72 | 72 | self.assertRaises(ValueError, eval, code) | |
| 73 | 73 | ||
| 74 | + class ActiveExceptionTests(unittest.TestCase): | ||
| 75 | + def test_exc_info_no_exception(self): | ||
| 76 | + self.assertEqual(sys.exc_info(), (None, None, None)) | ||
| 77 | + | ||
| 78 | + def test_sys_exception_no_exception(self): | ||
| 79 | + self.assertEqual(sys.exception(), None) | ||
| 80 | + | ||
| 81 | + def test_exc_info_with_exception_instance(self): | ||
| 82 | + def f(): | ||
| 83 | + raise ValueError(42) | ||
| 84 | + | ||
| 85 | + try: | ||
| 86 | + f() | ||
| 87 | + except Exception as e_: | ||
| 88 | + e = e_ | ||
| 89 | + exc_info = sys.exc_info() | ||
| 90 | + | ||
| 91 | + self.assertIsInstance(e, ValueError) | ||
| 92 | + self.assertIs(exc_info[0], ValueError) | ||
| 93 | + self.assertIs(exc_info[1], e) | ||
| 94 | + self.assertIs(exc_info[2], e.__traceback__) | ||
| 95 | + | ||
| 96 | + def test_exc_info_with_exception_type(self): | ||
| 97 | + def f(): | ||
| 98 | + raise ValueError | ||
| 99 | + | ||
| 100 | + try: | ||
| 101 | + f() | ||
| 102 | + except Exception as e_: | ||
| 103 | + e = e_ | ||
| 104 | + exc_info = sys.exc_info() | ||
| 105 | + | ||
| 106 | + self.assertIsInstance(e, ValueError) | ||
| 107 | + self.assertIs(exc_info[0], ValueError) | ||
| 108 | + self.assertIs(exc_info[1], e) | ||
| 109 | + self.assertIs(exc_info[2], e.__traceback__) | ||
| 110 | + | ||
| 111 | + def test_sys_exception_with_exception_instance(self): | ||
| 112 | + def f(): | ||
| 113 | + raise ValueError(42) | ||
| 114 | + | ||
| 115 | + try: | ||
| 116 | + f() | ||
| 117 | + except Exception as e_: | ||
| 118 | + e = e_ | ||
| 119 | + exc = sys.exception() | ||
| 120 | + | ||
| 121 | + self.assertIsInstance(e, ValueError) | ||
| 122 | + self.assertIs(exc, e) | ||
| 123 | + | ||
| 124 | + def test_sys_exception_with_exception_type(self): | ||
| 125 | + def f(): | ||
| 126 | + raise ValueError | ||
| 127 | + | ||
| 128 | + try: | ||
| 129 | + f() | ||
| 130 | + except Exception as e_: | ||
| 131 | + e = e_ | ||
| 132 | + exc = sys.exception() | ||
| 133 | + | ||
| 134 | + self.assertIsInstance(e, ValueError) | ||
| 135 | + self.assertIs(exc, e) | ||
| 136 | + | ||
| 74 | 137 | ||
| 75 | 138 | class ExceptHookTest(unittest.TestCase): | |
| 76 | 139 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1 @@ | |||
| 1 | + Added the :meth:`sys.exception` method which returns the active exception instance. | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -771,6 +771,28 @@ sys_excepthook_impl(PyObject *module, PyObject *exctype, PyObject *value, | |||
| 771 | 771 | } | |
| 772 | 772 | ||
| 773 | 773 | ||
| 774 | + /*[clinic input] | ||
| 775 | + sys.exception | ||
| 776 | + | ||
| 777 | + Return the current exception. | ||
| 778 | + | ||
| 779 | + Return the most recent exception caught by an except clause | ||
| 780 | + in the current stack frame or in an older stack frame, or None | ||
| 781 | + if no such exception exists. | ||
| 782 | + [clinic start generated code]*/ | ||
| 783 | + | ||
| 784 | + static PyObject * | ||
| 785 | + sys_exception_impl(PyObject *module) | ||
| 786 | + /*[clinic end generated code: output=2381ee2f25953e40 input=c88fbb94b6287431]*/ | ||
| 787 | + { | ||
| 788 | + _PyErr_StackItem *err_info = _PyErr_GetTopmostException(_PyThreadState_GET()); | ||
| 789 | + if (err_info->exc_value != NULL) { | ||
| 790 | + return Py_NewRef(err_info->exc_value); | ||
| 791 | + } | ||
| 792 | + Py_RETURN_NONE; | ||
| 793 | + } | ||
| 794 | + | ||
| 795 | + | ||
| 774 | 796 | /*[clinic input] | |
| 775 | 797 | sys.exc_info | |
| 776 | 798 | ||
@@ -1963,6 +1985,7 @@ static PyMethodDef sys_methods[] = { | |||
| 1963 | 1985 | SYS__CURRENT_FRAMES_METHODDEF | |
| 1964 | 1986 | SYS__CURRENT_EXCEPTIONS_METHODDEF | |
| 1965 | 1987 | SYS_DISPLAYHOOK_METHODDEF | |
| 1988 | + SYS_EXCEPTION_METHODDEF | ||
| 1966 | 1989 | SYS_EXC_INFO_METHODDEF | |
| 1967 | 1990 | SYS_EXCEPTHOOK_METHODDEF | |
| 1968 | 1991 | SYS_EXIT_METHODDEF | |
@@ -2457,7 +2480,8 @@ Functions:\n\ | |||
| 2457 | 2480 | \n\ | |
| 2458 | 2481 | displayhook() -- print an object to the screen, and save it in builtins._\n\ | |
| 2459 | 2482 | excepthook() -- print an exception and its traceback to sys.stderr\n\ | |
| 2460 | - exc_info() -- return thread-safe information about the current exception\n\ | ||
| 2483 | + exception() -- return the current thread's active exception\n\ | ||
| 2484 | + exc_info() -- return information about the current thread's active exception\n\ | ||
| 2461 | 2485 | exit() -- exit the interpreter by raising SystemExit\n\ | |
| 2462 | 2486 | getdlopenflags() -- returns flags to be used for dlopen() calls\n\ | |
| 2463 | 2487 | getprofile() -- get the global profiling function\n\ | |
| Back | FazBrowse Home | New Git URL |
0 commit comments