[Python-Dev] line numbers, pass statements, implicit returns (original) (raw)
Jeremy Hylton jeremy at alum.mit.edu
Tue Apr 4 21:45:16 CEST 2006
- Previous message: [Python-Dev] line numbers, pass statements, implicit returns
- Next message: [Python-Dev] Saving the hash value of tuples
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
On 4/2/06, Guido van Rossum <guido at python.org> wrote:
On 4/1/06, Jeremy Hylton <jeremy at alum.mit.edu> wrote: > There are several test cases in testtrace that are commented out. We > did this when we merged the ast-branch and promised to come back to > them. I'm coming back to them now, but the test aren't documented > well and the feature they test isn't specified well. > > The failing tests I've looked at so far involving pass statements and > implicit "return None" statements generated by the compiler. The > tests seem to verify that > > 1) if you have a function that ends with an if/else where the body > of the else is pass, > there is no line number associated with the return > 2) if you have a function that ends with a try/except where the > body of the except is pass, > there is a line number associated with the return. > > Here's a failing example > > def ireturnexample(): > a = 5 > b = 5 > if a == b: > b = a+1 > else: > pass > > The code is traced and testtrace verifies that the return is > associated with line 4! > > In these cases, the ast compiler will always associate a line number > with the return. (Technically with the LOADCONST preceding the > RETURNVALUE.) This happens pretty much be accident. It always > associates a line number with the first opcode generated after a new > statement is visited. Since a Pass statement node has no opcode, the > return generates the first opcode. > > Now I could add some special cases to the compiler to preserve the old > behavior, the question is: Why bother? It's such an unlikely case (an > else that has no effect). Does anyone depend on the current behavior > for the ireturnexample()? It seems sensible to me to always generate > a line number for the pass + return case, just so you see the control > flow as you step through the debugger.
Makes sense to me. I can't imagine what this was testing except perhaps a corner case in the algorithm for generating the (insanely complicated) linenumber mapping table. > The other case that has changed is that the new compiler does not > generate code for "while 0:" I don't remember why <0.5 wink>. There > are several test cases that verify line numbers for code using this > kind of bogus construct. There are no lines anymore, so I would > change the tests so that they don't expect the lines in question. But > I have no idea what they are trying to test. Does anyone know? Not me. This is definitely not part of the language spec! :-)
It needs to be part of some spec, I think. It's probably part of the implementation rather than the language, but we need some description of what the trace hooks are supposed to do. The unittests are some kind of spec, but not a great one (because they don't seem exhaustive and don't explain why they work the way they do). Should we write an informational PEP, then, that explains the conditions under which you get a line event in trace mode? And how much do we care about compatibility from release to release?
Here's another case that came up while pursuing these tests. It looks like the old compiler generated lnotab entries with a 0 change in line number, merely so that the trace code would generate an event on that line. The problem case is a for loop, where there is a line number set for the SETUP_LOOP instruction. You'd like a line event for the last time through the for loop, when the iterator is consumed, and to get that it appears that the lnotab has an entry with a 0 increment in line number and a non-zero increment in bytecode offset. There's no comment in the lnotab code that mentions that as a possibility, so it came as a surprise to me :-). The question, then, is how many cases are there like this. It may only be possible to answer this by walking through the old compiler code and noting all the uncommented special cases.
Looks like a project for alpha 2.
Jeremy
- Previous message: [Python-Dev] line numbers, pass statements, implicit returns
- Next message: [Python-Dev] Saving the hash value of tuples
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]