This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: Incorrect stacksize in code object
Type: compile error Stage: resolved
Components: Interpreter Core Versions: Python 3.9
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: Nosy List: serhiy.storchaka, skip.montanaro
Priority: normal Keywords:

Created on 2020-04-18 03:37 by skip.montanaro, last changed 2022-04-11 14:59 by admin. This issue is now closed.

Messages (3)
msg366692 - (view) Author: Skip Montanaro (skip.montanaro) * (Python triager) Date: 2020-04-18 03:37
Consider this trivial function:

>>> def f():
...   while True:
...     pass
...

and its disassembly:

>>> dis.dis(f)
  3     >>    0 JUMP_ABSOLUTE               0
              2 LOAD_CONST                  0 (None)
              4 RETURN_VALUE

Despite its infinite-loop-ness, the generated LOAD_CONST/RETURN_VALUE pair suggests the code object's stacksize should be 1, but it's 0:

>>> print(f.__code__.co_stacksize)
0

I understand that the compiler might have decided the code was unreachable and the LOAD_CONST instruction would never be reached, but if that was the case, why would that instruction pair be generated?

This is only of interest because my register virtual machine translator trusts that the co_nlocals and co_stacksize attributes of the code object reflect the actual space allocation in the frame object. I can use

max(1, f.__code__.co_stacksize + f.__code__.co_nlocals)

as the allocated locals+stack space. (That first slot in the frame object will always be available.) That makes this example translate, but doesn't guarantee there's not a bug in determination of the stack size which could pop up again later.
msg366694 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2020-04-18 07:21
The stack size is correct. The unreachable code is left because some code (in particularly the lineno setter of the frame object) depends on instructions which may be in the unreachable code to determines the boundaries of programming blocks. It is safer to keep some unreachable code.

You can just ignore the code which uses the stack past co_stacksize.
msg366707 - (view) Author: Skip Montanaro (skip.montanaro) * (Python triager) Date: 2020-04-18 12:47
Thanks, Serhiy.
History
Date User Action Args
2022-04-11 14:59:29adminsetgithub: 84495
2020-04-18 12:47:24skip.montanarosetstatus: open -> closed
resolution: not a bug
messages: + msg366707

stage: resolved
2020-04-18 07:21:28serhiy.storchakasetnosy: + serhiy.storchaka
messages: + msg366694
2020-04-18 03:37:01skip.montanarocreate