I am bundling a Python application along with its virtenv environment inside an RPM for easier deployment. Is it a sound decision to omit all the .pyo
and .pyc
files?
What I would do instead is to invoke compileall.py
in the post-install action from within the virtenv
instance. Does that work, or will this mess up things?
Note: I realize that I could try on one machine, but a.) this wouldn't give me a conclusive answer as to whether this will work on other machines and b.) others may have the same question and I didn't find it answered.
Having a *. pyc file saves the compilation time of converting the python source code to byte code, every time the file is imported.
Files with the “pyc” extension are the cached, compiled bytecode that Python creates the first time you run your program, or whenever the source file has changed. You should generally ignore these files, but they should not be checked into version control systems like git.
Python can now be prevented from writing . pyc or . pyo files by supplying the -B switch to the Python interpreter, or by setting the PYTHONDONTWRITEBYTECODE environment variable before running the interpreter. This setting is available to Python programs as the sys.
. py files contain the source code of a program. Whereas, . pyc file contains the bytecode of your program.
You could indeed omit them - they are either generated (if you have write access), or the .py
is parsed every time you import it (which costs time).
But, depending on your distribution, your RPM system might contain easy scripts for compiling .py
files and bundle the .pyo
and .pyc
files on distribution, which makes the task quite easy.
$ rpm --showrc | grep -A 7 py.*_compile
-14: py3_compile(O)
find %1 -name '*.pyc' -exec rm -f {} ";"
python3 -c "import sys, os, compileall; br='%{buildroot}'; compileall.compile_dir(sys.argv[1], ddir=br and (sys.argv[1][len(os.path.abspath(br)):]+'/') or None)" %1
%{-O:
find %1 -name '*.pyo' -exec rm -f {} ";"
python3 -O -c "import sys, os, compileall; br='%{buildroot}'; compileall.compile_dir(sys.argv[1], ddir=br and (sys.argv[1][len(os.path.abspath(br)):]+'/') or None)" %1
}
-14: py3_incdir /usr/include/python3.3m
--
-14: py_compile(O)
find %1 -name '*.pyc' -exec rm -f {} \;
python -c "import sys, os, compileall; br='%{buildroot}'; compileall.compile_dir(sys.argv[1], ddir=br and (sys.argv[1][len(os.path.abspath(br)):]+'/') or None)" %1
%{-O:
find %1 -name '*.pyo' -exec rm -f {} \;
python -O -c "import sys, os, compileall; br='%{buildroot}'; compileall.compile_dir(sys.argv[1], ddir=br and (sys.argv[1][len(os.path.abspath(br)):]+'/') or None)" %1
}
-14: py_incdir %{py_prefix}/include/python%{py_ver}
I. e., you can put %py_compile
resp. %py3_compile
into your %build
section and you have what you need.
But, as said, you as well can omit them if you want to use them from several Python installations of various version numbers. But then you should make sure the .pyc
and .pyo
files are never created, as this might mess up things.
It's safe as long as you have their .py
files. As .pyo
and .pyc
files are generated from the original .py
files.
See also What do the python file extensions, .pyc .pyd .pyo stand for? and If Python is interpreted, what are .pyc files?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With