"raise" followed by conditional statement (python) -
i'm trying understand python 2.5 code , came across pattern:
def __init__(self, matrix, top_buttons, side_buttons, config_button): raise isinstance(matrix, buttonmatrixelement) or assertionerror raise matrix.width() == 8 , 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 testing out in shell simple conditional statements this:
>>> str = 'hello' >>> raise len(str) == 5 or assertionerror traceback (most recent phone call last): file "<pyshell#6>", line 1, in <module> raise len(str) == 5 or assertionerror typeerror: exceptions must classes, instances, or strings (deprecated), not bool
so judging test, @ to the lowest degree way tried it, can't raise boolean statement. mean raise conditional look , why work in __init__
function not in test code?
the code nonsense, botched effort @ looks assert
statement fails, have discovered.
what should have written is:
assert isinstance(matrix, buttonmatrixelement)
etcetera.
it appears found decompiled ableton live scripts, decompilation script produced wrong python code. bytecode assert
looks (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 looks if whatever automated process used decompile bytecode translated code see rather recognise assert
.
note if isinstance()
phone call returns true
, jump instruction (index 12, jump_if_true
) jumps past raise_varargs
instruction, while re-constructed code doesn't. compare actual raise ... or ...
statement, you'll notice jump doesn't go past 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 code generator not sophisticated handle this; if assume or
generates jump_if_true
, don't handle offsets properly, can see how error made.
python conditional-statements python-2.5 raise
No comments:
Post a Comment