fix: sysmon coverage for nested context managers#2123
fix: sysmon coverage for nested context managers#2123miketheman wants to merge 5 commits intocoveragepy:mainfrom
Conversation
Signed-off-by: Mike Fiedler <miketheman@gmail.com>
Signed-off-by: Mike Fiedler <miketheman@gmail.com>
Signed-off-by: Mike Fiedler <miketheman@gmail.com>
Signed-off-by: Mike Fiedler <miketheman@gmail.com>
fc197cc to
02cca71
Compare
|
Can you tell me more about the theory of this fix? I was surprised to see UNWIND events handled, since this problem didn't involve exceptions. Indeed, deleting that addition didn't change the outcome. We don't need the UNWIND handling. What does last_lines do for us here and how does it fix the measurement of with statements? |
I can back that out, however my understanding is if there's an observed exception during the test suite run, memory will bloat since
It maps each active function call (by frame id) to the last line we saw in it. Why do we need to track stuff? When we see a LINE event, remember it. When we see the next LINE event, record the transition. An example: LINE event: line 5 → remember "last line was 5" Previously, sysmon would say "I've seen line 5, don't tell me about it again." Now we need to hear about every line execution to track transitions. |
|
Oh, I hadn't noticed this yet: # Don't return DISABLE: keep getting LINE events for arc tracking.
return NoneThis undoes the entire benefit of sys.monitoring. If we're going to change that we might as well use the C tracer. |
Instead of disabling all line visits for all lines, only do so when we encounter a multi-visit, like in a `with` block, thus preserving most of sysmon's performance benefits in most cases. Signed-off-by: Mike Fiedler <miketheman@gmail.com>
Very good point - shows how much I know about sysmon! 🤦 I took another pass at this, and added a helper method that checks the bytecode and makes a decision based on that, so the sysmon performance would be preserved for most code except those using these deeply-nested context managers. Let me know what you think! |
| return jumps | ||
|
|
||
|
|
||
| def multi_visit_lines(code: CodeType) -> set[TLineNo]: |
There was a problem hiding this comment.
This is interesting. Can you show the dis output of the with statements to help me understand what this function is identifying?
There was a problem hiding this comment.
I tried to get some information this way, by replacing the behavior from InstructionWalker with inline calls to dis - I'm not 100% certain it's right, but maybe it helps? https://gist.github.com/miketheman/0ff15be2efea2573ae46e52bef069c77#file-debug1_output-txt
Resolves #1987