[Python-checkins] bpo-38021: Modify AIX platform_tag so it covers PEP 425 needs (GH-17303)

Nick Coghlan webhook-mailer at python.org
Sun Dec 15 09:18:00 EST 2019


https://github.com/python/cpython/commit/39afa2d3147e4b05a1161cc90dbf09b95072c2bb
commit: 39afa2d3147e4b05a1161cc90dbf09b95072c2bb
branch: master
author: Michael Felt <aixtools at users.noreply.github.com>
committer: Nick Coghlan <ncoghlan at gmail.com>
date: 2019-12-16T00:17:53+10:00
summary:

bpo-38021: Modify AIX platform_tag so it covers PEP 425 needs (GH-17303)

Provides a richer platform tag for AIX that we expect to be sufficient for PEP 425
binary distribution identification. Any backports to earlier Python versions will be
handled via setuptools.

Patch by Michael Felt.

files:
A Lib/_aix_support.py
A Misc/NEWS.d/next/Core and Builtins/2019-09-03-19-16-57.bpo-38021.KnUhdB.rst
M Doc/distutils/apiref.rst
M Lib/distutils/util.py
M Lib/sysconfig.py
M configure
M configure.ac
M pyconfig.h.in

diff --git a/Doc/distutils/apiref.rst b/Doc/distutils/apiref.rst
index 80136b8a6bcdd..12e0c0b2c9757 100644
--- a/Doc/distutils/apiref.rst
+++ b/Doc/distutils/apiref.rst
@@ -1142,6 +1142,24 @@ other utility module.
 
    * ``macosx-10.6-intel``
 
+   For AIX, Python 3.9 and later return a string starting with "aix", followed
+   by additional fields (separated by ``'-'``) that represent the combined
+   values of AIX Version, Release and Technology Level (first field), Build Date
+   (second field), and bit-size (third field). Python 3.8 and earlier returned
+   only a single additional field with the AIX Version and Release.
+
+   Examples of returned values on AIX:
+
+   * ``aix-5307-0747-32`` # 32-bit build on AIX ``oslevel -s``: 5300-07-00-0000
+
+   * ``aix-7105-1731-64`` # 64-bit build on AIX ``oslevel -s``: 7100-05-01-1731
+
+   * ``aix-7.2``          # Legacy form reported in Python 3.8 and earlier
+
+   .. versionchanged:: 3.9
+      The AIX platform string format now also includes the technology level,
+      build date, and ABI bit-size.
+
 
 .. function:: convert_path(pathname)
 
diff --git a/Lib/_aix_support.py b/Lib/_aix_support.py
new file mode 100644
index 0000000000000..2c5cd3297de30
--- /dev/null
+++ b/Lib/_aix_support.py
@@ -0,0 +1,99 @@
+"""Shared AIX support functions."""
+
+import sys
+from sysconfig import get_config_var
+
+# subprocess is not necessarily available early in the build process
+# if not available, the config_vars are also definitely not available
+# supply substitutes to bootstrap the build
+try:
+    import subprocess
+    _have_subprocess = True
+    _tmp_bd = get_config_var("AIX_BUILDDATE")
+    _bgt = get_config_var("BUILD_GNU_TYPE")
+except ImportError:  # pragma: no cover
+    _have_subprocess = False
+    _tmp_bd = None
+    _bgt = "powerpc-ibm-aix6.1.7.0"
+
+# if get_config_var("AIX_BUILDDATE") was unknown, provide a substitute,
+# impossible builddate to specify 'unknown'
+_MISSING_BD = 9898
+try:
+    _bd = int(_tmp_bd)
+except TypeError:
+    _bd = _MISSING_BD
+
+# Infer the ABI bitwidth from maxsize (assuming 64 bit as the default)
+_sz = 32 if sys.maxsize == (2**31-1) else 64
+
+
+def _aix_tag(vrtl, bd):
+    # type: (List[int], int) -> str
+    # vrtl[version, release, technology_level]
+    return "aix-{:1x}{:1d}{:02d}-{:04d}-{}".format(vrtl[0], vrtl[1], vrtl[2], bd, _sz)
+
+
+# extract version, release and technology level from a VRMF string
+def _aix_vrtl(vrmf):
+    # type: (str) -> List[int]
+    v, r, tl = vrmf.split(".")[:3]
+    return [int(v[-1]), int(r), int(tl)]
+
+
+def _aix_bosmp64():
+    # type: () -> Tuple[str, int]
+    """
+    Return a Tuple[str, int] e.g., ['7.1.4.34', 1806]
+    The fileset bos.mp64 is the AIX kernel. It's VRMF and builddate
+    reflect the current ABI levels of the runtime environment.
+    """
+    if _have_subprocess:
+        # We expect all AIX systems to have lslpp installed in this location
+        out = subprocess.check_output(["/usr/bin/lslpp", "-Lqc", "bos.mp64"])
+        out = out.decode("utf-8").strip().split(":")  # type: ignore
+        # Use str() and int() to help mypy see types
+        return str(out[2]), int(out[-1])
+    else:
+        from os import uname
+
+        osname, host, release, version, machine = uname()
+        return "{}.{}.0.0".format(version, release), _MISSING_BD
+
+
+def aix_platform():
+    # type: () -> str
+    """
+    AIX filesets are identified by four decimal values: V.R.M.F.
+    V (version) and R (release) can be retreived using ``uname``
+    Since 2007, starting with AIX 5.3 TL7, the M value has been
+    included with the fileset bos.mp64 and represents the Technology
+    Level (TL) of AIX. The F (Fix) value also increases, but is not
+    relevant for comparing releases and binary compatibility.
+    For binary compatibility the so-called builddate is needed.
+    Again, the builddate of an AIX release is associated with bos.mp64.
+    AIX ABI compatibility is described  as guaranteed at: https://www.ibm.com/\
+    support/knowledgecenter/en/ssw_aix_72/install/binary_compatability.html
+
+    For pep425 purposes the AIX platform tag becomes:
+    "aix-{:1x}{:1d}{:02d}-{:04d}-{}".format(v, r, tl, builddate, bitsize)
+    e.g., "aix-6107-1415-32" for AIX 6.1 TL7 bd 1415, 32-bit
+    and, "aix-6107-1415-64" for AIX 6.1 TL7 bd 1415, 64-bit
+    """
+    vrmf, bd = _aix_bosmp64()
+    return _aix_tag(_aix_vrtl(vrmf), bd)
+
+
+# extract vrtl from the BUILD_GNU_TYPE as an int
+def _aix_bgt():
+    # type: () -> List[int]
+    assert _bgt
+    return _aix_vrtl(vrmf=_bgt)
+
+
+def aix_buildtag():
+    # type: () -> str
+    """
+    Return the platform_tag of the system Python was built on.
+    """
+    return _aix_tag(_aix_bgt(), _bd)
diff --git a/Lib/distutils/util.py b/Lib/distutils/util.py
index 17a94bc428324..4b002ecef1df8 100644
--- a/Lib/distutils/util.py
+++ b/Lib/distutils/util.py
@@ -79,7 +79,8 @@ def get_host_platform():
             machine += ".%s" % bitness[sys.maxsize]
         # fall through to standard osname-release-machine representation
     elif osname[:3] == "aix":
-        return "%s-%s.%s" % (osname, version, release)
+        from _aix_support import aix_platform
+        return aix_platform()
     elif osname[:6] == "cygwin":
         osname = "cygwin"
         rel_re = re.compile (r'[\d.]+', re.ASCII)
diff --git a/Lib/sysconfig.py b/Lib/sysconfig.py
index b9e2fafbc084a..64cf1560d99e6 100644
--- a/Lib/sysconfig.py
+++ b/Lib/sysconfig.py
@@ -665,7 +665,8 @@ def get_platform():
             machine += ".%s" % bitness[sys.maxsize]
         # fall through to standard osname-release-machine representation
     elif osname[:3] == "aix":
-        return "%s-%s.%s" % (osname, version, release)
+        from _aix_support import aix_platform
+        return aix_platform()
     elif osname[:6] == "cygwin":
         osname = "cygwin"
         import re
diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-09-03-19-16-57.bpo-38021.KnUhdB.rst b/Misc/NEWS.d/next/Core and Builtins/2019-09-03-19-16-57.bpo-38021.KnUhdB.rst
new file mode 100644
index 0000000000000..d971647c21eae
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2019-09-03-19-16-57.bpo-38021.KnUhdB.rst	
@@ -0,0 +1,4 @@
+Provide a platform tag for AIX that is sufficient for PEP425 binary
+distribution identification.
+
+Patch by Michael Felt
diff --git a/configure b/configure
index 44f14c3c2cfe1..a2c7ddf595db2 100755
--- a/configure
+++ b/configure
@@ -10028,7 +10028,21 @@ $as_echo "no" >&6; }
 
 fi
 rm -f core conftest.err conftest.$ac_objext \
-    conftest$ac_exeext conftest.$ac_ext;;
+    conftest$ac_exeext conftest.$ac_ext
+# BUILD_GNU_TYPE + AIX_BUILDDATE are used to construct the platform_tag
+# of the AIX system used to build/package Python executable. This tag serves
+# as a baseline for bdist module packages
+               { $as_echo "$as_me:${as_lineno-$LINENO}: checking for the system builddate" >&5
+$as_echo_n "checking for the system builddate... " >&6; }
+               AIX_BUILDDATE=$(lslpp -Lcq bos.mp64 | awk -F:  '{ print $NF }')
+
+cat >>confdefs.h <<_ACEOF
+#define AIX_BUILDDATE $AIX_BUILDDATE
+_ACEOF
+
+               { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AIX_BUILDDATE" >&5
+$as_echo "$AIX_BUILDDATE" >&6; }
+               ;;
 	*) ;;
 esac
 
@@ -10267,7 +10281,6 @@ fi
 
 
 
-
 if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
 	if test -n "$ac_tool_prefix"; then
   # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args.
diff --git a/configure.ac b/configure.ac
index 0b28dda44cdb8..57dca35723c67 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2858,7 +2858,17 @@ case "$ac_sys_system" in
 		  AC_MSG_RESULT(yes)
 		],[
 		  AC_MSG_RESULT(no)
-		]);;
+		])
+dnl The AIX_BUILDDATE is obtained from the kernel fileset - bos.mp64
+# BUILD_GNU_TYPE + AIX_BUILDDATE are used to construct the platform_tag
+# of the AIX system used to build/package Python executable. This tag serves
+# as a baseline for bdist module packages
+               AC_MSG_CHECKING(for the system builddate)
+               AIX_BUILDDATE=$(lslpp -Lcq bos.mp64 | awk -F:  '{ print $NF }')
+               AC_DEFINE_UNQUOTED([AIX_BUILDDATE], [$AIX_BUILDDATE],
+                   [BUILD_GNU_TYPE + AIX_BUILDDATE are used to construct the PEP425 tag of the build system.])
+               AC_MSG_RESULT($AIX_BUILDDATE)
+               ;;
 	*) ;;
 esac
 
diff --git a/pyconfig.h.in b/pyconfig.h.in
index 50af4c6fee43d..e053be15a1180 100644
--- a/pyconfig.h.in
+++ b/pyconfig.h.in
@@ -8,6 +8,10 @@
 /* Define if building universal (internal helper macro) */
 #undef AC_APPLE_UNIVERSAL_BUILD
 
+/* BUILD_GNU_TYPE + AIX_BUILDDATE are used to construct the PEP425 tag of the
+   build system. */
+#undef AIX_BUILDDATE
+
 /* Define for AIX if your compiler is a genuine IBM xlC/xlC_r and you want
    support for AIX C++ shared extension modules. */
 #undef AIX_GENUINE_CPLUSPLUS



More information about the Python-checkins mailing list