GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — `dis.dis()` reports line numbers where there are none. · Issue #107932 · python/cpython

dis.dis() reports line numbers where there are none. #107932

New issue
Copy link
New issue
Copy link
Closed
#107988
Closed
dis.dis() reports line numbers where there are none.#107932
#107988
Copy link
Labels
type-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error

Description

@markshannon
markshannon
opened on Aug 14, 2023
Issue body actions

Take this example function from #107901:

def f():
   for i in range(30000000):
      if not i%1000000:
          pass

dis.dis produces the following output:

  1           0 RESUME                   0

  2           2 LOAD_GLOBAL              1 (range + NULL)
             12 LOAD_CONST               1 (30000000)
             14 CALL                     1
             22 GET_ITER
        >>   24 FOR_ITER                14 (to 56)
             28 STORE_FAST               0 (i)

  3          30 LOAD_FAST                0 (i)
             32 LOAD_CONST               2 (1000000)
             34 BINARY_OP                6 (%)
             38 TO_BOOL
             46 POP_JUMP_IF_FALSE        2 (to 52)
             48 JUMP_BACKWARD           14 (to 24)

  4     >>   52 JUMP_BACKWARD           16 (to 24)

  2     >>   56 END_FOR
             58 RETURN_CONST             0 (None)

Which has incorrect line numbers.
The issue is not that the line numbers are wrong, but that you can't tell from the dis output.
The whole point of dis is show what is going on at the bytecode level, so it is failing if it gives wrong line numbers.
The actual line numbers can be see from co_lines()

>>> list(f.__code__.co_lines())
[(0, 2, 1), (2, 30, 2), (30, 48, 3), (48, 52, None), (52, 56, 4), (56, 60, 2)]

The correct output should be:

   1           0 RESUME                   0

   2           2 LOAD_GLOBAL              1 (range + NULL)
              12 LOAD_CONST               1 (30000000)
              14 CALL                     1
              22 GET_ITER
         >>   24 FOR_ITER                14 (to 56)
              28 STORE_FAST               0 (i)

   3          30 LOAD_FAST                0 (i)
              32 LOAD_CONST               2 (1000000)
              34 BINARY_OP                6 (%)
              38 TO_BOOL
              46 POP_JUMP_IF_FALSE        2 (to 52)
None          48 JUMP_BACKWARD           14 (to 24)

   4     >>   52 JUMP_BACKWARD           16 (to 24)

   2     >>   56 END_FOR
              58 RETURN_CONST             0 (None)

Linked PRs

  • gh-107932: Fix dis module for bytecode that does not have an associated source line #107988
  • gh-107932: Fix test_dis #108479
  • gh-107932: Fix merge conflict in test_dis #108478
Reacted by sunmy2019

Activity

  1. markshannon
    added
    type-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
    on Aug 14, 2023
  2. markshannon commented on Aug 14, 2023

    @markshannon
    markshannon
    on Aug 14, 2023
    MemberAuthor
    More actions

    I've submitted this as a "bug", but it could be argued it is a behavior change, so I think it shouldn't be backported.

    @iritkatriel thoughts?

  3. iritkatriel commented on Aug 14, 2023

    @iritkatriel
    iritkatriel
    on Aug 14, 2023
    Member
    More actions

    I think I'd call it a bug and backport.

  4. CorvinM commented on Aug 14, 2023

    @CorvinM
    CorvinM
    on Aug 14, 2023
    Contributor
    More actions

    Are bytecodes that do not map back to any source line intended behavior? Older versions of python seem to not generate the bytecode that has no source line for this fragment (tested on 3.10)

    Was working on a PR for this but most of dis.py makes the assumption of every bytecode has a source line so the behavior change is getting vague and messy quickly. For example findlinestarts() ignores line=None so dis() (and many of the other exported functions that depend on it) group these lines in with the previous block of bytecodes.

    I'm happy to keep working on the patch but looking for some assurance the actual "bug" is disassembly related rather than in the bytecode generator before continuing further.

  5. carljm commented on Aug 15, 2023

    @carljm
    carljm
    on Aug 15, 2023
    Member
    More actions

    It is definitely intentional that the compiler can generate instructions that are "synthetic" and don't map directly to any line number in the source. And yes, this is a change in recent Python versions, that didn't used to be possible. So it's not too surprising that dis.py may have "every instruction has a line number" assumptions built into it, and it may not be a trivial change (and may require some design decisions) to untangle those assumptions correctly.

    Reacted by Corvin McPherson
  6. CorvinM
    added 2 commits that reference this issue on Aug 15, 2023

    Fix dis module for bytecode that does not have an associated source line

    This issue will close once commit 751f57f is merged into the 'main' branch.
    751f57f

    WIP Merge branch 'main' into pythongh-107932

    This issue will close once commit c8aaa8d is merged into the 'main' branch.
    c8aaa8d
  7. markshannon
    closed this as completedin #107988on Aug 25, 2023
  8. markshannon
    added a commit that references this issue on Aug 25, 2023

    gh-107932: Fix dis module for bytecode that does not have an associat…

    24aa249
  9. erlend-aasland
    added a commit that references this issue on Aug 25, 2023

    pythongh-107932: Fix test_dis

    2593565
  10. serhiy-storchaka commented on Aug 25, 2023

    @serhiy-storchaka
    serhiy-storchaka
    on Aug 25, 2023
    Member
    More actions

    It broke the tests.

  11. serhiy-storchaka
    reopened this on Aug 25, 2023
  12. AlexWaygood commented on Aug 25, 2023

    @AlexWaygood
    AlexWaygood
    on Aug 25, 2023
    Member
    More actions

    It broke the tests.

    They will be fixed by #108478 @serhiy-storchaka

  13. markshannon
    added a commit that references this issue on Aug 25, 2023

    gh-107932: Fix merge conflict in test_dis (GH-108478)

    bc2f9e6
  14. AlexWaygood commented on Aug 25, 2023

    @AlexWaygood
    AlexWaygood
    on Aug 25, 2023
    Member
    More actions

    It broke the tests.

    They will be fixed by #108478 @serhiy-storchaka

    now merged

    Reacted by Serhiy Storchaka
  15. AlexWaygood
    closed this as completedon Aug 25, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    type-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      You are visitor 01402503 — GeezerVison does not store the pages you look up.
      Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.