diff options
author | William Deegan <bill@baddogconsulting.com> | 2016-09-30 19:04:09 (GMT) |
---|---|---|
committer | William Deegan <bill@baddogconsulting.com> | 2016-09-30 19:04:09 (GMT) |
commit | 696af9192158271e5167e6227a5dfaa614a2fb06 (patch) | |
tree | 9783594e71e74327c1c82dea4315e1df3aac1606 /src/engine/SCons | |
parent | f3a1b325d4baf5f4bc554a596b676e2029046b7c (diff) | |
parent | 6dd3fd8b838d18d65edd6e7adabf3a363437f8a9 (diff) | |
download | SCons-696af9192158271e5167e6227a5dfaa614a2fb06.zip SCons-696af9192158271e5167e6227a5dfaa614a2fb06.tar.gz SCons-696af9192158271e5167e6227a5dfaa614a2fb06.tar.bz2 |
update from upstream
Diffstat (limited to 'src/engine/SCons')
45 files changed, 443 insertions, 139 deletions
diff --git a/src/engine/SCons/Action.py b/src/engine/SCons/Action.py index 7e1f8f1..de9bf5c 100644 --- a/src/engine/SCons/Action.py +++ b/src/engine/SCons/Action.py @@ -645,7 +645,7 @@ def _subproc(scons_env, cmd, error = 'ignore', **kw): # Ensure that the ENV values are all strings: new_env = {} - for key, value in ENV.items(): + for key, value in list(ENV.items()): if is_List(value): # If the value is a list, then we assume it is a path list, # because that's a pretty common list-like value to stick @@ -772,7 +772,7 @@ class CommandAction(_ActionAction): ENV = get_default_ENV(env) # Ensure that the ENV values are all strings: - for key, value in ENV.items(): + for key, value in list(ENV.items()): if not is_String(value): if is_List(value): # If the value is a list, then we assume it is a @@ -1206,7 +1206,7 @@ class ActionCaller(object): def subst_kw(self, target, source, env): kw = {} - for key in self.kw.keys(): + for key in list(self.kw.keys()): kw[key] = self.subst(self.kw[key], target, source, env) return kw diff --git a/src/engine/SCons/ActionTests.py b/src/engine/SCons/ActionTests.py index 9007183..b790ccc 100644 --- a/src/engine/SCons/ActionTests.py +++ b/src/engine/SCons/ActionTests.py @@ -132,7 +132,7 @@ class Environment(object): self.d['SPAWN'] = scons_env['SPAWN'] self.d['PSPAWN'] = scons_env['PSPAWN'] self.d['ESCAPE'] = scons_env['ESCAPE'] - for k, v in kw.items(): + for k, v in list(kw.items()): self.d[k] = v # Just use the underlying scons_subst*() utility methods. def subst(self, strSubst, raw=0, target=[], source=[], conv=None): @@ -157,12 +157,12 @@ class Environment(object): def Clone(self, **kw): res = Environment() res.d = SCons.Util.semi_deepcopy(self.d) - for k, v in kw.items(): + for k, v in list(kw.items()): res.d[k] = v return res def sig_dict(self): d = {} - for k,v in self.items(): d[k] = v + for k,v in list(self.items()): d[k] = v d['TARGETS'] = ['__t1__', '__t2__', '__t3__', '__t4__', '__t5__', '__t6__'] d['TARGET'] = d['TARGETS'][0] d['SOURCES'] = ['__s1__', '__s2__', '__s3__', '__s4__', '__s5__', '__s6__'] diff --git a/src/engine/SCons/Builder.py b/src/engine/SCons/Builder.py index 50e85ec..c7bce3a 100644 --- a/src/engine/SCons/Builder.py +++ b/src/engine/SCons/Builder.py @@ -229,7 +229,7 @@ class OverrideWarner(collections.UserDict): def warn(self): if self.already_warned: return - for k in self.keys(): + for k in list(self.keys()): if k in misleading_keywords: alt = misleading_keywords[k] msg = "Did you mean to use `%s' instead of `%s'?" % (alt, k) diff --git a/src/engine/SCons/BuilderTests.py b/src/engine/SCons/BuilderTests.py index 1e544a1..ca35abc 100644 --- a/src/engine/SCons/BuilderTests.py +++ b/src/engine/SCons/BuilderTests.py @@ -79,7 +79,7 @@ class Environment(object): self.d['SHELL'] = scons_env['SHELL'] self.d['SPAWN'] = scons_env['SPAWN'] self.d['ESCAPE'] = scons_env['ESCAPE'] - for k, v in kw.items(): + for k, v in list(kw.items()): self.d[k] = v global env_arg2nodes_called env_arg2nodes_called = None @@ -140,7 +140,7 @@ class Environment(object): return list(self.d.items()) def sig_dict(self): d = {} - for k,v in self.items(): d[k] = v + for k,v in list(self.items()): d[k] = v d['TARGETS'] = ['__t1__', '__t2__', '__t3__', '__t4__', '__t5__', '__t6__'] d['TARGET'] = d['TARGETS'][0] d['SOURCES'] = ['__s1__', '__s2__', '__s3__', '__s4__', '__s5__', '__s6__'] diff --git a/src/engine/SCons/Debug.py b/src/engine/SCons/Debug.py index 9e520ff..6ac5f27 100644 --- a/src/engine/SCons/Debug.py +++ b/src/engine/SCons/Debug.py @@ -89,7 +89,7 @@ def dumpLoggedInstances(classes, file=sys.stdout): obj = ref() if obj is not None: file.write(' %s:\n' % obj) - for key, value in obj.__dict__.items(): + for key, value in list(obj.__dict__.items()): file.write(' %20s : %s\n' % (key, value)) @@ -163,7 +163,7 @@ def caller_trace(back=0): # print a single caller and its callers, if any def _dump_one_caller(key, file, level=0): leader = ' '*level - for v,c in sorted([(-v,c) for c,v in caller_dicts[key].items()]): + for v,c in sorted([(-v,c) for c,v in list(caller_dicts[key].items())]): file.write("%s %6d %s:%d(%s)\n" % ((leader,-v) + func_shorten(c[-3:]))) if c in caller_dicts: _dump_one_caller(c, file, level+1) diff --git a/src/engine/SCons/Defaults.py b/src/engine/SCons/Defaults.py index f1d5bca..f095982 100644 --- a/src/engine/SCons/Defaults.py +++ b/src/engine/SCons/Defaults.py @@ -459,7 +459,7 @@ def processDefines(defs): else: l.append(str(d[0])) elif SCons.Util.is_Dict(d): - for macro,value in d.items(): + for macro,value in list(d.items()): if value is not None: l.append(str(macro) + '=' + str(value)) else: diff --git a/src/engine/SCons/Environment.py b/src/engine/SCons/Environment.py index d979005..ed8ef78 100644 --- a/src/engine/SCons/Environment.py +++ b/src/engine/SCons/Environment.py @@ -152,7 +152,7 @@ def _set_BUILDERS(env, key, value): except KeyError: bd = BuilderDict(kwbd, env) env._dict[key] = bd - for k, v in value.items(): + for k, v in list(value.items()): if not SCons.Builder.is_a_Builder(v): raise SCons.Errors.UserError('%s is not a Builder.' % repr(v)) bd.update(value) @@ -324,7 +324,7 @@ class BuilderDict(UserDict): delattr(self.env, item) def update(self, dict): - for i, v in dict.items(): + for i, v in list(dict.items()): self.__setitem__(i, v) @@ -515,7 +515,7 @@ class SubstitutionEnvironment(object): def subst_kw(self, kw, raw=0, target=None, source=None): nkw = {} - for k, v in kw.items(): + for k, v in list(kw.items()): k = self.subst(k, raw, target, source) if SCons.Util.is_String(v): v = self.subst(v, raw, target, source) @@ -627,7 +627,7 @@ class SubstitutionEnvironment(object): if not o: return self overrides = {} merges = None - for key, value in o.items(): + for key, value in list(o.items()): if key == 'parse_flags': merges = value else: @@ -815,7 +815,7 @@ class SubstitutionEnvironment(object): if not unique: self.Append(**args) return self - for key, value in args.items(): + for key, value in list(args.items()): if not value: continue try: @@ -984,7 +984,7 @@ class Base(SubstitutionEnvironment): # Now restore the passed-in and customized variables # to the environment, since the values the user set explicitly # should override any values set by the tools. - for key, val in save.items(): + for key, val in list(save.items()): self._dict[key] = val # Finally, apply any flags to be merged in @@ -1185,7 +1185,7 @@ class Base(SubstitutionEnvironment): if SCons.Util.is_List(val): if key == 'CPPDEFINES': tmp = [] - for (k, v) in orig.iteritems(): + for (k, v) in orig.items(): if v is not None: tmp.append((k, v)) else: @@ -1247,7 +1247,7 @@ class Base(SubstitutionEnvironment): values move to end. """ kw = copy_non_reserved_keywords(kw) - for key, val in kw.items(): + for key, val in list(kw.items()): if SCons.Util.is_List(val): val = _delete_duplicates(val, delete_existing) if key not in self._dict or self._dict[key] in ('', None): @@ -1273,7 +1273,7 @@ class Base(SubstitutionEnvironment): # Construct a list of (key, value) tuples. if SCons.Util.is_Dict(dk): tmp = [] - for (k, v) in dk.iteritems(): + for (k, v) in dk.items(): if v is not None: tmp.append((k, v)) else: @@ -1321,7 +1321,7 @@ class Base(SubstitutionEnvironment): # Construct a list of (key, value) tuples. if SCons.Util.is_Dict(val): tmp = [] - for (k, v) in val.iteritems(): + for (k, v) in val.items(): if v is not None: tmp.append((k, v)) else: @@ -1350,7 +1350,7 @@ class Base(SubstitutionEnvironment): dk = [dk] elif SCons.Util.is_Dict(dk): tmp = [] - for (k, v) in dk.iteritems(): + for (k, v) in dk.items(): if v is not None: tmp.append((k, v)) else: @@ -1363,7 +1363,7 @@ class Base(SubstitutionEnvironment): val = [val] elif SCons.Util.is_Dict(val): tmp = [] - for i,j in val.items(): + for i,j in list(val.items()): if j is not None: tmp.append((i,j)) else: @@ -1405,7 +1405,7 @@ class Base(SubstitutionEnvironment): # so the tools can use the new variables kw = copy_non_reserved_keywords(kw) new = {} - for key, value in kw.items(): + for key, value in list(kw.items()): new[key] = SCons.Subst.scons_subst_once(value, self, key) clone.Replace(**new) @@ -1605,7 +1605,7 @@ class Base(SubstitutionEnvironment): in an Environment. """ kw = copy_non_reserved_keywords(kw) - for key, val in kw.items(): + for key, val in list(kw.items()): # It would be easier on the eyes to write this using # "continue" statements whenever we finish processing an item, # but Python 1.5.2 apparently doesn't let you use "continue" @@ -1696,7 +1696,7 @@ class Base(SubstitutionEnvironment): values move to front. """ kw = copy_non_reserved_keywords(kw) - for key, val in kw.items(): + for key, val in list(kw.items()): if SCons.Util.is_List(val): val = _delete_duplicates(val, not delete_existing) if key not in self._dict or self._dict[key] in ('', None): @@ -1833,7 +1833,7 @@ class Base(SubstitutionEnvironment): uniq = {} for executor in [n.get_executor() for n in nodes]: uniq[executor] = 1 - for executor in uniq.keys(): + for executor in list(uniq.keys()): executor.add_pre_action(action) return nodes @@ -1843,7 +1843,7 @@ class Base(SubstitutionEnvironment): uniq = {} for executor in [n.get_executor() for n in nodes]: uniq[executor] = 1 - for executor in uniq.keys(): + for executor in list(uniq.keys()): executor.add_post_action(action) return nodes diff --git a/src/engine/SCons/Environment.xml b/src/engine/SCons/Environment.xml index b90f1d8..65d71ff 100644 --- a/src/engine/SCons/Environment.xml +++ b/src/engine/SCons/Environment.xml @@ -1100,7 +1100,7 @@ timestamp, such as can happen when restoring files from backup archives. <listitem> <para> Specifies that a target shall be considered out of date and rebuilt -if the dependency's content has changed sine the last time +if the dependency's content has changed since the last time the target was built, as determined be performing an MD5 checksum on the dependency's contents @@ -1117,7 +1117,7 @@ can be used as a synonym for <listitem> <para> Specifies that a target shall be considered out of date and rebuilt -if the dependency's content has changed sine the last time +if the dependency's content has changed since the last time the target was built, except that dependencies with a timestamp that matches the last time the target was rebuilt will be diff --git a/src/engine/SCons/EnvironmentTests.py b/src/engine/SCons/EnvironmentTests.py index 4b57763..e3259d4 100644 --- a/src/engine/SCons/EnvironmentTests.py +++ b/src/engine/SCons/EnvironmentTests.py @@ -164,7 +164,7 @@ class TestEnvironmentFixture(object): default_keys = { 'CC' : 'cc', 'CCFLAGS' : '-DNDEBUG', 'ENV' : { 'TMP' : '/tmp' } } - for key, value in default_keys.items(): + for key, value in list(default_keys.items()): if key not in kw: kw[key] = value if 'BUILDERS' not in kw: diff --git a/src/engine/SCons/Node/Alias.py b/src/engine/SCons/Node/Alias.py index a035816..f229a9f 100644 --- a/src/engine/SCons/Node/Alias.py +++ b/src/engine/SCons/Node/Alias.py @@ -89,7 +89,7 @@ class AliasNodeInfo(SCons.Node.NodeInfoBase): """ # TODO check or discard version del state['_version_id'] - for key, value in state.items(): + for key, value in list(state.items()): if key not in ('__weakref__',): setattr(self, key, value) diff --git a/src/engine/SCons/Node/FS.py b/src/engine/SCons/Node/FS.py index 71511b5..0de3989 100644 --- a/src/engine/SCons/Node/FS.py +++ b/src/engine/SCons/Node/FS.py @@ -696,7 +696,7 @@ class Base(SCons.Node.Node): return self._memo['_save_str'] except KeyError: pass - result = sys.intern(self._get_str()) + result = SCons.Util.silent_intern(self._get_str()) self._memo['_save_str'] = result return result @@ -1607,7 +1607,7 @@ class Dir(Base): This clears any cached information that is invalidated by changing the repository.""" - for node in self.entries.values(): + for node in list(self.entries.values()): if node != self.dir: if node != self and isinstance(node, Dir): node.__clearRepositoryCache(duplicate) @@ -2179,7 +2179,7 @@ class Dir(Base): for x in excludeList: r = self.glob(x, ondisk, source, strings) excludes.extend(r) - result = filter(lambda x: not any(fnmatch.fnmatch(str(x), str(e)) for e in SCons.Util.flatten(excludes)), result) + result = [x for x in result if not any(fnmatch.fnmatch(str(x), str(e)) for e in SCons.Util.flatten(excludes))] return sorted(result, key=lambda a: str(a)) def _glob1(self, pattern, ondisk=True, source=False, strings=False): @@ -2203,7 +2203,7 @@ class Dir(Base): # We use the .name attribute from the Node because the keys of # the dir.entries dictionary are normalized (that is, all upper # case) on case-insensitive systems like Windows. - node_names = [ v.name for k, v in dir.entries.items() + node_names = [ v.name for k, v in list(dir.entries.items()) if k not in ('.', '..') ] names.extend(node_names) if not strings: @@ -2481,7 +2481,7 @@ class FileNodeInfo(SCons.Node.NodeInfoBase): """ # TODO check or discard version del state['_version_id'] - for key, value in state.items(): + for key, value in list(state.items()): if key not in ('__weakref__',): setattr(self, key, value) @@ -2670,7 +2670,11 @@ class File(Base): return contents[len(codecs.BOM_UTF16_LE):].decode('utf-16-le') if contents.startswith(codecs.BOM_UTF16_BE): return contents[len(codecs.BOM_UTF16_BE):].decode('utf-16-be') - return contents + try: + return contents.decode() + except UnicodeDecodeError: + return contents + def get_content_hash(self): """ diff --git a/src/engine/SCons/Node/Python.py b/src/engine/SCons/Node/Python.py index f151fc5..92cc320 100644 --- a/src/engine/SCons/Node/Python.py +++ b/src/engine/SCons/Node/Python.py @@ -67,7 +67,7 @@ class ValueNodeInfo(SCons.Node.NodeInfoBase): """ # TODO check or discard version del state['_version_id'] - for key, value in state.items(): + for key, value in list(state.items()): if key not in ('__weakref__',): setattr(self, key, value) diff --git a/src/engine/SCons/Node/__init__.py b/src/engine/SCons/Node/__init__.py index 00ddf2f..2bf38c2 100644 --- a/src/engine/SCons/Node/__init__.py +++ b/src/engine/SCons/Node/__init__.py @@ -382,7 +382,7 @@ class NodeInfoBase(object): try: field_list = self.field_list except AttributeError: - field_list = getattr(self, '__dict__', {}).keys() + field_list = list(getattr(self, '__dict__', {}).keys()) for obj in type(self).mro(): for slot in getattr(obj, '__slots__', ()): if slot not in ('__weakref__', '__dict__'): @@ -427,7 +427,7 @@ class NodeInfoBase(object): # TODO check or discard version del state['_version_id'] - for key, value in state.items(): + for key, value in list(state.items()): if key not in ('__weakref__',): setattr(self, key, value) @@ -488,7 +488,7 @@ class BuildInfoBase(object): """ # TODO check or discard version del state['_version_id'] - for key, value in state.items(): + for key, value in list(state.items()): if key not in ('__weakref__',): setattr(self, key, value) @@ -1338,7 +1338,7 @@ class Node(object, with_metaclass(NoSlotsPyPy)): # dictionary patterns I found all ended up using "not in" # internally anyway...) if self.ignore_set: - iter = chain.from_iterable(filter(None, [self.sources, self.depends, self.implicit])) + iter = chain.from_iterable([_f for _f in [self.sources, self.depends, self.implicit] if _f]) children = [] for i in iter: @@ -1372,7 +1372,7 @@ class Node(object, with_metaclass(NoSlotsPyPy)): # using dictionary keys, lose the order, and the only ordered # dictionary patterns I found all ended up using "not in" # internally anyway...) - return list(chain.from_iterable(filter(None, [self.sources, self.depends, self.implicit]))) + return list(chain.from_iterable([_f for _f in [self.sources, self.depends, self.implicit] if _f])) def children(self, scan=1): """Return a list of the node's direct children, minus those @@ -1396,7 +1396,7 @@ class Node(object, with_metaclass(NoSlotsPyPy)): def Decider(self, function): foundkey = None - for k, v in _decider_map.iteritems(): + for k, v in _decider_map.items(): if v == function: foundkey = k break @@ -1609,8 +1609,8 @@ class Node(object, with_metaclass(NoSlotsPyPy)): new_bkids = new.bsources + new.bdepends + new.bimplicit new_bkidsigs = new.bsourcesigs + new.bdependsigs + new.bimplicitsigs - osig = dict(zip(old_bkids, old_bkidsigs)) - nsig = dict(zip(new_bkids, new_bkidsigs)) + osig = dict(list(zip(old_bkids, old_bkidsigs))) + nsig = dict(list(zip(new_bkids, new_bkidsigs))) # The sources and dependencies we'll want to report are all stored # as relative paths to this target's directory, but we want to diff --git a/src/engine/SCons/SConf.py b/src/engine/SCons/SConf.py index d56b333..c68d1c6 100644 --- a/src/engine/SCons/SConf.py +++ b/src/engine/SCons/SConf.py @@ -132,7 +132,7 @@ def CreateConfigHBuilder(env): _stringConfigH) sconfigHBld = SCons.Builder.Builder(action=action) env.Append( BUILDERS={'SConfigHBuilder':sconfigHBld} ) - for k in _ac_config_hs.keys(): + for k in list(_ac_config_hs.keys()): env.SConfigHBuilder(k, env.Value(_ac_config_hs[k])) @@ -671,7 +671,7 @@ class SConfBase(object): """Adds all the tests given in the tests dictionary to this SConf instance """ - for name in tests.keys(): + for name in list(tests.keys()): self.AddTest(name, tests[name]) def _createDir( self, node ): diff --git a/src/engine/SCons/SConsign.py b/src/engine/SCons/SConsign.py index cb089aa..75d2c41 100644 --- a/src/engine/SCons/SConsign.py +++ b/src/engine/SCons/SConsign.py @@ -39,6 +39,8 @@ import pickle import SCons.dblite import SCons.Warnings +from SCons.compat import PICKLE_PROTOCOL + def corrupt_dblite_warning(filename): SCons.Warnings.warn(SCons.Warnings.CorruptSConsignWarning, "Ignoring corrupt .sconsign file: %s"%filename) @@ -153,7 +155,7 @@ class SConsignEntry(object): return state def __setstate__(self, state): - for key, value in state.items(): + for key, value in list(state.items()): if key not in ('_version_id','__weakref__'): setattr(self, key, value) @@ -197,7 +199,7 @@ class Base(object): pass def merge(self): - for key, node in self.to_be_merged.items(): + for key, node in list(self.to_be_merged.items()): entry = node.get_stored_info() try: ninfo = entry.ninfo @@ -243,7 +245,7 @@ class DB(Base): except Exception as e: SCons.Warnings.warn(SCons.Warnings.CorruptSConsignWarning, "Ignoring corrupt sconsign entry : %s (%s)\n"%(self.dir.get_tpath(), e)) - for key, entry in self.entries.items(): + for key, entry in list(self.entries.items()): entry.convert_from_sconsign(dir, key) if mode == "r": @@ -270,9 +272,9 @@ class DB(Base): # the Repository; we only write to our own .sconsign file, # not to .sconsign files in Repositories. path = normcase(self.dir.get_internal_path()) - for key, entry in self.entries.items(): + for key, entry in list(self.entries.items()): entry.convert_to_sconsign() - db[path] = pickle.dumps(self.entries, 1) + db[path] = pickle.dumps(self.entries, PICKLE_PROTOCOL) if sync: try: @@ -358,9 +360,9 @@ class DirFile(Dir): fname = self.sconsign except IOError: return - for key, entry in self.entries.items(): + for key, entry in list(self.entries.items()): entry.convert_to_sconsign() - pickle.dump(self.entries, file, 1) + pickle.dump(self.entries, file, PICKLE_PROTOCOL) file.close() if fname != self.sconsign: try: diff --git a/src/engine/SCons/Scanner/D.py b/src/engine/SCons/Scanner/D.py index 9402ed1..95496d5 100644 --- a/src/engine/SCons/Scanner/D.py +++ b/src/engine/SCons/Scanner/D.py @@ -32,8 +32,6 @@ Coded by Andy Friesen __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" -import re - import SCons.Scanner def DScanner(): @@ -43,13 +41,13 @@ def DScanner(): class D(SCons.Scanner.Classic): def __init__ (self): - SCons.Scanner.Classic.__init__ (self, + SCons.Scanner.Classic.__init__ ( + self, name = "DScanner", suffixes = '$DSUFFIXES', path_variable = 'DPATH', - regex = 'import\s+(?:[a-zA-Z0-9_.]+)\s*(?:,\s*(?:[a-zA-Z0-9_.]+)\s*)*;') - - self.cre2 = re.compile ('(?:import\s)?\s*([a-zA-Z0-9_.]+)\s*(?:,|;)', re.M) + regex = '(?:import\s+)([\w\s=,.]+)(?:\s*:[\s\w,=]+)?(?:;)' + ) def find_include(self, include, source_dir, path): # translate dots (package separators) to slashes @@ -62,8 +60,10 @@ class D(SCons.Scanner.Classic): def find_include_names(self, node): includes = [] - for i in self.cre.findall(node.get_text_contents()): - includes = includes + self.cre2.findall(i) + for iii in self.cre.findall(node.get_text_contents()): + for jjj in iii.split(','): + kkk = jjj.split('=')[-1] + includes.append(kkk.strip()) return includes # Local Variables: diff --git a/src/engine/SCons/Scanner/DTests.py b/src/engine/SCons/Scanner/DTests.py new file mode 100644 index 0000000..51e527a --- /dev/null +++ b/src/engine/SCons/Scanner/DTests.py @@ -0,0 +1,282 @@ +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +import unittest + +import TestCmd +import TestUnit + +import SCons.Scanner.D + +test = TestCmd.TestCmd(workdir = '') + +import collections +import os + +class DummyEnvironment(collections.UserDict): + def __init__(self, **kw): + collections.UserDict.__init__(self) + self.data.update(kw) + self.fs = SCons.Node.FS.FS(test.workpath('')) + + def Dictionary(self, *args): + return self.data + + def subst(self, strSubst, target=None, source=None, conv=None): + if strSubst[0] == '$': + return self.data[strSubst[1:]] + return strSubst + + def subst_list(self, strSubst, target=None, source=None, conv=None): + if strSubst[0] == '$': + return [self.data[strSubst[1:]]] + return [[strSubst]] + + def subst_path(self, path, target=None, source=None, conv=None): + if not isinstance(path, list): + path = [path] + return list(map(self.subst, path)) + + def get_calculator(self): + return None + + def get_factory(self, factory): + return factory or self.fs.File + + def Dir(self, filename): + return self.fs.Dir(filename) + + def File(self, filename): + return self.fs.File(filename) + +if os.path.normcase('foo') == os.path.normcase('FOO'): + my_normpath = os.path.normcase +else: + my_normpath = os.path.normpath + +def deps_match(self, deps, headers): + global my_normpath + scanned = list(map(my_normpath, list(map(str, deps)))) + expect = list(map(my_normpath, headers)) + self.failUnless(scanned == expect, "expect %s != scanned %s" % (expect, scanned)) + +""" +Examples from https://dlang.org/spec/module.html + +D Language: 2.071.1 +Accessed: 11 August 2016 +""" + +# Regular import +test.write('basic.d',""" +import A; + +void main() {} +""") + +# Static import +test.write('static.d',""" +static import A; + +void main() +{ + std.stdio.writeln("hello!"); // ok, writeln is fully qualified +} +""") + +# Public import +test.write('public.d',""" +public import A; + +void main() {} +""") + +# Renamed import +test.write('rename.d',""" +import B = A; + +void main() +{ + io.writeln("hello!"); // ok, calls std.stdio.writeln +} +""") + +# Selective import +test.write('selective.d',""" +import A : B, C; + +void main() +{ + writeln("hello!"); // ok, writeln bound into current namespace + foo("world"); // ok, calls std.stdio.write() +} +""") + +# Renamed and Selective import +test.write('renameAndSelective.d',""" +import B = A : C = D; + +void main() +{ +} +""") + +# Scoped import +test.write('scoped.d',""" +void main() +{ + import A; +} +""") + +# Combinatorial import +test.write('combinatorial.d',""" +import A, B, CCC = C, DDD = D : EEE = FFF; + +void main() +{ +} +""") + +# Subdirs import +test.write('subdirs.d',""" +import X.Y, X.Z, X.X.X; + +void main() {} +""") + +# Multiple import +test.write('multiple.d',""" +public import B; +static import C; + +import X = X.Y : Q, R, S, T = U; +void main() +{ + import A; +} +""") + +# Multiline import +test.write('multiline.d',""" +import +A; + +void main() {} +""") + +test.write('A.d',""" +module A; +void main() {} +""") + +test.write('B.d',""" +module B; +void main() {} +""") + +test.write('C.d',""" +module C; +void main() {} +""") + +test.write('D.d',""" +module D; +void main() {} +""") + +test.subdir('X', os.path.join('X','X')) + +test.write(os.path.join('X','Y.d'),""" +module Y; +void main() {} +""") + +test.write(os.path.join('X','Z.d'),""" +module Z; +void main() {} +""") + +test.write(os.path.join('X','X','X.d'),""" +module X; +void main() {} +""") + +class DScannerTestCase(unittest.TestCase): + def helper(self, filename, headers): + env = DummyEnvironment() + s = SCons.Scanner.D.DScanner() + path = s.path(env) + deps = s(env.File(filename), env, path) + deps_match(self, deps, headers) + + def test_BasicImport(self): + self.helper('basic.d', ['A.d']) + + def test_StaticImport(self): + self.helper('static.d', ['A.d']) + + def test_publicImport(self): + self.helper('public.d', ['A.d']) + + def test_RenameImport(self): + self.helper('rename.d', ['A.d']) + + def test_SelectiveImport(self): + self.helper('selective.d', ['A.d']) + + def test_RenameAndSelectiveImport(self): + self.helper('renameAndSelective.d', ['A.d']) + + def test_ScopedImport(self): + self.helper('scoped.d', ['A.d']) + + def test_CombinatorialImport(self): + self.helper('combinatorial.d', ['A.d', 'B.d', 'C.d', 'D.d']) + + def test_SubdirsImport(self): + self.helper('subdirs.d', [os.path.join('X','X','X.d'), os.path.join('X','Y.d'), os.path.join('X','Z.d')]) + + def test_MultipleImport(self): + self.helper('multiple.d', ['A.d', 'B.d', 'C.d', os.path.join('X','Y.d')]) + + def test_MultilineImport(self): + self.helper('multiline.d', ['A.d']) + +if __name__ == "__main__": + suite = unittest.TestSuite() + tclasses = [ + DScannerTestCase, + ] + for tclass in tclasses: + names = unittest.getTestCaseNames(tclass, 'test_') + suite.addTests(list(map(tclass, names))) + TestUnit.run(suite) + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Scanner/LaTeX.py b/src/engine/SCons/Scanner/LaTeX.py index 2cb1ed5..1e0fea1 100644 --- a/src/engine/SCons/Scanner/LaTeX.py +++ b/src/engine/SCons/Scanner/LaTeX.py @@ -200,14 +200,14 @@ class LaTeX(SCons.Scanner.Base): """ def __init__(self, dictionary): self.dictionary = {} - for k,n in dictionary.items(): + for k,n in list(dictionary.items()): self.dictionary[k] = ( SCons.Scanner.FindPathDirs(n), FindENVPathDirs(n) ) def __call__(self, env, dir=None, target=None, source=None, argument=None): di = {} - for k,(c,cENV) in self.dictionary.items(): + for k,(c,cENV) in list(self.dictionary.items()): di[k] = ( c(env, dir=None, target=None, source=None, argument=None) , cENV(env, dir=None, target=None, source=None, diff --git a/src/engine/SCons/Script/Interactive.py b/src/engine/SCons/Script/Interactive.py index e7a0658..3c3d23a 100644 --- a/src/engine/SCons/Script/Interactive.py +++ b/src/engine/SCons/Script/Interactive.py @@ -121,7 +121,7 @@ class SConsInteractiveCmd(cmd.Cmd): def __init__(self, **kw): cmd.Cmd.__init__(self) - for key, val in kw.items(): + for key, val in list(kw.items()): setattr(self, key, val) if sys.platform == 'win32': @@ -250,7 +250,7 @@ class SConsInteractiveCmd(cmd.Cmd): while n: n = walker.get_next() - for node in seen_nodes.keys(): + for node in list(seen_nodes.keys()): # Call node.clear() to clear most of the state node.clear() # node.clear() doesn't reset node.state, so call diff --git a/src/engine/SCons/Script/Main.py b/src/engine/SCons/Script/Main.py index c0b22a7..f8cb24c 100644 --- a/src/engine/SCons/Script/Main.py +++ b/src/engine/SCons/Script/Main.py @@ -727,7 +727,7 @@ def _load_site_scons_dir(topdir, site_dir_name=None): modname = os.path.basename(pathname)[:-len(sfx)] site_m = {"__file__": pathname, "__name__": modname, "__doc__": None} re_special = re.compile("__[^_]+__") - for k in m.__dict__.keys(): + for k in list(m.__dict__.keys()): if not re_special.match(k): site_m[k] = m.__dict__[k] diff --git a/src/engine/SCons/Script/SConsOptions.py b/src/engine/SCons/Script/SConsOptions.py index b2f2858..501e4ce 100644 --- a/src/engine/SCons/Script/SConsOptions.py +++ b/src/engine/SCons/Script/SConsOptions.py @@ -638,7 +638,7 @@ def Parser(version): for value in value__.split(','): if value in debug_options: parser.values.debug.append(value) - elif value in deprecated_debug_options.keys(): + elif value in list(deprecated_debug_options.keys()): parser.values.debug.append(value) try: parser.values.delayed_warnings diff --git a/src/engine/SCons/Script/SConscript.py b/src/engine/SCons/Script/SConscript.py index 6480ace..a7c8a37 100644 --- a/src/engine/SCons/Script/SConscript.py +++ b/src/engine/SCons/Script/SConscript.py @@ -526,7 +526,7 @@ class SConsEnvironment(SCons.Environment.Base): return x ls = list(map(subst_element, ls)) subst_kw = {} - for key, val in kw.items(): + for key, val in list(kw.items()): if SCons.Util.is_String(val): val = self.subst(val) elif SCons.Util.is_List(val): diff --git a/src/engine/SCons/Taskmaster.py b/src/engine/SCons/Taskmaster.py index 0f4fd21..461a556 100644 --- a/src/engine/SCons/Taskmaster.py +++ b/src/engine/SCons/Taskmaster.py @@ -479,7 +479,7 @@ class Task(object): if p.ref_count == 0: self.tm.candidates.append(p) - for p, subtract in parents.items(): + for p, subtract in list(parents.items()): p.ref_count = p.ref_count - subtract if T: T.write(self.trace_message(u'Task.postprocess()', p, diff --git a/src/engine/SCons/Tool/MSCommon/common.py b/src/engine/SCons/Tool/MSCommon/common.py index bcfee2b..b14eba1 100644 --- a/src/engine/SCons/Tool/MSCommon/common.py +++ b/src/engine/SCons/Tool/MSCommon/common.py @@ -114,7 +114,7 @@ def normalize_env(env, keys, force=False): Note: the environment is copied.""" normenv = {} if env: - for k in env.keys(): + for k in list(env.keys()): normenv[k] = copy.deepcopy(env[k]) for k in keys: @@ -219,7 +219,7 @@ def parse_output(output, keep = ("INCLUDE", "LIB", "LIBPATH", "PATH")): dkeep[key].append(p) for line in output.splitlines(): - for k,v in rdk.items(): + for k,v in list(rdk.items()): m = v.match(line) if m: add_env(m, k) diff --git a/src/engine/SCons/Tool/MSCommon/vc.py b/src/engine/SCons/Tool/MSCommon/vc.py index f96b8ca..baa4025 100644 --- a/src/engine/SCons/Tool/MSCommon/vc.py +++ b/src/engine/SCons/Tool/MSCommon/vc.py @@ -514,7 +514,7 @@ def msvc_setup_env(env): SCons.Warnings.warn(SCons.Warnings.VisualCMissingWarning, warn_msg) return None - for k, v in d.items(): + for k, v in list(d.items()): debug('vc.py:msvc_setup_env() env:%s -> %s'%(k,v)) env.PrependENVPath(k, v, delete_existing=True) diff --git a/src/engine/SCons/Tool/MSCommon/vs.py b/src/engine/SCons/Tool/MSCommon/vs.py index 31197ef..4bda406 100644 --- a/src/engine/SCons/Tool/MSCommon/vs.py +++ b/src/engine/SCons/Tool/MSCommon/vs.py @@ -545,7 +545,7 @@ def msvs_setup_env(env): env['ENV'] = save_ENV vars = parse_output(output, vars) - for k, v in vars.items(): + for k, v in list(vars.items()): env.PrependENVPath(k, v, delete_existing=1) def query_versions(): diff --git a/src/engine/SCons/Tool/aixlink.py b/src/engine/SCons/Tool/aixlink.py index bfddf0a..3117c55 100644 --- a/src/engine/SCons/Tool/aixlink.py +++ b/src/engine/SCons/Tool/aixlink.py @@ -65,7 +65,7 @@ def exists(env): # TODO: sync with link.smart_link() to choose a linker linkers = { 'CXX': ['aixc++'], 'CC': ['aixcc'] } alltools = [] - for langvar, linktools in linkers.items(): + for langvar, linktools in list(linkers.items()): if langvar in env: # use CC over CXX when user specified CC but not CXX return SCons.Tool.FindTool(linktools, env) alltools.extend(linktools) diff --git a/src/engine/SCons/Tool/docbook/__init__.py b/src/engine/SCons/Tool/docbook/__init__.py index 2b22e17..8a7b2e7 100644 --- a/src/engine/SCons/Tool/docbook/__init__.py +++ b/src/engine/SCons/Tool/docbook/__init__.py @@ -461,7 +461,7 @@ def DocbookEpub(env, target, source=None, *args, **kw): # Create xpath context xpath_context = doc.xpathNewContext() # Register namespaces - for key, val in nsmap.iteritems(): + for key, val in nsmap.items(): xpath_context.xpathRegisterNs(key, val) if hasattr(opf, 'xpathEval') and xpath_context: diff --git a/src/engine/SCons/Tool/gnulink.py b/src/engine/SCons/Tool/gnulink.py index b1d5088..cf1ce85 100644 --- a/src/engine/SCons/Tool/gnulink.py +++ b/src/engine/SCons/Tool/gnulink.py @@ -67,7 +67,7 @@ def exists(env): # TODO: sync with link.smart_link() to choose a linker linkers = { 'CXX': ['g++'], 'CC': ['gcc'] } alltools = [] - for langvar, linktools in linkers.items(): + for langvar, linktools in list(linkers.items()): if langvar in env: # use CC over CXX when user specified CC but not CXX return SCons.Tool.FindTool(linktools, env) alltools.extend(linktools) diff --git a/src/engine/SCons/Tool/install.py b/src/engine/SCons/Tool/install.py index e16bb5f..ee15753 100644 --- a/src/engine/SCons/Tool/install.py +++ b/src/engine/SCons/Tool/install.py @@ -244,7 +244,7 @@ def add_versioned_targets_to_INSTALLED_FILES(target, source, env): Verbose = False _INSTALLED_FILES.extend(target) if Verbose: - print("add_versioned_targets_to_INSTALLED_FILES: target={:r}".format(map(str, target))) + print("add_versioned_targets_to_INSTALLED_FILES: target={:r}".format(list(map(str, target)))) symlinks = listShlibLinksToInstall(target[0], source, env) if symlinks: SCons.Tool.EmitLibSymlinks(env, symlinks, target[0]) diff --git a/src/engine/SCons/Tool/intelc.py b/src/engine/SCons/Tool/intelc.py index b39cae5..02da912 100644 --- a/src/engine/SCons/Tool/intelc.py +++ b/src/engine/SCons/Tool/intelc.py @@ -500,14 +500,14 @@ def generate(env, version=None, abi=None, topdir=None, verbose=0): 'LIB' : libdir, 'PATH' : bindir, 'LD_LIBRARY_PATH' : libdir} - for p in paths.keys(): + for p in list(paths.keys()): env.PrependENVPath(p, os.path.join(topdir, paths[p])) if is_mac: paths={'INCLUDE' : 'include', 'LIB' : libdir, 'PATH' : bindir, 'LD_LIBRARY_PATH' : libdir} - for p in paths.keys(): + for p in list(paths.keys()): env.PrependENVPath(p, os.path.join(topdir, paths[p])) if is_windows: # env key reg valname default subdir of top diff --git a/src/engine/SCons/Tool/msvs.py b/src/engine/SCons/Tool/msvs.py index 6e91909..50f6b27 100644 --- a/src/engine/SCons/Tool/msvs.py +++ b/src/engine/SCons/Tool/msvs.py @@ -54,6 +54,7 @@ import SCons.Warnings from .MSCommon import msvc_exists, msvc_setup_env_once from SCons.Defaults import processDefines +from SCons.compat import PICKLE_PROTOCOL ############################################################################## # Below here are the classes and functions for generation of @@ -209,11 +210,11 @@ class _UserGenerator(object): dbg_settings and bool([ds for ds in dbg_settings if ds]) if self.createfile: - dbg_settings = dict(zip(variants, dbg_settings)) - for var, src in dbg_settings.items(): + dbg_settings = dict(list(zip(variants, dbg_settings))) + for var, src in list(dbg_settings.items()): # Update only expected keys trg = {} - for key in [k for k in self.usrdebg.keys() if k in src]: + for key in [k for k in list(self.usrdebg.keys()) if k in src]: trg[key] = str(src[key]) self.configs[var].debug = trg @@ -300,7 +301,7 @@ class _GenerateV7User(_UserGenerator): debug = self.configs[kind].debug if debug: debug_settings = '\n'.join(['\t\t\t\t%s="%s"' % (key, xmlify(value)) - for key, value in debug.items() + for key, value in list(debug.items()) if value is not None]) self.usrfile.write(self.usrconf % locals()) self.usrfile.write('\t</Configurations>\n</VisualStudioUserFile>') @@ -362,7 +363,7 @@ class _GenerateV10User(_UserGenerator): debug = self.configs[kind].debug if debug: debug_settings = '\n'.join(['\t\t<%s>%s</%s>' % (key, xmlify(value), key) - for key, value in debug.items() + for key, value in list(debug.items()) if value is not None]) self.usrfile.write(self.usrconf % locals()) self.usrfile.write('</Project>') @@ -532,7 +533,7 @@ class _DSPGenerator(object): AddConfig(self, variants[i], buildtarget[i], outdir[i], runfile[i], cmdargs[i]) self.platforms = [] - for key in self.configs.keys(): + for key in list(self.configs.keys()): platform = self.configs[key].platform if not platform in self.platforms: self.platforms.append(platform) @@ -641,10 +642,10 @@ class _GenerateV6DSP(_DSPGenerator): if self.nokeep == 0: # now we pickle some data and add it to the file -- MSDEV will ignore it. - pdata = pickle.dumps(self.configs,1) + pdata = pickle.dumps(self.configs,PICKLE_PROTOCOL) pdata = base64.encodestring(pdata) self.file.write(pdata + '\n') - pdata = pickle.dumps(self.sources,1) + pdata = pickle.dumps(self.sources,PICKLE_PROTOCOL) pdata = base64.encodestring(pdata) self.file.write(pdata + '\n') @@ -655,7 +656,7 @@ class _GenerateV6DSP(_DSPGenerator): 'Resource Files': 'r|rc|ico|cur|bmp|dlg|rc2|rct|bin|cnt|rtf|gif|jpg|jpeg|jpe', 'Other Files': ''} - for kind in sorted(categories.keys(), key=lambda a: a.lower()): + for kind in sorted(list(categories.keys()), key=lambda a: a.lower()): if not self.sources[kind]: continue # skip empty groups @@ -913,15 +914,15 @@ class _GenerateV7DSP(_DSPGenerator, _GenerateV7User): if self.nokeep == 0: # now we pickle some data and add it to the file -- MSDEV will ignore it. - pdata = pickle.dumps(self.configs,1) + pdata = pickle.dumps(self.configs,PICKLE_PROTOCOL) pdata = base64.encodestring(pdata) self.file.write('<!-- SCons Data:\n' + pdata + '\n') - pdata = pickle.dumps(self.sources,1) + pdata = pickle.dumps(self.sources,PICKLE_PROTOCOL) pdata = base64.encodestring(pdata) self.file.write(pdata + '-->\n') def printSources(self, hierarchy, commonprefix): - sorteditems = sorted(hierarchy.items(), key=lambda a: a[0].lower()) + sorteditems = sorted(list(hierarchy.items()), key=lambda a: a[0].lower()) # First folders, then files for key, value in sorteditems: @@ -951,7 +952,7 @@ class _GenerateV7DSP(_DSPGenerator, _GenerateV7User): self.file.write('\t<Files>\n') - cats = sorted([k for k in categories.keys() if self.sources[k]], + cats = sorted([k for k in list(categories.keys()) if self.sources[k]], key=lambda a: a.lower()) for kind in cats: if len(cats) > 1: @@ -1232,15 +1233,15 @@ class _GenerateV10DSP(_DSPGenerator, _GenerateV10User): if self.nokeep == 0: # now we pickle some data and add it to the file -- MSDEV will ignore it. - pdata = pickle.dumps(self.configs,1) + pdata = pickle.dumps(self.configs,PICKLE_PROTOCOL) pdata = base64.encodestring(pdata) self.file.write('<!-- SCons Data:\n' + pdata + '\n') - pdata = pickle.dumps(self.sources,1) + pdata = pickle.dumps(self.sources,PICKLE_PROTOCOL) pdata = base64.encodestring(pdata) self.file.write(pdata + '-->\n') def printFilters(self, hierarchy, name): - sorteditems = sorted(hierarchy.items(), key = lambda a: a[0].lower()) + sorteditems = sorted(list(hierarchy.items()), key = lambda a: a[0].lower()) for key, value in sorteditems: if SCons.Util.is_Dict(value): @@ -1257,7 +1258,7 @@ class _GenerateV10DSP(_DSPGenerator, _GenerateV10User): 'Resource Files': 'None', 'Other Files': 'None'} - sorteditems = sorted(hierarchy.items(), key = lambda a: a[0].lower()) + sorteditems = sorted(list(hierarchy.items()), key = lambda a: a[0].lower()) # First folders, then files for key, value in sorteditems: @@ -1283,7 +1284,7 @@ class _GenerateV10DSP(_DSPGenerator, _GenerateV10User): 'Resource Files': 'r;rc;ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe', 'Other Files': ''} - cats = sorted([k for k in categories.keys() if self.sources[k]], + cats = sorted([k for k in list(categories.keys()) if self.sources[k]], key = lambda a: a.lower()) # print vcxproj.filters file first @@ -1441,7 +1442,7 @@ class _GenerateV7DSW(_DSWGenerator): AddConfig(self, variant) self.platforms = [] - for key in self.configs.keys(): + for key in list(self.configs.keys()): platform = self.configs[key].platform if not platform in self.platforms: self.platforms.append(platform) @@ -1606,7 +1607,7 @@ class _GenerateV7DSW(_DSWGenerator): '\tEndGlobalSection\n') self.file.write('EndGlobal\n') if self.nokeep == 0: - pdata = pickle.dumps(self.configs,1) + pdata = pickle.dumps(self.configs,PICKLE_PROTOCOL) pdata = base64.encodestring(pdata) self.file.write(pdata + '\n') diff --git a/src/engine/SCons/Tool/msvsTests.py b/src/engine/SCons/Tool/msvsTests.py index 2bd640f..bf82114 100644 --- a/src/engine/SCons/Tool/msvsTests.py +++ b/src/engine/SCons/Tool/msvsTests.py @@ -624,7 +624,7 @@ class msvsTestCase(unittest.TestCase): tests_cmdargs = [(None, dict.fromkeys(list_variant, '')), ('', dict.fromkeys(list_variant, '')), (list_cmdargs[0], dict.fromkeys(list_variant, list_cmdargs[0])), - (list_cmdargs, dict(zip(list_variant, list_cmdargs)))] + (list_cmdargs, dict(list(zip(list_variant, list_cmdargs))))] # Run the test for each test case for param_cmdargs, expected_cmdargs in tests_cmdargs: @@ -651,8 +651,8 @@ class msvsTestCase(unittest.TestCase): 'cmdargs': expected_cmdargs[variant_platform]} # Create parameter environment with final parameter dictionary - param_dict = dict(zip(('variant', 'runfile', 'buildtarget', 'outdir'), - [list(l) for l in zip(*param_configs)])) + param_dict = dict(list(zip(('variant', 'runfile', 'buildtarget', 'outdir'), + [list(l) for l in zip(*param_configs)]))) param_dict['cmdargs'] = param_cmdargs # Hack to be able to run the test with a 'DummyEnv' @@ -668,8 +668,8 @@ class msvsTestCase(unittest.TestCase): genDSP = function_test(dspfile, source, env) # Check expected result - self.assertListEqual(genDSP.configs.keys(), expected_configs.keys()) - for key in genDSP.configs.keys(): + self.assertListEqual(list(genDSP.configs.keys()), list(expected_configs.keys())) + for key in list(genDSP.configs.keys()): self.assertDictEqual(genDSP.configs[key].__dict__, expected_configs[key]) class msvs6aTestCase(msvsTestCase): diff --git a/src/engine/SCons/Tool/packaging/__init__.py b/src/engine/SCons/Tool/packaging/__init__.py index 1a95abe..1727938 100644 --- a/src/engine/SCons/Tool/packaging/__init__.py +++ b/src/engine/SCons/Tool/packaging/__init__.py @@ -72,7 +72,7 @@ def Tag(env, target, source, *more_tags, **kw_tags): target=env.Flatten(target) for t in target: - for (k,v) in kw_tags.items(): + for (k,v) in list(kw_tags.items()): # all file tags have to start with PACKAGING_, so we can later # differentiate between "normal" object attributes and the # packaging attributes. As the user should not be bothered with diff --git a/src/engine/SCons/Tool/packaging/ipk.py b/src/engine/SCons/Tool/packaging/ipk.py index c666033..ad4fe0f 100644 --- a/src/engine/SCons/Tool/packaging/ipk.py +++ b/src/engine/SCons/Tool/packaging/ipk.py @@ -169,7 +169,7 @@ Description: $X_IPK_DESCRIPTION # # close all opened files - for f in opened_files.values(): + for f in list(opened_files.values()): f.close() # call a user specified function diff --git a/src/engine/SCons/Tool/packaging/msi.py b/src/engine/SCons/Tool/packaging/msi.py index c25f856..73d3567 100644 --- a/src/engine/SCons/Tool/packaging/msi.py +++ b/src/engine/SCons/Tool/packaging/msi.py @@ -172,7 +172,7 @@ def generate_guids(root): # find all XMl nodes matching the key, retrieve their attribute, hash their # subtree, convert hash to string and add as a attribute to the xml node. - for (key,value) in needs_id.items(): + for (key,value) in list(needs_id.items()): node_list = root.getElementsByTagName(key) attribute = value for node in node_list: @@ -335,7 +335,7 @@ def build_wxsfile_file_section(root, files, NAME, VERSION, VENDOR, filename_set, } # fill in the default tags given above. - for k,v in [ (k, v) for (k,v) in h.items() if not hasattr(file, k) ]: + for k,v in [ (k, v) for (k,v) in list(h.items()) if not hasattr(file, k) ]: setattr( file, k, v ) File = factory.createElement( 'File' ) @@ -382,7 +382,7 @@ def build_wxsfile_features_section(root, files, NAME, VERSION, SUMMARY, id_set): Feature.attributes['Description'] = escape( SUMMARY ) Feature.attributes['Display'] = 'expand' - for (feature, files) in create_feature_dict(files).items(): + for (feature, files) in list(create_feature_dict(files).items()): SubFeature = factory.createElement('Feature') SubFeature.attributes['Level'] = '1' diff --git a/src/engine/SCons/Tool/packaging/rpm.py b/src/engine/SCons/Tool/packaging/rpm.py index eac3c43..0931c77 100644 --- a/src/engine/SCons/Tool/packaging/rpm.py +++ b/src/engine/SCons/Tool/packaging/rpm.py @@ -95,6 +95,8 @@ def collectintargz(target, source, env): # find the .spec file for rpm and add it since it is not necessarily found # by the FindSourceFiles function. sources.extend( [s for s in source if str(s).rfind('.spec')!=-1] ) + # sort to keep sources from changing order across builds + sources.sort() # as the source contains the url of the source package this rpm package # is built from, we extract the target name @@ -269,7 +271,7 @@ def build_specfile_filesection(spec, files): for file in files: # build the tagset tags = {} - for k in supported_tags.keys(): + for k in list(supported_tags.keys()): try: v = file.GetTag(k) if v: @@ -330,7 +332,7 @@ class SimpleTagCompiler(object): international = [t for t in replacements if is_international(t[0])] for key, replacement in international: try: - x = [t for t in values.items() if strip_country_code(t[0]) == key] + x = [t for t in list(values.items()) if strip_country_code(t[0]) == key] int_values_for_key = [(get_country_code(t[0]),t[1]) for t in x] for v in int_values_for_key: str = str + replacement % v diff --git a/src/engine/SCons/Tool/rpmutils.py b/src/engine/SCons/Tool/rpmutils.py index 3eeed1d..d4db417 100644 --- a/src/engine/SCons/Tool/rpmutils.py +++ b/src/engine/SCons/Tool/rpmutils.py @@ -520,7 +520,7 @@ def updateRpmDicts(rpmrc, pyfile): if l.startswith('# Start of rpmrc dictionaries'): pm = 1 # Write data sections to single dictionaries - for key, entries in data.items(): + for key, entries in list(data.items()): out.write("%s = {\n" % key) for arch in sorted(entries.keys()): out.write(" '%s' : ['%s'],\n" % (arch, "','".join(entries[arch]))) diff --git a/src/engine/SCons/Tool/swig.py b/src/engine/SCons/Tool/swig.py index fa86174..9935de8 100644 --- a/src/engine/SCons/Tool/swig.py +++ b/src/engine/SCons/Tool/swig.py @@ -143,7 +143,7 @@ def _get_swig_version(env, swig): # MAYBE: out = SCons.Util.to_str (pipe.stdout.read()) out = pipe.stdout.read() - match = re.search(r'SWIG Version\s+(\S+).*', out, re.MULTILINE) + match = re.search(b'SWIG Version\s+(\S+).*', out, re.MULTILINE) if match: if verbose: print("Version is:%s"%match.group(1)) return match.group(1) diff --git a/src/engine/SCons/Util.py b/src/engine/SCons/Util.py index 0be6196..7653acd 100644 --- a/src/engine/SCons/Util.py +++ b/src/engine/SCons/Util.py @@ -477,7 +477,7 @@ _semi_deepcopy_dispatch = d = {} def semi_deepcopy_dict(x, exclude = [] ): copy = {} - for key, val in x.items(): + for key, val in list(x.items()): # The regular Python copy.deepcopy() also deepcopies the key, # as follows: # @@ -1037,7 +1037,7 @@ class OrderedDict(UserDict): if key not in self._keys: self._keys.append(key) def update(self, dict): - for (key, val) in dict.items(): + for (key, val) in list(dict.items()): self.__setitem__(key, val) def values(self): @@ -1059,7 +1059,7 @@ class Selector(OrderedDict): # Try to perform Environment substitution on the keys of # the dictionary before giving up. s_dict = {} - for (k,v) in self.items(): + for (k,v) in list(self.items()): if k is not None: s_k = env.subst(k) if s_k in s_dict: @@ -1425,14 +1425,22 @@ def AddMethod(obj, function, name=None): else: function = RenameFunction(function, name) + # Note the Python version checks - WLB + # Python 3.3 dropped the 3rd parameter from types.MethodType if hasattr(obj, '__class__') and obj.__class__ is not type: # "obj" is an instance, so it gets a bound method. - method = MethodType(function, obj, obj.__class__) - setattr(obj, name, method) + if sys.version_info[:2] > (3, 2): + method = MethodType(function, obj) + else: + method = MethodType(function, obj, obj.__class__) else: # "obj" is a class, so it gets an unbound method. - function = MethodType(function, None, obj) - setattr(obj, name, function) + if sys.version_info[:2] > (3, 2): + method = MethodType(function, None) + else: + method = MethodType(function, None, obj) + + setattr(obj, name, method) def RenameFunction(function, name): """ @@ -1553,14 +1561,12 @@ del __revision__ def to_bytes (s): if isinstance (s, bytes) or bytes is str: return s - else: - return bytes (s, 'utf-8') + return bytes (s, 'utf-8') def to_str (s): - if bytes is str: + if bytes is str or is_String(s): return s - else: - return str (s, 'utf-8') + return str (s, 'utf-8') # Local Variables: # tab-width:4 diff --git a/src/engine/SCons/Variables/EnumVariableTests.py b/src/engine/SCons/Variables/EnumVariableTests.py index 931dfe2..edc2973 100644 --- a/src/engine/SCons/Variables/EnumVariableTests.py +++ b/src/engine/SCons/Variables/EnumVariableTests.py @@ -124,7 +124,7 @@ class EnumVariableTestCase(unittest.TestCase): 'C' : ['C', 'three', 'three'], } - for k, l in table.items(): + for k, l in list(table.items()): x = o0.converter(k) assert x == l[0], "o0 got %s, expected %s" % (x, l[0]) x = o1.converter(k) @@ -188,7 +188,7 @@ class EnumVariableTestCase(unittest.TestCase): 'no_v' : [invalid, invalid, invalid], } - for v, l in table.items(): + for v, l in list(table.items()): l[0](o0, v) l[1](o1, v) l[2](o2, v) diff --git a/src/engine/SCons/Variables/__init__.py b/src/engine/SCons/Variables/__init__.py index b03e5b5..ce3541c 100644 --- a/src/engine/SCons/Variables/__init__.py +++ b/src/engine/SCons/Variables/__init__.py @@ -185,7 +185,7 @@ class Variables(object): if args is None: args = self.args - for arg, value in args.items(): + for arg, value in list(args.items()): added = False for option in self.options: if arg in list(option.aliases) + [ option.key ]: diff --git a/src/engine/SCons/compat/__init__.py b/src/engine/SCons/compat/__init__.py index 6f20b73..c6c7214 100644 --- a/src/engine/SCons/compat/__init__.py +++ b/src/engine/SCons/compat/__init__.py @@ -88,6 +88,12 @@ def rename_module(new, old): # In 3.x, 'pickle' automatically loads the fast version if available. rename_module('pickle', 'cPickle') +# Default pickle protocol. Higher protocols are more efficient/featureful +# but incompatible with older Python versions. On Python 2.7 this is 2. +# Negative numbers choose the highest available protocol. +import pickle +PICKLE_PROTOCOL=pickle.HIGHEST_PROTOCOL + # TODO: FIXME # In 3.x, 'profile' automatically loads the fast version if available. rename_module('profile', 'cProfile') diff --git a/src/engine/SCons/cpp.py b/src/engine/SCons/cpp.py index 60cfcea..18f154a 100644 --- a/src/engine/SCons/cpp.py +++ b/src/engine/SCons/cpp.py @@ -72,7 +72,7 @@ cpp_lines_dict = { # the corresponding compiled regular expression that fetches the arguments # we care about. Table = {} -for op_list, expr in cpp_lines_dict.items(): +for op_list, expr in list(cpp_lines_dict.items()): e = re.compile(expr) for op in op_list: Table[op] = e @@ -87,7 +87,7 @@ del op_list override = { 'if' : 'if(?!def)', } -l = [override.get(x, x) for x in Table.keys()] +l = [override.get(x, x) for x in list(Table.keys())] # Turn the list of expressions into one big honkin' regular expression @@ -130,7 +130,7 @@ CPP_to_Python_Ops_Sub = lambda m: CPP_to_Python_Ops_Dict[m.group(0)] # re module, as late as version 2.2.2, empirically matches the # "!" in "!=" first, instead of finding the longest match. # What's up with that? -l = sorted(CPP_to_Python_Ops_Dict.keys(), key=lambda a: len(a), reverse=True) +l = sorted(list(CPP_to_Python_Ops_Dict.keys()), key=lambda a: len(a), reverse=True) # Turn the list of keys into one regular expression that will allow us # to substitute all of the operators at once. @@ -266,7 +266,7 @@ class PreProcessor(object): d = { 'scons_current_file' : self.scons_current_file } - for op in Table.keys(): + for op in list(Table.keys()): d[op] = getattr(self, 'do_' + op) self.default_table = d diff --git a/src/engine/SCons/dblite.py b/src/engine/SCons/dblite.py index b12d320..588a7ab 100644 --- a/src/engine/SCons/dblite.py +++ b/src/engine/SCons/dblite.py @@ -2,13 +2,13 @@ # Extended for Unicode by Steven Knight. from __future__ import print_function -import SCons.compat - import os import pickle import shutil import time +from SCons.compat import PICKLE_PROTOCOL + keep_all_files = 00000 ignore_corrupt_dbfiles = 0 @@ -48,6 +48,7 @@ class dblite(object): _open = open _pickle_dump = staticmethod(pickle.dump) + _pickle_protocol = PICKLE_PROTOCOL _os_chmod = os.chmod try: _os_chown = os.chown @@ -119,7 +120,7 @@ class dblite(object): def sync(self): self._check_writable() f = self._open(self._tmp_name, "wb", self._mode) - self._pickle_dump(self._dict, f, 1) + self._pickle_dump(self._dict, f, self._pickle_protocol) f.close() # Windows doesn't allow renaming if the file exists, so unlink # it first, chmod'ing it to make sure we can do so. On UNIX, we |