"raise" followed by a conditional expression (python)

I am trying to understand the python 2.5 code and I came across this pattern:

def __init__(self, matrix, top_buttons, side_buttons, config_button):
        raise isinstance(matrix, ButtonMatrixElement) or AssertionError
        raise matrix.width() == 8 and matrix.height() == 8 or AssertionError
        raise isinstance(top_buttons, tuple) or AssertionError
        raise len(top_buttons) == 8 or AssertionError
        raise isinstance(side_buttons, tuple) or AssertionError
        raise len(side_buttons) == 8 or AssertionError
        raise isinstance(config_button, ButtonElement) or AssertionError


I tried to test this in the shell with some simple conditional statements like:

>>> str = 'hello'
>>> raise len(str) == 5 or AssertionError

Traceback (most recent call last):
  File "<pyshell#6>", line 1, in <module>
    raise len(str) == 5 or AssertionError
TypeError: exceptions must be classes, instances, or strings (deprecated), not bool


So, judging from this test, at least the way I tried it, you cannot raise a boolean assertion. What does it mean to raise a conditional expression and why does it work in a function __init__

but not in my test code?


source to share

2 answers

The code is silly, a failed attempt at something that looks like a assert

that doesn't work as you discovered.

What they should have written:

assert isinstance(matrix, ButtonMatrixElement)



It looks like you discovered decompiled Ableton Live scripts , but the decompiled script caused the wrong Python code. The bytecode for assert

looks like this (Python 2.5 bytecode):

>>> import dis
>>> dis.dis(compile('''assert isinstance(matrix, ButtonMatrixElement)''', '<stdin>', 'exec'))
  1           0 LOAD_NAME                0 (isinstance)
              3 LOAD_NAME                1 (matrix)
              6 LOAD_NAME                2 (ButtonMatrixElement)
              9 CALL_FUNCTION            2
             12 JUMP_IF_TRUE             7 (to 22)
             15 POP_TOP             
             16 LOAD_GLOBAL              3 (AssertionError)
             19 RAISE_VARARGS            1
        >>   22 POP_TOP             
             23 LOAD_CONST               0 (None)
             26 RETURN_VALUE        


and it looks like some kind of automatic process was used to decompile the bytecode translated into the code you see, rather than recognize it as assert


Note that if the call isinstance()

returns True

, the branch instruction (index 12, JUMP_IF_TRUE

) jumps past the instruction RAISE_VARARGS

, but the rebuilt code does not. Compare this to the actual statement raise ... or ...

, you will notice that the jump does not pass by raise


>>> dis.dis(compile('raise foo or bar', '<stdin>', 'exec'))
  1           0 LOAD_NAME                0 (foo)
              3 JUMP_IF_TRUE             4 (to 10)
              6 POP_TOP             
              7 LOAD_NAME                1 (bar)
        >>   10 RAISE_VARARGS            1
             13 LOAD_CONST               0 (None)
             16 RETURN_VALUE        


Presumably the code generator was just not hard to handle; if you assume you are only or

generating JUMP_IF_TRUE

and not handling offsets as expected, you can see how the error was made.



As stated earlier, this is a bug in the decompiler that was used in the python-based bytecode reverse engineering process. If you want to decompile the files yourself, you can use the following version of the script:


The above error should be fixed. When you decompile MainSelectorComponent.pyc

with this version, you get:

class MainSelectorComponent(ModeSelectorComponent):
    """ Class that reassigns the button on the launchpad to different functions """

    def __init__(self, matrix, top_buttons, side_buttons, config_button):
        assert isinstance(matrix, ButtonMatrixElement)
        assert matrix.width() == 8 and matrix.height() == 8
        assert isinstance(top_buttons, tuple)
        assert len(top_buttons) == 8
        assert isinstance(side_buttons, tuple)
        assert len(side_buttons) == 8
        assert isinstance(config_button, ButtonElement)




All Articles