◐ Shell
reader mode source ↗
Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
File filter
Conversations
Jump to
Diff view
Apply and reload
Show whitespace
Diff view
Apply and reload
31 changes: 16 additions & 15 deletions Doc/library/dis.rst
Original file line number Diff line number Diff line change
@@ -726,9 +726,8 @@ iterations of the loop.

.. opcode:: BEGIN_FINALLY

Pushes ``NULL`` onto the stack for using it in :opcode:`END_FINALLY`,
:opcode:`POP_FINALLY`, :opcode:`WITH_CLEANUP_START` and
:opcode:`WITH_CLEANUP_FINISH`. Starts the :keyword:`finally` block.

.. versionadded:: 3.8

Expand Up @@ -774,29 +773,31 @@ iterations of the loop.

Starts cleaning up the stack when a :keyword:`with` statement block exits.

At the top of the stack are either ``NULL`` (pushed by
:opcode:`BEGIN_FINALLY`) or 6 values pushed if an exception has been
raised in the with block. Below is the context manager's
:meth:`~object.__exit__` or :meth:`~object.__aexit__` bound method.

If TOS is ``NULL``, calls ``SECOND(None, None, None)``,
removes the function from the stack, leaving TOS, and pushes ``None``
to the stack. Otherwise calls ``SEVENTH(TOP, SECOND, THIRD)``,
shifts the bottom 3 values of the stack down, replaces the empty spot
with ``NULL`` and pushes TOS. Finally pushes the result of the call.


.. opcode:: WITH_CLEANUP_FINISH

Finishes cleaning up the stack when a :keyword:`with` statement block exits.

TOS is result of ``__exit__()`` or ``__aexit__()`` function call pushed
by :opcode:`WITH_CLEANUP_START`. SECOND is ``None`` or an exception type
(pushed when an exception has been raised).

Pops two values from the stack. If SECOND is not None and TOS is true
unwinds the EXCEPT_HANDLER block which was created when the exception
was caught and pushes ``NULL`` to the stack.


All of the following opcodes use their arguments.
Expand Down
3 changes: 2 additions & 1 deletion Lib/importlib/_bootstrap_external.py
Original file line number Diff line number Diff line change
@@ -266,6 +266,7 @@ def _write_atomic(path, data, mode=0o666):
# Python 3.8a1 3400 (move frame block handling to compiler #17611)
# Python 3.8a1 3401 (add END_ASYNC_FOR #33041)
# Python 3.8a1 3410 (PEP570 Python Positional-Only Parameters #36540)
#
# MAGIC must change whenever the bytecode emitted by the compiler may no
# longer be understood by older implementations of the eval loop (usually
Expand All @@ -274,7 +275,7 @@ def _write_atomic(path, data, mode=0o666):
# Whenever MAGIC_NUMBER is changed, the ranges in the magic_values array
# in PC/launcher.c must also be updated.

MAGIC_NUMBER = (3410).to_bytes(2, 'little') + b'\r\n'
_RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little') # For import.c

_PYCACHE = '__pycache__'
Expand Down
39 changes: 21 additions & 18 deletions Lib/test/test_dis.py
Original file line number Diff line number Diff line change
Expand Up @@ -752,11 +752,12 @@ async def async_def():
Positional-only arguments: 0
Kw-only arguments: 0
Number of locals: 2
Stack size: 10
Flags: OPTIMIZED, NEWLOCALS, NOFREE, COROUTINE
Constants:
0: None
1: 1
Names:
0: b
1: c
Expand Down Expand Up @@ -977,7 +978,7 @@ def jumpy():
Instruction(opname='LOAD_CONST', opcode=100, arg=6, argval='Who let lolcatz into this test suite?', argrepr="'Who let lolcatz into this test suite?'", offset=96, starts_line=None, is_jump_target=False),
Instruction(opname='CALL_FUNCTION', opcode=131, arg=1, argval=1, argrepr='', offset=98, starts_line=None, is_jump_target=False),
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=100, starts_line=None, is_jump_target=False),
Instruction(opname='SETUP_FINALLY', opcode=122, arg=70, argval=174, argrepr='to 174', offset=102, starts_line=20, is_jump_target=True),
Instruction(opname='SETUP_FINALLY', opcode=122, arg=12, argval=118, argrepr='to 118', offset=104, starts_line=None, is_jump_target=False),
Instruction(opname='LOAD_CONST', opcode=100, arg=5, argval=1, argrepr='1', offset=106, starts_line=21, is_jump_target=False),
Instruction(opname='LOAD_CONST', opcode=100, arg=7, argval=0, argrepr='0', offset=108, starts_line=None, is_jump_target=False),
Expand All @@ -997,29 +998,31 @@ def jumpy():
Instruction(opname='CALL_FUNCTION', opcode=131, arg=1, argval=1, argrepr='', offset=136, starts_line=None, is_jump_target=False),
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=138, starts_line=None, is_jump_target=False),
Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=140, starts_line=None, is_jump_target=False),
Instruction(opname='JUMP_FORWARD', opcode=110, arg=26, argval=170, argrepr='to 170', offset=142, starts_line=None, is_jump_target=False),
Instruction(opname='END_FINALLY', opcode=88, arg=None, argval=None, argrepr='', offset=144, starts_line=None, is_jump_target=True),
Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=146, starts_line=25, is_jump_target=True),
Instruction(opname='SETUP_WITH', opcode=143, arg=14, argval=164, argrepr='to 164', offset=148, starts_line=None, is_jump_target=False),
Instruction(opname='STORE_FAST', opcode=125, arg=1, argval='dodgy', argrepr='dodgy', offset=150, starts_line=None, is_jump_target=False),
Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=152, starts_line=26, is_jump_target=False),
Instruction(opname='LOAD_CONST', opcode=100, arg=9, argval='Never reach this', argrepr="'Never reach this'", offset=154, starts_line=None, is_jump_target=False),
Instruction(opname='CALL_FUNCTION', opcode=131, arg=1, argval=1, argrepr='', offset=156, starts_line=None, is_jump_target=False),
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=158, starts_line=None, is_jump_target=False),
Instruction(opname='POP_BLOCK', opcode=87, arg=None, argval=None, argrepr='', offset=160, starts_line=None, is_jump_target=False),
Instruction(opname='BEGIN_FINALLY', opcode=53, arg=None, argval=None, argrepr='', offset=162, starts_line=None, is_jump_target=False),
Instruction(opname='WITH_CLEANUP_START', opcode=81, arg=None, argval=None, argrepr='', offset=164, starts_line=None, is_jump_target=True),
Instruction(opname='WITH_CLEANUP_FINISH', opcode=82, arg=None, argval=None, argrepr='', offset=166, starts_line=None, is_jump_target=False),
Instruction(opname='END_FINALLY', opcode=88, arg=None, argval=None, argrepr='', offset=168, starts_line=None, is_jump_target=False),
Instruction(opname='POP_BLOCK', opcode=87, arg=None, argval=None, argrepr='', offset=170, starts_line=None, is_jump_target=True),
Instruction(opname='BEGIN_FINALLY', opcode=53, arg=None, argval=None, argrepr='', offset=172, starts_line=None, is_jump_target=False),
Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=174, starts_line=28, is_jump_target=True),
Instruction(opname='LOAD_CONST', opcode=100, arg=10, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=176, starts_line=None, is_jump_target=False),
Instruction(opname='CALL_FUNCTION', opcode=131, arg=1, argval=1, argrepr='', offset=178, starts_line=None, is_jump_target=False),
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=180, starts_line=None, is_jump_target=False),
Instruction(opname='END_FINALLY', opcode=88, arg=None, argval=None, argrepr='', offset=182, starts_line=None, is_jump_target=False),
Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=184, starts_line=None, is_jump_target=False),
Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=186, starts_line=None, is_jump_target=False),
]

# One last piece of inspect fodder to check the default line number handling
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
2 changes: 1 addition & 1 deletion Objects/frameobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno, void *Py_UNUSED(ignore
delta++;
}
}
if (op != FOR_ITER && code[target_addr] != END_ASYNC_FOR) {
blockstack[blockstack_top++] = target_addr;
}
break;
Expand Down
Loading
Toggle all file notes Toggle all file annotations