How can I unit test that something behaves differently when Python is in optimised mode? -
python allows run script in "optimised mode" passing -o option. if save script "assert.py":
assert false print("hello") then these 2 invocations of python result in different output (one prints exception message , stack trace, while other says hello):
python -m assert python -o -m assert the author of python script can determine whether python in optimised mode checking value of global name __debug__. allows different things depending upon whether running in optimised mode or not.
suppose want 1 thing if python in optimised mode, , quite different thing if not. easy enough - can use if __debug__:. suppose want unit test behaviour in each case correct. how should go doing this?
it occurred me set value of __debug__, you're not allowed this:
>>> __debug__ = false file "<stdin>", line 1 syntaxerror: assignment keyword >>>
consider code:
assert 123 if __debug__: do_something() optimized bytecode empty. assert , bare if __debug__ statements evaluated during bytecode compilation, not @ runtime. so, if succeed @ changing __debug__ (e.g. setattr(builtins, '__debug__', true)), still won't able execute code.
the way have run test suite twice, first without -o, -o. can automate part, don't have manually.
for completeness:
$ python3 >>> dis.dis('assert 123') 1 0 load_const 0 (123) 3 pop_jump_if_true 12 6 load_global 0 (assertionerror) 9 raise_varargs 1 >> 12 load_const 1 (none) 15 return_value >>> dis.dis('if __debug__: do_something()') 1 0 load_name 0 (do_something) 3 call_function 0 (0 positional, 0 keyword pair) 6 pop_top 7 load_const 0 (none) 10 return_value $ python3 -o >>> dis.dis('assert 123') 1 0 load_const 0 (none) 3 return_value >>> dis.dis('if __debug__: do_something()') 1 0 load_const 0 (none) 3 return_value note bare if __debug__ statements optimized out. if use complex conditions, appear in bytecode:
$ python3 -o >>> dis.dis('if __debug__ , something_else: do_something()') 1 0 load_name 0 (__debug__) 3 pop_jump_if_false 22 6 load_name 1 (something_else) 9 pop_jump_if_false 22 12 load_name 2 (do_something) 15 call_function 0 (0 positional, 0 keyword pair) 18 pop_top 19 jump_forward 0 (to 22) >> 22 load_const 0 (none) 25 return_value
Comments
Post a Comment