mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 05:31:20 +00:00 
			
		
		
		
	[3.13] gh-128799: Add frame of except* to traceback when wrapping a naked exception (#128971) (#129299)
This commit is contained in:
		
							parent
							
								
									fcb265671c
								
							
						
					
					
						commit
						a853e2f076
					
				
					 3 changed files with 40 additions and 0 deletions
				
			
		|  | @ -2938,6 +2938,33 @@ def exc(): | ||||||
|         report = self.get_report(exc) |         report = self.get_report(exc) | ||||||
|         self.assertEqual(report, expected) |         self.assertEqual(report, expected) | ||||||
| 
 | 
 | ||||||
|  |     def test_exception_group_wrapped_naked(self): | ||||||
|  |         # See gh-128799 | ||||||
|  | 
 | ||||||
|  |         def exc(): | ||||||
|  |             try: | ||||||
|  |                 raise Exception(42) | ||||||
|  |             except* Exception as e: | ||||||
|  |                 raise | ||||||
|  | 
 | ||||||
|  |         expected = (f'  + Exception Group Traceback (most recent call last):\n' | ||||||
|  |                     f'  |   File "{__file__}", line {self.callable_line}, in get_exception\n' | ||||||
|  |                     f'  |     exception_or_callable()\n' | ||||||
|  |                     f'  |     ~~~~~~~~~~~~~~~~~~~~~^^\n' | ||||||
|  |                     f'  |   File "{__file__}", line {exc.__code__.co_firstlineno + 3}, in exc\n' | ||||||
|  |                     f'  |     except* Exception as e:\n' | ||||||
|  |                     f'  |         raise\n' | ||||||
|  |                     f'  | ExceptionGroup:  (1 sub-exception)\n' | ||||||
|  |                     f'  +-+---------------- 1 ----------------\n' | ||||||
|  |                     f'    | Traceback (most recent call last):\n' | ||||||
|  |                     f'    |   File "{__file__}", line {exc.__code__.co_firstlineno + 2}, in exc\n' | ||||||
|  |                     f'    |     raise Exception(42)\n' | ||||||
|  |                     f'    | Exception: 42\n' | ||||||
|  |                     f'    +------------------------------------\n') | ||||||
|  | 
 | ||||||
|  |         report = self.get_report(exc) | ||||||
|  |         self.assertEqual(report, expected) | ||||||
|  | 
 | ||||||
|     def test_KeyboardInterrupt_at_first_line_of_frame(self): |     def test_KeyboardInterrupt_at_first_line_of_frame(self): | ||||||
|         # see GH-93249 |         # see GH-93249 | ||||||
|         def f(): |         def f(): | ||||||
|  |  | ||||||
|  | @ -0,0 +1 @@ | ||||||
|  | Add frame of ``except*`` to traceback when it wraps a naked exception. | ||||||
|  | @ -27,6 +27,7 @@ | ||||||
| #include "pycore_setobject.h"     // _PySet_Update() | #include "pycore_setobject.h"     // _PySet_Update() | ||||||
| #include "pycore_sliceobject.h"   // _PyBuildSlice_ConsumeRefs | #include "pycore_sliceobject.h"   // _PyBuildSlice_ConsumeRefs | ||||||
| #include "pycore_sysmodule.h"     // _PySys_Audit() | #include "pycore_sysmodule.h"     // _PySys_Audit() | ||||||
|  | #include "pycore_traceback.h"     // _PyTraceBack_FromFrame | ||||||
| #include "pycore_tuple.h"         // _PyTuple_ITEMS() | #include "pycore_tuple.h"         // _PyTuple_ITEMS() | ||||||
| #include "pycore_typeobject.h"    // _PySuper_Lookup() | #include "pycore_typeobject.h"    // _PySuper_Lookup() | ||||||
| #include "pycore_uop_ids.h"       // Uops | #include "pycore_uop_ids.h"       // Uops | ||||||
|  | @ -2018,6 +2019,17 @@ _PyEval_ExceptionGroupMatch(PyObject* exc_value, PyObject *match_type, | ||||||
|             if (wrapped == NULL) { |             if (wrapped == NULL) { | ||||||
|                 return -1; |                 return -1; | ||||||
|             } |             } | ||||||
|  |             PyThreadState *tstate = _PyThreadState_GET(); | ||||||
|  |             _PyInterpreterFrame *frame = _PyThreadState_GetFrame(tstate); | ||||||
|  |             PyFrameObject *f = _PyFrame_GetFrameObject(frame); | ||||||
|  |             if (f != NULL) { | ||||||
|  |                 PyObject *tb = _PyTraceBack_FromFrame(NULL, f); | ||||||
|  |                 if (tb == NULL) { | ||||||
|  |                     return -1; | ||||||
|  |                 } | ||||||
|  |                 PyException_SetTraceback(wrapped, tb); | ||||||
|  |                 Py_DECREF(tb); | ||||||
|  |             } | ||||||
|             *match = wrapped; |             *match = wrapped; | ||||||
|         } |         } | ||||||
|         *rest = Py_NewRef(Py_None); |         *rest = Py_NewRef(Py_None); | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Irit Katriel
						Irit Katriel