Tuesday 15 June 2010

"raise" followed by conditional statement (python) -



"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