
Tim Peters wrote:
[Vladimir Marangozov]
... And the whole point of the solution we were thinking of is to make sure that the debugger (and other objects, like tracebacks) do read the line number only when the main loop fires a "line" event via a hook.
Given the state of the art, however, nobody can guarantee that the line number is not fetched in legacy code from the frame directly, through f.lineno (for whatever purpose).
I really don't think we care about that. Guido, do we <wink>?
f_lineno is conceptually an internal implementation detail of frame objects, and Guido has often warned that if you access the internals you're on your own (I don't think even Michael's bytecodehacks cares about this one <wink>). So long as all uses of f_lineno in the std distribution can be faked, I think it's fine to just get rid of that member.
WRT your later msg, strongly doubt tstate->ticker will help: it's an integer in range(tstate->interp->checkinterval + 1), and wraps around over & over. Besides, the modular base (checkinterval) can be changed by the user at any time. tstate->ticker is thus but the circular shadow of a legion of ghosts.
It isn't worth all these brain cells just to preserve an internal detail!
It is! <wink>
OK, it would be worth it if it were easy <wink> -- but it's not.
It is! I think I found the solution :-) Whenever f.f_lineno is accessed, the compiler generates a LOAD_ATTR relative to f. Therefore, updating f->f_lasti = INSTR_OFFSET() in LOAD_ATTR + trapping "lineno" access in frameobject.c with PyCode_Addr2Line(f->f_lasti) ensures that we'll always get the right line number. Of course, this makes the update of f->f_lasti for every LOAD_ATTR, but given the ranking of SET_LINENO compared to LOAD_ATTR in the DXP and MAL's frequency charts, I think this is a pure win! Et voila <wink>. I'll update my patch at SF later. now-back-to-work'ly y'rs -- Vladimir MARANGOZOV | Vladimir.Marangozov@inrialpes.fr http://sirac.inrialpes.fr/~marangoz | tel:(+33-4)76615277 fax:76615252