Skip to content
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

bug in the linenumbers for generator/list/set/dict expressions (python 3.8-3.10) #100537

Closed
15r10nk opened this issue Dec 26, 2022 · 3 comments
Closed
Labels
3.8 (EOL) end of life 3.9 only security fixes 3.10 only security fixes type-bug An unexpected behavior, bug, or error

Comments

@15r10nk
Copy link
Contributor

15r10nk commented Dec 26, 2022

The following code produces the wrong line number in the traceback.

script:

import dis

def f():
    return list(q+"" for q in [""])==list(

        q+"" for q in [5])



dis.dis(f.__code__)
f()

output (Python 3.8.12):

  4           0 LOAD_GLOBAL              0 (list)
              2 LOAD_CONST               1 (<code object <genexpr> at 0x7f6d135df9d0, file "genexpr.py", line 4>)
              4 LOAD_CONST               2 ('f.<locals>.<genexpr>')
              6 MAKE_FUNCTION            0
              8 LOAD_CONST               3 (('',))
             10 GET_ITER
             12 CALL_FUNCTION            1
             14 CALL_FUNCTION            1
             16 LOAD_GLOBAL              0 (list)
             18 LOAD_CONST               1 (<code object <genexpr> at 0x7f6d135df9d0, file "genexpr.py", line 4>)
             20 LOAD_CONST               2 ('f.<locals>.<genexpr>')
             22 MAKE_FUNCTION            0

  6          24 LOAD_CONST               4 ((5,))

  4          26 GET_ITER
             28 CALL_FUNCTION            1
             30 CALL_FUNCTION            1
             32 COMPARE_OP               2 (==)
             34 RETURN_VALUE

Disassembly of <code object <genexpr> at 0x7f6d135df9d0, file "genexpr.py", line 4>:
  4           0 LOAD_FAST                0 (.0)
        >>    2 FOR_ITER                14 (to 18)
              4 STORE_FAST               1 (q)
              6 LOAD_FAST                1 (q)
              8 LOAD_CONST               0 ('')
             10 BINARY_ADD
             12 YIELD_VALUE
             14 POP_TOP
             16 JUMP_ABSOLUTE            2
        >>   18 LOAD_CONST               1 (None)
             20 RETURN_VALUE
Traceback (most recent call last):
  File "genexpr.py", line 11, in <module>
    f()
  File "genexpr.py", line 4, in f
    return list(q+"" for q in [""])==list(
  File "genexpr.py", line 4, in <genexpr>
    return list(q+"" for q in [""])==list(                  
TypeError: unsupported operand type(s) for +: 'int' and 'str'

The traceback shows that q is iterating over [""] and the exception says that q is an int.

the expected output in the traceback would be:

  File "genexpr.py", line 6, in <genexpr>
    q+"" for q in [5])

The reason seems to be that the both gerator-expressions are using the same bytecode (it should not be the same bytecode, because the code is on different lines).

Adding one newline changes the situation (which I can not explain).

script:

import dis

def f():
    return list(
        q+"" for q in [""])==list(

        q+"" for q in [5])



dis.dis(f.__code__)
f()

output (Python 3.8.12):

  4           0 LOAD_GLOBAL              0 (list)
              2 LOAD_CONST               1 (<code object <genexpr> at 0x7f493201c9d0, file "genexpr.py", line 4>)
              4 LOAD_CONST               2 ('f.<locals>.<genexpr>')
              6 MAKE_FUNCTION            0

  5           8 LOAD_CONST               3 (('',))

  4          10 GET_ITER
             12 CALL_FUNCTION            1
             14 CALL_FUNCTION            1

  5          16 LOAD_GLOBAL              0 (list)
             18 LOAD_CONST               4 (<code object <genexpr> at 0x7f493201ca80, file "genexpr.py", line 5>)
             20 LOAD_CONST               2 ('f.<locals>.<genexpr>')
             22 MAKE_FUNCTION            0

  7          24 LOAD_CONST               5 ((5,))

  5          26 GET_ITER
             28 CALL_FUNCTION            1
             30 CALL_FUNCTION            1

  4          32 COMPARE_OP               2 (==)
             34 RETURN_VALUE

Disassembly of <code object <genexpr> at 0x7f493201c9d0, file "genexpr.py", line 4>:
  4           0 LOAD_FAST                0 (.0)
        >>    2 FOR_ITER                14 (to 18)

  5           4 STORE_FAST               1 (q)
              6 LOAD_FAST                1 (q)
              8 LOAD_CONST               0 ('')
             10 BINARY_ADD
             12 YIELD_VALUE
             14 POP_TOP
             16 JUMP_ABSOLUTE            2
        >>   18 LOAD_CONST               1 (None)
             20 RETURN_VALUE

Disassembly of <code object <genexpr> at 0x7f493201ca80, file "genexpr.py", line 5>:
  5           0 LOAD_FAST                0 (.0)
        >>    2 FOR_ITER                14 (to 18)

  7           4 STORE_FAST               1 (q)
              6 LOAD_FAST                1 (q)
              8 LOAD_CONST               0 ('')
             10 BINARY_ADD
             12 YIELD_VALUE
             14 POP_TOP
             16 JUMP_ABSOLUTE            2
        >>   18 LOAD_CONST               1 (None)
             20 RETURN_VALUE
Traceback (most recent call last):
  File "genexpr.py", line 12, in <module>
    f()
  File "genexpr.py", line 5, in f
    q+"" for q in [""])==list(
  File "genexpr.py", line 7, in <genexpr>
    q+"" for q in [5])
TypeError: unsupported operand type(s) for +: 'int' and 'str'

I bisected the bug town to this commit: b619b09

The same problem exists also for list/set/dict-expressions

@15r10nk 15r10nk added the type-bug An unexpected behavior, bug, or error label Dec 26, 2022
@sobolevn
Copy link
Member

Looks like it is fixed on main and 3.11:

Traceback (most recent call last):
  File "/Users/sobolev/Desktop/cpython/ex.py", line 12, in <module>
    f()
  File "/Users/sobolev/Desktop/cpython/ex.py", line 5, in f
    q+"" for q in [""])==list(
                         ^^^^^
  File "/Users/sobolev/Desktop/cpython/ex.py", line 7, in <genexpr>
    q+"" for q in [5])
    ~^~~
TypeError: unsupported operand type(s) for +: 'int' and 'str'

@sobolevn sobolevn added 3.10 only security fixes 3.9 only security fixes 3.8 (EOL) end of life labels Dec 27, 2022
@15r10nk
Copy link
Contributor Author

15r10nk commented Dec 27, 2022

Yes, there is no problem in 3.11.

One similar issue I know there is #95150 (which I reported) but this was only a problem if the comprehension are on the same line.

There where some bigger changes in 3.11 for the line number code. It might be that this issue was fixed without knowing that it existed. But this is only speculation.

@iritkatriel
Copy link
Member

3.10 is in security-fix only mode now, so this is out of date.

@iritkatriel iritkatriel closed this as not planned Won't fix, can't repro, duplicate, stale Apr 5, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
3.8 (EOL) end of life 3.9 only security fixes 3.10 only security fixes type-bug An unexpected behavior, bug, or error
Projects
None yet
Development

No branches or pull requests

3 participants