diff --git a/replace-imp-with-importlib.patch b/replace-imp-with-importlib.patch new file mode 100644 index 0000000..f19323c --- /dev/null +++ b/replace-imp-with-importlib.patch @@ -0,0 +1,318 @@ +From 01a444c023fbc109d0ad1a563c80e3a98c067cb8 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Mat=C4=9Bj=20Cepl?= +Date: Wed, 25 Jul 2018 12:25:03 +0200 +Subject: [PATCH] Replace use of imp library with importlib. + +imp library has been deprecated since 3.4 and in 3.7 it finally breaks +builds. + +Presrving compatibility with python >= 2.7. +--- + src/CHANGES.txt | 3 + + src/engine/SCons/Platform/__init__.py | 13 +-- + src/engine/SCons/Script/Main.py | 95 ++++++++++++++------- + src/engine/SCons/Tool/__init__.py | 5 +- + src/engine/SCons/Tool/packaging/__init__.py | 29 +++++-- + src/engine/SCons/Util.py | 2 + + src/engine/SCons/compat/__init__.py | 8 +- + 7 files changed, 102 insertions(+), 53 deletions(-) + +--- a/engine/SCons/Platform/__init__.py ++++ b/engine/SCons/Platform/__init__.py +@@ -47,14 +47,15 @@ __revision__ = "src/engine/SCons/Platfor + + import SCons.compat + +-import imp + import os ++import importlib + import sys + import tempfile + + import SCons.Errors + import SCons.Subst + import SCons.Tool ++import SCons.Util + + + def platform_default(): +@@ -100,13 +101,7 @@ def platform_module(name = platform_defa + eval(full_name) + else: + try: +- file, path, desc = imp.find_module(name, +- sys.modules['SCons.Platform'].__path__) +- try: +- mod = imp.load_module(full_name, file, path, desc) +- finally: +- if file: +- file.close() ++ mod = importlib.import_module(full_name) + except ImportError: + try: + import zipimport +@@ -114,7 +109,7 @@ def platform_module(name = platform_defa + mod = importer.load_module(full_name) + except ImportError: + raise SCons.Errors.UserError("No platform named '%s'" % name) +- setattr(SCons.Platform, name, mod) ++ setattr(SCons.Platform, name, mod) + return sys.modules[full_name] + + def DefaultToolList(platform, env): +--- a/engine/SCons/Script/Main.py ++++ b/engine/SCons/Script/Main.py +@@ -711,54 +711,89 @@ def _load_site_scons_dir(topdir, site_di + sys.path = [os.path.abspath(site_dir)] + sys.path + site_init_file = os.path.join(site_dir, site_init_filename) + site_tools_dir = os.path.join(site_dir, site_tools_dirname) +- if os.path.exists(site_init_file): +- import imp, re +- try: ++ ++ if SCons.Util.PY2 or SCons.Util.PY34: ++ if os.path.exists(site_init_file): ++ import imp, re + try: +- fp, pathname, description = imp.find_module(site_init_modname, +- [site_dir]) +- # Load the file into SCons.Script namespace. This is +- # opaque and clever; m is the module object for the +- # SCons.Script module, and the exec ... in call executes a +- # file (or string containing code) in the context of the +- # module's dictionary, so anything that code defines ends +- # up adding to that module. This is really short, but all +- # the error checking makes it longer. ++ try: ++ fp, pathname, description = imp.find_module(site_init_modname, ++ [site_dir]) ++ # Load the file into SCons.Script namespace. This is ++ # opaque and clever; m is the module object for the ++ # SCons.Script module, and the exec ... in call executes a ++ # file (or string containing code) in the context of the ++ # module's dictionary, so anything that code defines ends ++ # up adding to that module. This is really short, but all ++ # the error checking makes it longer. ++ try: ++ m = sys.modules['SCons.Script'] ++ except Exception as e: ++ fmt = 'cannot import site_init.py: missing SCons.Script module {}' ++ raise SCons.Errors.InternalError(fmt.format(repr(e))) ++ try: ++ sfx = description[0] ++ modname = os.path.basename(pathname)[:-len(sfx)] ++ site_m = {"__file__": pathname, "__name__": modname, "__doc__": None} ++ re_special = re.compile("__[^_]+__") ++ for k in list(m.__dict__.keys()): ++ if not re_special.match(k): ++ site_m[k] = m.__dict__[k] ++ ++ # This is the magic. ++ exec(compile(fp.read(), fp.name, 'exec'), site_m) ++ except KeyboardInterrupt: ++ raise ++ except Exception as e: ++ fmt = '*** Error loading site_init file %s:\n' ++ sys.stderr.write(fmt % repr(site_init_file)) ++ raise ++ else: ++ for k in site_m: ++ if not re_special.match(k): ++ m.__dict__[k] = site_m[k] ++ except KeyboardInterrupt: ++ raise ++ except ImportError as e: ++ fmt = '*** cannot import site init file %s:\n' ++ sys.stderr.write(fmt % repr(site_init_file)) ++ raise ++ finally: ++ if fp: ++ fp.close() ++ else: # Python >= 3.5 ++ if os.path.exists(site_init_file): ++ import importlib.util, importlib.machinery ++ try: ++ loader_details = ( ++ importlib.machinery.ExtensionFileLoader, ++ importlib.machinery.EXTENSION_SUFFIXES ++ ) ++ finder = importlib.machinery.FileFinder(site_dir, ++ loader_details) ++ spec = finder.find_spec(site_init_modname) + try: + m = sys.modules['SCons.Script'] + except Exception as e: + fmt = 'cannot import site_init.py: missing SCons.Script module %s' + raise SCons.Errors.InternalError(fmt % repr(e)) + try: +- sfx = description[0] +- modname = os.path.basename(pathname)[:-len(sfx)] +- site_m = {"__file__": pathname, "__name__": modname, "__doc__": None} +- re_special = re.compile("__[^_]+__") +- for k in list(m.__dict__.keys()): +- if not re_special.match(k): +- site_m[k] = m.__dict__[k] +- ++ mod = importlib.util.module_from_spec(spec) + # This is the magic. +- exec(compile(fp.read(), fp.name, 'exec'), site_m) ++ exec(mod.__loader__.get_code(mod.__name__), m.__dict__) + except KeyboardInterrupt: + raise + except Exception as e: +- fmt = '*** Error loading site_init file %s:\n' +- sys.stderr.write(fmt % repr(site_init_file)) ++ fmt = '*** Error loading site_init file {}:\n' ++ sys.stderr.write(fmt.format(repr(site_init_file))) + raise +- else: +- for k in site_m: +- if not re_special.match(k): +- m.__dict__[k] = site_m[k] + except KeyboardInterrupt: + raise + except ImportError as e: + fmt = '*** cannot import site init file %s:\n' + sys.stderr.write(fmt % repr(site_init_file)) + raise +- finally: +- if fp: +- fp.close() ++ + if os.path.exists(site_tools_dir): + # prepend to DefaultToolpath + SCons.Tool.DefaultToolpath.insert(0, os.path.abspath(site_tools_dir)) +--- a/engine/SCons/Tool/__init__.py ++++ b/engine/SCons/Tool/__init__.py +@@ -54,6 +54,7 @@ import SCons.Scanner.D + import SCons.Scanner.LaTeX + import SCons.Scanner.Prog + import SCons.Scanner.SWIG ++import SCons.Util + import collections + + DefaultToolpath=[] +@@ -136,7 +137,7 @@ class Tool(object): + sys.path = self.toolpath + sys.path + # sys.stderr.write("Tool:%s\nPATH:%s\n"%(self.name,sys.path)) + +- if sys.version_info[0] < 3 or (sys.version_info[0] == 3 and sys.version_info[1] in (0,1,2,3,4)): ++ if SCons.Util.PY2 or SCons.Util.PY34: + # Py 2 code + try: + try: +@@ -238,7 +239,7 @@ class Tool(object): + setattr(SCons.Tool, self.name, module) + + found_module = module +- ++ + if found_module is not None: + sys.path = oldpythonpath + return found_module +--- a/engine/SCons/Tool/packaging/__init__.py ++++ b/engine/SCons/Tool/packaging/__init__.py +@@ -30,10 +30,10 @@ __revision__ = "src/engine/SCons/Tool/pa + import SCons.Environment + from SCons.Variables import * + from SCons.Errors import * +-from SCons.Util import is_List, make_path_relative ++from SCons.Util import is_List, is_String, make_path_relative, PY2, PY34 + from SCons.Warnings import warn, Warning + +-import os, imp ++import os + import SCons.Defaults + + __all__ = [ 'src_targz', 'src_tarbz2', 'src_zip', 'tarbz2', 'targz', 'zip', 'rpm', 'msi', 'ipk' ] +@@ -63,7 +63,7 @@ def Tag(env, target, source, *more_tags, + for x in more_tags: + kw_tags[x] = '' + +- if not SCons.Util.is_List(target): ++ if not is_List(target): + target=[target] + else: + # hmm, sometimes the target list, is a list of a list +@@ -117,8 +117,21 @@ def Package(env, target=None, source=Non + # load the needed packagers. + def load_packager(type): + try: +- file,path,desc=imp.find_module(type, __path__) +- return imp.load_module(type, file, path, desc) ++ if PY2 or PY34: ++ import imp ++ file,path,desc=imp.find_module(type, __path__) ++ return imp.load_module(type, file, path, desc) ++ else: ++ import importlib.util, importlib.machinery ++ loader_details = ( ++ importlib.machinery.ExtensionFileLoader, ++ importlib.machinery.EXTENSION_SUFFIXES ++ ) ++ finder = importlib.machinery.FileFinder(__path__, ++ loader_details) ++ spec = finder.find_spec(type) ++ mod = importlib.util.module_from_spec(spec) ++ spec.loader.exec_module(mod) + except ImportError as e: + raise EnvironmentError("packager %s not available: %s"%(type,str(e))) + +@@ -251,12 +264,12 @@ def putintopackageroot(target, source, e + All attributes of the source file will be copied to the new file. + """ + # make sure the packageroot is a Dir object. +- if SCons.Util.is_String(pkgroot): pkgroot=env.Dir(pkgroot) +- if not SCons.Util.is_List(source): source=[source] ++ if is_String(pkgroot): pkgroot=env.Dir(pkgroot) ++ if not is_List(source): source=[source] + + new_source = [] + for file in source: +- if SCons.Util.is_String(file): file = env.File(file) ++ if is_String(file): file = env.File(file) + + if file.is_under(pkgroot): + new_source.append(file) +--- a/engine/SCons/Util.py ++++ b/engine/SCons/Util.py +@@ -35,6 +35,8 @@ import codecs + import pprint + + PY3 = sys.version_info[0] == 3 ++PY2 = sys.version_info[0] == 2 ++PY34 = sys.version_info[0] == 3 and sys.version_info[1] <= 4 + + try: + from UserDict import UserDict +--- a/engine/SCons/compat/__init__.py ++++ b/engine/SCons/compat/__init__.py +@@ -61,7 +61,7 @@ __revision__ = "src/engine/SCons/compat/ + + import os + import sys +-import imp # Use the "imp" module to protect imports from fixers. ++import importlib # Use the "importlib" module to protect imports from fixers. + + PYPY = hasattr(sys, 'pypy_translation_info') + +@@ -71,8 +71,8 @@ def import_as(module, name): + Imports the specified module (from our local directory) as the + specified name, returning the loaded module object. + """ +- dir = os.path.split(__file__)[0] +- return imp.load_module(name, *imp.find_module(module, [dir])) ++ sys.modules[name] = importlib.import_module(module) ++ return sys.modules[name] + + + def rename_module(new, old): +@@ -81,7 +81,7 @@ def rename_module(new, old): + Used for purely cosmetic name changes in Python 3.x. + """ + try: +- sys.modules[new] = imp.load_module(old, *imp.find_module(old)) ++ sys.modules[new] = importlib.import_module(old) + return True + except ImportError: + return False diff --git a/scons-3.0.0-fix-install.patch b/scons-3.0.0-fix-install.patch index a2bac1e..e2fbdfa 100644 --- a/scons-3.0.0-fix-install.patch +++ b/scons-3.0.0-fix-install.patch @@ -2,11 +2,9 @@ setup.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) -Index: scons-3.0.0/setup.py -=================================================================== ---- scons-3.0.0.orig/setup.py -+++ scons-3.0.0/setup.py -@@ -386,7 +386,7 @@ class install_data(_install_data): +--- a/setup.py ++++ b/setup.py +@@ -376,7 +376,7 @@ class install_data(_install_data): if is_win32: dir = 'Doc' else: @@ -15,7 +13,7 @@ Index: scons-3.0.0/setup.py self.data_files = [(dir, man_pages)] man_dir = os.path.join(self.install_dir, dir) msg = "Installed SCons man pages into %s" % man_dir -@@ -506,7 +506,7 @@ arguments = { +@@ -496,7 +496,7 @@ arguments = { 'docbook-xsl-1.76.1/xhtml/*', 'docbook-xsl-1.76.1/xhtml-1_1/*', 'utils/*']}, diff --git a/scons.changes b/scons.changes index 763787d..3e53a68 100644 --- a/scons.changes +++ b/scons.changes @@ -1,3 +1,10 @@ +------------------------------------------------------------------- +Wed Jul 25 12:10:25 UTC 2018 - mcepl@suse.com + +- Add replace-imp-with-importlib.patch (from the upstream PR + https://github.com/SCons/scons/pull/3159) +- Remove compatibility ifs for SLE < 13 + ------------------------------------------------------------------- Fri Nov 24 08:48:43 UTC 2017 - mpluskal@suse.com diff --git a/scons.spec b/scons.spec index d4608bb..bdc2918 100644 --- a/scons.spec +++ b/scons.spec @@ -1,7 +1,7 @@ # # spec file for package scons # -# Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2018 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 @@ -16,27 +16,23 @@ # -%define with_python3 (0%{?suse_version} > 1320) Name: scons Version: 3.0.1 Release: 0 Summary: Replacement for Make License: MIT Group: Development/Tools/Building -Url: http://www.scons.org/ +URL: http://www.scons.org/ Source0: http://prdownloads.sourceforge.net/scons/%{name}-%{version}.tar.gz #http://www.scons.org/doc/%%{version}/HTML/scons-user.html Source1: scons-user.html-%{version}.tar.bz2 # Sets _mandir to _datadir/man instead of _prefix/man Patch0: %{name}-3.0.0-fix-install.patch +Patch1: replace-imp-with-importlib.patch BuildRequires: fdupes -BuildArch: noarch -%if %{with_python3} BuildRequires: python3-devel >= 3.5 -Requires: python3-base >= 3.5 -%else -BuildRequires: python-devel >= 2.7 -%endif +Requires: python3-base >= 3.5 +BuildArch: noarch %description SCons is a make replacement that provides a range of enhanced features, @@ -48,51 +44,25 @@ full power of Python to control compilation. %prep %setup -q -a1 %patch0 -p1 +%patch1 -p1 -# fix libdir for qt -patch -p0 <