Search code examples
pythonopcodedillsystem-error

Can't solve "SystemError: unknown opcode"


I am executing a notebook on my laptop and I get the following error.

XXX lineno: 17, opcode: 120
---------------------------------------------------------------------------
SystemError                               Traceback (most recent call last)
Input In [3], in <cell line: 3>()
      1 gym = Gym(0, 0, 0, 0).from_dill(BACKUP)
      2 ticker = gym.api.returnTicker()
----> 3 gym.wallet = gym.get_wallet()
      4 plot_donut_gym_wallet(gym)
      5 plot_donut_gym_wallet_makers(gym)

File <ipython-input-3-1c4842a503bf>:17, in get_wallet(self)

SystemError: unknown opcode

As you can see, the error happens during a function call. The function itself is not the problem, if I define and run ithe function inside a cell it simply works. But importing the function from its own module leads to this error. I have looked around for hints, all the forum I have read are pointing to some problem with having multiple Python installations. However, I tried using new environments, both using venv and conda and I get the same error. The same code on other machines works, so it appear to be something related to my particular installation, but I can't figure out how to fix it. I tried reinstalling conda, making new envs, upgrading python. Iteted this with Python 3.8, 3.9 and 3.10, I always get the same error. Any help is very welcome.

Since the function is from a class previously serialized using dill, this dill-related issue may be relevant https://github.com/uqfoundation/dill/issues/438


Solution

  • Code objects (from functions and class methods) serialized with dill are not guaranteed to work across different Python versions, because the list of valid opcodes change from version to version. In cases where there is an opcode unknown to the interpreter deserializing ("unpickling") the code object, the functions and classes are successfully recreated, but fail to execute as in your example.

    The code in your example may have been created in Python 2, or Python 3.11 beta... It's impossible to know just by looking. You should ask whoever created the pickle file.


    Edit: If you don't have the source code of the functions and methods, you may be able to reconstruct their source using a decompiler like decompyle3 (or uncompyle6 for other Python versions) and re-generate these faulty code objects with another Python version.

    An example in Python3.7:

    >>> def f(x, *, verbose=False):
    ...     y = x*x
    ...     if verbose:
    ...         print(y)
    ...     return y
    ...
    >>> import inspect
    >>> f_sign = inspect.signature(f)
    <Signature (x, *, verbose=False)>
    >>> 
    >>> import os
    >>> import decompyle3
    >>> with open(os.devnull, 'w') as null:
    ...     f_code = decompyle3.main.decompile(f.__code__, out=null)
    ... 
    >>> f_code
    <decompyle3.semantics.pysource.SourceWalker object at 0x7f8932f14990>
    >>> 
    >>> from textwrap import indent
    >>> print("def {}{}:\n{}".format(f.__name__, f_sign, indent(f_code.text, "    ")))
    def f(x, *, verbose=False):
        y = x * x
        if verbose:
            print('x**2 =', y)
        return y