Skip to content

Commit 3fe921c

Browse files
authored
Revert "bpo-43693: Add the MAKE_CELL opcode and interleave fast locals offsets. (gh-26396)" (GH-26597)
This reverts commit 631f993.
1 parent 781dc76 commit 3fe921c

File tree

16 files changed

+4231
-4466
lines changed

16 files changed

+4231
-4466
lines changed

Doc/library/dis.rst

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1056,14 +1056,6 @@ All of the following opcodes use their arguments.
10561056
Deletes local ``co_varnames[var_num]``.
10571057

10581058

1059-
.. opcode:: MAKE_CELL (i)
1060-
1061-
Creates a new cell in slot ``i``. If that slot is empty then
1062-
that value is stored into the new cell.
1063-
1064-
.. versionadded:: 3.11
1065-
1066-
10671059
.. opcode:: LOAD_CLOSURE (i)
10681060

10691061
Pushes a reference to the cell contained in slot ``i`` of the "fast locals"

Include/cpython/code.h

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,9 @@
22
# error "this header file must not be included directly"
33
#endif
44

5-
/* Each instruction in a code object is a fixed-width value,
6-
* currently 2 bytes: 1-byte opcode + 1-byte oparg. The EXTENDED_ARG
7-
* opcode allows for larger values but the current limit is 3 uses
8-
* of EXTENDED_ARG (see Python/wordcode_helpers.h), for a maximum
9-
* 32-bit value. This aligns with the note in Python/compile.c
10-
* (compiler_addop_i_line) indicating that the max oparg value is
11-
* 2**32 - 1, rather than INT_MAX.
12-
*/
13-
145
typedef uint16_t _Py_CODEUNIT;
6+
// Each oparg must fit in the second half of _Py_CODEUNIT, hence 8 bits.
7+
#define _Py_MAX_OPARG 255
158

169
#ifdef WORDS_BIGENDIAN
1710
# define _Py_OPCODE(word) ((word) >> 8)

Include/internal/pycore_frame.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,6 @@ _PyFrame_GetBuiltins(PyFrameObject *f)
3232

3333
int _PyFrame_TakeLocals(PyFrameObject *f);
3434

35-
PyAPI_FUNC(int) _PyFrame_OpAlreadyRan(PyFrameObject *f, int opcode, int oparg);
36-
3735
#ifdef __cplusplus
3836
}
3937
#endif

Include/opcode.h

Lines changed: 4 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Lib/importlib/_bootstrap_external.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -357,7 +357,6 @@ def _write_atomic(path, data, mode=0o666):
357357
# Python 3.11a1 3452 (drop nlocals from marshaled code objects)
358358
# Python 3.11a1 3453 (add co_fastlocalnames and co_fastlocalkinds)
359359
# Python 3.11a1 3454 (compute cell offsets relative to locals bpo-43693)
360-
# Python 3.11a1 3455 (add MAKE_CELL bpo-43693)
361360

362361
#
363362
# MAGIC must change whenever the bytecode emitted by the compiler may no
@@ -367,7 +366,7 @@ def _write_atomic(path, data, mode=0o666):
367366
# Whenever MAGIC_NUMBER is changed, the ranges in the magic_values array
368367
# in PC/launcher.c must also be updated.
369368

370-
MAGIC_NUMBER = (3455).to_bytes(2, 'little') + b'\r\n'
369+
MAGIC_NUMBER = (3454).to_bytes(2, 'little') + b'\r\n'
371370
_RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little') # For import.c
372371

373372
_PYCACHE = '__pycache__'

Lib/opcode.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -181,16 +181,14 @@ def jabs_op(name, op):
181181
def_op('MAKE_FUNCTION', 132) # Flags
182182
def_op('BUILD_SLICE', 133) # Number of items
183183

184-
def_op('MAKE_CELL', 135)
184+
def_op('LOAD_CLOSURE', 135)
185185
hasfree.append(135)
186-
def_op('LOAD_CLOSURE', 136)
186+
def_op('LOAD_DEREF', 136)
187187
hasfree.append(136)
188-
def_op('LOAD_DEREF', 137)
188+
def_op('STORE_DEREF', 137)
189189
hasfree.append(137)
190-
def_op('STORE_DEREF', 138)
190+
def_op('DELETE_DEREF', 138)
191191
hasfree.append(138)
192-
def_op('DELETE_DEREF', 139)
193-
hasfree.append(139)
194192

195193
def_op('CALL_FUNCTION_KW', 141) # #args + #kwargs
196194
def_op('CALL_FUNCTION_EX', 142) # Flags

Lib/test/test_dis.py

Lines changed: 61 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -427,17 +427,15 @@ def foo(x):
427427
return foo
428428

429429
dis_nested_0 = """\
430-
0 MAKE_CELL 2 (y)
431-
432-
%3d 2 LOAD_CLOSURE 2 (y)
433-
4 BUILD_TUPLE 1
434-
6 LOAD_CONST 1 (<code object foo at 0x..., file "%s", line %d>)
435-
8 LOAD_CONST 2 ('_h.<locals>.foo')
436-
10 MAKE_FUNCTION 8 (closure)
437-
12 STORE_FAST 1 (foo)
438-
439-
%3d 14 LOAD_FAST 1 (foo)
440-
16 RETURN_VALUE
430+
%3d 0 LOAD_CLOSURE 2 (y)
431+
2 BUILD_TUPLE 1
432+
4 LOAD_CONST 1 (<code object foo at 0x..., file "%s", line %d>)
433+
6 LOAD_CONST 2 ('_h.<locals>.foo')
434+
8 MAKE_FUNCTION 8 (closure)
435+
10 STORE_FAST 1 (foo)
436+
437+
%3d 12 LOAD_FAST 1 (foo)
438+
14 RETURN_VALUE
441439
""" % (_h.__code__.co_firstlineno + 1,
442440
__file__,
443441
_h.__code__.co_firstlineno + 1,
@@ -446,17 +444,15 @@ def foo(x):
446444

447445
dis_nested_1 = """%s
448446
Disassembly of <code object foo at 0x..., file "%s", line %d>:
449-
0 MAKE_CELL 1 (x)
450-
451-
%3d 2 LOAD_CLOSURE 1 (x)
452-
4 BUILD_TUPLE 1
453-
6 LOAD_CONST 1 (<code object <listcomp> at 0x..., file "%s", line %d>)
454-
8 LOAD_CONST 2 ('_h.<locals>.foo.<locals>.<listcomp>')
455-
10 MAKE_FUNCTION 8 (closure)
456-
12 LOAD_DEREF 2 (y)
457-
14 GET_ITER
458-
16 CALL_FUNCTION 1
459-
18 RETURN_VALUE
447+
%3d 0 LOAD_CLOSURE 1 (x)
448+
2 BUILD_TUPLE 1
449+
4 LOAD_CONST 1 (<code object <listcomp> at 0x..., file "%s", line %d>)
450+
6 LOAD_CONST 2 ('_h.<locals>.foo.<locals>.<listcomp>')
451+
8 MAKE_FUNCTION 8 (closure)
452+
10 LOAD_DEREF 2 (y)
453+
12 GET_ITER
454+
14 CALL_FUNCTION 1
455+
16 RETURN_VALUE
460456
""" % (dis_nested_0,
461457
__file__,
462458
_h.__code__.co_firstlineno + 1,
@@ -962,64 +958,59 @@ def jumpy():
962958
#print('expected_opinfo_jumpy = [\n ',
963959
#',\n '.join(map(str, _instructions)), ',\n]', sep='')
964960

965-
#dis.dis(outer)
966961

967962
Instruction = dis.Instruction
968963
expected_opinfo_outer = [
969-
Instruction(opname='MAKE_CELL', opcode=135, arg=3, argval='a', argrepr='a', offset=0, starts_line=None, is_jump_target=False),
970-
Instruction(opname='MAKE_CELL', opcode=135, arg=4, argval='b', argrepr='b', offset=2, starts_line=None, is_jump_target=False),
971-
Instruction(opname='LOAD_CONST', opcode=100, arg=8, argval=(3, 4), argrepr='(3, 4)', offset=4, starts_line=2, is_jump_target=False),
972-
Instruction(opname='LOAD_CLOSURE', opcode=136, arg=3, argval='a', argrepr='a', offset=6, starts_line=None, is_jump_target=False),
973-
Instruction(opname='LOAD_CLOSURE', opcode=136, arg=4, argval='b', argrepr='b', offset=8, starts_line=None, is_jump_target=False),
974-
Instruction(opname='BUILD_TUPLE', opcode=102, arg=2, argval=2, argrepr='', offset=10, starts_line=None, is_jump_target=False),
975-
Instruction(opname='LOAD_CONST', opcode=100, arg=3, argval=code_object_f, argrepr=repr(code_object_f), offset=12, starts_line=None, is_jump_target=False),
976-
Instruction(opname='LOAD_CONST', opcode=100, arg=4, argval='outer.<locals>.f', argrepr="'outer.<locals>.f'", offset=14, starts_line=None, is_jump_target=False),
977-
Instruction(opname='MAKE_FUNCTION', opcode=132, arg=9, argval=9, argrepr='defaults, closure', offset=16, starts_line=None, is_jump_target=False),
978-
Instruction(opname='STORE_FAST', opcode=125, arg=2, argval='f', argrepr='f', offset=18, starts_line=None, is_jump_target=False),
979-
Instruction(opname='LOAD_GLOBAL', opcode=116, arg=0, argval='print', argrepr='print', offset=20, starts_line=7, is_jump_target=False),
980-
Instruction(opname='LOAD_DEREF', opcode=137, arg=3, argval='a', argrepr='a', offset=22, starts_line=None, is_jump_target=False),
981-
Instruction(opname='LOAD_DEREF', opcode=137, arg=4, argval='b', argrepr='b', offset=24, starts_line=None, is_jump_target=False),
982-
Instruction(opname='LOAD_CONST', opcode=100, arg=5, argval='', argrepr="''", offset=26, starts_line=None, is_jump_target=False),
983-
Instruction(opname='LOAD_CONST', opcode=100, arg=6, argval=1, argrepr='1', offset=28, starts_line=None, is_jump_target=False),
984-
Instruction(opname='BUILD_LIST', opcode=103, arg=0, argval=0, argrepr='', offset=30, starts_line=None, is_jump_target=False),
985-
Instruction(opname='BUILD_MAP', opcode=105, arg=0, argval=0, argrepr='', offset=32, starts_line=None, is_jump_target=False),
986-
Instruction(opname='LOAD_CONST', opcode=100, arg=7, argval='Hello world!', argrepr="'Hello world!'", offset=34, starts_line=None, is_jump_target=False),
987-
Instruction(opname='CALL_FUNCTION', opcode=131, arg=7, argval=7, argrepr='', offset=36, starts_line=None, is_jump_target=False),
988-
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=38, starts_line=None, is_jump_target=False),
989-
Instruction(opname='LOAD_FAST', opcode=124, arg=2, argval='f', argrepr='f', offset=40, starts_line=8, is_jump_target=False),
990-
Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=42, starts_line=None, is_jump_target=False),
964+
Instruction(opname='LOAD_CONST', opcode=100, arg=8, argval=(3, 4), argrepr='(3, 4)', offset=0, starts_line=2, is_jump_target=False),
965+
Instruction(opname='LOAD_CLOSURE', opcode=135, arg=3, argval='a', argrepr='a', offset=2, starts_line=None, is_jump_target=False),
966+
Instruction(opname='LOAD_CLOSURE', opcode=135, arg=4, argval='b', argrepr='b', offset=4, starts_line=None, is_jump_target=False),
967+
Instruction(opname='BUILD_TUPLE', opcode=102, arg=2, argval=2, argrepr='', offset=6, starts_line=None, is_jump_target=False),
968+
Instruction(opname='LOAD_CONST', opcode=100, arg=3, argval=code_object_f, argrepr=repr(code_object_f), offset=8, starts_line=None, is_jump_target=False),
969+
Instruction(opname='LOAD_CONST', opcode=100, arg=4, argval='outer.<locals>.f', argrepr="'outer.<locals>.f'", offset=10, starts_line=None, is_jump_target=False),
970+
Instruction(opname='MAKE_FUNCTION', opcode=132, arg=9, argval=9, argrepr='defaults, closure', offset=12, starts_line=None, is_jump_target=False),
971+
Instruction(opname='STORE_FAST', opcode=125, arg=2, argval='f', argrepr='f', offset=14, starts_line=None, is_jump_target=False),
972+
Instruction(opname='LOAD_GLOBAL', opcode=116, arg=0, argval='print', argrepr='print', offset=16, starts_line=7, is_jump_target=False),
973+
Instruction(opname='LOAD_DEREF', opcode=136, arg=3, argval='a', argrepr='a', offset=18, starts_line=None, is_jump_target=False),
974+
Instruction(opname='LOAD_DEREF', opcode=136, arg=4, argval='b', argrepr='b', offset=20, starts_line=None, is_jump_target=False),
975+
Instruction(opname='LOAD_CONST', opcode=100, arg=5, argval='', argrepr="''", offset=22, starts_line=None, is_jump_target=False),
976+
Instruction(opname='LOAD_CONST', opcode=100, arg=6, argval=1, argrepr='1', offset=24, starts_line=None, is_jump_target=False),
977+
Instruction(opname='BUILD_LIST', opcode=103, arg=0, argval=0, argrepr='', offset=26, starts_line=None, is_jump_target=False),
978+
Instruction(opname='BUILD_MAP', opcode=105, arg=0, argval=0, argrepr='', offset=28, starts_line=None, is_jump_target=False),
979+
Instruction(opname='LOAD_CONST', opcode=100, arg=7, argval='Hello world!', argrepr="'Hello world!'", offset=30, starts_line=None, is_jump_target=False),
980+
Instruction(opname='CALL_FUNCTION', opcode=131, arg=7, argval=7, argrepr='', offset=32, starts_line=None, is_jump_target=False),
981+
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=34, starts_line=None, is_jump_target=False),
982+
Instruction(opname='LOAD_FAST', opcode=124, arg=2, argval='f', argrepr='f', offset=36, starts_line=8, is_jump_target=False),
983+
Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=38, starts_line=None, is_jump_target=False),
991984
]
992985

993986
expected_opinfo_f = [
994-
Instruction(opname='MAKE_CELL', opcode=135, arg=3, argval='c', argrepr='c', offset=0, starts_line=None, is_jump_target=False),
995-
Instruction(opname='MAKE_CELL', opcode=135, arg=4, argval='d', argrepr='d', offset=2, starts_line=None, is_jump_target=False),
996-
Instruction(opname='LOAD_CONST', opcode=100, arg=5, argval=(5, 6), argrepr='(5, 6)', offset=4, starts_line=3, is_jump_target=False),
997-
Instruction(opname='LOAD_CLOSURE', opcode=136, arg=5, argval='a', argrepr='a', offset=6, starts_line=None, is_jump_target=False),
998-
Instruction(opname='LOAD_CLOSURE', opcode=136, arg=6, argval='b', argrepr='b', offset=8, starts_line=None, is_jump_target=False),
999-
Instruction(opname='LOAD_CLOSURE', opcode=136, arg=3, argval='c', argrepr='c', offset=10, starts_line=None, is_jump_target=False),
1000-
Instruction(opname='LOAD_CLOSURE', opcode=136, arg=4, argval='d', argrepr='d', offset=12, starts_line=None, is_jump_target=False),
1001-
Instruction(opname='BUILD_TUPLE', opcode=102, arg=4, argval=4, argrepr='', offset=14, starts_line=None, is_jump_target=False),
1002-
Instruction(opname='LOAD_CONST', opcode=100, arg=3, argval=code_object_inner, argrepr=repr(code_object_inner), offset=16, starts_line=None, is_jump_target=False),
1003-
Instruction(opname='LOAD_CONST', opcode=100, arg=4, argval='outer.<locals>.f.<locals>.inner', argrepr="'outer.<locals>.f.<locals>.inner'", offset=18, starts_line=None, is_jump_target=False),
1004-
Instruction(opname='MAKE_FUNCTION', opcode=132, arg=9, argval=9, argrepr='defaults, closure', offset=20, starts_line=None, is_jump_target=False),
1005-
Instruction(opname='STORE_FAST', opcode=125, arg=2, argval='inner', argrepr='inner', offset=22, starts_line=None, is_jump_target=False),
1006-
Instruction(opname='LOAD_GLOBAL', opcode=116, arg=0, argval='print', argrepr='print', offset=24, starts_line=5, is_jump_target=False),
1007-
Instruction(opname='LOAD_DEREF', opcode=137, arg=5, argval='a', argrepr='a', offset=26, starts_line=None, is_jump_target=False),
1008-
Instruction(opname='LOAD_DEREF', opcode=137, arg=6, argval='b', argrepr='b', offset=28, starts_line=None, is_jump_target=False),
1009-
Instruction(opname='LOAD_DEREF', opcode=137, arg=3, argval='c', argrepr='c', offset=30, starts_line=None, is_jump_target=False),
1010-
Instruction(opname='LOAD_DEREF', opcode=137, arg=4, argval='d', argrepr='d', offset=32, starts_line=None, is_jump_target=False),
1011-
Instruction(opname='CALL_FUNCTION', opcode=131, arg=4, argval=4, argrepr='', offset=34, starts_line=None, is_jump_target=False),
1012-
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=36, starts_line=None, is_jump_target=False),
1013-
Instruction(opname='LOAD_FAST', opcode=124, arg=2, argval='inner', argrepr='inner', offset=38, starts_line=6, is_jump_target=False),
1014-
Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=40, starts_line=None, is_jump_target=False),
987+
Instruction(opname='LOAD_CONST', opcode=100, arg=5, argval=(5, 6), argrepr='(5, 6)', offset=0, starts_line=3, is_jump_target=False),
988+
Instruction(opname='LOAD_CLOSURE', opcode=135, arg=5, argval='a', argrepr='a', offset=2, starts_line=None, is_jump_target=False),
989+
Instruction(opname='LOAD_CLOSURE', opcode=135, arg=6, argval='b', argrepr='b', offset=4, starts_line=None, is_jump_target=False),
990+
Instruction(opname='LOAD_CLOSURE', opcode=135, arg=3, argval='c', argrepr='c', offset=6, starts_line=None, is_jump_target=False),
991+
Instruction(opname='LOAD_CLOSURE', opcode=135, arg=4, argval='d', argrepr='d', offset=8, starts_line=None, is_jump_target=False),
992+
Instruction(opname='BUILD_TUPLE', opcode=102, arg=4, argval=4, argrepr='', offset=10, starts_line=None, is_jump_target=False),
993+
Instruction(opname='LOAD_CONST', opcode=100, arg=3, argval=code_object_inner, argrepr=repr(code_object_inner), offset=12, starts_line=None, is_jump_target=False),
994+
Instruction(opname='LOAD_CONST', opcode=100, arg=4, argval='outer.<locals>.f.<locals>.inner', argrepr="'outer.<locals>.f.<locals>.inner'", offset=14, starts_line=None, is_jump_target=False),
995+
Instruction(opname='MAKE_FUNCTION', opcode=132, arg=9, argval=9, argrepr='defaults, closure', offset=16, starts_line=None, is_jump_target=False),
996+
Instruction(opname='STORE_FAST', opcode=125, arg=2, argval='inner', argrepr='inner', offset=18, starts_line=None, is_jump_target=False),
997+
Instruction(opname='LOAD_GLOBAL', opcode=116, arg=0, argval='print', argrepr='print', offset=20, starts_line=5, is_jump_target=False),
998+
Instruction(opname='LOAD_DEREF', opcode=136, arg=5, argval='a', argrepr='a', offset=22, starts_line=None, is_jump_target=False),
999+
Instruction(opname='LOAD_DEREF', opcode=136, arg=6, argval='b', argrepr='b', offset=24, starts_line=None, is_jump_target=False),
1000+
Instruction(opname='LOAD_DEREF', opcode=136, arg=3, argval='c', argrepr='c', offset=26, starts_line=None, is_jump_target=False),
1001+
Instruction(opname='LOAD_DEREF', opcode=136, arg=4, argval='d', argrepr='d', offset=28, starts_line=None, is_jump_target=False),
1002+
Instruction(opname='CALL_FUNCTION', opcode=131, arg=4, argval=4, argrepr='', offset=30, starts_line=None, is_jump_target=False),
1003+
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=32, starts_line=None, is_jump_target=False),
1004+
Instruction(opname='LOAD_FAST', opcode=124, arg=2, argval='inner', argrepr='inner', offset=34, starts_line=6, is_jump_target=False),
1005+
Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=36, starts_line=None, is_jump_target=False),
10151006
]
10161007

10171008
expected_opinfo_inner = [
10181009
Instruction(opname='LOAD_GLOBAL', opcode=116, arg=0, argval='print', argrepr='print', offset=0, starts_line=4, is_jump_target=False),
1019-
Instruction(opname='LOAD_DEREF', opcode=137, arg=2, argval='a', argrepr='a', offset=2, starts_line=None, is_jump_target=False),
1020-
Instruction(opname='LOAD_DEREF', opcode=137, arg=3, argval='b', argrepr='b', offset=4, starts_line=None, is_jump_target=False),
1021-
Instruction(opname='LOAD_DEREF', opcode=137, arg=4, argval='c', argrepr='c', offset=6, starts_line=None, is_jump_target=False),
1022-
Instruction(opname='LOAD_DEREF', opcode=137, arg=5, argval='d', argrepr='d', offset=8, starts_line=None, is_jump_target=False),
1010+
Instruction(opname='LOAD_DEREF', opcode=136, arg=2, argval='a', argrepr='a', offset=2, starts_line=None, is_jump_target=False),
1011+
Instruction(opname='LOAD_DEREF', opcode=136, arg=3, argval='b', argrepr='b', offset=4, starts_line=None, is_jump_target=False),
1012+
Instruction(opname='LOAD_DEREF', opcode=136, arg=4, argval='c', argrepr='c', offset=6, starts_line=None, is_jump_target=False),
1013+
Instruction(opname='LOAD_DEREF', opcode=136, arg=5, argval='d', argrepr='d', offset=8, starts_line=None, is_jump_target=False),
10231014
Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='e', argrepr='e', offset=10, starts_line=None, is_jump_target=False),
10241015
Instruction(opname='LOAD_FAST', opcode=124, arg=1, argval='f', argrepr='f', offset=12, starts_line=None, is_jump_target=False),
10251016
Instruction(opname='CALL_FUNCTION', opcode=131, arg=6, argval=6, argrepr='', offset=14, starts_line=None, is_jump_target=False),

Lib/test/test_scope.py

Lines changed: 0 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -176,57 +176,6 @@ def bar():
176176
self.assertEqual(foo(a=42), 50)
177177
self.assertEqual(foo(), 25)
178178

179-
def testCellIsArgAndEscapes(self):
180-
# We need to be sure that a cell passed in as an arg still
181-
# gets wrapped in a new cell if the arg escapes into an
182-
# inner function (closure).
183-
184-
def external():
185-
value = 42
186-
def inner():
187-
return value
188-
cell, = inner.__closure__
189-
return cell
190-
cell_ext = external()
191-
192-
def spam(arg):
193-
def eggs():
194-
return arg
195-
return eggs
196-
197-
eggs = spam(cell_ext)
198-
cell_closure, = eggs.__closure__
199-
cell_eggs = eggs()
200-
201-
self.assertIs(cell_eggs, cell_ext)
202-
self.assertIsNot(cell_eggs, cell_closure)
203-
204-
def testCellIsLocalAndEscapes(self):
205-
# We need to be sure that a cell bound to a local still
206-
# gets wrapped in a new cell if the local escapes into an
207-
# inner function (closure).
208-
209-
def external():
210-
value = 42
211-
def inner():
212-
return value
213-
cell, = inner.__closure__
214-
return cell
215-
cell_ext = external()
216-
217-
def spam(arg):
218-
cell = arg
219-
def eggs():
220-
return cell
221-
return eggs
222-
223-
eggs = spam(cell_ext)
224-
cell_closure, = eggs.__closure__
225-
cell_eggs = eggs()
226-
227-
self.assertIs(cell_eggs, cell_ext)
228-
self.assertIsNot(cell_eggs, cell_closure)
229-
230179
def testRecursion(self):
231180

232181
def f(x):

0 commit comments

Comments
 (0)