I am looking for a way to pass miscellaneous options using runpy or other tools.
In particular, I would like to get the output of an optimized python script in another non-optimized python script.
python -O tobeoptimized.py
I have tried using subprocess but I can't extract the object that I need as I do in runpy.
from subprocess import PIPE, run
command = ['python','-O','tobeoptimized.py']
result = run(command, stdout=PIPE, stderr=PIPE, universal_newlines=True)
It's doable.
The compile
built-in function takes optimize parameter. Its values are 0, 1 and 2. If it's 0
which is like without -O
, 1
is -O
and 2
is -OO
on the command line.
To make runpy
run module / path optimized it must be patched. Before doing that I'll define two functions for illustration.
This is a test module. If it's run without optimization it won't print.
app.py
assert 0, "assert zero"
print("Optimized")
These two functions don't do all the details as runpy
does. So won't function in full.
import importlib
import runpy
optimize = 1
def run_module(mod_name):
spec = importlib.util.find_spec(mod_name)
source = spec.loader.get_source(spec.name)
code = compile(source, spec.name + ".py", "exec", optimize=optimize)
d = {}
exec(code, d)
return d
def run_path(path):
with open(path) as f:
source = f.read()
code = compile(source, path, "exec", optimize=optimize)
d = {}
exec(code, d)
return d
This one is to patch a function in runpy
which runpy.run_module
uses to get code object of the module to run. The patch provides optimized code object.
import runpy
optimize = 1
def _get_module_details_wrapper(func):
def tmp(*args, **kwargs):
mod_name, spec, _ = func(*args, **kwargs)
source = spec.loader.get_source(spec.name)
code = compile(source, spec.name + ".py", "exec", optimize=optimize)
return mod_name, spec, code
return tmp
runpy._get_module_details = _get_module_details_wrapper(runpy._get_module_details)
runpy.run_module('app')
UPDATE
runpy.run_path
can be run with optimization turned on.
def optimize_compile(o):
from functools import partial
import builtins
builtins.compile = partial(compile, optimize=o)
optimize_compile(1)
runpy.run_path("app.py")
optimize_compile(0)
try:
runpy.run_path("app.py")
except AssertionError:
print("assertion")
optimize_compile(1)
runpy.run_path("app.py")