automake
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: python debugging on trunk


From: Zack Weinberg
Subject: Re: python debugging on trunk
Date: Mon, 26 Sep 2022 18:50:28 -0400
User-agent: Cyrus-JMAP/3.7.0-alpha0-968-g04df58079d-fm-20220921.001-g04df5807

On Mon, Sep 26, 2022, at 12:23 PM, Karl Berry wrote:
> Is anyone up for debugging some Python-related test failures on
> RHEL-based systems?

I have access to a RHEL7 system, I know Python, and this sounds much
less unpleasant than everything else I'm supposed to be doing today.

> I have a suspicion the problem is that on RHEL systems, "python" invokes
> "python2" (because that's what the Python maintainers recommend, as I
> understand it), but the tests are assuming it invokes "python3".

Indeed:

$ lsb_release -d
Description: Red Hat Enterprise Linux Workstation release 7.9 (Maipo)
$ python --version
Python 2.7.5
$ python3 --version
Python 3.6.8

I have very strong opinions on this topic, having had to deal with a
lot of badly-written Python 2 code that, in the worst case, silently
corrupts data when run under Python 3.  IMNSHO, the bare command name
"python" and the absolute pathname "/usr/bin/python" MUST[rfc2119] be
*permanently reserved* for the Python 2 interpreter.  It's fine for
them not to exist at all, but if they exist and they invoke Python 3,
that is a *bug* in the distribution.

(Yes, there's a PEP that says something different -- IMO it is wrong,
its authors probably hadn't encountered the *really* troublesome
Python 2 code that I have.)

---
RHEL7, unsurprisingly, ships with Autoconf 2.69.  Before attempting to
build Automake from Git, I built Autoconf 2.71 from the tarball
release, installed it in a subdirectory of my homedir, and made that
directory come first on PATH.  There were no unexpected test failures
in Autoconf's testsuite. Other relevant tool versions include:

$ perl --version
This is perl 5, version 16, subversion 3 (v5.16.3) built for 
x86_64-linux-thread-multi
(with 44 registered patches, see perl -V for more detail)

$ m4 --version
m4 (GNU M4) 1.4.16

$ /bin/sh --version
GNU bash, version 4.2.46(2)-release (x86_64-redhat-linux-gnu)

$ make --version
GNU Make 3.82

$ sort --version
sort (GNU coreutils) 8.22

$ gcc --version
gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-44)

$ libtool --version
libtool (GNU libtool) 2.4.2

I see these Automake testsuite failures:

Testsuite summary for GNU Automake 1.16i
========================================
# TOTAL: 2988
# PASS:  2877
# SKIP:  54
# XFAIL: 39
# FAIL:  18
# XPASS: 0
# ERROR: 0

FAIL: t/canon7
FAIL: t/fort5
FAIL: t/instmany-python
FAIL: t/ltinit
FAIL: t/nobase-python
FAIL: t/pr401b
FAIL: t/py-compile-basedir
FAIL: t/py-compile-basic
FAIL: t/py-compile-destdir
FAIL: t/py-compile-option-terminate
FAIL: t/python-pr10995
FAIL: t/python-prefix
FAIL: t/python-vars
FAIL: t/python10
FAIL: t/python12
FAIL: t/python3
FAIL: t/subobj9
FAIL: t/suffix5

That's _most_ of the failures you got, plus some more:

+FAIL: t/canon7
+FAIL: t/fort5
+FAIL: t/ltinit
+FAIL: t/pr401b
+FAIL: t/python10
+FAIL: t/subobj9
+FAIL: t/suffix5
-FAIL: t/subobj-pr13928-more-langs

There are only two failure modes:

canon7, fort5, ltinit, pr401b, subobj9, suffix5

ERROR: files left in build directory after distclean:
./.__afsxxxx

I did the build in an AFS volume; these are the AFS equivalent of
the NFS "silly rename" hack (apparently it can happen with SMB as well).
"make distcleancheck" should ignore these.

instmany-python, nobase-python, py-compile-basic, py-compile-destdir,
py-compile-option-terminate, pyghon-pr10995, python-prefix,
python-vars, python10, python12, python3

AttributeError: 'module' object has no attribute 'implementation'

This is coming from this code in lib/py-compile (there are three
copies of it):

    if hasattr(sys.implementation, 'cache_tag'):
        py_compile.compile(filepath, 
importlib.util.cache_from_source(filepath), path)
    else:
        py_compile.compile(filepath, filepath + 'c', path)

sys.implementation was added in Python 3.3 and
importlib.util.cache_from_source was added in 3.4.
Python 2.7's importlib _only_ has 'import_module'.

The appended patch should address both issues.  Note that I have only
tested it with Python 2.7 and 3.6.  It _may_ not be correct for Python
in the 3.0--3.3 (inclusive) range; I cannot conveniently test that.

zw

  * lib/am/distdir.am (distcleancheck_listfiles): Filter out "silly rename"
  files, unavoidably created by deleting files that are still open in some
  process on various network file systems.

  * lib/py-compile: Test directly for availability of
  importlib.util.cache_from_source.  Untangle logic for when to generate
  -O and -OO bytecode.  Reformat embedded Python fragments.

diff --git a/lib/am/distdir.am b/lib/am/distdir.am
index 0f591266d..b8d90e572 100644
--- a/lib/am/distdir.am
+++ b/lib/am/distdir.am
@@ -568,7 +568,9 @@ distuninstallcheck:
 ## Define distcleancheck_listfiles and distcleancheck separately
 ## from distcheck, so that they can be overridden by the user.
 .PHONY: distcleancheck
-distcleancheck_listfiles = find . -type f -print
+distcleancheck_listfiles = \
+  find . \( -type f -a \! \
+  \( -name .nfs* -o -name .smb* -o -name .__afs* \) \) -print
 distcleancheck: distclean
        @if test '$(srcdir)' = . ; then \
          echo "ERROR: distcleancheck can only run from a VPATH build" ; \
diff --git a/lib/py-compile b/lib/py-compile
index 24a8a1a54..de0f02e32 100755
--- a/lib/py-compile
+++ b/lib/py-compile
@@ -1,7 +1,7 @@
 #!/bin/sh
 # py-compile - Compile a Python program
 
-scriptversion=2022-02-06.07; # UTC
+scriptversion=2022-09-26.22; # UTC
 
 # Copyright (C) 2000-2022 Free Software Foundation, Inc.
 
@@ -141,88 +141,83 @@ python_minor=`$PYTHON -c 'import sys; 
print(sys.version_info[1])'`
 $PYTHON -c "
 import sys, os, py_compile, importlib
 
+# 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
+    if (
+            not os.path.exists(filepath)
+            or not (len(filepath) >= 3 and filepath[-3:] == '.py')
+     ):
+        continue
     sys.stdout.write(file + ' ')
     sys.stdout.flush()
-    if hasattr(sys.implementation, 'cache_tag'):
-        py_compile.compile(filepath, 
importlib.util.cache_from_source(filepath), path)
-    else:
-        py_compile.compile(filepath, filepath + 'c', path)
+    py_compile.compile(filepath, destpath(filepath), path)
 sys.stdout.write('\n')" "$@" || exit $?
 
 # Then byte compile w/optimization all the modules.
-case $python_major.$python_minor in
-2.*)
-  $PYTHON -O -c "
+$PYTHON -O -c "
 import sys, os, py_compile, importlib
 
-# pypy does not use .pyo optimization
-if hasattr(sys, 'pypy_translation_info'):
+# 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
+    if (
+            not os.path.exists(filepath)
+            or not (len(filepath) >= 3 and filepath[-3:] == '.py')
+    ):
+        continue
     sys.stdout.write(file + ' ')
     sys.stdout.flush()
-    if hasattr(sys.implementation, 'cache_tag'):
-        py_compile.compile(filepath, 
importlib.util.cache_from_source(filepath), path)
-    else:
-        py_compile.compile(filepath, filepath + 'o', path)
+    py_compile.compile(filepath, destpath(filepath), path)
 sys.stdout.write('\n')" "$@" 2>/dev/null || exit $?
-  ;;
-*)  # Python 3+
-  $PYTHON -O -c "
-import sys, os, py_compile, importlib
-
-print('Byte-compiling python modules (optimized versions) ...')
-for file in sys.argv[1:]:
-    $pathtrans
-    $filetrans
-    if not os.path.exists(filepath) or not (len(filepath) >= 3
-                                            and filepath[-3:] == '.py'):
-           continue
-    print(file, end=' ', flush=True)
-    if hasattr(sys.implementation, 'cache_tag'):
-        py_compile.compile(filepath, 
importlib.util.cache_from_source(filepath), path)
-    else:
-        py_compile.compile(filepath, filepath + 'o', path)
-print()" "$@" 2>/dev/null || exit $?
-  ;;
-esac
 
 # 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 3.5+
-  # See https://bugs.gnu.org/38043 for background.
+*)
   $PYTHON -OO -c "
-import sys, os, py_compile, imp
+import sys, os, py_compile, importlib
 
-print('Byte-compiling python modules (-OO version) ...')
+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'):
+    if (
+            not os.path.exists(filepath)
+            or not (len(filepath) >= 3 and filepath[-3:] == '.py')
+    ):
         continue
-    print(file, end=' ', flush=True)
-    if hasattr(imp, 'get_tag'):
-        py_compile.compile(filepath, imp.cache_from_source(filepath), path)
-    else:
-        py_compile.compile(filepath, filepath + 'o', path)
-print()" "$@" 2>/dev/null || exit $?
+    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
 
--end--



reply via email to

[Prev in Thread] Current Thread [Next in Thread]