mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 13:41:24 +00:00 
			
		
		
		
	gh-93691: fix too broad source locations of with-statement instructions (#120125)
This commit is contained in:
		
							parent
							
								
									d68a22e7a6
								
							
						
					
					
						commit
						eca3f7762c
					
				
					 3 changed files with 47 additions and 3 deletions
				
			
		|  | @ -5,6 +5,7 @@ | |||
| __email__ = "mbland at acm dot org" | ||||
| 
 | ||||
| import sys | ||||
| import traceback | ||||
| import unittest | ||||
| from collections import deque | ||||
| from contextlib import _GeneratorContextManager, contextmanager, nullcontext | ||||
|  | @ -749,5 +750,48 @@ def testEnterReturnsTuple(self): | |||
|             self.assertEqual(10, b1) | ||||
|             self.assertEqual(20, b2) | ||||
| 
 | ||||
|     def testExceptionLocation(self): | ||||
|         # The location of an exception raised from | ||||
|         # __init__, __enter__ or __exit__ of a context | ||||
|         # manager should be just the context manager expression, | ||||
|         # pinpointing the precise context manager in case there | ||||
|         # is more than one. | ||||
| 
 | ||||
|         def init_raises(): | ||||
|             try: | ||||
|                 with self.Dummy(), self.InitRaises() as cm, self.Dummy() as d: | ||||
|                     pass | ||||
|             except Exception as e: | ||||
|                 return e | ||||
| 
 | ||||
|         def enter_raises(): | ||||
|             try: | ||||
|                 with self.EnterRaises(), self.Dummy() as d: | ||||
|                     pass | ||||
|             except Exception as e: | ||||
|                 return e | ||||
| 
 | ||||
|         def exit_raises(): | ||||
|             try: | ||||
|                 with self.ExitRaises(), self.Dummy() as d: | ||||
|                     pass | ||||
|             except Exception as e: | ||||
|                 return e | ||||
| 
 | ||||
|         for func, expected in [(init_raises, "self.InitRaises()"), | ||||
|                                (enter_raises, "self.EnterRaises()"), | ||||
|                                (exit_raises, "self.ExitRaises()"), | ||||
|                               ]: | ||||
|             with self.subTest(func): | ||||
|                 exc = func() | ||||
|                 f = traceback.extract_tb(exc.__traceback__)[0] | ||||
|                 indent = 16 | ||||
|                 co = func.__code__ | ||||
|                 self.assertEqual(f.lineno, co.co_firstlineno + 2) | ||||
|                 self.assertEqual(f.end_lineno, co.co_firstlineno + 2) | ||||
|                 self.assertEqual(f.line[f.colno - indent : f.end_colno - indent], | ||||
|                                  expected) | ||||
| 
 | ||||
| 
 | ||||
| if __name__ == '__main__': | ||||
|     unittest.main() | ||||
|  |  | |||
|  | @ -0,0 +1 @@ | |||
| Fix source locations of instructions generated for with statements. | ||||
|  | @ -5900,7 +5900,7 @@ compiler_async_with(struct compiler *c, stmt_ty s, int pos) | |||
| 
 | ||||
|     /* Evaluate EXPR */ | ||||
|     VISIT(c, expr, item->context_expr); | ||||
| 
 | ||||
|     loc = LOC(item->context_expr); | ||||
|     ADDOP(c, loc, BEFORE_ASYNC_WITH); | ||||
|     ADDOP_I(c, loc, GET_AWAITABLE, 1); | ||||
|     ADDOP_LOAD_CONST(c, loc, Py_None); | ||||
|  | @ -5998,7 +5998,7 @@ compiler_with(struct compiler *c, stmt_ty s, int pos) | |||
|     /* Evaluate EXPR */ | ||||
|     VISIT(c, expr, item->context_expr); | ||||
|     /* Will push bound __exit__ */ | ||||
|     location loc = LOC(s); | ||||
|     location loc = LOC(item->context_expr); | ||||
|     ADDOP(c, loc, BEFORE_WITH); | ||||
|     ADDOP_JUMP(c, loc, SETUP_WITH, final); | ||||
| 
 | ||||
|  | @ -6031,7 +6031,6 @@ compiler_with(struct compiler *c, stmt_ty s, int pos) | |||
|     /* For successful outcome:
 | ||||
|      * call __exit__(None, None, None) | ||||
|      */ | ||||
|     loc = LOC(s); | ||||
|     RETURN_IF_ERROR(compiler_call_exit_with_nones(c, loc)); | ||||
|     ADDOP(c, loc, POP_TOP); | ||||
|     ADDOP_JUMP(c, loc, JUMP, exit); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Irit Katriel
						Irit Katriel