After a while of looking for the duplicates in here the only thing I find is no-ops and optimizing with Cython which is completely unrelated. What I'm trying to accomplish is to dynamically set python -O
flag at runtime.
Basically, there is one value sys.flags.optimize
which is read-only. I'm looking for an option to change it or to find a place which can have this value changed and affects the bytecode generating.
According to the doc the official way is to call it before the interpreter is spin up, so I wonder if it's even possible, however this is what I've found:
Python/compiler.c -> c_optimize
optimization_level
setup in C from environment variablePYTHONOPTIMIZE
Lib/py_compile.py
Which seems like py_compile
is called "somewhere" (GitHub search shows only doc or tests, not the actual caller at runtime) and manages the optimization_level
in the compiler.c
from above. That would mean I can change it within Python and make compiled interpreter assemble me code with and without optimizations in the same session/process.
I can't seem to find the CLI params parsing though, nor any related "state" that can be changed at runtime.
My target (for now) is to optionally allow/remove assert
keyword which can be done by -O
alone (via compiler_assert()
that needs the level set, however I'm struggling with finding the "missing link" between C code building AST and the actual Python code which seems to be holding the config state (because py_compile
contains raw optimize
values) and seems to be compiling and loading the bytecode for the interpreter itself.
Is there any way to change the optimization_level
so that I can achieve this behavior and pretty much do this in a single Python session?
>>> # change optimize to 1
>>> def test(): assert True
>>> import dis
>>> dis.dis(test)
1 0 LOAD_CONST 0 (None)
2 RETURN_VALUE
>>> # change optimize to 0
>>> dis.dis(test)
1 0 LOAD_CONST 1 (True)
2 POP_JUMP_IF_TRUE 8
4 LOAD_GLOBAL 0 (AssertionError)
6 RAISE_VARARGS 1
>> 8 LOAD_CONST 0 (None)
10 RETURN_VALUE