mirror of
				https://github.com/python/cpython.git
				synced 2025-11-03 23:21:29 +00:00 
			
		
		
		
	Fix issue #1689458 by teaching frame_setlineno how to jump to the first line of
a code object.
This commit is contained in:
		
							parent
							
								
									cf4ad76a0a
								
							
						
					
					
						commit
						c8d30fec16
					
				
					 2 changed files with 41 additions and 14 deletions
				
			
		| 
						 | 
					@ -740,6 +740,27 @@ def test_18_no_jump_to_non_integers(self):
 | 
				
			||||||
    def test_19_no_jump_without_trace_function(self):
 | 
					    def test_19_no_jump_without_trace_function(self):
 | 
				
			||||||
        no_jump_without_trace_function()
 | 
					        no_jump_without_trace_function()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_jump_to_firstlineno(self):
 | 
				
			||||||
 | 
					        # This tests that PDB can jump back to the first line in a
 | 
				
			||||||
 | 
					        # file.  See issue #1689458.  It can only be triggered in a
 | 
				
			||||||
 | 
					        # function call if the function is defined on a single line.
 | 
				
			||||||
 | 
					        code = compile("""
 | 
				
			||||||
 | 
					# Comments don't count.
 | 
				
			||||||
 | 
					output.append(2)  # firstlineno is here.
 | 
				
			||||||
 | 
					output.append(3)
 | 
				
			||||||
 | 
					output.append(4)
 | 
				
			||||||
 | 
					""", "<fake module>", "exec")
 | 
				
			||||||
 | 
					        class fake_function:
 | 
				
			||||||
 | 
					            func_code = code
 | 
				
			||||||
 | 
					            jump = (2, 0)
 | 
				
			||||||
 | 
					        tracer = JumpTracer(fake_function)
 | 
				
			||||||
 | 
					        sys.settrace(tracer.trace)
 | 
				
			||||||
 | 
					        namespace = {"output": []}
 | 
				
			||||||
 | 
					        exec code in namespace
 | 
				
			||||||
 | 
					        sys.settrace(None)
 | 
				
			||||||
 | 
					        self.compare_jump_output([2, 3, 2, 3, 4], namespace["output"])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def test_main():
 | 
					def test_main():
 | 
				
			||||||
    test_support.run_unittest(
 | 
					    test_support.run_unittest(
 | 
				
			||||||
        TraceTestCase,
 | 
					        TraceTestCase,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -140,10 +140,15 @@ frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno)
 | 
				
			||||||
			     new_lineno);
 | 
								     new_lineno);
 | 
				
			||||||
		return -1;
 | 
							return -1;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						else if (new_lineno == f->f_code->co_firstlineno) {
 | 
				
			||||||
	/* Find the bytecode offset for the start of the given line, or the
 | 
							new_lasti = 0;
 | 
				
			||||||
	 * first code-owning line after it. */
 | 
							new_lineno = f->f_code->co_firstlineno;
 | 
				
			||||||
	PyString_AsStringAndSize(f->f_code->co_lnotab, &lnotab, &lnotab_len);
 | 
						}
 | 
				
			||||||
 | 
						else {
 | 
				
			||||||
 | 
							/* Find the bytecode offset for the start of the given
 | 
				
			||||||
 | 
							 * line, or the first code-owning line after it. */
 | 
				
			||||||
 | 
							PyString_AsStringAndSize(f->f_code->co_lnotab,
 | 
				
			||||||
 | 
										 &lnotab, &lnotab_len);
 | 
				
			||||||
		addr = 0;
 | 
							addr = 0;
 | 
				
			||||||
		line = f->f_code->co_firstlineno;
 | 
							line = f->f_code->co_firstlineno;
 | 
				
			||||||
		new_lasti = -1;
 | 
							new_lasti = -1;
 | 
				
			||||||
| 
						 | 
					@ -156,6 +161,7 @@ frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno)
 | 
				
			||||||
				break;
 | 
									break;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* If we didn't reach the requested line, return an error. */
 | 
						/* If we didn't reach the requested line, return an error. */
 | 
				
			||||||
	if (new_lasti == -1) {
 | 
						if (new_lasti == -1) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue