FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

Incorrect locations for code following `case` blocks · Issue #103971 · python/cpython · GitHub

Repository navigation

Incorrect locations for code following case blocks #103971

Closed

Description

Bug report

In the following example, the debugger hits a breakpoint that is set in the aVariable = ... line, which is in an if-statement whose condition is False and which should therefore not be executed. When I run the example with coverage (under PyCharm 2023.1), that line turns green. The print statement is not executed, which matches the expectation.

The assignment does not actually happen. It somehow just hits the line without really executing it.

Minimal reproducible example:

match 1:
    case 1:
        if False:
            print('this should not be executed')
            aVariable = 'somehow, we can hit a breakpoint here'

The same happens, if the last statement in the unreachable code is a pass. If I replace it with e.g. a print() statement, then everything behaves as expected.

If we extend the example a little bit, that behavior is reproducible for an unreachable else block, too:

match 1:
    case 1:
        if True:
            pass
        else:
            anotherVariable = 'somehow, we can hit a breakpoint here, too'

Your environment

python --version
Python 3.11.3
lsb_release -a
No LSB modules are available.
Distributor ID:	Ubuntu
Description:	Ubuntu 22.04.2 LTS
Release:	22.04
Codename:	jammy

I initially encountered that behavior in a 3.10 version. Due to the fact that I thought, I could fix it with an upgrade to 3.11, I don't know the exact minor version of 3.10.

I double-checked this with the first online Python debugger that I could find and it behaves the same way.

Linked PRs

Activity

  1. gaogaotiantian commented on Apr 28, 2023

    Member

    Confirmed that this happens with pdb on 3.11 too. Not reproducible in main, bytecode is different.

    3.11:

      0           0 RESUME                   0
    
      1           2 LOAD_CONST               0 (1)
    
      2           4 LOAD_CONST               0 (1)
                  6 COMPARE_OP               2 (==)
                 12 POP_JUMP_FORWARD_IF_FALSE     3 (to 20)
    
      3          14 NOP
    
      5          16 LOAD_CONST               4 (None)
                 18 RETURN_VALUE
    
      2     >>   20 LOAD_CONST               4 (None)
                 22 RETURN_VALUE

    RETURN_VALUE was set at the last line(5) of the case block, so even though it's unreachable, it was hit.

    3.12(main):

      0           0 RESUME                   0
    
      1           2 LOAD_CONST               0 (1)
    
      2           4 LOAD_CONST               0 (1)
                  6 COMPARE_OP              40 (==)
                 10 POP_JUMP_IF_FALSE        1 (to 14)
    
      3          12 RETURN_CONST             1 (None)
    
      2     >>   14 RETURN_CONST             1 (None)

    RETURN_CONST is at line 3, which is correct.

    Not 100% sure if this is a bug that we want to fix in 3.11? 3.10 is already closed for bug fix right? We need expertise from the compiler side.

  2. brandtbucher commented on Apr 28, 2023

    Member

    Yeah, this is a bug, and should be fixed in 3.11. From a first glance, this should be as simple as saving and restoring the current location when entering/exiting case bodies in the compiler.

    Any takers? Otherwise, I can pick it up.

  3. added
    interpreter-core(Objects, Python, Grammar, and Parser dirs)
    3.11only security fixes
    triagedThe issue has been accepted as valid by a triager.
    on Apr 28, 2023
  4. self-assigned this
    on Apr 28, 2023
  5. brandtbucher commented on Apr 28, 2023

    Member

    There are two places where VISIT_SEQ(c, stmt, m->body); is called in the 3.11 version of compile.c. I think that the fix should be as simple as calling UNSET_LOC(c); after each, to keep the last line number from leaking into the following control-flow.

  6. brandtbucher commented on Apr 28, 2023

    Member

    This will also need one or more regression tests for the cases shown here. Thankfully, we already have good scaffolding for that in test.test_patma.TestTracing.

    Even though the bug is only in 3.11, I'd like to see the tests forward-ported to 3.12 after.

  7. terryjreedy commented on Apr 28, 2023

    Member

    I reproduced this in IDLE's debugger. Either 'Go' or 'Step, Step, Step' skips over line 4 to line 5, but a subsequent Go/Step does not execute line 5. Change line 5 to a print and is is skipped as expected. IDLE Debugger uses a subclass of bdb, so the bug is not in pdb.

  8. brandtbucher commented on Apr 28, 2023

    Member

    Yep, this is a compiler bug (3.12 cleaned up how we handle locations to avoid issues like this, which is why it's silently fixed there).

  9. added a commit that references this issue on Apr 28, 2023
  10. marvinweitzel commented on Apr 28, 2023

    Author

    I just wanted to say how much I appreciate your responses and your extremely fast investigation of this issue.

    Thanks a lot for taking this seriously!

  11. changed the title [-]Match-case can hit a breakpoint in unreachable code and coverage turns green for that line[/-] [+]Incorrect line numbers following `case` blocks[/+] on Apr 28, 2023
  12. changed the title [-]Incorrect line numbers following `case` blocks[/-] [+]Incorrect locations for code following `case` blocks[/+] on Apr 28, 2023
  13. added a commit that references this issue on Apr 28, 2023
  14. added a commit that references this issue on Apr 28, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

3.11only security fixeseasyinterpreter-core(Objects, Python, Grammar, and Parser dirs)triagedThe issue has been accepted as valid by a triager.type-bugAn unexpected behavior, bug, or error

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions


    Back | FazBrowse Home | New Git URL