diff --git a/check-pyc-timestamps.py b/check-pyc-timestamps.py index 8378c3e..1b174a1 100644 --- a/check-pyc-timestamps.py +++ b/check-pyc-timestamps.py @@ -16,6 +16,7 @@ LEVELS = (None, 1, 2) # list of globs of test and other files that we expect not to have bytecode not_compiled = [ '/usr/bin/*', + '/usr/lib/rpm/redhat/*', '*/test/badsyntax_*.py', '*/tokenizedata/bad_coding.py', '*/tokenizedata/bad_coding2.py', diff --git a/import_all_modules_py3_12.py b/import_all_modules_py3_12.py new file mode 100644 index 0000000..3930236 --- /dev/null +++ b/import_all_modules_py3_12.py @@ -0,0 +1,171 @@ +'''Script to perform import of each module given to %%py_check_import +''' +import argparse +import importlib +import fnmatch +import os +import re +import site +import sys + +from contextlib import contextmanager +from pathlib import Path + + +def read_modules_files(file_paths): + '''Read module names from the files (modules must be newline separated). + + Return the module names list or, if no files were provided, an empty list. + ''' + + if not file_paths: + return [] + + modules = [] + for file in file_paths: + file_contents = file.read_text() + modules.extend(file_contents.split()) + return modules + + +def read_modules_from_cli(argv): + '''Read module names from command-line arguments (space or comma separated). + + Return the module names list. + ''' + + if not argv: + return [] + + # %%py3_check_import allows to separate module list with comma or whitespace, + # we need to unify the output to a list of particular elements + modules_as_str = ' '.join(argv) + modules = re.split(r'[\s,]+', modules_as_str) + # Because of shell expansion in some less typical cases it may happen + # that a trailing space will occur at the end of the list. + # Remove the empty items from the list before passing it further + modules = [m for m in modules if m] + return modules + + +def filter_top_level_modules_only(modules): + '''Filter out entries with nested modules (containing dot) ie. 'foo.bar'. + + Return the list of top-level modules. + ''' + + return [module for module in modules if '.' not in module] + + +def any_match(text, globs): + '''Return True if any of given globs fnmatchcase's the given text.''' + + return any(fnmatch.fnmatchcase(text, g) for g in globs) + + +def exclude_unwanted_module_globs(globs, modules): + '''Filter out entries which match the either of the globs given as argv. + + Return the list of filtered modules. + ''' + + return [m for m in modules if not any_match(m, globs)] + + +def read_modules_from_all_args(args): + '''Return a joined list of modules from all given command-line arguments. + ''' + + modules = read_modules_files(args.filename) + modules.extend(read_modules_from_cli(args.modules)) + if args.exclude: + modules = exclude_unwanted_module_globs(args.exclude, modules) + + if args.top_level: + modules = filter_top_level_modules_only(modules) + + # Error when someone accidentally managed to filter out everything + if len(modules) == 0: + raise ValueError('No modules to check were left') + + return modules + + +def import_modules(modules): + '''Procedure to perform import check for each module name from the given list of modules. + ''' + + for module in modules: + print('Check import:', module, file=sys.stderr) + importlib.import_module(module) + + +def argparser(): + parser = argparse.ArgumentParser( + description='Generate list of all importable modules for import check.' + ) + parser.add_argument( + 'modules', nargs='*', + help=('Add modules to check the import (space or comma separated).'), + ) + parser.add_argument( + '-f', '--filename', action='append', type=Path, + help='Add importable module names list from file.', + ) + parser.add_argument( + '-t', '--top-level', action='store_true', + help='Check only top-level modules.', + ) + parser.add_argument( + '-e', '--exclude', action='append', + help='Provide modules globs to be excluded from the check.', + ) + return parser + + +@contextmanager +def remove_unwanteds_from_sys_path(): + '''Remove cwd and this script's parent from sys.path for the import test. + Bring the original contents back after import is done (or failed) + ''' + + cwd_absolute = Path.cwd().absolute() + this_file_parent = Path(__file__).parent.absolute() + old_sys_path = list(sys.path) + for path in old_sys_path: + if Path(path).absolute() in (cwd_absolute, this_file_parent): + sys.path.remove(path) + try: + yield + finally: + sys.path = old_sys_path + + +def addsitedirs_from_environ(): + '''Load directories from the _PYTHONSITE environment variable (separated by :) + and load the ones already present in sys.path via site.addsitedir() + to handle .pth files in them. + + This is needed to properly import old-style namespace packages with nspkg.pth files. + See https://bugzilla.redhat.com/2018551 for a more detailed rationale.''' + for path in os.getenv('_PYTHONSITE', '').split(':'): + if path in sys.path: + site.addsitedir(path) + + +def main(argv=None): + + cli_args = argparser().parse_args(argv) + + if not cli_args.modules and not cli_args.filename: + raise ValueError('No modules to check were provided') + + modules = read_modules_from_all_args(cli_args) + + with remove_unwanteds_from_sys_path(): + addsitedirs_from_environ() + import_modules(modules) + + +if __name__ == '__main__': + main() diff --git a/macros.python3.12 b/macros.python3.12 new file mode 100644 index 0000000..56cb141 --- /dev/null +++ b/macros.python3.12 @@ -0,0 +1,91 @@ +%__python3 /usr/bin/python3.12 +%python3_pkgversion 3.12 + +# The following are macros from macros.python3 in Fedora that are newer/different than those in the python3-rpm-macros package in RHEL 8. +# These macros overwrite/supercede some of the macros in the python3-rpm-macros package in RHEL. + +# nb: $RPM_BUILD_ROOT is not set when the macros are expanded (at spec parse time) +# so we set it manually (to empty string), making our Python prefer the correct install scheme location +# platbase/base is explicitly set to %%{_prefix} to support custom values, such as /app for flatpaks +%python3_sitelib %(RPM_BUILD_ROOT= %{__python3} -Ic "import sysconfig; print(sysconfig.get_path('purelib', vars={'platbase': '%{_prefix}', 'base': '%{_prefix}'}))") +%python3_sitearch %(RPM_BUILD_ROOT= %{__python3} -Ic "import sysconfig; print(sysconfig.get_path('platlib', vars={'platbase': '%{_prefix}', 'base': '%{_prefix}'}))") +%python3_version %(RPM_BUILD_ROOT= %{__python3} -Ic "import sys; sys.stdout.write('{0.major}.{0.minor}'.format(sys.version_info))") +%python3_version_nodots %(RPM_BUILD_ROOT= %{__python3} -Ic "import sys; sys.stdout.write('{0.major}{0.minor}'.format(sys.version_info))") +%python3_platform %(RPM_BUILD_ROOT= %{__python3} -Ic "import sysconfig; print(sysconfig.get_platform())") +%python3_platform_triplet %(RPM_BUILD_ROOT= %{__python3} -Ic "import sysconfig; print(sysconfig.get_config_var('MULTIARCH'))") +%python3_ext_suffix %(RPM_BUILD_ROOT= %{__python3} -Ic "import sysconfig; print(sysconfig.get_config_var('EXT_SUFFIX'))") +%python3_cache_tag %(RPM_BUILD_ROOT= %{__python3} -Ic "import sys; print(sys.implementation.cache_tag)") + +%_py3_shebang_s s +%_py3_shebang_P %(RPM_BUILD_ROOT= %{__python3} -Ic "import sys; print('P' if hasattr(sys.flags, 'safe_path') else '')") +%py3_shbang_opts -%{?_py3_shebang_s}%{?_py3_shebang_P} + +%py3_shebang_fix %{expand:\\\ + if [ -z "%{?py3_shebang_flags}" ]; then + shebang_flags="-k" + else + shebang_flags="-ka%{py3_shebang_flags}" + fi + %{__python3} -B %{_rpmconfigdir}/redhat/pathfix_py3_12.py -pni %{__python3} $shebang_flags} + +%py3_install() %{expand:\\\ + CFLAGS="${CFLAGS:-${RPM_OPT_FLAGS}}" LDFLAGS="${LDFLAGS:-${RPM_LD_FLAGS}}"\\\ + %{__python3} %{py_setup} %{?py_setup_args} install -O1 --skip-build --root %{buildroot} --prefix %{_prefix} %{?*} + rm -rfv %{buildroot}%{_bindir}/__pycache__ +} + +%py3_install_egg() %{expand:\\\ + mkdir -p %{buildroot}%{python3_sitelib} + %{__python3} -m easy_install -m --prefix %{buildroot}%{_prefix} -Z dist/*-py%{python3_version}.egg %{?*} + rm -rfv %{buildroot}%{_bindir}/__pycache__ +} + +%py3_install_wheel() %{expand:\\\ + %{__python3} -m pip install -I dist/%{1} --root %{buildroot} --prefix %{_prefix} --no-deps --no-index --no-warn-script-location + rm -rfv %{buildroot}%{_bindir}/__pycache__ + for distinfo in %{buildroot}%{python3_sitelib}/*.dist-info %{buildroot}%{python3_sitearch}/*.dist-info; do + if [ -f ${distinfo}/direct_url.json ]; then + rm -fv ${distinfo}/direct_url.json + sed -i '/direct_url.json/d' ${distinfo}/RECORD + fi + done +} + +# With $PATH and $PYTHONPATH set to the %%buildroot, +# try to import the Python 3 module(s) given as command-line args or read from file (-f). +# Respect the custom values of %%py3_shebang_flags or set nothing if it's undefined. +# Filter and check import on only top-level modules using -t flag. +# Exclude unwanted modules by passing their globs to -e option. +# Useful as a smoke test in %%check when running tests is not feasible. +# Use spaces or commas as separators if providing list directly. +# Use newlines as separators if providing list in a file. +%py3_check_import(e:tf:) %{expand:\\\ + PATH="%{buildroot}%{_bindir}:$PATH"\\\ + PYTHONPATH="${PYTHONPATH:-%{buildroot}%{python3_sitearch}:%{buildroot}%{python3_sitelib}}"\\\ + _PYTHONSITE="%{buildroot}%{python3_sitearch}:%{buildroot}%{python3_sitelib}"\\\ + PYTHONDONTWRITEBYTECODE=1\\\ + %{lua: + local command = "%{__python3} " + if rpm.expand("%{?py3_shebang_flags}") ~= "" then + command = command .. "-%{py3_shebang_flags}" + end + command = command .. " %{_rpmconfigdir}/redhat/import_all_modules_py3_12.py " + -- handle multiline arguments correctly, see https://bugzilla.redhat.com/2018809 + local args=rpm.expand('%{?**}'):gsub("[%s\\\\]*%s+", " ") + print(command .. args) + } +} + +# Environment variables used by %%pytest, %%tox or standalone, e.g.: +# %%{py3_test_envvars} %%{python3} -m unittest +%py3_test_envvars %{expand:\\\ + CFLAGS="${CFLAGS:-${RPM_OPT_FLAGS}}" LDFLAGS="${LDFLAGS:-${RPM_LD_FLAGS}}"\\\ + PATH="%{buildroot}%{_bindir}:$PATH"\\\ + PYTHONPATH="${PYTHONPATH:-%{buildroot}%{python3_sitearch}:%{buildroot}%{python3_sitelib}}"\\\ + PYTHONDONTWRITEBYTECODE=1\\\ + %{?__pytest_addopts:PYTEST_ADDOPTS="${PYTEST_ADDOPTS:-} %{__pytest_addopts}"}\\\ + PYTEST_XDIST_AUTO_NUM_WORKERS=%{_smp_build_ncpus}} + +# This is intended for Python 3 only, hence also no Python version in the name. +%__pytest /usr/bin/pytest-%{python3_version} +%pytest %py3_test_envvars %__pytest diff --git a/pathfix_py3_12.py b/pathfix_py3_12.py new file mode 100644 index 0000000..1d7db3a --- /dev/null +++ b/pathfix_py3_12.py @@ -0,0 +1,199 @@ +#!/usr/bin/env python3 + +import sys +import os +from stat import * +import getopt + +err = sys.stderr.write +dbg = err +rep = sys.stdout.write + +new_interpreter = None +preserve_timestamps = False +create_backup = True +keep_flags = False +add_flags = b'' + + +def main(): + global new_interpreter + global preserve_timestamps + global create_backup + global keep_flags + global add_flags + + usage = ('usage: %s -i /interpreter -p -n -k -a file-or-directory ...\n' % + sys.argv[0]) + try: + opts, args = getopt.getopt(sys.argv[1:], 'i:a:kpn') + except getopt.error as msg: + err(str(msg) + '\n') + err(usage) + sys.exit(2) + for o, a in opts: + if o == '-i': + new_interpreter = a.encode() + if o == '-p': + preserve_timestamps = True + if o == '-n': + create_backup = False + if o == '-k': + keep_flags = True + if o == '-a': + add_flags = a.encode() + if b' ' in add_flags: + err("-a option doesn't support whitespaces") + sys.exit(2) + if not new_interpreter or not new_interpreter.startswith(b'/') or \ + not args: + err('-i option or file-or-directory missing\n') + err(usage) + sys.exit(2) + bad = 0 + for arg in args: + if os.path.isdir(arg): + if recursedown(arg): bad = 1 + elif os.path.islink(arg): + err(arg + ': will not process symbolic links\n') + bad = 1 + else: + if fix(arg): bad = 1 + sys.exit(bad) + + +def ispython(name): + return name.endswith('.py') + + +def recursedown(dirname): + dbg('recursedown(%r)\n' % (dirname,)) + bad = 0 + try: + names = os.listdir(dirname) + except OSError as msg: + err('%s: cannot list directory: %r\n' % (dirname, msg)) + return 1 + names.sort() + subdirs = [] + for name in names: + if name in (os.curdir, os.pardir): continue + fullname = os.path.join(dirname, name) + if os.path.islink(fullname): pass + elif os.path.isdir(fullname): + subdirs.append(fullname) + elif ispython(name): + if fix(fullname): bad = 1 + for fullname in subdirs: + if recursedown(fullname): bad = 1 + return bad + + +def fix(filename): +## dbg('fix(%r)\n' % (filename,)) + try: + f = open(filename, 'rb') + except IOError as msg: + err('%s: cannot open: %r\n' % (filename, msg)) + return 1 + with f: + line = f.readline() + fixed = fixline(line) + if line == fixed: + rep(filename+': no change\n') + return + head, tail = os.path.split(filename) + tempname = os.path.join(head, '@' + tail) + try: + g = open(tempname, 'wb') + except IOError as msg: + err('%s: cannot create: %r\n' % (tempname, msg)) + return 1 + with g: + rep(filename + ': updating\n') + g.write(fixed) + BUFSIZE = 8*1024 + while 1: + buf = f.read(BUFSIZE) + if not buf: break + g.write(buf) + + # Finishing touch -- move files + + mtime = None + atime = None + # First copy the file's mode to the temp file + try: + statbuf = os.stat(filename) + mtime = statbuf.st_mtime + atime = statbuf.st_atime + os.chmod(tempname, statbuf[ST_MODE] & 0o7777) + except OSError as msg: + err('%s: warning: chmod failed (%r)\n' % (tempname, msg)) + # Then make a backup of the original file as filename~ + if create_backup: + try: + os.rename(filename, filename + '~') + except OSError as msg: + err('%s: warning: backup failed (%r)\n' % (filename, msg)) + else: + try: + os.remove(filename) + except OSError as msg: + err('%s: warning: removing failed (%r)\n' % (filename, msg)) + # Now move the temp file to the original file + try: + os.rename(tempname, filename) + except OSError as msg: + err('%s: rename failed (%r)\n' % (filename, msg)) + return 1 + if preserve_timestamps: + if atime and mtime: + try: + os.utime(filename, (atime, mtime)) + except OSError as msg: + err('%s: reset of timestamp failed (%r)\n' % (filename, msg)) + return 1 + # Return success + return 0 + + +def parse_shebang(shebangline): + shebangline = shebangline.rstrip(b'\n') + start = shebangline.find(b' -') + if start == -1: + return b'' + return shebangline[start:] + + +def populate_flags(shebangline): + old_flags = b'' + if keep_flags: + old_flags = parse_shebang(shebangline) + if old_flags: + old_flags = old_flags[2:] + if not (old_flags or add_flags): + return b'' + # On Linux, the entire string following the interpreter name + # is passed as a single argument to the interpreter. + # e.g. "#! /usr/bin/python3 -W Error -s" runs "/usr/bin/python3 "-W Error -s" + # so shebang should have single '-' where flags are given and + # flag might need argument for that reasons adding new flags is + # between '-' and original flags + # e.g. #! /usr/bin/python3 -sW Error + return b' -' + add_flags + old_flags + + +def fixline(line): + if not line.startswith(b'#!'): + return line + + if b"python" not in line: + return line + + flags = populate_flags(line) + return b'#! ' + new_interpreter + flags + b'\n' + + +if __name__ == '__main__': + main() diff --git a/python3.12.spec b/python3.12.spec index 2c51485..8bcdd8d 100644 --- a/python3.12.spec +++ b/python3.12.spec @@ -1,3 +1,6 @@ +%global __python3 /usr/bin/python3.12 +%global python3_pkgversion 3.12 + # ================== # Top-level metadata # ================== @@ -17,8 +20,8 @@ URL: https://www.python.org/ #global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 2%{?dist} -License: Python-2.0.1 +Release: 1%{?dist} +License: Python # ================================== @@ -31,12 +34,8 @@ License: Python-2.0.1 # Main Python, i.e. whether this is the main Python version in the distribution # that owns /usr/bin/python3 and other unique paths # This also means the built subpackages are called python3 rather than python3X -# By default, this is determined by the %%__default_python3_pkgversion value -%if "%{?__default_python3_pkgversion}" == "%{pybasever}" -%bcond_without main_python -%else +# RHEL: Disabled by default %bcond_with main_python -%endif # If this is *not* Main Python, should it contain `Provides: python(abi) ...`? # In Fedora no package shall depend on an alternative Python via this tag, so we do not provide it. @@ -58,16 +57,11 @@ License: Python-2.0.1 # IMPORTANT: When bootstrapping, it's very likely python-pip-wheel is # not available. Turn off the rpmwheels bcond until # python-pip is built with a wheel to get around the issue. -%bcond_with bootstrap +%bcond_without bootstrap # Whether to use RPM build wheels from the python-{pip,setuptools,wheel}-wheel packages # Uses upstream bundled prebuilt wheels otherwise -# Only F39+ has a pip new enough to work with Python 3.12 -%if 0%{?fedora} >= 39 || 0%{?rhel} >= 10 -%bcond_without rpmwheels -%else %bcond_with rpmwheels -%endif # If the rpmwheels condition is disabled, we use the bundled wheel packages # from Python with the versions below. # This needs to be manually updated when we update Python. @@ -210,13 +204,6 @@ Provides: bundled(python3dist(packaging)) = 23 # on files that test invalid syntax. %undefine py_auto_byte_compile -# When a main_python build is attempted despite the %%__default_python3_pkgversion value -# We undefine magic macros so the python3-... package does not provide wrong python3X-... -%if %{with main_python} && ("%{?__default_python3_pkgversion}" != "%{pybasever}") -%undefine __pythonname_provides -%{warn:Doing a main_python build with wrong %%__default_python3_pkgversion (0%{?__default_python3_pkgversion}, but this is %pyshortver)} -%endif - %if %{with main_python} # To keep the upgrade path clean, we Obsolete python3.X from the python3 # package and python3.X-foo from individual subpackages. @@ -272,7 +259,7 @@ BuildRequires: openssl-devel BuildRequires: pkgconfig BuildRequires: python-rpm-macros BuildRequires: readline-devel -BuildRequires: redhat-rpm-config >= 127 +BuildRequires: redhat-rpm-config BuildRequires: sqlite-devel BuildRequires: gdb @@ -326,6 +313,11 @@ Source1: %{url}ftp/python/%{general_version}/Python-%{upstream_version}.tar.xz.a # The release manager for Python 3.12 is Thomas Wouters Source2: https://github.com/Yhg1s.gpg +# Sources for the python3.12-rpm-macros +Source3: macros.python3.12 +Source4: import_all_modules_py3_12.py +Source5: pathfix_py3_12.py + # A simple script to check timestamps of bytecode files # Run in check section with Python that is currently being built # Originally written by bkabrda @@ -499,12 +491,12 @@ Summary: Python runtime libraries %if %{with rpmwheels} Requires: %{python_wheel_pkg_prefix}-pip-wheel >= 23.1.2 # Bundled libb2 is CC0, covered by grandfathering exception -License: Python-2.0.1 AND CC0-1.0 +License: Python and CC0 %else Provides: bundled(python3dist(pip)) = %{pip_version} %pip_bundled_provides # License manually combined form Python + pip -License: Python-2.0.1 AND CC0-1.0 AND MIT AND Apache-2.0 AND BSD-2-Clause AND BSD-3-Clause AND ISC AND LGPL-2.1-only AND MPL-2.0 AND (Apache-2.0 OR BSD-2-Clause) +License: Python and CC0 and MIT and ASL 2.0 and BSD and ISC and LGPLv2 and MPLv2.0 and (ASL 2.0 or BSD) %endif %unversioned_obsoletes_of_python3_X_if_main libs @@ -632,12 +624,12 @@ Requires: %{pkgname}-libs%{?_isa} = %{version}-%{release} Requires: %{python_wheel_pkg_prefix}-setuptools-wheel Requires: %{python_wheel_pkg_prefix}-wheel-wheel %else -Provides: bundled(python3dist(setuptools)) = %{setuptools_version} +Provides: bundled(python%{python3_pkgversion}dist(setuptools)) = %{setuptools_version} %setuptools_bundled_provides -Provides: bundled(python3dist(wheel)) = %{wheel_version} +Provides: bundled(python%{python3_pkgversion}dist(wheel)) = %{wheel_version} %wheel_bundled_provides # License manually combined from Python + setuptools + wheel -License: Python-2.0.1 AND MIT AND Apache-2.0 AND (Apache-2.0 OR BSD-2-Clause) +License: Python and MIT and ASL 2.0 and (ASL 2.0 or BSD) %endif %unversioned_obsoletes_of_python3_X_if_main test @@ -684,6 +676,24 @@ The debug runtime additionally supports debug builds of C-API extensions %endif # with debug_build +# We package the python3.12-rpm-macros in RHEL8 as to properly set the +# %%__python3 and %%python3_pkgversion macros as well as provide modern +# versions the current base macros. +%package -n %{pkgname}-rpm-macros +Summary: RPM macros for building RPMs with Python %{pybasever} +License: MIT +Provides: python-modular-rpm-macros == %{pybasever} +Conflicts: python-modular-rpm-macros > %{pybasever} +Requires: python3-rpm-macros +BuildArch: noarch + +%description -n %{pkgname}-rpm-macros +RPM macros for building RPMs with Python %{pybasever} from the python%{pyshortver} module. +If you want to build an RPM against the python%{pyshortver} module, you need to add: + + BuildRequire: %{pkgname}-rpm-macros. + + # ====================================================== # The prep phase of the build: # ====================================================== @@ -692,14 +702,6 @@ The debug runtime additionally supports debug builds of C-API extensions %gpgverify -k2 -s1 -d0 %autosetup -S git_am -n Python-%{upstream_version} -# Verify the second level of bundled provides is up to date -# Arguably this should be done in %%check, but %%prep has a faster feedback loop -# setuptools.whl does not contain the vendored.txt files -if [ -f %{_rpmconfigdir}/pythonbundles.py ]; then - %{_rpmconfigdir}/pythonbundles.py <(unzip -p Lib/ensurepip/_bundled/pip-*.whl pip/_vendor/vendor.txt) --compare-with '%pip_bundled_provides' - %{_rpmconfigdir}/pythonbundles.py <(unzip -p Lib/test/wheel-*.whl wheel/vendored/vendor.txt) --compare-with '%wheel_bundled_provides' -fi - %if %{with rpmwheels} rm Lib/ensurepip/_bundled/pip-%{pip_version}-py3-none-any.whl rm Lib/test/setuptools-%{setuptools_version}-py3-none-any.whl @@ -720,6 +722,11 @@ rm -r Modules/_decimal/libmpdec rm configure pyconfig.h.in +# Python 3.12 requires autoconf 2.71 which is not available in RHEL, +# we verified that it builds also with autoconf 2.69 therefore we +# are unpinning it +sed -i 's/AC_PREREQ(\[2.71/AC_PREREQ(\[2.69/' configure.ac + # ====================================================== # Configuring and building the code: # ====================================================== @@ -1000,8 +1007,11 @@ done # Switch all shebangs to refer to the specific Python version. # This currently only covers files matching ^[a-zA-Z0-9_]+\.py$, # so handle files named using other naming scheme separately. +# - RHEL 8 note: we use %%{SOURCE5} instead of pathfix.py, because in RHEL 8 we +# ship our own versioned pathfix_py3_12.py in this package, but during +# bootstrap it's not yet installed. LD_LIBRARY_PATH=./build/optimized ./build/optimized/python \ - %{_rpmconfigdir}/redhat/pathfix.py \ + %{SOURCE5} \ -i "%{_bindir}/python%{pybasever}" -pn \ %{buildroot} \ %{buildroot}%{_bindir}/*%{pybasever}.py \ @@ -1103,6 +1113,16 @@ for file in %{buildroot}%{pylibdir}/pydoc_data/topics.py $(grep --include='*.py' rm ${directory}/{__pycache__/${module}.cpython-%{pyshortver}.opt-?.pyc,${module}.py} done +# Python RPM macros for python3.12-rpm-macros +mkdir -p %{buildroot}%{rpmmacrodir}/ +install -m 644 %{SOURCE3} \ + %{buildroot}/%{rpmmacrodir}/ + +# Add scripts that are being used by python3.12-rpm-macros +mkdir -p %{buildroot}%{_rpmconfigdir}/redhat +install -m 644 %{SOURCE4} %{buildroot}%{_rpmconfigdir}/redhat/ +install -m 644 %{SOURCE5} %{buildroot}%{_rpmconfigdir}/redhat/ + # ====================================================== # Checks for packaging issues # ====================================================== @@ -1188,6 +1208,12 @@ CheckPython optimized %endif # with tests +%files -n %{pkgname}-rpm-macros +%{rpmmacrodir}/macros.python%{pybasever} +%{_rpmconfigdir}/redhat/import_all_modules_py3_12.py +%{_rpmconfigdir}/redhat/pathfix_py3_12.py + + %files -n %{pkgname} %doc README.rst @@ -1685,91 +1711,50 @@ CheckPython optimized # ====================================================== %changelog -* Mon Dec 18 2023 Lumír Balhar - 3.12.1-2 -- Security fix for CVE-2023-27043 (rhbz#2196190) +* Wed Dec 20 2023 Tomáš Hrnčiar - 3.12.1-1 +- Initial package +- Fedora contributions by: + Björn Esser + Bohuslav Kabrda + Charalampos Stratakis + Dan Horák + David Malcolm + Dennis Gilmore + Florian Weimer + Gwyn Ciesla + Igor Gnatenko + Iryna Shcherbina + Jaroslav Škarvada + Jason ティビツ + Kalev Lember + Karsten Hopp + Lumir Balhar + Marcel Plch + Matej Stuchlik + Michal Cyprian + Michal Toman + Miro Hrončok + Nicolas Chauvet + Orion Poplawski + Patrik Kopkan + Peter Robinson + Petr Šplíchal + Petr Viktorin + Rex Dieter + Richard W.M. Jones + Robert Kuska + Sahana Prasad + Stephen Gallagher + Than Ngo + Thomas Spura + Till Maas + Tomáš Hrnčiar + Tomas Mraz + Tomas Orsava + Tomas Radej + Toshio Kuratomi + Victor Stinner + Ville Skyttä + Yaakov Selkowitz + Zbigniew Jędrzejewski-Szmek -* Fri Dec 08 2023 Tomáš Hrnčiar - 3.12.1-1 -- Update to 3.12.1 -- Own stray directories in /usr/lib64/python3.12 -- Fixes: rhbz#2252143 - -* Thu Oct 05 2023 Yaakov Selkowitz - 3.12.0-2 -- Use bundled libb2 in RHEL builds - -* Mon Oct 02 2023 Miro Hrončok - 3.12.0-1 -- Update to 3.12.0 final - -* Tue Sep 19 2023 Miro Hrončok - 3.12.0~rc3-1 -- Update to 3.12.0rc3 - -* Wed Sep 06 2023 Tomáš Hrnčiar - 3.12.0~rc2-1 -- Update to 3.12.0rc2 - -* Mon Aug 07 2023 Tomáš Hrnčiar - 3.12.0~rc1-1 -- Update to 3.12.0rc1 - -* Wed Aug 02 2023 Charalampos Stratakis - 3.12.0~b4-3 -- Remove extra distro-applied CFLAGS passed to user built C extensions -- https://fedoraproject.org/wiki/Changes/Python_Extension_Flags_Reduction - -* Fri Jul 21 2023 Fedora Release Engineering - 3.12.0~b4-2 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild - -* Wed Jul 12 2023 Miro Hrončok - 3.12.0~b4-1 -- Update to 3.12.0b4 - -* Wed Jun 21 2023 Tomáš Hrnčiar - 3.12.0~b3-2 -- Backport upstream patch to add PyType_GetDict() function - -* Tue Jun 20 2023 Tomáš Hrnčiar - 3.12.0~b3-1 -- Update to 3.12.0b3 - -* Tue Jun 13 2023 Python Maint - 3.12.0~b2-3 -- Rebuilt for Python 3.12 - -* Tue Jun 13 2023 Python Maint - 3.12.0~b2-2 -- Bootstrap for Python 3.12 - -* Wed Jun 07 2023 Tomáš Hrnčiar - 3.12.0~b2-1 -- Update to 3.12.0b2 - -* Mon May 29 2023 Miro Hrončok - 3.12.0~b1-2 -- Use wheels from RPMs, at least on Fedora 39+ -- On older Fedora releases, declare bundled() provides and a complex License tag - -* Tue May 23 2023 Tomáš Hrnčiar - 3.12.0~b1-1 -- Update to 3.12.0b1 - -* Wed Apr 05 2023 Tomáš Hrnčiar - 3.12.0~a7-1 -- Update to 3.12.0a7 - -* Thu Mar 23 2023 Miro Hrončok - 3.12.0~a6-2 -- Increase the test timeout during package build - -* Wed Mar 08 2023 Tomáš Hrnčiar - 3.12.0~a6-1 -- Update to 3.12.0a6 - -* Wed Feb 08 2023 Tomáš Hrnčiar - 3.12.0~a5-1 -- Update to 3.12.0a5 - -* Fri Jan 20 2023 Fedora Release Engineering - 3.12.0~a4-2 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild - -* Wed Jan 11 2023 Tomáš Hrnčiar - 3.12.0~a4-1 -- Update to 3.12.0a4 - -* Mon Dec 19 2022 Miro Hrončok - 3.12.0~a3-2 -- No longer patch the default bytecode cache invalidation policy - -* Wed Dec 07 2022 Tomáš Hrnčiar - 3.12.0~a3-1 -- Update to 3.12.0a3 - -* Tue Nov 15 2022 Tomáš Hrnčiar - 3.12.0~a2-1 -- Update to 3.12.0a2 -- Fixes: rhbz#2133847 - -* Thu Oct 27 2022 Miro Hrončok - 3.12.0~a1-2 -- Finish initial bootstrap of Python 3.12.0a1 - -* Wed Oct 26 2022 Tomáš Hrnčiar - 3.12.0~a1-1 -- Initial Python 3.12 package forked from Python 3.11