Edit

kc3-lang/automake/lib/py-compile

Branch :

  • Show log

    Commit

  • Author : Karl Berry
    Date : 2025-02-09 09:36:24
    Hash : 0ea7ef97
    Message : python: restore more compatible behavior for $PYTHON. For https://bugs.gnu.org/74434. * lib/py-compile: if $PYTHON -V does not include the string "python" (case-insensitive), consider the support intentionally disabled and exit successfully, unless PYTHON is set to false, in which case exit unsuccessfully. This is closer to the old behavior. Mention this in the help message. * t/py-compile-env.sh: add test for PYTHON=:. * NEWS: mention this. (And, en passant, add some past bug#s and clarify that only RCS/SCCS pattern rules were disabled, not all.)

  • lib/py-compile
  • #!/bin/sh
    # py-compile - Compile a Python program
    
    scriptversion=2024-12-03.03; # UTC
    
    # Copyright (C) 2000-2025 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 <https://www.gnu.org/licenses/>.
    
    # 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 <bug-automake@gnu.org> or send patches to
    # <automake-patches@gnu.org>.
    
    if test -z "$PYTHON"; then
      PYTHON=python
    fi
    
    me=py-compile
    
    # People apparently set PYTHON=: and expect the result to be true.
    # For the same reason, we output to stdout instead of stderr. Bizarre.
    if $PYTHON -V 2>/dev/null | grep -i python >/dev/null; then :; else
      echo "$me: Invalid python executable (according to -V): $PYTHON"
      echo "$me: Python support disabled"
      if test x"$PYTHON" = xfalse; then
        # But, as a special case, make PYTHON=false exit unsuccessfully,
        # since that was the traditional behavior.
        exit 1
        # In the past, setting PYTHON to any command that exited unsuccessfully
        # caused py-compile to exit unsuccessfully. Let's not try to
        # replicate that unless and until needed.
      else
       exit 0
      fi
    fi
      
    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 FILES as Python scripts.  Use --destdir to specify a
    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
    
    The Python interpreter to use is taken from the environment variable
    PYTHON, or "python" by default.
    
    For compatibility: as a special case, if PYTHON=false (that is, the
    command named "false"), this script will exit unsuccessfully. Otherwise,
    if $PYTHON -V does not include the string "Python", this script will
    emit a message to standard output and exit successfully.
    
    Report bugs to <bug-automake@gnu.org>.
    GNU Automake home page: <https://www.gnu.org/software/automake/>.
    General help using GNU software: <https://www.gnu.org/gethelp/>.
    EOF
          exit $?
          ;;
        -v|--version)
          echo "$me (GNU Automake) $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 nil t)
    # time-stamp-start: "scriptversion="
    # time-stamp-format: "%:y-%02m-%02d.%02H"
    # time-stamp-time-zone: "UTC0"
    # time-stamp-end: "; # UTC"
    # End: