Bump to python3 3.12.0 accepted/tizen_base accepted/tizen_base_asan accepted/tizen_base_toolchain accepted/tizen_base_x accepted/tizen_base_x_asan sandbox/python3_3.12.0 tizen_base accepted/tizen/base/20240328.043050 accepted/tizen/base/asan/20240406.082308 accepted/tizen/base/toolchain/20240424.234719 accepted/tizen/base/x/20240328.090047 accepted/tizen/base/x/asan/20240412.003402
authorTizenOpenSource <tizenopensrc@samsung.com>
Thu, 4 Jan 2024 01:45:54 +0000 (10:45 +0900)
committerTizenOpenSource <tizenopensrc@samsung.com>
Thu, 4 Jan 2024 01:45:54 +0000 (10:45 +0900)
Signed-off-by: TizenOpenSource <tizenopensrc@samsung.com>
18 files changed:
packaging/Added-no_sanitize_hwaddress.patch [new file with mode: 0644]
packaging/Avoid-ProcessPoolExecutor.patch [new file with mode: 0644]
packaging/PACKAGING-NOTES [new file with mode: 0644]
packaging/Skip_unittest.patch [new file with mode: 0644]
packaging/add_path_environment.patch [new file with mode: 0644]
packaging/add_pie_compile_option.patch [new file with mode: 0644]
packaging/baselibs.conf [new file with mode: 0644]
packaging/import_failed.map [new file with mode: 0644]
packaging/import_failed.py [new file with mode: 0644]
packaging/macros.python3.py [new file with mode: 0644]
packaging/pre_checkin.sh [new file with mode: 0644]
packaging/python3-base.spec [new file with mode: 0644]
packaging/python3-rpmlintrc [new file with mode: 0644]
packaging/python3.csh [new file with mode: 0644]
packaging/python3.sh [new file with mode: 0644]
packaging/python3.spec [new file with mode: 0644]
packaging/python3start [new file with mode: 0644]
packaging/skipped_tests.py [new file with mode: 0644]

diff --git a/packaging/Added-no_sanitize_hwaddress.patch b/packaging/Added-no_sanitize_hwaddress.patch
new file mode 100644 (file)
index 0000000..d628504
--- /dev/null
@@ -0,0 +1,61 @@
+From bcf1b3584704e3fea441067afb5cc1c5c875f770 Mon Sep 17 00:00:00 2001
+From: Andrey Kazmin <a.kazmin@partner.samsung.com>
+Date: Tue, 8 Jun 2021 16:25:32 +0300
+Subject: [PATCH 3/3] Added no_sanitize_hwaddress attribute for
+ address_in_range
+
+Added new attribute for address_in_range to disable HWASan instrumentation.
+
+Change-Id: I4c446585f144f034dc79e4dc938ef4b8f8401199
+Signed-off-by: Andrey Kazmin <a.kazmin@partner.samsung.com>
+---
+ Objects/obmalloc.c | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+diff --git a/Objects/obmalloc.c b/Objects/obmalloc.c
+index eb34f10b..9284c7ff 100644
+--- a/Objects/obmalloc.c
++++ b/Objects/obmalloc.c
+@@ -34,6 +34,10 @@ static void _PyMem_SetupDebugHooksDomain(PyMemAllocatorDomain domain);
+ #    define _Py_NO_SANITIZE_ADDRESS \
+         __attribute__((no_sanitize("address")))
+ #  endif
++#  if __has_feature(hwaddress_sanitizer) /* is ASAN enabled? */
++#    define _Py_NO_SANITIZE_HWADDRESS \
++        __attribute__((no_sanitize("hwaddress")))
++#  endif
+ #  if __has_feature(thread_sanitizer)  /* is TSAN enabled? */
+ #    define _Py_NO_SANITIZE_THREAD __attribute__((no_sanitize_thread))
+ #  endif
+@@ -44,6 +48,10 @@ static void _PyMem_SetupDebugHooksDomain(PyMemAllocatorDomain domain);
+ #  if defined(__SANITIZE_ADDRESS__)    /* GCC 4.8+, is ASAN enabled? */
+ #    define _Py_NO_SANITIZE_ADDRESS \
+         __attribute__((no_sanitize_address))
++#  endif
++#  if defined(__SANITIZE_HWADDRESS__)    /* GCC 10+, is HWASAN enabled? */
++#    define _Py_NO_SANITIZE_HWADDRESS \
++        __attribute__((no_sanitize_hwaddress))
+ #  endif
+    // TSAN is supported since GCC 5.1, but __SANITIZE_THREAD__ macro
+    // is provided only since GCC 7.
+@@ -55,6 +63,9 @@ static void _PyMem_SetupDebugHooksDomain(PyMemAllocatorDomain domain);
+ #ifndef _Py_NO_SANITIZE_ADDRESS
+ #  define _Py_NO_SANITIZE_ADDRESS
+ #endif
++#ifndef _Py_NO_SANITIZE_HWADDRESS
++#  define _Py_NO_SANITIZE_HWADDRESS
++#endif
+ #ifndef _Py_NO_SANITIZE_THREAD
+ #  define _Py_NO_SANITIZE_THREAD
+ #endif
+@@ -1408,6 +1419,7 @@ extremely desirable that it be this fast.
+ */
+
+ static bool _Py_NO_SANITIZE_ADDRESS
++            _Py_NO_SANITIZE_HWADDRESS
+             _Py_NO_SANITIZE_THREAD
+             _Py_NO_SANITIZE_MEMORY
+ address_in_range(void *p, poolp pool)
+--
+2.25.1
+
diff --git a/packaging/Avoid-ProcessPoolExecutor.patch b/packaging/Avoid-ProcessPoolExecutor.patch
new file mode 100644 (file)
index 0000000..9485794
--- /dev/null
@@ -0,0 +1,13 @@
+diff --git a/Makefile.pre.in b/Makefile.pre.in
+index 09ceccd..417bc50 100644
+--- a/Makefile.pre.in
++++ b/Makefile.pre.in
+@@ -2231,7 +2231,7 @@ TESTSUBDIRS=     idlelib/idle_test \
+               test/xmltestdata/c14n-20 \
+               test/ziptestdata
+-COMPILEALL_OPTS=-j0
++COMPILEALL_OPTS=-j1
+ TEST_MODULES=@TEST_MODULES@
diff --git a/packaging/PACKAGING-NOTES b/packaging/PACKAGING-NOTES
new file mode 100644 (file)
index 0000000..69e640f
--- /dev/null
@@ -0,0 +1,58 @@
+Notes for packagers of Python3
+==============================
+
+I. python3 and python3-base naming confusion
+--------------------------------------------
+
+1. the important stuff first
+
+This is package "python3". However, master spec file for this package is "python3-base.spec".
+That means that all important changes should be put into "python3-base.spec" and then submitted
+against "python3" in OBS.
+
+Changelogs of python3-base and python3 will be merged at some point. Now they arent,
+but feel free to enter changes in either or both.
+
+2. why is that?
+
+Technical reasons. python3-base was originally supposed to be a minimal package with no external
+dependencies - so that it can build early in the distribution rebuild. There were also some
+build loops involved.
+Turns out, 90% of Python's standard library can be built without external dependencies. That's
+what we do - in python3-base. python3 then only contains the remaining bits - dependency-heavy
+subpackages, plus small bits depending on common packages (OpenSSL, expat, readline)
+Logically, python3-base must be the master spec because it builds the important parts.
+
+3. why not rename the whole package to python3-base?
+
+Because that would be stupid. The package is called python3.
+
+4. so why not make python3 the minimal package and put the rest in python3-the-rest?
+
+Because other distributions use python3-base as the minimal package as well. Also, packages
+that require python3 expect the whole deal, not a stripped-down version.
+
+5. alright, let's build python3-base from python3.spec and python3 from someother.spec
+
+Tried that, abandoned it. It is more trouble than it's worth.
+
+
+II. pre_checkin.sh
+------------------
+
+Our pre_checkin.sh takes care of copying relevant portions of python3-base.spec to python3.spec.
+The "relevant portions" are:
+* list of patches
+* list of macro definitions
+* patch apply sequence in %prep
+
+That means that when you're adding a patch, you need only add it to python3-base.spec and it will appear
+magically in python3.spec too.
+
+If you want to replicate another section from py3-base to py3, just mark the section with
+NEW-SECTION-BEGIN and NEW-SECTION-END (in both py3-base and py3) and add NEW-SECTION to list of $sections
+in pre_checkin.sh
+
+pre_checkin.sh also finds the newest python tarball in the source directory and updates versions
+in all specfiles to match it. Therefore, you usually don't need to update version numbers in specs
+when you update Python
diff --git a/packaging/Skip_unittest.patch b/packaging/Skip_unittest.patch
new file mode 100644 (file)
index 0000000..d16b1b3
--- /dev/null
@@ -0,0 +1,13 @@
+diff --git a/Makefile.pre.in b/Makefile.pre.in
+index 09ceccd..42e284e 100644
+--- a/Makefile.pre.in
++++ b/Makefile.pre.in
+@@ -656,7 +656,7 @@ profile-run-stamp:
+       $(MAKE) profile-gen-stamp
+       # Next, run the profile task to generate the profile information.
+       @ # FIXME: can't run for a cross build
+-      $(LLVM_PROF_FILE) $(RUNSHARED) ./$(BUILDPYTHON) $(PROFILE_TASK) || true
++      # $(LLVM_PROF_FILE) $(RUNSHARED) ./$(BUILDPYTHON) $(PROFILE_TASK) || true
+       $(LLVM_PROF_MERGER)
+       # Remove profile generation binary since we are done with it.
+       $(MAKE) clean-retain-profile
diff --git a/packaging/add_path_environment.patch b/packaging/add_path_environment.patch
new file mode 100644 (file)
index 0000000..f264b9a
--- /dev/null
@@ -0,0 +1,10 @@
+diff --git a/Misc/python-config.sh.in b/Misc/python-config.sh.in
+index 2602fe24..3c1fd243 100644
+--- a/Misc/python-config.sh.in
++++ b/Misc/python-config.sh.in
+@@ -1,4 +1,5 @@
+ #!/bin/sh
++PATH=/bin:/usr/bin:/sbin:/usr/sbin
+
+ # Keep this script in sync with python-config.in
+
diff --git a/packaging/add_pie_compile_option.patch b/packaging/add_pie_compile_option.patch
new file mode 100644 (file)
index 0000000..04376e6
--- /dev/null
@@ -0,0 +1,13 @@
+diff --git a/configure.ac b/configure.ac
+index 789df36e..ae403066 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -2755,7 +2755,7 @@ then
+           LINKFORSHARED="-Wl,-E -Wl,+s";;
+ #         LINKFORSHARED="-Wl,-E -Wl,+s -Wl,+b\$(BINLIBDEST)/lib-dynload";;
+       Linux-android*) LINKFORSHARED="-pie -Xlinker -export-dynamic";;
+-      Linux*|GNU*) LINKFORSHARED="-Xlinker -export-dynamic";;
++      Linux*|GNU*) LINKFORSHARED="-pie -Xlinker -export-dynamic";;
+       # -u libsys_s pulls in all symbols in libsys
+       Darwin/*)
+               LINKFORSHARED="$extra_undefs -framework CoreFoundation"
diff --git a/packaging/baselibs.conf b/packaging/baselibs.conf
new file mode 100644 (file)
index 0000000..b94f2b0
--- /dev/null
@@ -0,0 +1,3 @@
+python3
+python3-base
+libpython3_91_0
diff --git a/packaging/import_failed.map b/packaging/import_failed.map
new file mode 100644 (file)
index 0000000..9f6c970
--- /dev/null
@@ -0,0 +1,7 @@
+python3-tools: turtledemo
+python3-idle: idlelib
+python3-testsuite: test _ctypes_test _testbuffer _testcapi _testimportmultiple _testmultiphase xxlimited
+python3-tk: tkinter _tkinter
+python3-curses: curses _curses _curses_panel
+python3-dbm: dbm _dbm _gdbm
+python3: ensurepip sqlite3 xml xmlrpc _hashlib pyexpat readline _sqlite3 _ssl
diff --git a/packaging/import_failed.py b/packaging/import_failed.py
new file mode 100644 (file)
index 0000000..801b175
--- /dev/null
@@ -0,0 +1,26 @@
+import sys, os
+from sysconfig import get_path
+
+failed_map_path = os.path.join(get_path('stdlib'), '_import_failed', 'import_failed.map')
+
+if __spec__:
+    failed_name = __spec__.name
+else:
+    failed_name = __name__
+
+for line in open(failed_map_path):
+    words = line.strip().split()
+    if not words or words[0][0] == '#':
+        continue
+    assert words[0][-1] == ':'
+    package = words[0][:-1]
+
+    if failed_name in words[1:]:
+        raise ImportError("""Module '{}' is not installed.
+Use:
+  sudo zypper install {}
+to install it.""".format(failed_name, package))
+
+raise ImportError("""Module '{}' is not installed.
+It is supposed to be part of python3 distribution, but missing from failed import map.
+Please file a bug on the SUSE Bugzilla.""".format(failed_name))
diff --git a/packaging/macros.python3.py b/packaging/macros.python3.py
new file mode 100644 (file)
index 0000000..46676d2
--- /dev/null
@@ -0,0 +1,31 @@
+#!/usr/bin/python3
+
+""" generate macros.python3 file from known values """
+
+import sys,os
+from sysconfig import get_path, get_config_var
+
+version = "{}.{}".format(*sys.version_info)
+
+macros = {
+    "py3_ver":          version,
+    "python3_version":  version,
+    "py3_prefix":       sys.prefix,
+# hack-fix for bnc#787526 - get_path can't be used this way in python build dir
+#    "py3_incdir":       get_path("include"),
+    "py3_incdir":       "/usr/include/python" + version ,
+    "py3_soflags":      get_config_var("SOABI"),
+    "python3_sitelib":  get_path("purelib"),
+    "python3_sitearch": get_path("platlib"),
+    "py3_compile(O)": """
+find %1 -name '*.pyc' -exec rm -f {} ";"
+python3 -c "import sys, os, compileall; br='%{buildroot}'; compileall.compile_dir(sys.argv[1], ddir=br and (sys.argv[1][len(os.path.abspath(br)):]+'/') or None)" %1
+%{-O:
+find %1 -name '*.pyo' -exec rm -f {} ";"
+python3 -O -c "import sys, os, compileall; br='%{buildroot}'; compileall.compile_dir(sys.argv[1], ddir=br and (sys.argv[1][len(os.path.abspath(br)):]+'/') or None)" %1
+}""",
+}
+
+for (macro,definition) in macros.items():
+    definition = "\\\n".join(definition.split("\n"))
+    print( "%{} {}".format(macro, definition))
diff --git a/packaging/pre_checkin.sh b/packaging/pre_checkin.sh
new file mode 100644 (file)
index 0000000..c4c36c2
--- /dev/null
@@ -0,0 +1,122 @@
+#!/bin/bash
+# This script is called automatically during autobuild checkin.
+#
+#
+#
+# ...or is it?
+# it really doesn't seem so, you know. go run it manually.
+
+master=python3-base.spec
+
+# calculate version number from newest tar name
+VERSION=`ls *.tar.xz | grep '^Python-' | tail -n 1 | sed -r 's/^Python-([0-9]+\.[0-9]+.[0-9a-z]+)\.tar.*$/\1/'`
+if echo $VERSION | grep -q Python; then
+    echo "Version is $VERSION and that's not right, fix the script."
+    exit 1
+fi
+# VERSION = 3.3.0
+
+Version=${VERSION/[a-z]*/}      # 3.3.0
+tar_suffix=${VERSION#$Version}  # b1
+a_version=(${Version//\./ })    # 3 3 0
+
+python_version=${VERSION:0:3}                   # 3.3
+python_version_abitag=${python_version//./}     # 33
+python_version_soname=${python_version//./_}    # 3_3
+
+if [ -n "$tar_suffix" ]; then
+    Version=$Version~$tar_suffix           # 3.3.0~b1
+    tarversion=$VERSION                    # 3.3.0b1
+else
+    tarversion="%{version}"
+fi
+
+# set Version for every spec
+sed -i -r 's/(^Version:[ \t]+).*/\1'"$Version"'/' python3*.spec
+# set tarversion for every spec
+sed -i -r 's/(^%define[ \t]+tarversion[ \t]+).*/\1'$tarversion'/' python3*.spec
+
+for varname in python_version{,_abitag,_soname}; do
+    eval varvalue=\$$varname
+    sed -i -r 's/(^%define[ \t]+'$varname'[ \t]+).*/\1'$varvalue'/' $master
+done
+
+
+# update baselibs
+sed -i -r 's/^libpython.*$/libpython'$python_version_soname'm1_0/' baselibs.conf
+
+
+# copy definition sections
+
+
+sections="COMMON-PATCH COMMON-DEF COMMON-PREP"
+
+for slave in python3.spec python3-doc.spec; do
+{
+    prev=1
+    for section in $sections; do
+        begin="/$section-BEGIN/"
+        end="/$section-END/"
+        sed -n -e "${prev},${begin}p" $slave
+        sed -n -e "${begin},${end}p" $master | head -n -1 | tail -n +2
+        prev=$end
+    done
+    sed -n -e "${prev},\$p" $slave
+} > $slave.tmp && mv $slave.tmp $slave
+done
+
+osc service localrun format_spec_file
+
+
+# create import_failed.map from package definitions
+
+MAPFILE=import_failed.map
+function new_map_line () {
+    if [ -z "$1" -o -z "$2" ]; then
+        return
+    fi
+    if [ "$1" == "python3-base" ]; then
+        return
+    fi
+    echo "$1:$2" >> $MAPFILE.tmp
+}
+
+for spec in *.spec; do
+    basename=${spec%.spec}
+    package=
+    modules=
+    while read line; do
+        case $line in
+            "%files -n "*)
+                new_map_line $package "$modules"
+                package=${line#"%files -n "}
+                modules=
+                ;;
+            "%files "*)
+                new_map_line $package "$modules"
+                package=$basename-${line#"%files "}
+                modules=
+                ;;
+            "%files")
+                new_map_line $package "$modules"
+                package=$basename
+                modules=
+                ;;
+            "%{sitedir}/"*)
+                word=${line#"%{sitedir}/"}
+                if ! echo $word | grep -q /; then
+                    modules="$modules $word"
+                fi
+                ;;
+            "%{dynlib "*"}")
+                word=${line#"%{dynlib "}
+                word=${word%"}"}
+                modules="$modules $word"
+                ;;
+        esac
+    done < $spec
+    new_map_line $package "$modules"
+done
+
+mv $MAPFILE.tmp $MAPFILE
+
diff --git a/packaging/python3-base.spec b/packaging/python3-base.spec
new file mode 100644 (file)
index 0000000..174325c
--- /dev/null
@@ -0,0 +1,648 @@
+#
+# spec file for package python3-base
+#
+# Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany.
+#
+# All modifications and additions to the file contributed by third parties
+# remain the property of their copyright owners, unless otherwise agreed
+# upon. The license for this file, and modifications and additions to the
+# file, is the same license as for the pristine package itself (unless the
+# license for the pristine package is not an Open Source License, in which
+# case the license is the MIT License). An "Open Source License" is a
+# license that conforms to the Open Source Definition (Version 1.9)
+# published by the Open Source Initiative.
+
+# Please submit bugfixes or comments via http://bugs.opensuse.org/
+#
+
+
+# !!!!
+# this is the master spec file, but changes should be submitted
+# against python3, not python3-base
+#
+# see PACKAGING-NOTES for details
+# !!!!
+### COMMON-DEF-BEGIN ###
+%define         tarversion %{version}
+%define         tarname    Python-%{tarversion}
+# the versions are autogenerated from pre_checkin.sh
+# based on the current source tarball
+%define         python_version          3.12
+%define         python_version_abitag   312
+%define         python_version_soname   3_12
+
+%define         sitedir         %{_libdir}/python%{python_version}
+
+# three possible ABI kinds: m - pymalloc, d - debug build; see PEP 3149
+%define         abi_kind   %{nil}
+# python ABI version - used in some file names
+%define         python_abi %{python_version}%{abi_kind}
+# soname ABI tag defined in PEP 3149
+%define         abi_tag    %{python_version_abitag}%{abi_kind}
+# version part of "libpython" package
+%define         so_version %{python_version_soname}%{abi_kind}1_0
+
+# rpm and python have different ideas about what is an arch-dependent name, so:
+%if %{__isa_name} == ppc
+%define archname %(echo %{_arch} | sed s/ppc/powerpc/)
+%else
+%define archname %{_arch}
+%endif
+
+%define dynlib() %{sitedir}/lib-dynload/%{1}.cpython-%{abi_tag}-%{archname}-%{_os}%{?_gnu}.so
+%define __spec_check_pre exit 0
+### COMMON-DEF-END ###
+
+# that thing where "without" means "default=on" and vice versa
+%bcond_without testsuite
+%if 0%{?do_profiling}
+%bcond_without profileopt
+%else
+%bcond_with    profileopt
+%endif
+
+Name:           python3-base
+Version:        3.12.0
+Release:        0
+Summary:        Python 3 Interpreter and Stdlib Core
+License:        Python-2.0
+Group:          Development/Languages/Python
+Url:            http://www.python.org/
+
+##### SOURCE FILES #####
+Source0:        %{version}/%{tarname}.tgz
+Source3:        baselibs.conf
+Source5:        python3start
+Source6:        python3.sh
+Source7:        python3.csh
+Source8:        macros.python3.py
+Source9:        import_failed.py
+Source10:       import_failed.map
+Source11:       add_pie_compile_option.patch
+Source12:       add_path_environment.patch
+Source13:       Skip_unittest.patch
+Source14:       Avoid-ProcessPoolExecutor.patch
+Source15:       Added-no_sanitize_hwaddress.patch
+
+
+# The following files are not used in the build.
+# They are listed here to work around missing functionality in rpmbuild,
+# which would otherwise exclude them from distributed src.rpm files.
+Source100:      PACKAGING-NOTES
+Source101:      python3-rpmlintrc
+Source102:      pre_checkin.sh
+Source103:      skipped_tests.py
+
+##### REQURES, PROVIDES, OBSOLETES #####
+#Requires:       python-rpm-macros
+Recommends:     python3 = %{version}
+#Recommends:     python3-ensurepip
+
+# python 3.1 didn't have a separate python-base, so it is wrongly
+# not a conflict to have python3-3.1 and python3-base > 3.1
+Obsoletes:      python3 < 3.2
+# no Provides, because python3 is obviously provided by package python3
+
+# python 3.4 provides asyncio
+Provides:       python3-asyncio = %{version}
+Obsoletes:      python3-asyncio < %{version}
+
+# python 3.6 provides typing
+Provides:       python3-typing = %{version}
+Obsoletes:      python3-typing < %{version}
+
+##### BUILDREQUIRES #####
+# SECTION required for basic build
+BuildRequires:  automake
+BuildRequires:  autoconf-archive
+BuildRequires:  pkgconfig
+# /SECTION
+# SECTION required for core modules
+# The compression-related ones could be moved to python3 if necessary, with the exception of zlib.
+# _bz2
+BuildRequires:  bzip2-devel
+# _ctypes
+BuildRequires:  libffi-devel
+# _lzma
+BuildRequires:  lzma-devel
+# ssl
+BuildRequires:  pkgconfig(openssl3)
+# zlib
+BuildRequires:  zlib-devel
+
+BuildRequires:  libexpat-devel
+BuildRequires:  gdbm-devel
+BuildRequires:  gettext-tools
+BuildRequires:  gmp-devel
+BuildRequires:  intltool
+BuildRequires:  ncurses-devel
+BuildRequires:  readline-devel
+BuildRequires:  sqlite-devel
+BuildRequires:  xz
+
+
+# /SECTION
+# SECTION required for build and testsuite
+BuildRequires:  fdupes
+# netcfg is needed *only* for /etc/services for one test in test_asyncio
+# this could be moved to python3 if needed, it's just more convenient here
+#BuildRequires:  netcfg
+BuildRequires:  timezone
+BuildRequires:  xz
+# /SECTION
+
+
+%description
+Python is an interpreted, object-oriented programming language, and is
+often compared to Tcl, Perl, Scheme, or Java.  You can find an overview
+of Python in the documentation and tutorials included in the python-doc
+package.
+
+This package contains the interpreter core and most commonly used modules
+from the standard library. This is sufficient for many usecases, but it
+excludes components that depend on external libraries, most notably XML,
+database and UI toolkits support.
+
+
+%package -n python3-tools
+Summary:        Python Utility and Demonstration Scripts
+Group:          Development/Languages/Python
+Requires:       %{name} = %{version}
+Obsoletes:      python3-demo < %{version}
+Provides:       python3-demo = %{version}
+Obsoletes:      python3-2to3 < %{version}
+Provides:       python3-2to3 = %{version}
+
+%description -n python3-tools
+A number of scripts that are useful for building, testing or extending Python,
+and a set of demonstration programs.
+
+
+%package -n python3-idle
+Summary:        An Integrated Development Environment for Python
+Group:          Development/Languages/Python
+Requires:       %{name} = %{version}
+Requires:       python3-tk
+
+%description -n python3-idle
+IDLE is a Tkinter based integrated development environment for Python.
+It features a multi-window text editor with multiple undo, Python
+colorizing, and many other things, as well as a Python shell window and
+a debugger.
+
+
+%package -n python3-devel
+Summary:        Include Files and Libraries Mandatory for Building Python Modules
+Group:          Development/Languages/Python
+Requires:       %{name} = %{version}
+
+%description -n python3-devel
+The Python programming language's interpreter can be extended with
+dynamically loaded extensions and can be embedded in other programs.
+
+This package contains header files, a static library, and development
+tools for building Python modules, extending the Python interpreter or
+embedding Python in applications.
+
+This also includes the Python distutils, which were in the Python
+package up to version 2.2.2.
+
+
+%package -n python3-testsuite
+Summary:        Unit tests for Python and its standard library
+Group:          Development/Languages/Python
+Requires:       python3 = %{version}
+Requires:       python3-tk = %{version}
+
+%description -n python3-testsuite
+Unit tests that are useful for verifying integrity and functionality
+of the installed Python interpreter and standard library.
+They are a documented part of stdlib, as a module 'test'.
+
+%package -n libpython%{so_version}
+Summary:        Python Interpreter shared library
+Group:          Development/Languages/Python
+
+%description -n libpython%{so_version}
+Python is an interpreted, object-oriented programming language, and is
+often compared to Tcl, Perl, Scheme, or Java.  You can find an overview
+of Python in the documentation and tutorials included in the python-doc
+(HTML) or python-doc-pdf (PDF) packages.
+
+This package contains libpython3.2 shared library for embedding in
+other applications.
+
+%prep
+%setup -q -n %{tarname}
+%{__patch} -p1 < %{SOURCE11}
+%{__patch} -p1 < %{SOURCE12}
+%{__patch} -p1 < %{SOURCE13}
+%{__patch} -p1 < %{SOURCE14}
+%{__patch} -p1 < %{SOURCE15}
+
+### COMMON-PREP-BEGIN ###
+
+# drop Autoconf version requirement
+sed -i 's/^AC_PREREQ/dnl AC_PREREQ/' configure.ac
+
+# fix shebangs - convert /usr/local/bin/python and /usr/bin/env/python to /usr/bin/python3
+for dir in Lib Tools; do
+    # find *.py, filter to files that contain bad shebangs
+    # break up "/""usr" like this to prevent replacing with %{_prefix}
+    find $dir -name '*.py' -type f -print0 \
+        | xargs -0 grep -lE '^#! *(/''usr/.*bin/(env +)?)?python' \
+        | xargs sed -r -i -e '1s@^#![[:space:]]*(/''usr/(local/)?bin/(env +)?)?python([0-9]+(\.[0-9]+)?)?@#!%{_bindir}/python3@'
+done
+
+# drop in-tree libffi and expat
+rm -fr Modules/_ctypes/libffi* Modules/_ctypes/darwin
+rm -fr Modules/expat
+
+# drop duplicate README from site-packages
+rm -f Lib/site-packages/README.txt
+
+### COMMON-PREP-END ###
+
+%build
+### COMMON-CONFIG-BEGIN ###
+# use rpm_opt_flags
+export OPT="%{optflags} -DOPENSSL_LOAD_CONF $(pkg-config --cflags-only-I libffi)"
+
+touch -r %{SOURCE0} Makefile.pre.in
+
+autoreconf -fi
+
+%if 0%{?sles_version}
+sed -e 's/-fprofile-correction//' -i Makefile.pre.in
+%endif
+
+%{?asan: export ASAN_OPTIONS=use_sigaltstack=false:`cat /ASAN_OPTIONS` }
+
+%configure \
+    --prefix=%{_prefix} \
+    --libdir=%{_libdir} \
+    --mandir=%{_mandir} \
+    --docdir=%{_docdir}/python \
+    --with-platlibdir=%{_lib} \
+    --enable-ipv6 \
+    --with-fpectl \
+    --enable-shared \
+    --with-ensurepip=no \
+    --with-system-ffi \
+    --with-system-expat \
+    --enable-lto \
+    --enable-loadable-sqlite-extensions \
+    --enable-optimizations
+
+# prevent make from trying to rebuild PYTHON_FOR_GEN stuff
+# make -t Python/Python-ast.c \
+#         Objects/typeslots.inc \
+#         Python/opcode_targets.h \
+#         Include/opcode.h
+
+### COMMON-CONFIG-END ###
+
+%if %{with profileopt}
+    target=profile-opt
+%else
+    target=all
+%endif
+LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH \
+    make %{?_smp_mflags} BASE_LIB=%{_lib} $target
+
+%check
+# exclude test_gdb -- it doesn't run in buildservice anyway, and fails on missing debuginfos
+# when you install gdb into your test env
+EXCLUDE="test_gdb"
+
+%ifarch %{arm}
+# test_multiprocessing_forkserver is racy
+EXCLUDE="$EXCLUDE test_multiprocessing_forkserver"
+%endif
+%ifarch ppc ppc64 ppc64le
+# exclue test_faulthandler due to bnc#831629
+EXCLUDE="$EXCLUDE test_faulthandler"
+%endif
+# some tests break in QEMU
+%if 0%{?qemu_user_space_build} > 0
+EXCLUDE="$EXCLUDE test_multiprocessing_fork test_multiprocessing_forkserver test_multiprocessing_main_handling test_multiprocessing_spawn test_threading test_threadedtempfile test_io test_posix test_ioctl test_mmap test_openpty test_pty test_time test_subprocess test_asyncore test_asyncio test_os test_faulthandler"
+# qemu bug (siginterrupt handling)
+EXCLUDE="$EXCLUDE test_signal"
+%endif
+
+# This test (part of test_uuid) requires real network interfaces
+# so that ifconfig output has "HWaddr <something>".  Some kvm instances
+# done have any such interface breaking the uuid module.
+EXCLUDE="$EXCLUDE test_uuid"
+
+# XML tests
+EXCLUDE="$EXCLUDE test_docxmlrpc test_minidom test_pulldom test_pyexpat \
+    test_xml_etree test_xml_etree_c test_xmlrpc test_xmlrpc_net"
+# tests for components that require XML indirectly
+EXCLUDE="$EXCLUDE test_plistlib test_venv \
+    test_multiprocessing_fork test_multiprocessing_forkserver test_multiprocessing_spawn"
+
+# Limit virtual memory to avoid spurious failures
+if test $(ulimit -v) = unlimited || test $(ulimit -v) -gt 10000000; then
+  ulimit -v 10000000 || :
+fi
+
+%if %{with testsuite}
+make -j1 test TESTOPTS="-u none -x $EXCLUDE"
+# use network, be verbose:
+#make test TESTOPTS="-l -u network -v"
+%endif
+
+%install
+rm -rf $RPM_BUILD_ROOT
+
+make \
+    OPT="%{optflags} -fPIC" \
+    DESTDIR=%{buildroot} \
+    install
+
+# remove .a
+find %{buildroot} -name "*.a" -exec rm {} ";"
+
+# install "site-packages" and __pycache__ for third parties
+install -d -m 755 %{buildroot}%{sitedir}/site-packages
+install -d -m 755 %{buildroot}%{sitedir}/site-packages/__pycache__
+# and their 32bit counterparts explicitly
+mkdir -p %{buildroot}%{_prefix}/lib/python%{python_version}/site-packages/__pycache__
+
+# cleanup parts that don't belong
+for dir in curses dbm ensurepip sqlite3 tkinter xml xmlrpc; do
+    find %{buildroot}%{sitedir}/$dir/* -maxdepth 0 -name "test" -o -exec rm -rf {} ";"
+done
+rm -f $RPM_BUILD_ROOT%{dynlib _curses}
+rm -f $RPM_BUILD_ROOT%{dynlib _curses_panel}
+
+# overwrite the copied binary with a link
+ln -sf python%{python_version} %{buildroot}%{_bindir}/python3
+
+# link shared library instead of static library that tools expect
+#ln -s libpython%{python_abi}.so %{buildroot}%{_libdir}/python%{python_version}/config-%{python_abi}-%{archname}-%{_os}%{?_gnu}%{?armsuffix}/libpython%{python_abi}.so
+ln -s libpython%{python_abi}.so %{buildroot}%{_libdir}/python%{python_version}/config-%{python_abi}-%{archname}-%{_os}%{?_gnu}/libpython%{python_abi}.so
+
+# replace duplicate .pyo/.pyc with hardlinks
+%fdupes %{buildroot}/%{sitedir}
+
+# documentation
+export PDOCS=%{buildroot}%{_docdir}/%{name}
+install -d -m 755 $PDOCS
+#install -c -m 644 %{SOURCE4} $PDOCS/
+install -c -m 644 LICENSE    $PDOCS/
+install -c -m 644 README.rst $PDOCS/
+
+# tools
+for x in `find Tools/ \( -not -name Makefile \) -print | sort` ; do
+  test -d $x && ( install -c -m 755 -d $PDOCS/$x ) \
+             || ( install -c -m 644 $x $PDOCS/$x )
+done
+# clean up the bat files
+find $PDOCS -name "*.bat" -exec rm {} ";"
+
+# install devel files to /config
+#cp Makefile Makefile.pre.in Makefile.pre $RPM_BUILD_ROOT%{sitedir}/config-%{python_abi}/
+
+# move idle config into /etc
+install -d -m 755 %{buildroot}%{_sysconfdir}/idle3
+(
+    cd %{buildroot}/%{sitedir}/idlelib/
+    for file in *.def ; do
+        mv $file %{buildroot}%{_sysconfdir}/idle3/
+        ln -sf %{_sysconfdir}/idle3/$file  %{buildroot}/%{sitedir}/idlelib/
+    done
+)
+
+# startup scripts
+mkdir -p %{buildroot}%{_sysconfdir}/profile.d
+install -m 644 %{SOURCE5} %{buildroot}%{_sysconfdir} # python3start
+install -m 644 %{SOURCE6} %{SOURCE7} %{buildroot}%{_sysconfdir}/profile.d # python3.sh, python3.csh
+
+# RPM macros
+mkdir -p %{buildroot}%{_sysconfdir}/rpm
+LD_LIBRARY_PATH=. ./python %{S:8} > $RPM_BUILD_ROOT/etc/rpm/macros.python3 # macros.python3.py
+
+# import_failed hooks
+FAILDIR=%{buildroot}/%{sitedir}/_import_failed
+mkdir $FAILDIR
+install -m 644 %{SOURCE9} %{SOURCE10} $FAILDIR # import_failed.*
+LD_LIBRARY_PATH=. ./python -c "from py_compile import compile; compile('$FAILDIR/import_failed.py', dfile='%{sitedir}/_import_failed/import_failed.py')"
+LD_LIBRARY_PATH=. ./python -O -c "from py_compile import compile; compile('$FAILDIR/import_failed.py', dfile='%{sitedir}/_import_failed/import_failed.py')"
+(
+    cd $FAILDIR
+    while read package modules; do
+        for module in $modules; do
+            ln import_failed.py $module.py
+            pushd __pycache__
+            for i in import_failed*; do
+                ln $i "$module${i#import_failed}"
+            done
+            popd
+        done
+    done < %{SOURCE10}
+)
+echo %{sitedir}/_import_failed > %{buildroot}/%{sitedir}/site-packages/zzzz-import-failed-hooks.pth
+
+%post -n libpython%{so_version} -p /sbin/ldconfig
+
+%postun -n libpython%{so_version} -p /sbin/ldconfig
+
+%files -n libpython%{so_version}
+%defattr(644, root,root)
+%{_libdir}/libpython%{python_abi}.so.*
+
+%files -n python3-tools
+%defattr(644, root, root, 755)
+%{sitedir}/turtledemo
+%license LICENSE
+%{_bindir}/2to3
+%attr(755, root, root)%{_bindir}/2to3-%{python_version}
+%doc %{_docdir}/%{name}/Tools
+
+%files -n python3-idle
+%defattr(644, root, root, 755)
+%{sitedir}/idlelib
+%dir %{_sysconfdir}/idle3
+%config %{_sysconfdir}/idle3/*
+%doc Lib/idlelib/NEWS.txt
+%doc Lib/idlelib/README.txt
+%doc Lib/idlelib/TODO.txt
+%doc Lib/idlelib/extend.txt
+%doc Lib/idlelib/ChangeLog
+%{_bindir}/idle3
+%attr(755, root, root) %{_bindir}/idle%{python_version}
+
+%files -n python3-devel
+%defattr(644, root, root, 755)
+%license LICENSE
+%{_libdir}/libpython%{python_abi}.so
+%{_libdir}/libpython3.so
+%{_libdir}/pkgconfig/*
+%{_includedir}/python%{python_abi}
+%{sitedir}/config-%{python_abi}-*
+%defattr(755, root, root)
+%{_bindir}/python%{python_abi}-config
+%{_bindir}/python%{python_version}-config
+%{_bindir}/python3-config
+
+%files -n python3-testsuite
+%defattr(644, root, root, 755)
+%license LICENSE
+%{sitedir}/test
+%{dynlib _ctypes_test}
+%{dynlib _testbuffer}
+%{dynlib _testcapi}
+%{dynlib _testinternalcapi}
+%{dynlib _testimportmultiple}
+%{dynlib _testmultiphase}
+%{dynlib xxlimited}
+# workaround for missing packages
+%dir %{sitedir}/sqlite3
+%dir %{sitedir}/tkinter
+
+%files
+%defattr(644, root, root, 755)
+# profile files
+%config %{_sysconfdir}/python3start
+%config %{_sysconfdir}/profile.d/python3.*
+%license LICENSE
+# docs
+%dir %{_docdir}/%{name}
+%doc %{_docdir}/%{name}/README.rst
+%doc %{_docdir}/%{name}/LICENSE
+
+%{_mandir}/man1/python3.1*
+%{_mandir}/man1/python%{python_version}.1*
+# license text, not a doc because the code can use it at run-time
+%{sitedir}/LICENSE.txt
+# RPM macros
+%{_sysconfdir}/rpm/macros.python3
+# binary parts
+%dir %{sitedir}/lib-dynload
+
+%{dynlib array}
+%{dynlib _asyncio}
+%{dynlib audioop}
+%{dynlib binascii}
+%{dynlib _bisect}
+%{dynlib _bz2}
+%{dynlib cmath}
+%{dynlib _codecs_cn}
+%{dynlib _codecs_hk}
+%{dynlib _codecs_iso2022}
+%{dynlib _codecs_jp}
+%{dynlib _codecs_kr}
+%{dynlib _codecs_tw}
+%{dynlib _contextvars}
+%{dynlib _crypt}
+%{dynlib _csv}
+%{dynlib _ctypes}
+%{dynlib _datetime}
+%{dynlib _decimal}
+%{dynlib _elementtree}
+%{dynlib fcntl}
+%{dynlib grp}
+%{dynlib _hashlib}
+%{dynlib _heapq}
+%{dynlib _json}
+%{dynlib _lsprof}
+%{dynlib _lzma}
+%{dynlib math}
+%{dynlib mmap}
+%{dynlib _multibytecodec}
+%{dynlib _multiprocessing}
+%{dynlib ossaudiodev}
+%{dynlib _opcode}
+%{dynlib _pickle}
+%{dynlib _posixsubprocess}
+%{dynlib pyexpat}
+%{dynlib _queue}
+%{dynlib _random}
+%{dynlib resource}
+%{dynlib select}
+%{dynlib _socket}
+%{dynlib _ssl}
+%{dynlib spwd}
+%{dynlib _struct}
+%{dynlib syslog}
+%{dynlib termios}
+%{dynlib unicodedata}
+%{dynlib _xxtestfuzz}
+%{dynlib zlib}
+# hashlib fallback modules
+%{dynlib _blake2}
+%{dynlib _md5}
+%{dynlib _sha1}
+%{dynlib _sha2}
+%{dynlib _sha3}
+
+%{dynlib _gdbm}
+%{dynlib _posixshmem}
+%{dynlib _sqlite3}
+%{dynlib _statistics}
+%{dynlib _xxsubinterpreters}
+%{dynlib _zoneinfo}
+%{dynlib readline}
+
+%{dynlib _testclinic}
+%{dynlib _testsinglephase}
+%{dynlib _xxinterpchannels}
+%{dynlib xxlimited_35}
+%{dynlib xxsubtype}
+
+# python parts
+%dir %{_prefix}/lib/python%{python_version}
+%dir %{_prefix}/lib/python%{python_version}/site-packages
+%dir %{_prefix}/lib/python%{python_version}/site-packages/__pycache__
+%dir %{sitedir}
+%dir %{sitedir}/site-packages
+%dir %{sitedir}/site-packages/__pycache__
+%{sitedir}/*.py
+%{sitedir}/asyncio
+%{sitedir}/ctypes
+%{sitedir}/collections
+%{sitedir}/concurrent
+%{sitedir}/email
+%{sitedir}/encodings
+%{sitedir}/html
+%{sitedir}/http
+%{sitedir}/importlib
+%{sitedir}/json
+%{sitedir}/lib2to3
+%{sitedir}/logging
+%{sitedir}/multiprocessing
+%{sitedir}/pydoc_data
+%{sitedir}/unittest
+%{sitedir}/urllib
+%{sitedir}/venv
+%{sitedir}/wsgiref
+%{sitedir}/zoneinfo
+%{sitedir}/__pycache__
+%{sitedir}/__phello__
+%{sitedir}/re
+%{sitedir}/tomllib
+%{sitedir}/zipfile
+# import-failed hooks
+%{sitedir}/_import_failed
+%{sitedir}/site-packages/zzzz-import-failed-hooks.pth
+# symlinks
+%{_bindir}/python3
+%{_bindir}/pydoc3
+
+# === add additional ===
+%exclude %{sitedir}/curses
+%exclude %{sitedir}/dbm
+%exclude %{sitedir}/ensurepip
+%exclude %{sitedir}/sqlite3
+%exclude %{sitedir}/tkinter
+%exclude %{sitedir}/xml
+%exclude %{sitedir}/xmlrpc
+
+# executables
+%attr(755, root, root) %{_bindir}/pydoc%{python_version}
+%attr(755, root, root) %{_bindir}/python%{python_abi}
+%attr(755, root, root) %{_bindir}/python%{python_version}
+
+%changelog
diff --git a/packaging/python3-rpmlintrc b/packaging/python3-rpmlintrc
new file mode 100644 (file)
index 0000000..3bcb9a2
--- /dev/null
@@ -0,0 +1,18 @@
+# RPM macros are not configuration:
+addFilter("non-conffile-in-etc /etc/rpm/macros.python3")
+# Obviously, these files are meant to be empty:
+addFilter("zero-length /usr/lib64/python3.3/test/nullcert.pem")
+addFilter("zero-length /usr/lib64/python3.3/test/namespace_pkgs/module_and_namespace_package/a_test/empty")
+
+addFilter("W: zero-length");
+addFilter("W: strange-permission");
+addFilter("W: python-bytecode-inconsistent-mtime");
+addFilter("W: package-with-huge-docs");
+addFilter("W: obsolete-not-provided");
+addFilter("W: macro-in-comment");
+addFilter("W: non-executable-script");
+addFilter("W: incoherent-version-dependency-on");
+addFilter("W: file-contains-date-and-time");
+
+addFilter("E: license-file-in-docs");
+addFilter("E: non-standard-group");
diff --git a/packaging/python3.csh b/packaging/python3.csh
new file mode 100644 (file)
index 0000000..b94d822
--- /dev/null
@@ -0,0 +1,2 @@
+# add python startup script for interactive sessions
+setenv PYTHONSTARTUP /etc/pythonstart
diff --git a/packaging/python3.sh b/packaging/python3.sh
new file mode 100644 (file)
index 0000000..887a886
--- /dev/null
@@ -0,0 +1,2 @@
+# add python startup script for interactive sessions
+export PYTHONSTARTUP=/etc/pythonstart
diff --git a/packaging/python3.spec b/packaging/python3.spec
new file mode 100644 (file)
index 0000000..532fe23
--- /dev/null
@@ -0,0 +1,307 @@
+#
+# spec file for package python3
+#
+# Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany.
+#
+# All modifications and additions to the file contributed by third parties
+# remain the property of their copyright owners, unless otherwise agreed
+# upon. The license for this file, and modifications and additions to the
+# file, is the same license as for the pristine package itself (unless the
+# license for the pristine package is not an Open Source License, in which
+# case the license is the MIT License). An "Open Source License" is a
+# license that conforms to the Open Source Definition (Version 1.9)
+# published by the Open Source Initiative.
+
+# Please submit bugfixes or comments via http://bugs.opensuse.org/
+#
+
+
+# do not add defs here, please edit python3-base.spec instead
+# and run pre_checkin.sh
+#
+# see PACKAGING-NOTES for details
+#
+### COMMON-DEF-BEGIN ###
+%define         tarversion %{version}
+%define         tarname    Python-%{tarversion}
+# the versions are autogenerated from pre_checkin.sh
+# based on the current source tarball
+%define         python_version          3.12
+%define         python_version_abitag   312
+%define         python_version_soname   3_12
+
+%define         sitedir         %{_libdir}/python%{python_version}
+
+# three possible ABI kinds: m - pymalloc, d - debug build; see PEP 3149
+%define         abi_kind   %{nil}
+# python ABI version - used in some file names
+%define         python_abi %{python_version}%{abi_kind}
+# soname ABI tag defined in PEP 3149
+%define         abi_tag    %{python_version_abitag}%{abi_kind}
+# version part of "libpython" package
+%define         so_version %{python_version_soname}%{abi_kind}1_0
+
+# rpm and python have different ideas about what is an arch-dependent name, so:
+%if %{__isa_name} == ppc
+%define archname %(echo %{_arch} | sed s/ppc/powerpc/)
+%else
+%define archname %{_arch}
+%endif
+
+%define dynlib() %{sitedir}/lib-dynload/%{1}.cpython-%{abi_tag}-%{archname}-%{_os}%{?_gnu}.so
+%define __spec_check_pre exit 0
+### COMMON-DEF-END ###
+#
+Name:           python3
+Version:        3.12.0
+Release:        1
+Summary:        Python 3 Interpreter
+License:        Python-2.0
+Group:          Development/Languages/Python
+Url:            http://www.python.org/
+Source0:        %{tarname}.tgz
+Source11:       add_pie_compile_option.patch
+Source12:       add_path_environment.patch
+Source13:       Skip_unittest.patch
+Source14:       Avoid-ProcessPoolExecutor.patch
+Source15:       Added-no_sanitize_hwaddress.patch
+
+BuildRequires:  automake
+BuildRequires:  autoconf-archive
+BuildRequires:  fdupes
+BuildRequires:  gcc-c++
+BuildRequires:  gdbm-devel
+BuildRequires:  gettext-tools
+BuildRequires:  gmp-devel
+BuildRequires:  intltool
+BuildRequires:  bzip2-devel
+BuildRequires:  libexpat-devel
+BuildRequires:  libffi-devel
+#BuildRequires:  libnsl-devel
+BuildRequires:  lzma-devel
+BuildRequires:  ncurses-devel
+#BuildRequires:  netcfg
+BuildRequires:  pkgconfig(openssl3)
+BuildRequires:  pkgconfig
+BuildRequires:  readline-devel
+BuildRequires:  sqlite-devel
+#BuildRequires:  tk-devel
+BuildRequires:  xz
+#BuildRequires:  pkgconfig(x11)
+Requires:       python3-base = %{version}
+Recommends:     python3-curses
+Recommends:     python3-dbm
+Recommends:     python3-idle
+Recommends:     python3-pip
+#Recommends:     python3-tk
+# some compatibility Provides
+Provides:       python3 = %{python_version}
+
+Provides:       python3-xml = %{version}
+Obsoletes:      python3-xml < %{version}
+#
+# do not add patches here, please edit python3-base.spec instead
+# and run pre_checkin.sh
+#
+# see PACKAGING-NOTES for details
+#
+
+
+%description
+Python 3 is modern interpreted, object-oriented programming language,
+often compared to Tcl, Perl, Scheme, or Java.  You can find an overview
+of Python in the documentation and tutorials included in the python-doc
+package.
+
+This package supplies rich command line features provided by readline,
+XML processing tools, "ensurepip" installer, and sqlite3 support for
+the interpreter core, thus forming a so called "extended" runtime.
+Installing "python3" is sufficient for the vast majority of usecases.
+In addition, recommended packages provide UI toolkit support (python3-curses,
+python3-tk), legacy UNIX database bindings (python3-dbm), and the IDLE
+development environment (python3-idle).
+
+%package tk
+Summary:        TkInter - Python Tk Interface
+Group:          Development/Libraries/Python
+Requires:       %{name} = %{version}
+
+%description tk
+Python interface to Tk. Tk is the GUI toolkit that comes with Tcl. The
+"xrpm" package uses this Python interface.
+
+%package curses
+Summary:        Python Interface to the (N)Curses Library
+Group:          Development/Libraries/Python
+Requires:       %{name} = %{version}
+
+%description curses
+An easy to use interface to the (n)curses CUI library. CUI stands for
+Console User Interface.
+
+%prep
+%setup -q -n %{tarname}
+%{__patch} -p1 < %{SOURCE11}
+%{__patch} -p1 < %{SOURCE12}
+%{__patch} -p1 < %{SOURCE13}
+%{__patch} -p1 < %{SOURCE14}
+%{__patch} -p1 < %{SOURCE15}
+
+### COMMON-PREP-BEGIN ###
+
+# drop Autoconf version requirement
+sed -i 's/^AC_PREREQ/dnl AC_PREREQ/' configure.ac
+
+# fix shebangs - convert /usr/local/bin/python and /usr/bin/env/python to /usr/bin/python3
+for dir in Lib Tools; do
+    # find *.py, filter to files that contain bad shebangs
+    # break up "/""usr" like this to prevent replacing with %{_prefix}
+    find $dir -name '*.py' -type f -print0 \
+        | xargs -0 grep -lE '^#! *(/''usr/.*bin/(env +)?)?python' \
+        | xargs sed -r -i -e '1s@^#![[:space:]]*(/''usr/(local/)?bin/(env +)?)?python([0-9]+(\.[0-9]+)?)?@#!%{_bindir}/python3@'
+done
+
+# drop in-tree libffi and expat
+rm -fr Modules/_ctypes/libffi* Modules/_ctypes/darwin
+rm -fr Modules/expat
+
+# drop duplicate README from site-packages
+rm -f Lib/site-packages/README.txt
+
+### COMMON-PREP-END ###
+
+%build
+### COMMON-CONFIG-BEGIN ###
+# use rpm_opt_flags
+export OPT="%{optflags} -DOPENSSL_LOAD_CONF $(pkg-config --cflags-only-I libffi)"
+export CFLAGS+=" -DNCURSES_INTERNALS"
+
+touch -r %{SOURCE0} Makefile.pre.in
+
+autoreconf -fi
+
+%if 0%{?sles_version}
+sed -e 's/-fprofile-correction//' -i Makefile.pre.in
+%endif
+
+%{?asan: export ASAN_OPTIONS=use_sigaltstack=false:`cat /ASAN_OPTIONS` }
+
+%configure \
+    --prefix=%{_prefix} \
+    --libdir=%{_libdir} \
+    --mandir=%{_mandir} \
+    --docdir=%{_docdir}/python \
+    --with-platlibdir=%{_lib} \
+    --enable-ipv6 \
+    --with-fpectl \
+    --enable-shared \
+    --with-ensurepip=no \
+    --with-system-ffi \
+    --with-system-expat \
+    --enable-lto \
+    --enable-loadable-sqlite-extensions
+
+# prevent make from trying to rebuild PYTHON_FOR_GEN stuff
+# make -t Python/Python-ast.c \
+#         Objects/typeslots.inc \
+#         Python/opcode_targets.h \
+#         Include/opcode.h
+
+### COMMON-CONFIG-END ###
+
+make %{?_smp_mflags} BASE_LIB=%{_lib}
+
+%check
+## Limit virtual memory to avoid spurious failures
+#if test $(ulimit -v) = unlimited || test $(ulimit -v) -gt 10000000; then
+#  ulimit -v 10000000 || :
+#fi
+
+## only test the parts skipped in python3-base
+#TESTS="test_curses test_dbm_gnu test_dbm_ndbm test_idle \
+#       test_readline test_sqlite test_tcl test_tix  test_tk \
+#       test_ttk_textonly"
+## redo tests with SSL parts
+#%if !0%{?qemu_user_space_build}
+#TESTS="$TESTS test_asyncio"
+#%endif
+
+## XML tests
+#TESTS="$TESTS test_docxmlrpc test_minidom test_pulldom test_pyexpat \
+#    test_xml_etree test_xml_etree_c test_xmlrpc test_xmlrpc_net"
+## XML-dependent tests
+#TESTS="$TESTS test_plistlib test_venv \
+#    test_multiprocessing_fork test_multiprocessing_forkserver test_multiprocessing_spawn"
+
+#make -j1 test TESTOPTS="-u curses $TESTS"
+
+%install
+rm -rf $RPM_BUILD_ROOT
+make \
+    OPT="%{optflags} -fPIC" \
+    DESTDIR=%{buildroot} \
+    install
+
+# clean out stuff that is in python-base and subpackages
+
+rm %{buildroot}%{_bindir}/*
+rm %{buildroot}%{_libdir}/lib*
+rm -r %{buildroot}%{_libdir}/pkgconfig
+rm -r %{buildroot}%{_mandir}/*
+rm -r %{buildroot}%{_includedir}/*
+
+rm -r %{buildroot}%{sitedir}/config*
+find %{buildroot}%{sitedir} -name "*.egg-info" -exec rm {} ";"
+rm -r %{buildroot}%{sitedir}/__pycache__
+rm -r %{buildroot}%{sitedir}/site-packages
+rm %{buildroot}%{sitedir}/*.*
+
+for module in \
+    asyncio ctypes collections concurrent distutils email encodings \
+    html http \
+    importlib json logging multiprocessing pydoc_data unittest \
+    urllib venv wsgiref lib2to3 test idlelib turtledemo zoneinfo \
+    __phello__ re tomllib zipfile
+do
+    rm -fr %{buildroot}%{sitedir}/$module
+done
+
+for library in \
+    array _asyncio audioop binascii _bisect _bz2 cmath _codecs_* _crypt _csv \
+    _contextvars _ctypes _datetime _decimal fcntl grp _hashlib _heapq _json _lsprof \
+    _lzma math mmap _multibytecodec _multiprocessing _opcode ossaudiodev \
+    parser _pickle _posixsubprocess _queue _random resource select _ssl _socket spwd \
+    _struct syslog termios _testbuffer _testimportmultiple _testmultiphase \
+    unicodedata zlib _ctypes_test _testcapi xxlimited \
+    _xxtestfuzz _md5 _sha1 _sha2 _sha3 _sha256 _sha512 _blake2 \
+    _elementtree _posixshmem _sqlite3 _statistics _testinternalcapi \
+    _xxsubinterpreters _zoneinfo pyexpat readline \
+    _testclinic _testsinglephase _xxinterpchannels xxlimited_35 xxsubtype 
+do
+    eval rm -f "%{buildroot}%{sitedir}/lib-dynload/$library.*"
+done
+
+rm -rf $RPM_BUILD_ROOT%{sitedir}/tkinter
+rm -rf $RPM_BUILD_ROOT%{sitedir}/dbm
+rm -f $RPM_BUILD_ROOT%{sitedir}/lib-dynload/_gdbm.*
+
+%fdupes %{buildroot}/%{_libdir}/python%{python_version}
+
+%files curses
+%defattr(644, root, root, 755)
+%license LICENSE
+%{sitedir}/curses
+%{dynlib _curses}
+
+%files
+%defattr(644, root, root, 755)
+%dir %{sitedir}
+%dir %{sitedir}/lib-dynload
+%license LICENSE
+%{sitedir}/ensurepip
+%{sitedir}/sqlite3
+%{sitedir}/xml
+%{sitedir}/xmlrpc
+
+%changelog
+
diff --git a/packaging/python3start b/packaging/python3start
new file mode 100644 (file)
index 0000000..5ba053d
--- /dev/null
@@ -0,0 +1,30 @@
+# startup script for python to enable saving of interpreter history and
+# enabling name completion
+
+# import needed modules
+import atexit
+import os
+import readline
+import rlcompleter
+
+# where is history saved
+historyPath = os.path.expanduser("~/.py3history")
+
+# handler for saving history
+def save_history(historyPath=historyPath):
+    import readline
+    readline.write_history_file(historyPath)
+
+# read history, if it exists
+if os.path.exists(historyPath):
+    readline.set_history_length(10000)
+    readline.read_history_file(historyPath)
+
+# register saving handler
+atexit.register(save_history)
+
+# enable completion
+readline.parse_and_bind('tab: complete')
+
+# cleanup
+del os, atexit, readline, rlcompleter, save_history, historyPath
diff --git a/packaging/skipped_tests.py b/packaging/skipped_tests.py
new file mode 100644 (file)
index 0000000..5b5a678
--- /dev/null
@@ -0,0 +1,72 @@
+#!/usr/bin/python3
+"""
+Simple regexp-based skipped test checker.
+It lists tests that are mentioned (presumably for exclusion)
+in BASE, and in MAIN (presumably for inclusion)
+and reports discrepancies.
+
+This will have a number of
+"""
+
+BASE = "python3-base.spec"
+MAIN = "python3.spec"
+
+import glob
+import re
+from os.path import basename
+
+alltests = set()
+qemu_exclusions = set()
+
+for item in glob.glob("Python-*/Lib/test/test_*"):
+    testname = basename(item)
+    if testname.endswith(".py"):
+        testname = testname[:-3]
+    alltests.add(testname)
+
+testre = re.compile(r'[\s"](test_\w+)\b')
+
+def find_tests_in_spec(specname):
+    global qemu_exclusions
+
+    found_tests = set()
+    with open(specname) as spec:
+        in_qemu = False
+        for line in spec:
+            line = line.strip()
+            if "#" in line:
+                line = line[:line.index("#")]
+            tests = set(testre.findall(line))
+            found_tests |= tests
+            if line == "%if 0%{?qemu_user_space_build} > 0":
+                in_qemu = True
+            if in_qemu:
+                if line == "%endif":
+                    in_qemu = False
+                qemu_exclusions |= tests
+    return found_tests
+
+excluded = find_tests_in_spec(BASE)
+included = find_tests_in_spec(MAIN)
+
+#print("--- excluded tests:", " ".join(sorted(excluded)))
+#print("--- included tests:", " ".join(sorted(included)))
+
+mentioned = excluded | included
+nonexistent = mentioned - alltests
+missing = excluded - included - qemu_exclusions
+
+print("--- the following tests are excluded for QEMU and not tested in python")
+print("--- (that probably means we don't need to worry about them)")
+for test in sorted(qemu_exclusions - included):
+    print(test)
+
+print("--- the following tests might be excluded from python-base but not tested in python:")
+for test in sorted(missing):
+    print(test)
+
+if nonexistent:
+    print("--- the following tests don't exist:")
+    for test in sorted(nonexistent):
+        print(test)
+