install-qa-check.d: Add check for missing Python bytecode (.pyc)
authorMichał Górny <mgorny@gentoo.org>
Wed, 23 Oct 2019 10:13:30 +0000 (12:13 +0200)
committerMichał Górny <mgorny@gentoo.org>
Fri, 1 Nov 2019 13:15:59 +0000 (14:15 +0100)
Add a check that detects Python modules that were not compiled after
installation.  To limit false positives, this is only done on modules
installed to site-packages.

Early testing of this check made it possible to detect a bug
in python_optimize.

Signed-off-by: Michał Górny <mgorny@gentoo.org>
metadata/install-qa-check.d/60python-pyc [new file with mode: 0644]

diff --git a/metadata/install-qa-check.d/60python-pyc b/metadata/install-qa-check.d/60python-pyc
new file mode 100644 (file)
index 0000000..ef668ae
--- /dev/null
@@ -0,0 +1,84 @@
+# Copyright 2019 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+# QA check: ensure that Python modules are compiled after installing
+# Maintainer: Python project <python@gentoo.org>
+
+inherit python-utils-r1
+
+python_pyc_check() {
+       local impl missing=() outdated=()
+       for impl in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do
+               python_export "${impl}" EPYTHON PYTHON
+               [[ -x ${PYTHON} ]] || continue
+               local sitedir=$(python_get_sitedir "${impl}")
+
+               if [[ -d ${D}${sitedir} ]]; then
+                       local suffixes=() subdir=
+                       case ${EPYTHON} in
+                               python2*)
+                                       suffixes=( .py{c,o} )
+                                       ;;
+                               pypy)
+                                       suffixes=( .pyc )
+                                       ;;
+                               python3*|pypy3*)
+                                       local tag=$("${PYTHON}" -c 'import sys; print(sys.implementation.cache_tag)')
+                                       suffixes=( ".${tag}"{,.opt-{1,2}}.pyc )
+                                       subdir=__pycache__/
+                                       ;;
+                               *)
+                                       # skip testing unknown impl
+                                       continue
+                                       ;;
+                       esac
+
+                       einfo "Verifying compiled files in ${sitedir}"
+                       local f s
+                       while read -d $'\0' -r f; do
+                               local dir=${f%/*}
+                               local basename=${f##*/}
+                               basename=${basename%.py}
+
+                               for s in "${suffixes[@]}"; do
+                                       local cache=${dir}/${subdir}${basename}${s}
+                                       if [[ ! -f ${cache} ]]; then
+                                               missing+=( "${cache}" )
+                                       elif [[ ${f} -nt ${cache} ]]; then
+                                               outdated+=( "${cache}" )
+                                       fi
+                               done
+                       done < <(find "${D}${sitedir}" -name '*.py' -print0)
+               fi
+       done
+
+       if [[ ${missing[@]} ]]; then
+               eqawarn
+               eqawarn "This package installs one or more Python modules that are not byte-compiled."
+               eqawarn "The following files are missing:"
+               eqawarn
+               eqatag -v python-pyc.missing "${missing[@]#${D}}"
+       fi
+
+       if [[ ${outdated[@]} ]]; then
+               eqawarn
+               eqawarn "This package installs one or more compiled Python modules that have older"
+               eqawarn "timestamps than the corresponding source files:"
+               eqawarn
+               eqatag -v python-pyc.outdated "${outdated[@]#${D}}"
+       fi
+
+       if [[ ${missing[@]} || ${outdated[@]} ]]; then
+               eqawarn
+               eqawarn "Please either fix the upstream build system to byte-compile Python modules"
+               eqawarn "correctly, or call python_optimize after installing them.  For more"
+               eqawarn "information, see:"
+               eqawarn "https://wiki.gentoo.org/wiki/Project:Python/Byte_compiling"
+               eqawarn
+       fi
+}
+
+python_pyc_check
+: # guarantee successful exit
+
+# vim:ft=ebuild