rocky/python-xdis

op_imports.get_opcode_module raises KeyError on Python 3.8.5

SuperStormer opened this issue · 2 comments

Attempting to decompile any pyc file on Python 3.8.5 using uncompyle6 errors with this message.

Traceback (most recent call last):
  File "/usr/local/bin/uncompyle6", line 5, in <module>
    from uncompyle6.bin.uncompile import main_bin
  File "/usr/local/lib/python3.8/site-packages/uncompyle6/__init__.py", line 53, in <module>
    import uncompyle6.semantics.pysource
  File "/usr/local/lib/python3.8/site-packages/uncompyle6/semantics/pysource.py", line 141, in <module>
    from uncompyle6.parsers.treenode import SyntaxTree
  File "/usr/local/lib/python3.8/site-packages/uncompyle6/parsers/treenode.py", line 3, in <module>
    from uncompyle6.scanners.tok import NoneToken
  File "/usr/local/lib/python3.8/site-packages/uncompyle6/scanners/tok.py", line 200, in <module>
    NoneToken = Token("LOAD_CONST", offset=-1, attr=None, pattr=None)
  File "/usr/local/lib/python3.8/site-packages/uncompyle6/scanners/tok.py", line 86, in __init__
    from xdis.std import _std_api
  File "/usr/local/lib/python3.8/site-packages/xdis/std.py", line 220, in <module>
    _std_api = make_std_api()
  File "/usr/local/lib/python3.8/site-packages/xdis/std.py", line 218, in make_std_api
    return _StdApi(python_version, variant)
  File "/usr/local/lib/python3.8/site-packages/xdis/std.py", line 73, in __init__
    self.opc = opc = get_opcode_module(python_version, variant)
  File "/usr/local/lib/python3.8/site-packages/xdis/op_imports.py", line 167, in get_opcode_module
    return op_imports[canonic_python_version[vers_str]]
KeyError: '3.8.5'

This should be easily fixable by changing these lines:

vers_str = '.'.join([str(v) for v in version_info[0:3]])
    if len(version_info) >= 3 and version_info[3] != 'final':
        vers_str += ''.join([str(v) for v in version_info[3:]])

to:

vers_str = '.'.join([str(v) for v in version_info[0:2]])

I'm not quite sure why this function is checking the micro release version in the first place; the op_imports dict should only need the major and minor release versions.

rocky commented

The version additions were fixed in 4bf7005

As for listing what exists, that's because this is to document what exists (excluding most beta and candidate releases).

And also Python being Python, magic numbers have switched mid version.

That said, there probably should be some sort of loose check version of get_opcode_module() or a parameter that loosens things. Feel free to put in a PR for that and we can discuss/review.