Skip to content

Commit aa2d29f

Browse files
Merge pull request MatthieuDartiailh#41 from serhiy-storchaka/py38
Support Python 3.8.
2 parents f63b5b9 + 29ba6aa commit aa2d29f

4 files changed

Lines changed: 257 additions & 148 deletions

File tree

bytecode/instr.py

Lines changed: 33 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -145,31 +145,32 @@ def _check_arg_int(name, arg):
145145
% name)
146146

147147

148-
_stack_effects = {
149-
# NOTE: the entries are all 2-tuples. Entry[0/False] is non-taken jumps.
150-
# Entry[1/True] is for taken jumps.
151-
152-
# opcodes not in dis.stack_effect
153-
_opcode.opmap['EXTENDED_ARG']: (0, 0),
154-
_opcode.opmap['NOP']: (0, 0),
155-
156-
# Jump taken/not-taken are different:
157-
_opcode.opmap['JUMP_IF_TRUE_OR_POP']: (-1, 0),
158-
_opcode.opmap['JUMP_IF_FALSE_OR_POP']: (-1, 0),
159-
_opcode.opmap['FOR_ITER']: (1, -1),
160-
_opcode.opmap['SETUP_WITH']: (1, 6),
161-
_opcode.opmap['SETUP_ASYNC_WITH']: (0, 5),
162-
_opcode.opmap['SETUP_EXCEPT']: (0, 6), # as of 3.7, below for <=3.6
163-
_opcode.opmap['SETUP_FINALLY']: (0, 6), # as of 3.7, below for <=3.6
164-
}
165-
166-
# More stack effect values that are unique to the version of Python.
167-
if sys.version_info < (3, 7):
168-
_stack_effects.update({
169-
_opcode.opmap['SETUP_WITH']: (7, 7),
170-
_opcode.opmap['SETUP_EXCEPT']: (6, 9),
171-
_opcode.opmap['SETUP_FINALLY']: (6, 9),
172-
})
148+
if sys.version_info < (3, 8):
149+
_stack_effects = {
150+
# NOTE: the entries are all 2-tuples. Entry[0/False] is non-taken jumps.
151+
# Entry[1/True] is for taken jumps.
152+
153+
# opcodes not in dis.stack_effect
154+
_opcode.opmap['EXTENDED_ARG']: (0, 0),
155+
_opcode.opmap['NOP']: (0, 0),
156+
157+
# Jump taken/not-taken are different:
158+
_opcode.opmap['JUMP_IF_TRUE_OR_POP']: (-1, 0),
159+
_opcode.opmap['JUMP_IF_FALSE_OR_POP']: (-1, 0),
160+
_opcode.opmap['FOR_ITER']: (1, -1),
161+
_opcode.opmap['SETUP_WITH']: (1, 6),
162+
_opcode.opmap['SETUP_ASYNC_WITH']: (0, 5),
163+
_opcode.opmap['SETUP_EXCEPT']: (0, 6), # as of 3.7, below for <=3.6
164+
_opcode.opmap['SETUP_FINALLY']: (0, 6), # as of 3.7, below for <=3.6
165+
}
166+
167+
# More stack effect values that are unique to the version of Python.
168+
if sys.version_info < (3, 7):
169+
_stack_effects.update({
170+
_opcode.opmap['SETUP_WITH']: (7, 7),
171+
_opcode.opmap['SETUP_EXCEPT']: (6, 9),
172+
_opcode.opmap['SETUP_FINALLY']: (6, 9),
173+
})
173174

174175

175176
class Instr:
@@ -307,15 +308,13 @@ def stack_effect(self, jump=None):
307308
else:
308309
arg = self._arg
309310

310-
effect = _stack_effects.get(self._opcode, None)
311-
if effect is not None:
312-
return max(effect) if jump is None else effect[jump]
313-
314-
# TODO: if dis.stack_effect ever expands to take the 'jump' parameter
315-
# then we should pass that through, and perhaps remove some of the
316-
# overrides that are set up in _init_stack_effects()
317-
318-
return dis.stack_effect(self._opcode, arg)
311+
if sys.version_info < (3, 8):
312+
effect = _stack_effects.get(self._opcode, None)
313+
if effect is not None:
314+
return max(effect) if jump is None else effect[jump]
315+
return dis.stack_effect(self._opcode, arg)
316+
else:
317+
return dis.stack_effect(self._opcode, arg, jump=jump)
319318

320319
def copy(self):
321320
return self.__class__(self._name, self._arg, lineno=self._lineno)

bytecode/tests/test_cfg.py

Lines changed: 93 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#!/usr/bin/env python3
22
import io
3+
import sys
34
import unittest
45
import contextlib
56
from bytecode import (Label, Compare, SetLineno, Instr,
@@ -221,60 +222,108 @@ def test_from_bytecode_loop(self):
221222
# break
222223
# continue
223224

224-
label_loop_start = Label()
225-
label_loop_exit = Label()
226-
label_loop_end = Label()
225+
if sys.version_info < (3, 8):
226+
label_loop_start = Label()
227+
label_loop_exit = Label()
228+
label_loop_end = Label()
227229

228-
code = Bytecode()
229-
code.extend((Instr('SETUP_LOOP', label_loop_end, lineno=1),
230-
Instr('LOAD_CONST', (1, 2, 3), lineno=1),
231-
Instr('GET_ITER', lineno=1),
232-
233-
label_loop_start,
234-
Instr('FOR_ITER', label_loop_exit, lineno=1),
235-
Instr('STORE_NAME', 'x', lineno=1),
236-
Instr('LOAD_NAME', 'x', lineno=2),
237-
Instr('LOAD_CONST', 2, lineno=2),
238-
Instr('COMPARE_OP', Compare.EQ, lineno=2),
239-
Instr('POP_JUMP_IF_FALSE', label_loop_start, lineno=2),
240-
Instr('BREAK_LOOP', lineno=3),
241-
Instr('JUMP_ABSOLUTE', label_loop_start, lineno=4),
242-
243-
Instr('JUMP_ABSOLUTE', label_loop_start, lineno=4),
244-
245-
label_loop_exit,
246-
Instr('POP_BLOCK', lineno=4),
247-
248-
label_loop_end,
249-
Instr('LOAD_CONST', None, lineno=4),
250-
Instr('RETURN_VALUE', lineno=4),
251-
))
252-
blocks = ControlFlowGraph.from_bytecode(code)
230+
code = Bytecode()
231+
code.extend((Instr('SETUP_LOOP', label_loop_end, lineno=1),
232+
Instr('LOAD_CONST', (1, 2, 3), lineno=1),
233+
Instr('GET_ITER', lineno=1),
234+
235+
label_loop_start,
236+
Instr('FOR_ITER', label_loop_exit, lineno=1),
237+
Instr('STORE_NAME', 'x', lineno=1),
238+
Instr('LOAD_NAME', 'x', lineno=2),
239+
Instr('LOAD_CONST', 2, lineno=2),
240+
Instr('COMPARE_OP', Compare.EQ, lineno=2),
241+
Instr('POP_JUMP_IF_FALSE', label_loop_start, lineno=2),
242+
Instr('BREAK_LOOP', lineno=3),
243+
Instr('JUMP_ABSOLUTE', label_loop_start, lineno=4),
244+
245+
Instr('JUMP_ABSOLUTE', label_loop_start, lineno=4),
246+
247+
label_loop_exit,
248+
Instr('POP_BLOCK', lineno=4),
249+
250+
label_loop_end,
251+
Instr('LOAD_CONST', None, lineno=4),
252+
Instr('RETURN_VALUE', lineno=4),
253+
))
254+
blocks = ControlFlowGraph.from_bytecode(code)
255+
256+
expected = [[Instr('SETUP_LOOP', blocks[8], lineno=1)],
257+
258+
[Instr('LOAD_CONST', (1, 2, 3), lineno=1),
259+
Instr('GET_ITER', lineno=1)],
260+
261+
[Instr('FOR_ITER', blocks[7], lineno=1)],
262+
263+
[Instr('STORE_NAME', 'x', lineno=1),
264+
Instr('LOAD_NAME', 'x', lineno=2),
265+
Instr('LOAD_CONST', 2, lineno=2),
266+
Instr('COMPARE_OP', Compare.EQ, lineno=2),
267+
Instr('POP_JUMP_IF_FALSE', blocks[2], lineno=2)],
253268

254-
expected = [[Instr('SETUP_LOOP', blocks[8], lineno=1)],
269+
[Instr('BREAK_LOOP', lineno=3)],
255270

256-
[Instr('LOAD_CONST', (1, 2, 3), lineno=1),
257-
Instr('GET_ITER', lineno=1)],
271+
[Instr('JUMP_ABSOLUTE', blocks[2], lineno=4)],
272+
273+
[Instr('JUMP_ABSOLUTE', blocks[2], lineno=4)],
274+
275+
[Instr('POP_BLOCK', lineno=4)],
276+
277+
[Instr('LOAD_CONST', None, lineno=4),
278+
Instr('RETURN_VALUE', lineno=4)]]
279+
self.assertBlocksEqual(blocks, *expected)
280+
else:
281+
label_loop_start = Label()
282+
label_loop_exit = Label()
283+
284+
code = Bytecode()
285+
code.extend((Instr('LOAD_CONST', (1, 2, 3), lineno=1),
286+
Instr('GET_ITER', lineno=1),
287+
288+
label_loop_start,
289+
Instr('FOR_ITER', label_loop_exit, lineno=1),
290+
Instr('STORE_NAME', 'x', lineno=1),
291+
Instr('LOAD_NAME', 'x', lineno=2),
292+
Instr('LOAD_CONST', 2, lineno=2),
293+
Instr('COMPARE_OP', Compare.EQ, lineno=2),
294+
Instr('POP_JUMP_IF_FALSE', label_loop_start, lineno=2),
295+
Instr('JUMP_ABSOLUTE', label_loop_exit, lineno=3),
296+
297+
Instr('JUMP_ABSOLUTE', label_loop_start, lineno=4),
298+
299+
Instr('JUMP_ABSOLUTE', label_loop_start, lineno=4),
300+
301+
label_loop_exit,
302+
Instr('LOAD_CONST', None, lineno=4),
303+
Instr('RETURN_VALUE', lineno=4),
304+
))
305+
blocks = ControlFlowGraph.from_bytecode(code)
258306

259-
[Instr('FOR_ITER', blocks[7], lineno=1)],
307+
expected = [[Instr('LOAD_CONST', (1, 2, 3), lineno=1),
308+
Instr('GET_ITER', lineno=1)],
260309

261-
[Instr('STORE_NAME', 'x', lineno=1),
262-
Instr('LOAD_NAME', 'x', lineno=2),
263-
Instr('LOAD_CONST', 2, lineno=2),
264-
Instr('COMPARE_OP', Compare.EQ, lineno=2),
265-
Instr('POP_JUMP_IF_FALSE', blocks[2], lineno=2)],
310+
[Instr('FOR_ITER', blocks[6], lineno=1)],
266311

267-
[Instr('BREAK_LOOP', lineno=3)],
312+
[Instr('STORE_NAME', 'x', lineno=1),
313+
Instr('LOAD_NAME', 'x', lineno=2),
314+
Instr('LOAD_CONST', 2, lineno=2),
315+
Instr('COMPARE_OP', Compare.EQ, lineno=2),
316+
Instr('POP_JUMP_IF_FALSE', blocks[1], lineno=2)],
268317

269-
[Instr('JUMP_ABSOLUTE', blocks[2], lineno=4)],
318+
[Instr('JUMP_ABSOLUTE', blocks[6], lineno=3)],
270319

271-
[Instr('JUMP_ABSOLUTE', blocks[2], lineno=4)],
320+
[Instr('JUMP_ABSOLUTE', blocks[1], lineno=4)],
272321

273-
[Instr('POP_BLOCK', lineno=4)],
322+
[Instr('JUMP_ABSOLUTE', blocks[1], lineno=4)],
274323

275-
[Instr('LOAD_CONST', None, lineno=4),
276-
Instr('RETURN_VALUE', lineno=4)]]
277-
self.assertBlocksEqual(blocks, *expected)
324+
[Instr('LOAD_CONST', None, lineno=4),
325+
Instr('RETURN_VALUE', lineno=4)]]
326+
self.assertBlocksEqual(blocks, *expected)
278327

279328

280329
class BytecodeBlocksFunctionalTests(TestCase):

0 commit comments

Comments
 (0)