Author control-k
Recipients control-k, serhiy.storchaka
Date 2019-08-29.10:19:18
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1567073958.75.0.110624243546.issue37971@roundup.psfhosted.org>
In-reply-to
Content
Digging around with the disassembler shows that this originates in the bytecode. 
Code:
--------
import dis
src = """
def printingdec(f):
    raise Exception()
    return f

def dummydec(f):
    return f

@printingdec
@dummydec
def foo():
    pass
"""
code = compile(src,filename="bug.py",mode='exec')
print(dis.dis(code))
--------- 

gives on 3.6:
  2           0 LOAD_CONST               0 (<code object printingdec at 0x7f86c87171e0, file "bug.py", line 2>)
              2 LOAD_CONST               1 ('printingdec')
              4 MAKE_FUNCTION            0
              6 STORE_NAME               0 (printingdec)

  6           8 LOAD_CONST               2 (<code object dummydec at 0x7f86c84b8660, file "bug.py", line 6>)
             10 LOAD_CONST               3 ('dummydec')
             12 MAKE_FUNCTION            0
             14 STORE_NAME               1 (dummydec)

  9          16 LOAD_NAME                0 (printingdec)

 10          18 LOAD_NAME                1 (dummydec)
             20 LOAD_CONST               4 (<code object foo at 0x7f86c84b8540, file "bug.py", line 9>)
             22 LOAD_CONST               5 ('foo')
             24 MAKE_FUNCTION            0
             26 CALL_FUNCTION            1
             28 CALL_FUNCTION            1
             30 STORE_NAME               2 (foo)
             32 LOAD_CONST               6 (None)
             34 RETURN_VALUE
None



and on 3.9:
  2           0 LOAD_CONST               0 (<code object printingdec at 0x7f5e13aaca80, file "bug.py", line 2>)
              2 LOAD_CONST               1 ('printingdec')
              4 MAKE_FUNCTION            0
              6 STORE_NAME               0 (printingdec)

  6           8 LOAD_CONST               2 (<code object dummydec at 0x7f5e13aacb30, file "bug.py", line 6>)
             10 LOAD_CONST               3 ('dummydec')
             12 MAKE_FUNCTION            0
             14 STORE_NAME               1 (dummydec)

  9          16 LOAD_NAME                0 (printingdec)

 10          18 LOAD_NAME                1 (dummydec)

 11          20 LOAD_CONST               4 (<code object foo at 0x7f5e13aacbe0, file "bug.py", line 9>)
             22 LOAD_CONST               5 ('foo')
             24 MAKE_FUNCTION            0
             26 CALL_FUNCTION            1
             28 CALL_FUNCTION            1
             30 STORE_NAME               2 (foo)
             32 LOAD_CONST               6 (None)
             34 RETURN_VALUE

Disassembly of <code object printingdec at 0x7f5e13aaca80, file "bug.py", line 2>:
  3           0 LOAD_GLOBAL              0 (Exception)
              2 CALL_FUNCTION            0
              4 RAISE_VARARGS            1

  4           6 LOAD_FAST                0 (f)
              8 RETURN_VALUE

Disassembly of <code object dummydec at 0x7f5e13aacb30, file "bug.py", line 6>:
  7           0 LOAD_FAST                0 (f)
              2 RETURN_VALUE

Disassembly of <code object foo at 0x7f5e13aacbe0, file "bug.py", line 9>:
 12           0 LOAD_CONST               0 (None)
              2 RETURN_VALUE
None


The change from 3.6 seems to be that a new line number is introduced for instruction 20, loading the function code, which seems reasonable.
It would feel natural if the line number of the decorator would be used for instructions 26 & 28, the decorator call.
History
Date User Action Args
2019-08-29 10:19:18control-ksetrecipients: + control-k, serhiy.storchaka
2019-08-29 10:19:18control-ksetmessageid: <1567073958.75.0.110624243546.issue37971@roundup.psfhosted.org>
2019-08-29 10:19:18control-klinkissue37971 messages
2019-08-29 10:19:18control-kcreate