Skip to content

Commit

Permalink
Add some very preliminary 3.10 opcode support.
Browse files Browse the repository at this point in the history
Generated by following the mostly automated steps at the beginning of
https://github.com/google/pytype/blob/master/docs/developers/python_version_upgrades.md.
With this, we actually get useful test results rather than a bunch of
key errors for missing Python 3.10 magic numbers.

For #1022.
  • Loading branch information
rchen152 committed Oct 6, 2021
1 parent 4d85974 commit a328993
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 4 deletions.
3 changes: 2 additions & 1 deletion pytype/pyc/generate_opcode_diffs.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
* "OPCODE MAPPING DIFF" is the content of a dictionary of opcode changes. Just
copy the python_{major}_{minor}_mapping definition in pyc/opcodes.py for the
previous version, change the version numbers, and replace the diff - it'll be
obvious where it goes.
obvious where it goes. Then add the new mapping to the mapping dict in the
top-level dis function in the same module.
* "OPCODE STUB IMPLEMENTATIONS" are new methods that should be added to vm.py.
"""

Expand Down
12 changes: 12 additions & 0 deletions pytype/pyc/magic.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,18 @@
3423: (3, 9), # a2
3424: (3, 9), # a2
3425: (3, 9), # a2

# Python 3.10
3430: (3, 10), # a1
3431: (3, 10), # a1
3432: (3, 10), # a2
3433: (3, 10), # a2
3434: (3, 10), # a6
3435: (3, 10), # a7
3436: (3, 10), # b1
3437: (3, 10), # b1
3438: (3, 10), # b1
3439: (3, 10), # b1
}


Expand Down
53 changes: 50 additions & 3 deletions pytype/pyc/opcodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,14 @@ def has_arg(cls):
return True


class LOAD_FOLDED_CONST(OpcodeWithArg): # A fake opcode used internally
FLAGS = HAS_ARGUMENT
__slots__ = ()

def __str__(self):
return self.basic_str() + " " + str(self.arg.value)


class POP_TOP(Opcode):
__slots__ = ()

Expand Down Expand Up @@ -797,12 +805,39 @@ class DICT_UPDATE(OpcodeWithArg):
__slots__ = ()


class LOAD_FOLDED_CONST(OpcodeWithArg): # A fake opcode used internally
class GET_LEN(Opcode):
__slots__ = ()


class MATCH_MAPPING(Opcode):
__slots__ = ()


class MATCH_SEQUENCE(Opcode):
__slots__ = ()


class MATCH_KEYS(Opcode):
__slots__ = ()


class COPY_DICT_WITHOUT_KEYS(Opcode):
__slots__ = ()


class ROT_N(OpcodeWithArg):
FLAGS = HAS_ARGUMENT
__slots__ = ()

def __str__(self):
return self.basic_str() + " " + str(self.arg.value)

class GEN_START(OpcodeWithArg):
FLAGS = HAS_ARGUMENT
__slots__ = ()


class MATCH_CLASS(OpcodeWithArg):
FLAGS = HAS_ARGUMENT
__slots__ = ()


def _overlay_mapping(mapping, new_entries):
Expand Down Expand Up @@ -974,6 +1009,17 @@ def _overlay_mapping(mapping, new_entries):
165: DICT_UPDATE,
})

python_3_10_mapping = _overlay_mapping(python_3_9_mapping, {
30: GET_LEN,
31: MATCH_MAPPING,
32: MATCH_SEQUENCE,
33: MATCH_KEYS,
34: COPY_DICT_WITHOUT_KEYS,
99: ROT_N,
129: GEN_START,
152: MATCH_CLASS,
})


class _LineNumberTableParser:
"""State machine for decoding a Python line number array."""
Expand Down Expand Up @@ -1113,6 +1159,7 @@ def dis(data, python_version, *args, **kwargs):
(3, 7): python_3_7_mapping,
(3, 8): python_3_8_mapping,
(3, 9): python_3_9_mapping,
(3, 10): python_3_10_mapping,
}[(major, minor)]
return _dis(data, mapping, *args, **kwargs)

Expand Down
34 changes: 34 additions & 0 deletions pytype/vm.py
Original file line number Diff line number Diff line change
Expand Up @@ -3766,3 +3766,37 @@ def byte_LOAD_ASSERTION_ERROR(self, state, op):
del op # unused
assertion_error = self.ctx.convert.name_to_value("builtins.AssertionError")
return state.push(assertion_error.to_variable(state.node))

# Stub implementations for opcodes new in Python 3.10.

def byte_GET_LEN(self, state, op):
del op
return state

def byte_MATCH_MAPPING(self, state, op):
del op
return state

def byte_MATCH_SEQUENCE(self, state, op):
del op
return state

def byte_MATCH_KEYS(self, state, op):
del op
return state

def byte_COPY_DICT_WITHOUT_KEYS(self, state, op):
del op
return state

def byte_ROT_N(self, state, op):
del op
return state

def byte_GEN_START(self, state, op):
del op
return state

def byte_MATCH_CLASS(self, state, op):
del op
return state

0 comments on commit a328993

Please sign in to comment.