#!/bin/sh # py-compile - Compile a Python program scriptversion=2023-03-30.00; # UTC # Copyright (C) 2000-2023 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # This file is maintained in Automake, please report # bugs to or send patches to # . if test -z "$PYTHON"; then PYTHON=python fi me=py-compile usage_error () { echo "$me: $*" >&2 echo "Try '$me --help' for more information." >&2 exit 1 } basedir= destdir= while test $# -ne 0; do case "$1" in --basedir) if test $# -lt 2; then usage_error "option '--basedir' requires an argument" else basedir=$2 fi shift ;; --destdir) if test $# -lt 2; then usage_error "option '--destdir' requires an argument" else destdir=$2 fi shift ;; -h|--help) cat <<\EOF Usage: py-compile [options] FILES... Byte compile some python scripts FILES. Use --destdir to specify any leading directory path to the FILES that you don't want to include in the byte compiled file. Specify --basedir for any additional path information you do want to be shown in the byte compiled file. Options: --basedir DIR Prefix all FILES with DIR, and include in error messages. --destdir DIR Prefix all FILES with DIR before compiling. -v, --version Display version information. -h, --help This help screen. Example: py-compile --destdir /tmp/pkg-root --basedir /usr/share/test test.py test2.py Report bugs to . EOF exit $? ;; -v|--version) echo "$me $scriptversion" exit $? ;; --) shift break ;; -*) usage_error "unrecognized option '$1'" ;; *) break ;; esac shift done if test $# -eq 0; then usage_error "no files given" fi # if basedir was given, then it should be prepended to filenames before # byte compilation. if test -z "$basedir"; then pathtrans="path = file" else pathtrans="path = os.path.join('$basedir', file)" fi # if destdir was given, then it needs to be prepended to the filename to # byte compile but not go into the compiled file. if test -z "$destdir"; then filetrans="filepath = path" else filetrans="filepath = os.path.normpath('$destdir' + os.sep + path)" fi python_major=`$PYTHON -c 'import sys; print(sys.version_info[0])'` if test -z "$python_major"; then usage_error "could not determine $PYTHON major version" fi case $python_major in [01]) usage_error "python version 0.x and 1.x not supported" ;; esac python_minor=`$PYTHON -c 'import sys; print(sys.version_info[1])'` # NB: When adding support for newer versions, prefer copying & adding new cases # rather than try to keep things merged with shell variables. # First byte compile (no optimization) all the modules. # This works for all currently known Python versions. $PYTHON -c " import sys, os, py_compile try: import importlib except ImportError: importlib = None # importlib.util.cache_from_source was added in 3.4 if ( hasattr(importlib, 'util') and hasattr(importlib.util, 'cache_from_source') ): destpath = importlib.util.cache_from_source else: destpath = lambda filepath: filepath + 'c' sys.stdout.write('Byte-compiling python modules...\n') for file in sys.argv[1:]: $pathtrans $filetrans if ( not os.path.exists(filepath) or not (len(filepath) >= 3 and filepath[-3:] == '.py') ): continue sys.stdout.write(file + ' ') sys.stdout.flush() py_compile.compile(filepath, destpath(filepath), path) sys.stdout.write('\n')" "$@" || exit $? # Then byte compile w/optimization all the modules. $PYTHON -O -c " import sys, os, py_compile try: import importlib except ImportError: importlib = None # importlib.util.cache_from_source was added in 3.4 if ( hasattr(importlib, 'util') and hasattr(importlib.util, 'cache_from_source') ): destpath = importlib.util.cache_from_source else: destpath = lambda filepath: filepath + 'o' # pypy2 does not use .pyo optimization if sys.version_info.major <= 2 and hasattr(sys, 'pypy_translation_info'): sys.exit(0) sys.stdout.write('Byte-compiling python modules (optimized versions) ...\n') for file in sys.argv[1:]: $pathtrans $filetrans if ( not os.path.exists(filepath) or not (len(filepath) >= 3 and filepath[-3:] == '.py') ): continue sys.stdout.write(file + ' ') sys.stdout.flush() py_compile.compile(filepath, destpath(filepath), path) sys.stdout.write('\n')" "$@" 2>/dev/null || exit $? # Then byte compile w/more optimization. # Only do this for Python 3.5+, see https://bugs.gnu.org/38043 for background. case $python_major.$python_minor in 2.*|3.[0-4]) ;; *) $PYTHON -OO -c " import sys, os, py_compile, importlib sys.stdout.write('Byte-compiling python modules (more optimized versions)' ' ...\n') for file in sys.argv[1:]: $pathtrans $filetrans if ( not os.path.exists(filepath) or not (len(filepath) >= 3 and filepath[-3:] == '.py') ): continue sys.stdout.write(file + ' ') sys.stdout.flush() py_compile.compile(filepath, importlib.util.cache_from_source(filepath), path) sys.stdout.write('\n')" "$@" 2>/dev/null || exit $? ;; esac # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End: