Skip to content

branch coverage of with statement in 2.7 #128

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
nedbat opened this issue May 18, 2011 · 4 comments
Closed

branch coverage of with statement in 2.7 #128

nedbat opened this issue May 18, 2011 · 4 comments
Labels
branch bug Something isn't working

Comments

@nedbat
Copy link
Owner

nedbat commented May 18, 2011

Originally reported by Christian Heimes (Bitbucket: tiran, GitHub: tiran)


With Python 2.7, branch detection doesn't get a with statement right with an inner return right. Coverage show the line "with open("test", "w") as f" as a branch, that never reaches "exit". Under Python 2.6 the with statement is shown as fully covered.

#!python

def example(): 
    with open("test", "w") as f: # exit
        f.write("") 
        return 1 
 
example() 

Tested with coverage 3.4 and 3.5a1.


@nedbat
Copy link
Owner Author

nedbat commented May 19, 2011

Original comment by Christian Heimes (Bitbucket: tiran, GitHub: tiran)


The problem could be caused by a change in Python 2.7's context protocol. Since 2.7 the enter and exit methods are looked up on the type rather than on the object. The lookup is done in the new opcode SETUP_WITH.

Python 2.7 dis

>>> dis.dis(cov.example)
  2           0 LOAD_GLOBAL              0 (open)
              3 LOAD_CONST               1 ('test')
              6 LOAD_CONST               2 ('w')
              9 CALL_FUNCTION            2
             12 SETUP_WITH              24 (to 39)
             15 STORE_FAST               0 (f)

  3          18 LOAD_FAST                0 (f)
             21 LOAD_ATTR                1 (write)
             24 LOAD_CONST               3 ('')
             27 CALL_FUNCTION            1
             30 POP_TOP             

  4          31 LOAD_CONST               4 (1)
             34 RETURN_VALUE        
             35 POP_BLOCK           
             36 LOAD_CONST               0 (None)
        >>   39 WITH_CLEANUP        
             40 END_FINALLY         
             41 LOAD_CONST               0 (None)
             44 RETURN_VALUE        

Python 2.6 dis

>>> dis.dis(cov.example)
  2           0 LOAD_GLOBAL              0 (open)
              3 LOAD_CONST               1 ('test')
              6 LOAD_CONST               2 ('w')
              9 CALL_FUNCTION            2
             12 DUP_TOP             
             13 LOAD_ATTR                1 (__exit__)
             16 ROT_TWO             
             17 LOAD_ATTR                2 (__enter__)
             20 CALL_FUNCTION            0
             23 STORE_FAST               0 (_[1])
             26 SETUP_FINALLY           30 (to 59)
             29 LOAD_FAST                0 (_[1])
             32 DELETE_FAST              0 (_[1])
             35 STORE_FAST               1 (f)

  3          38 LOAD_FAST                1 (f)
             41 LOAD_ATTR                3 (write)
             44 LOAD_CONST               3 ('')
             47 CALL_FUNCTION            1
             50 POP_TOP             

  4          51 LOAD_CONST               4 (1)
             54 RETURN_VALUE        
             55 POP_BLOCK           
             56 LOAD_CONST               0 (None)
        >>   59 WITH_CLEANUP        
             60 END_FINALLY         
             61 LOAD_CONST               0 (None)
             64 RETURN_VALUE        

@nedbat
Copy link
Owner Author

nedbat commented Aug 10, 2011

Turns out this was fixed in <<changeset 52789af288d1 (bb)>>, and discovered as tested in <<changeset de3815101d3d (bb)>>.

@nedbat
Copy link
Owner Author

nedbat commented Jul 25, 2013

Original comment by Gre7g Luterman (Bitbucket: gre7g, GitHub: gre7g)


I'm experiencing this issue too.

Coverage 3.6, tried both Python 2.6 and Python 2.7 and had the same results.

Screenshot: http://screencast.com/t/SRFFWkwFyHAU

@nedbat
Copy link
Owner Author

nedbat commented Jul 30, 2013

@gre7g: This issue is marked as resolved, can you provide a sample that demonstrates it still happening? Even if you can just point to an open source project with runnable tests that show it happening?

Notice that the original problem report mentioned a return statement inside a with statement, which is not how your code is structured.

@nedbat nedbat closed this as completed Jul 30, 2013
@nedbat nedbat added major bug Something isn't working branch labels Jun 23, 2018
agronholm added a commit to agronholm/coveragepy that referenced this issue Aug 16, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
branch bug Something isn't working
Projects
None yet
Development

No branches or pull requests

1 participant