diff options
Diffstat (limited to 'src/engine/SCons/Node')
-rw-r--r-- | src/engine/SCons/Node/Alias.py | 13 | ||||
-rw-r--r-- | src/engine/SCons/Node/AliasTests.py | 6 | ||||
-rw-r--r-- | src/engine/SCons/Node/FS.py | 248 | ||||
-rw-r--r-- | src/engine/SCons/Node/FSTests.py | 214 | ||||
-rw-r--r-- | src/engine/SCons/Node/NodeTests.py | 127 | ||||
-rw-r--r-- | src/engine/SCons/Node/Python.py | 4 | ||||
-rw-r--r-- | src/engine/SCons/Node/PythonTests.py | 6 | ||||
-rw-r--r-- | src/engine/SCons/Node/__init__.py | 87 |
8 files changed, 295 insertions, 410 deletions
diff --git a/src/engine/SCons/Node/Alias.py b/src/engine/SCons/Node/Alias.py index ff4a47e..291ac4d 100644 --- a/src/engine/SCons/Node/Alias.py +++ b/src/engine/SCons/Node/Alias.py @@ -30,23 +30,22 @@ This creates a hash of global Aliases (dummy targets). # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Node/Alias.py 4720 2010/03/24 03:14:11 jars" +__revision__ = "src/engine/SCons/Node/Alias.py 5023 2010/06/14 22:05:46 scons" -import string -import UserDict +import collections import SCons.Errors import SCons.Node import SCons.Util -class AliasNameSpace(UserDict.UserDict): +class AliasNameSpace(collections.UserDict): def Alias(self, name, **kw): if isinstance(name, SCons.Node.Alias.Alias): return name try: a = self[name] except KeyError: - a = apply(SCons.Node.Alias.Alias, (name,), kw) + a = SCons.Node.Alias.Alias(name, **kw) self[name] = a return a @@ -95,8 +94,8 @@ class Alias(SCons.Node.Node): def get_contents(self): """The contents of an alias is the concatenation of the content signatures of all its sources.""" - childsigs = map(lambda n: n.get_csig(), self.children()) - return string.join(childsigs, '') + childsigs = [n.get_csig() for n in self.children()] + return ''.join(childsigs) def sconsign(self): """An Alias is not recorded in .sconsign files""" diff --git a/src/engine/SCons/Node/AliasTests.py b/src/engine/SCons/Node/AliasTests.py index e7a16b3..56a5564 100644 --- a/src/engine/SCons/Node/AliasTests.py +++ b/src/engine/SCons/Node/AliasTests.py @@ -21,7 +21,7 @@ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Node/AliasTests.py 4720 2010/03/24 03:14:11 jars" +__revision__ = "src/engine/SCons/Node/AliasTests.py 5023 2010/06/14 22:05:46 scons" import sys import unittest @@ -51,7 +51,7 @@ class AliasTestCase(unittest.TestCase): def test_get_contents(self): """Test the get_contents() method """ - class DummyNode: + class DummyNode(object): def __init__(self, contents): self.contents = contents def get_csig(self): @@ -119,7 +119,7 @@ if __name__ == "__main__": ] for tclass in tclasses: names = unittest.getTestCaseNames(tclass, 'test_') - suite.addTests(map(tclass, names)) + suite.addTests(list(map(tclass, names))) if not unittest.TextTestRunner().run(suite).wasSuccessful(): sys.exit(1) diff --git a/src/engine/SCons/Node/FS.py b/src/engine/SCons/Node/FS.py index 10641e9..9298d98 100644 --- a/src/engine/SCons/Node/FS.py +++ b/src/engine/SCons/Node/FS.py @@ -31,73 +31,17 @@ that can be used by scripts or modules looking for the canonical default. # 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__ = "src/engine/SCons/Node/FS.py 4720 2010/03/24 03:14:11 jars" +__revision__ = "src/engine/SCons/Node/FS.py 5023 2010/06/14 22:05:46 scons" -from itertools import izip -import cStringIO import fnmatch import os -import os.path import re import shutil import stat -import string import sys import time - -try: - import codecs -except ImportError: - pass -else: - # TODO(2.2): Remove when 2.3 becomes the minimal supported version. - try: - codecs.BOM_UTF8 - except AttributeError: - codecs.BOM_UTF8 = '\xef\xbb\xbf' - try: - codecs.BOM_UTF16_LE - codecs.BOM_UTF16_BE - except AttributeError: - codecs.BOM_UTF16_LE = '\xff\xfe' - codecs.BOM_UTF16_BE = '\xfe\xff' - - # Provide a wrapper function to handle decoding differences in - # different versions of Python. Normally, we'd try to do this in the - # compat layer (and maybe it still makes sense to move there?) but - # that doesn't provide a way to supply the string class used in - # pre-2.3 Python versions with a .decode() method that all strings - # naturally have. Plus, the 2.[01] encodings behave differently - # enough that we have to settle for a lowest-common-denominator - # wrapper approach. - # - # Note that the 2.[012] implementations below may be inefficient - # because they perform an explicit look up of the encoding for every - # decode, but they're old enough (and we want to stop supporting - # them soon enough) that it's not worth complicating the interface. - # Think of it as additional incentive for people to upgrade... - try: - ''.decode - except AttributeError: - # 2.0 through 2.2: strings have no .decode() method - try: - codecs.lookup('ascii').decode - except AttributeError: - # 2.0 and 2.1: encodings are a tuple of functions, and the - # decode() function returns a (result, length) tuple. - def my_decode(contents, encoding): - return codecs.lookup(encoding)[1](contents)[0] - else: - # 2.2: encodings are an object with methods, and the - # .decode() method returns just the decoded bytes. - def my_decode(contents, encoding): - return codecs.lookup(encoding).decode(contents) - else: - # 2.3 or later: use the .decode() string method - def my_decode(contents, encoding): - return contents.decode(encoding) +import codecs import SCons.Action from SCons.Debug import logInstanceCreation @@ -256,11 +200,11 @@ def set_duplicate(duplicate): } if not duplicate in Valid_Duplicates: - raise SCons.Errors.InternalError, ("The argument of set_duplicate " + raise SCons.Errors.InternalError("The argument of set_duplicate " "should be in Valid_Duplicates") global Link_Funcs Link_Funcs = [] - for func in string.split(duplicate,'-'): + for func in duplicate.split('-'): if link_dict[func]: Link_Funcs.append(link_dict[func]) @@ -334,7 +278,7 @@ def get_MkdirBuilder(): name = "MkdirBuilder") return MkdirBuilder -class _Null: +class _Null(object): pass _null = _Null() @@ -373,25 +317,23 @@ if os.path.normcase("TeSt") == os.path.normpath("TeSt") and not _is_cygwin: return x else: def _my_normcase(x): - return string.upper(x) + return x.upper() -class DiskChecker: +class DiskChecker(object): def __init__(self, type, do, ignore): self.type = type self.do = do self.ignore = ignore - self.set_do() - def set_do(self): - self.__call__ = self.do - def set_ignore(self): - self.__call__ = self.ignore + self.func = do + def __call__(self, *args, **kw): + return self.func(*args, **kw) def set(self, list): if self.type in list: - self.set_do() + self.func = self.do else: - self.set_ignore() + self.func = self.ignore def do_diskcheck_match(node, predicate, errorfmt): result = predicate() @@ -407,7 +349,7 @@ def do_diskcheck_match(node, predicate, errorfmt): except (AttributeError, KeyError): pass if result: - raise TypeError, errorfmt % node.abspath + raise TypeError(errorfmt % node.abspath) def ignore_diskcheck_match(node, predicate, errorfmt): pass @@ -459,11 +401,14 @@ def set_diskcheck(list): dc.set(list) def diskcheck_types(): - return map(lambda dc: dc.type, diskcheckers) + return [dc.type for dc in diskcheckers] class EntryProxy(SCons.Util.Proxy): + + __str__ = SCons.Util.Delegate('__str__') + def __get_abspath(self): entry = self.get() return SCons.Subst.SpecialAttrWrapper(entry.get_abspath(), @@ -497,7 +442,7 @@ class EntryProxy(SCons.Util.Proxy): return self else: entry = self.get() - r = string.replace(entry.get_path(), os.sep, '/') + r = entry.get_path().replace(os.sep, '/') return SCons.Subst.SpecialAttrWrapper(r, entry.name + "_posix") def __get_windows_path(self): @@ -507,7 +452,7 @@ class EntryProxy(SCons.Util.Proxy): return self else: entry = self.get() - r = string.replace(entry.get_path(), os.sep, '\\') + r = entry.get_path().replace(os.sep, '\\') return SCons.Subst.SpecialAttrWrapper(r, entry.name + "_windows") def __get_srcnode(self): @@ -620,8 +565,8 @@ class Base(SCons.Node.Node): """ if isinstance(self, klass) or klass is Entry: return - raise TypeError, "Tried to lookup %s '%s' as a %s." %\ - (self.__class__.__name__, self.path, klass.__name__) + raise TypeError("Tried to lookup %s '%s' as a %s." %\ + (self.__class__.__name__, self.path, klass.__name__)) def get_dir(self): return self.dir @@ -647,7 +592,7 @@ class Base(SCons.Node.Node): return self._memo['_save_str'] except KeyError: pass - result = intern(self._get_str()) + result = sys.intern(self._get_str()) self._memo['_save_str'] = result return result @@ -753,8 +698,8 @@ class Base(SCons.Node.Node): try: i = path_elems.index(dir) except ValueError: pass else: path_elems = path_elems[i+1:] - path_elems = map(lambda n: n.name, path_elems) - return string.join(path_elems, os.sep) + path_elems = [n.name for n in path_elems] + return os.sep.join(path_elems) def set_src_builder(self, builder): """Set the source code builder for this node.""" @@ -911,7 +856,7 @@ class Entry(Base): self._morph() elif must_exist: msg = "No such file or directory: '%s'" % self.abspath - raise SCons.Errors.UserError, msg + raise SCons.Errors.UserError(msg) else: self.__class__ = File self._morph() @@ -990,7 +935,7 @@ class Entry(Base): def rel_path(self, other): d = self.disambiguate() if d.__class__ is Entry: - raise "rel_path() could not disambiguate File/Dir" + raise Exception("rel_path() could not disambiguate File/Dir") return d.rel_path(other) def new_ninfo(self): @@ -1010,7 +955,7 @@ class Entry(Base): _classEntry = Entry -class LocalFS: +class LocalFS(object): if SCons.Memoize.use_memoizer: __metaclass__ = SCons.Memoize.Memoized_Metaclass @@ -1249,7 +1194,7 @@ class FS(LocalFS): root = directory.root if os.sep != '/': - p = string.replace(p, os.sep, '/') + p = p.replace(os.sep, '/') return root._lookup_abs(p, fsclass, create) def Entry(self, name, directory = None, create = 1): @@ -1294,11 +1239,11 @@ class FS(LocalFS): if not isinstance(variant_dir, SCons.Node.Node): variant_dir = self.Dir(variant_dir) if src_dir.is_under(variant_dir): - raise SCons.Errors.UserError, "Source directory cannot be under variant directory." + raise SCons.Errors.UserError("Source directory cannot be under variant directory.") if variant_dir.srcdir: if variant_dir.srcdir == src_dir: return # We already did this. - raise SCons.Errors.UserError, "'%s' already has a source directory: '%s'."%(variant_dir, variant_dir.srcdir) + raise SCons.Errors.UserError("'%s' already has a source directory: '%s'."%(variant_dir, variant_dir.srcdir)) variant_dir.link(src_dir, duplicate) def Repository(self, *dirs): @@ -1327,12 +1272,12 @@ class FS(LocalFS): if start_dir.is_under(bd): # If already in the build-dir location, don't reflect return [orig], fmt % str(orig) - p = apply(os.path.join, [bd.path] + tail) + p = os.path.join(bd.path, *tail) targets.append(self.Entry(p)) tail = [dir.name] + tail dir = dir.up() if targets: - message = fmt % string.join(map(str, targets)) + message = fmt % ' '.join(map(str, targets)) return targets, message def Glob(self, pathname, ondisk=True, source=True, strings=False, cwd=None): @@ -1574,9 +1519,9 @@ class Dir(Base): i = self.path_elements.index(other) + 1 path_elems = ['..'] * (len(self.path_elements) - i) \ - + map(lambda n: n.name, other.path_elements[i:]) + + [n.name for n in other.path_elements[i:]] - result = string.join(path_elems, os.sep) + result = os.sep.join(path_elems) memo_dict[other] = result @@ -1622,7 +1567,7 @@ class Dir(Base): """A null "builder" for directories.""" global MkdirBuilder if self.builder is not MkdirBuilder: - apply(SCons.Node.Node.build, [self,], kw) + SCons.Node.Node.build(self, **kw) # # @@ -1641,7 +1586,7 @@ class Dir(Base): if p is None: # Don't use while: - else: for this condition because # if so, then parent is None and has no .path attribute. - raise SCons.Errors.StopError, parent.path + raise SCons.Errors.StopError(parent.path) parent = p listDirs.reverse() for dirnode in listDirs: @@ -1682,12 +1627,9 @@ class Dir(Base): """Return content signatures and names of all our children separated by new-lines. Ensure that the nodes are sorted.""" contents = [] - name_cmp = lambda a, b: cmp(a.name, b.name) - sorted_children = self.children()[:] - sorted_children.sort(name_cmp) - for node in sorted_children: + for node in sorted(self.children(), key=lambda t: t.name): contents.append('%s %s\n' % (node.get_csig(), node.name)) - return string.join(contents, '') + return ''.join(contents) def get_csig(self): """Compute the content signature for Directory nodes. In @@ -1783,7 +1725,7 @@ class Dir(Base): d[name] = result return result else: - return d.has_key(name) + return name in d memoizer_counters.append(SCons.Memoize.CountValue('srcdir_list')) @@ -1911,12 +1853,11 @@ class Dir(Base): in any way (or ignored, passing None is common). """ entries = self.entries - names = entries.keys() + names = list(entries.keys()) names.remove('.') names.remove('..') func(arg, self, names) - select_dirs = lambda n, e=entries: isinstance(e[n], Dir) - for dirname in filter(select_dirs, names): + for dirname in [n for n in names if isinstance(entries[n], Dir)]: entries[dirname].walk(func, arg) def glob(self, pathname, ondisk=True, source=False, strings=False): @@ -1953,9 +1894,8 @@ class Dir(Base): """ dirname, basename = os.path.split(pathname) if not dirname: - result = self._glob1(basename, ondisk, source, strings) - result.sort(lambda a, b: cmp(str(a), str(b))) - return result + return sorted(self._glob1(basename, ondisk, source, strings), + key=lambda t: str(t)) if has_glob_magic(dirname): list = self.glob(dirname, ondisk, source, strings=False) else: @@ -1964,10 +1904,9 @@ class Dir(Base): for dir in list: r = dir._glob1(basename, ondisk, source, strings) if strings: - r = map(lambda x, d=str(dir): os.path.join(d, x), r) + r = [os.path.join(str(dir), x) for x in r] result.extend(r) - result.sort(lambda a, b: cmp(str(a), str(b))) - return result + return sorted(result, key=lambda a: str(a)) def _glob1(self, pattern, ondisk=True, source=False, strings=False): """ @@ -1990,9 +1929,8 @@ 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() if k not in ('.', '..') ] - entry_names = filter(lambda n: n not in ('.', '..'), dir.entries.keys()) - node_names = map(lambda n, e=dir.entries: e[n].name, entry_names) + node_names = [ v.name for k, v in dir.entries.items() + if k not in ('.', '..') ] names.extend(node_names) if not strings: # Make sure the working directory (self) actually has @@ -2015,7 +1953,7 @@ class Dir(Base): # after we exit this loop. if pattern[0] != '.': #disk_names = [ d for d in disk_names if d[0] != '.' ] - disk_names = filter(lambda x: x[0] != '.', disk_names) + disk_names = [x for x in disk_names if x[0] != '.'] disk_names = fnmatch.filter(disk_names, pattern) dirEntry = dir.Entry for name in disk_names: @@ -2031,14 +1969,14 @@ class Dir(Base): names = set(names) if pattern[0] != '.': #names = [ n for n in names if n[0] != '.' ] - names = filter(lambda x: x[0] != '.', names) + names = [x for x in names if x[0] != '.'] names = fnmatch.filter(names, pattern) if strings: return names #return [ self.entries[_my_normcase(n)] for n in names ] - return map(lambda n, e=self.entries: e[_my_normcase(n)], names) + return [self.entries[_my_normcase(n)] for n in names] class RootDir(Dir): """A class for the root directory of a file system. @@ -2111,7 +2049,7 @@ class RootDir(Dir): except KeyError: if not create: msg = "No such file or directory: '%s' in '%s' (and create is False)" % (p, str(self)) - raise SCons.Errors.UserError, msg + raise SCons.Errors.UserError(msg) # There is no Node for this path name, and we're allowed # to create it. dir_name, file_name = os.path.split(p) @@ -2200,7 +2138,7 @@ class FileBuildInfo(SCons.Node.BuildInfoBase): except AttributeError: s = str(n) else: - s = string.replace(s, os.sep, '/') + s = s.replace(os.sep, '/') return s for attr in ['bsources', 'bdepends', 'bimplicit']: try: @@ -2208,7 +2146,7 @@ class FileBuildInfo(SCons.Node.BuildInfoBase): except AttributeError: pass else: - setattr(self, attr, map(node_to_str, val)) + setattr(self, attr, list(map(node_to_str, val))) def convert_from_sconsign(self, dir, name): """ Converts a newly-read FileBuildInfo object for in-SCons use @@ -2238,7 +2176,7 @@ class FileBuildInfo(SCons.Node.BuildInfoBase): except AttributeError: continue nodes = [] - for s, ni in izip(strings, nodeinfos): + for s, ni in zip(strings, nodeinfos): if not isinstance(s, SCons.Node.Node): s = ni.str_to_node(s) nodes.append(s) @@ -2247,11 +2185,11 @@ class FileBuildInfo(SCons.Node.BuildInfoBase): result = [] bkids = self.bsources + self.bdepends + self.bimplicit bkidsigs = self.bsourcesigs + self.bdependsigs + self.bimplicitsigs - for bkid, bkidsig in izip(bkids, bkidsigs): + for bkid, bkidsig in zip(bkids, bkidsigs): result.append(str(bkid) + ': ' + - string.join(bkidsig.format(names=names), ' ')) + ' '.join(bkidsig.format(names=names))) result.append('%s [%s]' % (self.bactsig, self.bact)) - return string.join(result, '\n') + return '\n'.join(result) class File(Base): """A class for files in a file system. @@ -2286,9 +2224,7 @@ class File(Base): def Dirs(self, pathlist): """Create a list of directories relative to the SConscript directory of this file.""" - # TODO(1.5) - # return [self.Dir(p) for p in pathlist] - return map(lambda p, s=self: s.Dir(p), pathlist) + return [self.Dir(p) for p in pathlist] def File(self, name): """Create a file node named 'name' relative to @@ -2336,38 +2272,24 @@ class File(Base): raise return contents - try: - import codecs - except ImportError: - get_text_contents = get_contents - else: - # This attempts to figure out what the encoding of the text is - # based upon the BOM bytes, and then decodes the contents so that - # it's a valid python string. - def get_text_contents(self): - contents = self.get_contents() - # The behavior of various decode() methods and functions - # w.r.t. the initial BOM bytes is different for different - # encodings and/or Python versions. ('utf-8' does not strip - # them, but has a 'utf-8-sig' which does; 'utf-16' seems to - # strip them; etc.) Just side step all the complication by - # explicitly stripping the BOM before we decode(). - if contents.startswith(codecs.BOM_UTF8): - contents = contents[len(codecs.BOM_UTF8):] - # TODO(2.2): Remove when 2.3 becomes floor. - #contents = contents.decode('utf-8') - contents = my_decode(contents, 'utf-8') - elif contents.startswith(codecs.BOM_UTF16_LE): - contents = contents[len(codecs.BOM_UTF16_LE):] - # TODO(2.2): Remove when 2.3 becomes floor. - #contents = contents.decode('utf-16-le') - contents = my_decode(contents, 'utf-16-le') - elif contents.startswith(codecs.BOM_UTF16_BE): - contents = contents[len(codecs.BOM_UTF16_BE):] - # TODO(2.2): Remove when 2.3 becomes floor. - #contents = contents.decode('utf-16-be') - contents = my_decode(contents, 'utf-16-be') - return contents + # This attempts to figure out what the encoding of the text is + # based upon the BOM bytes, and then decodes the contents so that + # it's a valid python string. + def get_text_contents(self): + contents = self.get_contents() + # The behavior of various decode() methods and functions + # w.r.t. the initial BOM bytes is different for different + # encodings and/or Python versions. ('utf-8' does not strip + # them, but has a 'utf-8-sig' which does; 'utf-16' seems to + # strip them; etc.) Just sidestep all the complication by + # explicitly stripping the BOM before we decode(). + if contents.startswith(codecs.BOM_UTF8): + return contents[len(codecs.BOM_UTF8):].decode('utf-8') + if contents.startswith(codecs.BOM_UTF16_LE): + 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 def get_content_hash(self): """ @@ -2603,7 +2525,7 @@ class File(Base): if scanner: # result = [n.disambiguate() for n in scanner(self, env, path)] result = scanner(self, env, path) - result = map(lambda N: N.disambiguate(), result) + result = [N.disambiguate() for N in result] else: result = [] @@ -2741,7 +2663,7 @@ class File(Base): self._createDir() except SCons.Errors.StopError, drive: desc = "No drive `%s' for target `%s'." % (drive, self) - raise SCons.Errors.StopError, desc + raise SCons.Errors.StopError(desc) # # @@ -2760,7 +2682,7 @@ class File(Base): e = Link(self, src, None) if isinstance(e, SCons.Errors.BuildError): desc = "Cannot duplicate `%s' in `%s': %s." % (src.path, self.dir.path, e.errstr) - raise SCons.Errors.StopError, desc + raise SCons.Errors.StopError(desc) self.linked = 1 # The Link() action may or may not have actually # created the file, depending on whether the -n @@ -3019,7 +2941,7 @@ class File(Base): children = self.children() executor = self.get_executor() # sigs = [n.get_cachedir_csig() for n in children] - sigs = map(lambda n: n.get_cachedir_csig(), children) + sigs = [n.get_cachedir_csig() for n in children] sigs.append(SCons.Util.MD5signature(executor.get_contents())) sigs.append(self.path) result = self.cachesig = SCons.Util.MD5collect(sigs) @@ -3034,7 +2956,7 @@ def get_default_fs(): default_fs = FS() return default_fs -class FileFinder: +class FileFinder(object): """ """ if SCons.Memoize.use_memoizer: @@ -3117,8 +3039,8 @@ class FileFinder: if verbose and not callable(verbose): if not SCons.Util.is_String(verbose): verbose = "find_file" - verbose = ' %s: ' % verbose - verbose = lambda s, v=verbose: sys.stdout.write(v + s) + _verbose = u' %s: ' % verbose + verbose = lambda s: sys.stdout.write(_verbose + s) filedir, filename = os.path.split(filename) if filedir: @@ -3150,10 +3072,10 @@ class FileFinder: # if isinstance(node, Dir) or isinstance(node, Entry): # return node # return None - #paths = filter(None, map(filedir_lookup, paths)) + #paths = [_f for _f in map(filedir_lookup, paths) if _f] self.default_filedir = filedir - paths = filter(None, map(self.filedir_lookup, paths)) + paths = [_f for _f in map(self.filedir_lookup, paths) if _f] result = None for dir in paths: diff --git a/src/engine/SCons/Node/FSTests.py b/src/engine/SCons/Node/FSTests.py index c059925..ee6a2f5 100644 --- a/src/engine/SCons/Node/FSTests.py +++ b/src/engine/SCons/Node/FSTests.py @@ -20,12 +20,14 @@ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # +from __future__ import division -__revision__ = "src/engine/SCons/Node/FSTests.py 4720 2010/03/24 03:14:11 jars" +__revision__ = "src/engine/SCons/Node/FSTests.py 5023 2010/06/14 22:05:46 scons" + +import SCons.compat import os import os.path -import string import sys import time import unittest @@ -40,16 +42,9 @@ import SCons.Warnings built_it = None -# This will be built-in in 2.3. For now fake it. -try : - True , False -except NameError : - True = 1 ; False = 0 - - scanner_count = 0 -class Scanner: +class Scanner(object): def __init__(self, node=None): global scanner_count scanner_count = scanner_count + 1 @@ -66,7 +61,7 @@ class Scanner: def recurse_nodes(self, nodes): return nodes -class Environment: +class Environment(object): def __init__(self): self.scanner = Scanner() def Dictionary(self, *args): @@ -80,7 +75,7 @@ class Environment: def _update(self, dict): pass -class Action: +class Action(object): def __call__(self, targets, sources, env, **kw): global built_it if kw.get('execute', 1): @@ -97,7 +92,7 @@ class Action: def get_implicit_deps(self, target, source, env): return [] -class Builder: +class Builder(object): def __init__(self, factory, action=Action()): self.factory = factory self.env = Environment() @@ -341,7 +336,7 @@ class VariantDirTestCase(unittest.TestCase): f11 = fs.File('src/file11') t, m = f11.alter_targets() - bdt = map(lambda n: n.path, t) + bdt = [n.path for n in t] var1_file11 = os.path.normpath('build/var1/file11') var2_file11 = os.path.normpath('build/var2/file11') assert bdt == [var1_file11, var2_file11], bdt @@ -349,11 +344,11 @@ class VariantDirTestCase(unittest.TestCase): f12 = fs.File('src/file12') f12.builder = 1 bdt, m = f12.alter_targets() - assert bdt == [], map(lambda n: n.path, bdt) + assert bdt == [], [n.path for n in bdt] d13 = fs.Dir('src/new_dir') t, m = d13.alter_targets() - bdt = map(lambda n: n.path, t) + bdt = [n.path for n in t] var1_new_dir = os.path.normpath('build/var1/new_dir') var2_new_dir = os.path.normpath('build/var2/new_dir') assert bdt == [var1_new_dir, var2_new_dir], bdt @@ -364,7 +359,7 @@ class VariantDirTestCase(unittest.TestCase): save_Link = SCons.Node.FS.Link def Link_IOError(target, source, env): - raise IOError, (17, "Link_IOError") + raise IOError(17, "Link_IOError") SCons.Node.FS.Link = SCons.Action.Action(Link_IOError, None) test.write(['work', 'src', 'IOError'], "work/src/IOError\n") @@ -434,7 +429,7 @@ class VariantDirTestCase(unittest.TestCase): assert r == d1, "%s != %s" % (r, d1) # verify the link creation attempts in file_link() - class LinkSimulator : + class LinkSimulator (object): """A class to intercept os.[sym]link() calls and track them.""" def __init__( self, duplicate, link, symlink, copy ) : @@ -445,7 +440,7 @@ class VariantDirTestCase(unittest.TestCase): self.have['copy'] = copy self.links_to_be_called = [] - for link in string.split(self.duplicate, '-'): + for link in self.duplicate.split('-'): if self.have[link]: self.links_to_be_called.append(link) @@ -817,7 +812,7 @@ class FileBuildInfoTestCase(_tempdirTestCase): 'actionsig [action]', ] - expect = string.join(expect_lines, '\n') + expect = '\n'.join(expect_lines) format = bi1.format() assert format == expect, (repr(expect), repr(format)) @@ -898,7 +893,7 @@ class FSTestCase(_tempdirTestCase): except TypeError: pass else: - raise Exception, "did not catch expected TypeError" + raise Exception("did not catch expected TypeError") assert x1.Entry(x4) == x4 try: @@ -906,7 +901,7 @@ class FSTestCase(_tempdirTestCase): except TypeError: pass else: - raise Exception, "did not catch expected TypeError" + raise Exception("did not catch expected TypeError") x6 = x1.File(x6) assert isinstance(x6, SCons.Node.FS.File) @@ -921,12 +916,12 @@ class FSTestCase(_tempdirTestCase): drive, path = os.path.splitdrive(os.getcwd()) def _do_Dir_test(lpath, path_, abspath_, up_path_, sep, fileSys=fs, drive=drive): - dir = fileSys.Dir(string.replace(lpath, '/', sep)) + dir = fileSys.Dir(lpath.replace('/', sep)) if os.sep != '/': - path_ = string.replace(path_, '/', os.sep) - abspath_ = string.replace(abspath_, '/', os.sep) - up_path_ = string.replace(up_path_, '/', os.sep) + path_ = path_.replace('/', os.sep) + abspath_ = abspath_.replace('/', os.sep) + up_path_ = up_path_.replace('/', os.sep) def strip_slash(p, drive=drive): if p[-1] == os.sep and len(p) > 1: @@ -937,7 +932,7 @@ class FSTestCase(_tempdirTestCase): path = strip_slash(path_) abspath = strip_slash(abspath_) up_path = strip_slash(up_path_) - name = string.split(abspath, os.sep)[-1] + name = abspath.split(os.sep)[-1] assert dir.name == name, \ "dir.name %s != expected name %s" % \ @@ -978,7 +973,7 @@ class FSTestCase(_tempdirTestCase): Dir_test('#', './', sub_dir, sub) try: - f2 = fs.File(string.join(['f1', 'f2'], sep), directory = d1) + f2 = fs.File(sep.join(['f1', 'f2']), directory = d1) except TypeError, x: assert str(x) == ("Tried to lookup File '%s' as a Dir." % d1_f1), x @@ -986,7 +981,7 @@ class FSTestCase(_tempdirTestCase): raise try: - dir = fs.Dir(string.join(['d1', 'f1'], sep)) + dir = fs.Dir(sep.join(['d1', 'f1'])) except TypeError, x: assert str(x) == ("Tried to lookup File '%s' as a Dir." % d1_f1), x @@ -1051,7 +1046,7 @@ class FSTestCase(_tempdirTestCase): assert built_it def match(path, expect): - expect = string.replace(expect, '/', os.sep) + expect = expect.replace('/', os.sep) assert path == expect, "path %s != expected %s" % (path, expect) e1 = fs.Entry("d1") @@ -1152,7 +1147,7 @@ class FSTestCase(_tempdirTestCase): # Make sure we can scan this file even if the target isn't # a file that has a scanner (it might be an Alias, e.g.). - class DummyNode: + class DummyNode(object): pass deps = f12.get_found_includes(env, s, DummyNode()) @@ -1195,17 +1190,12 @@ class FSTestCase(_tempdirTestCase): f1 = fs.File(test.workpath("binary_file")) assert f1.get_contents() == "Foo\x1aBar", f1.get_contents() - try: - # TODO(1.5) - eval('test_string = u"Foo\x1aBar"') - except SyntaxError: - pass - else: - # This tests to make sure we can decode UTF-8 text files. - test.write("utf8_file", test_string.encode('utf-8')) - f1 = fs.File(test.workpath("utf8_file")) - assert eval('f1.get_text_contents() == u"Foo\x1aBar"'), \ - f1.get_text_contents() + # This tests to make sure we can decode UTF-8 text files. + test_string = u"Foo\x1aBar" + test.write("utf8_file", test_string.encode('utf-8')) + f1 = fs.File(test.workpath("utf8_file")) + assert eval('f1.get_text_contents() == u"Foo\x1aBar"'), \ + f1.get_text_contents() def nonexistent(method, s): try: @@ -1213,7 +1203,7 @@ class FSTestCase(_tempdirTestCase): except SCons.Errors.UserError: pass else: - raise Exception, "did not catch expected UserError" + raise Exception("did not catch expected UserError") nonexistent(fs.Entry, 'nonexistent') nonexistent(fs.Entry, 'nonexistent/foo') @@ -1318,7 +1308,7 @@ class FSTestCase(_tempdirTestCase): # We round down the current time to the nearest even integer # value, subtract two to make sure the timestamp is not "now," # and then convert it back to a float. - tstamp = float(int(time.time() / 2) * 2) - 2 + tstamp = float(int(time.time() // 2) * 2) - 2.0 os.utime(test.workpath("tstamp"), (tstamp - 2.0, tstamp)) f = fs.File("tstamp") t = f.get_timestamp() @@ -1336,7 +1326,7 @@ class FSTestCase(_tempdirTestCase): f2 = test.workpath('tdir2', 'file2') test.write(f1, 'file1\n') test.write(f2, 'file2\n') - current_time = float(int(time.time() / 2) * 2) + current_time = float(int(time.time() // 2) * 2) t1 = current_time - 4.0 t2 = current_time - 2.0 os.utime(f1, (t1 - 2.0, t1)) @@ -1434,7 +1424,7 @@ class FSTestCase(_tempdirTestCase): test.subdir('sub', ['sub', 'dir']) def drive_workpath(drive, dirs, test=test): - x = apply(test.workpath, dirs) + x = test.workpath(*dirs) drive, path = os.path.splitdrive(x) return 'X:' + path @@ -1466,11 +1456,11 @@ class FSTestCase(_tempdirTestCase): seps = seps + ['/'] def _do_Dir_test(lpath, path_, up_path_, sep, fileSys=fs): - dir = fileSys.Dir(string.replace(lpath, '/', sep)) + dir = fileSys.Dir(lpath.replace('/', sep)) if os.sep != '/': - path_ = string.replace(path_, '/', os.sep) - up_path_ = string.replace(up_path_, '/', os.sep) + path_ = path_.replace('/', os.sep) + up_path_ = up_path_.replace('/', os.sep) def strip_slash(p): if p[-1] == os.sep and len(p) > 3: @@ -1478,7 +1468,7 @@ class FSTestCase(_tempdirTestCase): return p path = strip_slash(path_) up_path = strip_slash(up_path_) - name = string.split(path, os.sep)[-1] + name = path.split(os.sep)[-1] assert dir.name == name, \ "dir.name %s != expected name %s" % \ @@ -1577,8 +1567,8 @@ class FSTestCase(_tempdirTestCase): d1 = fs.Dir('d1') d2 = d1.Dir('d2') - dirs = string.split(os.path.normpath(d2.abspath), os.sep) - above_path = apply(os.path.join, ['..']*len(dirs) + ['above']) + dirs = os.path.normpath(d2.abspath).split(os.sep) + above_path = os.path.join(*['..']*len(dirs) + ['above']) above = d2.Dir(above_path) def test_rel_path(self): @@ -1667,16 +1657,11 @@ class FSTestCase(_tempdirTestCase): def test_proxy(self): """Test a Node.FS object wrapped in a proxy instance""" f1 = self.fs.File('fff') - class Proxy: - # Simplest possibly Proxy class that works for our test, - # this is stripped down from SCons.Util.Proxy. - def __init__(self, subject): - self.__subject = subject - def __getattr__(self, name): - return getattr(self.__subject, name) - p = Proxy(f1) + class MyProxy(SCons.Util.Proxy): + __str__ = SCons.Util.Delegate('__str__') + p = MyProxy(f1) f2 = self.fs.Entry(p) - assert f1 is f2, (f1, f2) + assert f1 is f2, (f1, str(f1), f2, str(f2)) @@ -1730,8 +1715,7 @@ class DirTestCase(_tempdirTestCase): fs.Dir(os.path.join('ddd', 'd1', 'f4')) fs.Dir(os.path.join('ddd', 'd1', 'f5')) dir.scan() - kids = map(lambda x: x.path, dir.children(None)) - kids.sort() + kids = sorted([x.path for x in dir.children(None)]) assert kids == [os.path.join('ddd', 'd1'), os.path.join('ddd', 'f1'), os.path.join('ddd', 'f2'), @@ -1756,8 +1740,7 @@ class DirTestCase(_tempdirTestCase): e = self.fs.Dir(os.path.join('d', 'empty')) s = self.fs.Dir(os.path.join('d', 'sub')) - #TODO(1.5) files = d.get_contents().split('\n') - files = string.split(d.get_contents(), '\n') + files = d.get_contents().split('\n') assert e.get_contents() == '', e.get_contents() assert e.get_text_contents() == '', e.get_text_contents() @@ -1776,14 +1759,12 @@ class DirTestCase(_tempdirTestCase): fs.File(os.path.join('ddd', 'f1')) dir.scan() - kids = map(lambda x: x.path, dir.children()) - kids.sort() + kids = sorted([x.path for x in dir.children()]) assert kids == [os.path.join('ddd', 'f1')], kids fs.File(os.path.join('ddd', 'f2')) dir.scan() - kids = map(lambda x: x.path, dir.children()) - kids.sort() + kids = sorted([x.path for x in dir.children()]) assert kids == [os.path.join('ddd', 'f1'), os.path.join('ddd', 'f2')], kids @@ -1818,8 +1799,8 @@ class DirTestCase(_tempdirTestCase): self.fs.VariantDir(sub2, src, duplicate=0) def check(result, expect): - result = map(str, result) - expect = map(os.path.normpath, expect) + result = list(map(str, result)) + expect = list(map(os.path.normpath, expect)) assert result == expect, result s = src.srcdir_list() @@ -1922,8 +1903,8 @@ class DirTestCase(_tempdirTestCase): exists_e.exists = return_true def check(result, expect): - result = map(str, result) - expect = map(os.path.normpath, expect) + result = list(map(str, result)) + expect = list(map(os.path.normpath, expect)) assert result == expect, result # First check from the source directory. @@ -2095,14 +2076,17 @@ class EntryTestCase(_tempdirTestCase): assert e4n.__class__ is SCons.Node.FS.File, e4n.__class__ assert not exists, "e4n exists?" - class MyCalc: + class MyCalc(object): def __init__(self, val): self.max_drift = 0 - class M: + class M(object): def __init__(self, val): self.val = val def collect(self, args): - return reduce(lambda x, y: x+y, args) + result = 0 + for a in args: + result += a + return result def signature(self, executor): return self.val + 222 self.module = M(val) @@ -2135,7 +2119,7 @@ class FileTestCase(_tempdirTestCase): d1 = self.fs.Dir('subdir/d1') d2 = self.fs.Dir('subdir/d2') dirs = fff.Dirs(['d1', 'd2']) - assert dirs == [d1, d2], map(str, dirs) + assert dirs == [d1, d2], list(map(str, dirs)) def test_exists(self): """Test the File.exists() method""" @@ -2248,8 +2232,7 @@ class GlobTestCase(_tempdirTestCase): strings_kwargs = copy.copy(kwargs) strings_kwargs['strings'] = True for input, string_expect, node_expect in cases: - r = apply(self.fs.Glob, (input,), strings_kwargs) - r.sort() + r = sorted(self.fs.Glob(input, **strings_kwargs)) assert r == string_expect, "Glob(%s, strings=True) expected %s, got %s" % (input, string_expect, r) # Now execute all of the cases without string=True and look for @@ -2259,26 +2242,25 @@ class GlobTestCase(_tempdirTestCase): # Verify those by running the list through str() before comparing # them with the expected list of strings. for input, string_expect, node_expect in cases: - r = apply(self.fs.Glob, (input,), kwargs) + r = self.fs.Glob(input, **kwargs) if node_expect: - r.sort(lambda a,b: cmp(a.path, b.path)) + r = sorted(r, key=lambda a: a.path) result = [] for n in node_expect: - if type(n) == type(''): + if isinstance(n, str): n = self.fs.Entry(n) result.append(n) fmt = lambda n: "%s %s" % (repr(n), repr(str(n))) else: - r = map(str, r) - r.sort() + r = sorted(map(str, r)) result = string_expect fmt = lambda n: n if r != result: import pprint print "Glob(%s) expected:" % repr(input) - pprint.pprint(map(fmt, result)) + pprint.pprint(list(map(fmt, result))) print "Glob(%s) got:" % repr(input) - pprint.pprint(map(fmt, r)) + pprint.pprint(list(map(fmt, r))) self.fail() def test_exact_match(self): @@ -2538,7 +2520,7 @@ class RepositoryTestCase(_tempdirTestCase): ] rep = self.fs.Dir('#').getRepositories() - r = map(lambda x, np=os.path.normpath: np(str(x)), rep) + r = [os.path.normpath(str(x)) for x in rep] assert r == expect, r def test_get_all_rdirs(self): @@ -2560,7 +2542,7 @@ class RepositoryTestCase(_tempdirTestCase): ] rep = self.fs.Dir('#').get_all_rdirs() - r = map(lambda x, np=os.path.normpath: np(str(x)), rep) + r = [os.path.normpath(str(x)) for x in rep] assert r == expect, r def test_rentry(self): @@ -2742,25 +2724,25 @@ class RepositoryTestCase(_tempdirTestCase): rep3_sub_d1 = fs.Dir(test.workpath('rep3', 'sub', 'd1')) r = fs.Top.Rfindalldirs((d1,)) - assert r == [d1], map(str, r) + assert r == [d1], list(map(str, r)) r = fs.Top.Rfindalldirs((d1, d2)) - assert r == [d1, d2], map(str, r) + assert r == [d1, d2], list(map(str, r)) r = fs.Top.Rfindalldirs(('d1',)) - assert r == [d1, rep1_d1, rep2_d1, rep3_d1], map(str, r) + assert r == [d1, rep1_d1, rep2_d1, rep3_d1], list(map(str, r)) r = fs.Top.Rfindalldirs(('#d1',)) - assert r == [d1, rep1_d1, rep2_d1, rep3_d1], map(str, r) + assert r == [d1, rep1_d1, rep2_d1, rep3_d1], list(map(str, r)) r = sub.Rfindalldirs(('d1',)) - assert r == [sub_d1, rep1_sub_d1, rep2_sub_d1, rep3_sub_d1], map(str, r) + assert r == [sub_d1, rep1_sub_d1, rep2_sub_d1, rep3_sub_d1], list(map(str, r)) r = sub.Rfindalldirs(('#d1',)) - assert r == [d1, rep1_d1, rep2_d1, rep3_d1], map(str, r) + assert r == [d1, rep1_d1, rep2_d1, rep3_d1], list(map(str, r)) r = fs.Top.Rfindalldirs(('d1', d2)) - assert r == [d1, rep1_d1, rep2_d1, rep3_d1, d2], map(str, r) + assert r == [d1, rep1_d1, rep2_d1, rep3_d1, d2], list(map(str, r)) def test_rexists(self): """Test the Entry.rexists() method""" @@ -2800,7 +2782,7 @@ class RepositoryTestCase(_tempdirTestCase): # We round down the current time to the nearest even integer # value, subtract two to make sure the timestamp is not "now," # and then convert it back to a float. - tstamp = float(int(time.time() / 2) * 2) - 2 + tstamp = float(int(time.time() // 2) * 2) - 2.0 os.utime(test.workpath("rep2", "tstamp"), (tstamp - 2.0, tstamp)) f = fs.File("tstamp") t = f.get_timestamp() @@ -2831,8 +2813,8 @@ class RepositoryTestCase(_tempdirTestCase): try: eval('test_string = u"Con\x1aTents\n"') except SyntaxError: - import UserString - class FakeUnicodeString(UserString.UserString): + import collections + class FakeUnicodeString(collections.UserString): def encode(self, encoding): return str(self) test_string = FakeUnicodeString("Con\x1aTents\n") @@ -2892,10 +2874,10 @@ class find_fileTestCase(unittest.TestCase): nodes.append(SCons.Node.FS.find_file('pseudo', paths)) nodes.append(SCons.Node.FS.find_file('same', paths)) - file_names = map(str, nodes) - file_names = map(os.path.normpath, file_names) + file_names = list(map(str, nodes)) + file_names = list(map(os.path.normpath, file_names)) expect = ['./foo', './bar/baz', './pseudo', './bar/same'] - expect = map(os.path.normpath, expect) + expect = list(map(os.path.normpath, expect)) assert file_names == expect, file_names # Make sure we don't blow up if there's already a File in place @@ -2904,11 +2886,11 @@ class find_fileTestCase(unittest.TestCase): # 'bar/baz' as a Dir. SCons.Node.FS.find_file('baz/no_file_here', paths) - import StringIO + import io save_sys_stdout = sys.stdout try: - sio = StringIO.StringIO() + sio = io.StringIO() sys.stdout = sio SCons.Node.FS.find_file('foo2', paths, verbose="xyz") expect = " xyz: looking for 'foo2' in '.' ...\n" + \ @@ -2916,7 +2898,7 @@ class find_fileTestCase(unittest.TestCase): c = sio.getvalue() assert c == expect, c - sio = StringIO.StringIO() + sio = io.StringIO() sys.stdout = sio SCons.Node.FS.find_file('baz2', paths, verbose=1) expect = " find_file: looking for 'baz2' in '.' ...\n" + \ @@ -2925,7 +2907,7 @@ class find_fileTestCase(unittest.TestCase): c = sio.getvalue() assert c == expect, c - sio = StringIO.StringIO() + sio = io.StringIO() sys.stdout = sio SCons.Node.FS.find_file('on_disk', paths, verbose=1) expect = " find_file: looking for 'on_disk' in '.' ...\n" + \ @@ -2965,8 +2947,8 @@ class stored_infoTestCase(unittest.TestCase): bi = f.get_stored_info() assert hasattr(bi, 'ninfo') - class MySConsign: - class Null: + class MySConsign(object): + class Null(object): def __init__(self): self.xyzzy = 7 def get_entry(self, name): @@ -3433,14 +3415,14 @@ class SaveStringsTestCase(unittest.TestCase): fs1.VariantDir('d0', 'src', duplicate=0) fs1.VariantDir('d1', 'src', duplicate=1) - s = map(str, nodes) - expect = map(os.path.normpath, ['src/f', 'd1/f', 'd0/b', 'd1/b']) + s = list(map(str, nodes)) + expect = list(map(os.path.normpath, ['src/f', 'd1/f', 'd0/b', 'd1/b'])) assert s == expect, s modify(nodes) - s = map(str, nodes) - expect = map(os.path.normpath, ['src/f', 'src/f', 'd0/b', 'd1/b']) + s = list(map(str, nodes)) + expect = list(map(os.path.normpath, ['src/f', 'src/f', 'd0/b', 'd1/b'])) assert s == expect, s SCons.Node.FS.save_strings(1) @@ -3449,14 +3431,14 @@ class SaveStringsTestCase(unittest.TestCase): fs2.VariantDir('d0', 'src', duplicate=0) fs2.VariantDir('d1', 'src', duplicate=1) - s = map(str, nodes) - expect = map(os.path.normpath, ['src/f', 'd1/f', 'd0/b', 'd1/b']) + s = list(map(str, nodes)) + expect = list(map(os.path.normpath, ['src/f', 'd1/f', 'd0/b', 'd1/b'])) assert s == expect, s modify(nodes) - s = map(str, nodes) - expect = map(os.path.normpath, ['src/f', 'd1/f', 'd0/b', 'd1/b']) + s = list(map(str, nodes)) + expect = list(map(os.path.normpath, ['src/f', 'd1/f', 'd0/b', 'd1/b'])) assert s == expect, 'node str() not cached: %s'%s @@ -3509,7 +3491,7 @@ if __name__ == "__main__": ] for tclass in tclasses: names = unittest.getTestCaseNames(tclass, 'test_') - suite.addTests(map(tclass, names)) + suite.addTests(list(map(tclass, names))) if not unittest.TextTestRunner().run(suite).wasSuccessful(): sys.exit(1) diff --git a/src/engine/SCons/Node/NodeTests.py b/src/engine/SCons/Node/NodeTests.py index c8e5d96..2a09187 100644 --- a/src/engine/SCons/Node/NodeTests.py +++ b/src/engine/SCons/Node/NodeTests.py @@ -19,17 +19,16 @@ # 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__ = "src/engine/SCons/Node/NodeTests.py 4720 2010/03/24 03:14:11 jars" +__revision__ = "src/engine/SCons/Node/NodeTests.py 5023 2010/06/14 22:05:46 scons" + +import SCons.compat +import collections import os import re -import string import sys -import types import unittest -import UserList import SCons.Errors import SCons.Node @@ -50,13 +49,13 @@ def _actionAppend(a1, a2): all.append(curr_a) elif isinstance(curr_a, MyListAction): all.extend(curr_a.list) - elif type(curr_a) == type([1,2]): + elif isinstance(curr_a, list): all.extend(curr_a) else: - raise 'Cannot Combine Actions' + raise Exception('Cannot Combine Actions') return MyListAction(all) -class MyActionBase: +class MyActionBase(object): def __add__(self, other): return _actionAppend(self, other) @@ -83,7 +82,7 @@ class MyAction(MyActionBase): def get_implicit_deps(self, target, source, env): return [] -class MyExecutor: +class MyExecutor(object): def __init__(self, env=None, targets=[], sources=[]): self.env = env self.targets = targets @@ -114,7 +113,7 @@ class MyListAction(MyActionBase): for A in self.list: A(target, source, env) -class Environment: +class Environment(object): def __init__(self, **kw): self._dict = {} self._dict.update(kw) @@ -125,7 +124,7 @@ class Environment: def Override(self, overrides): d = self._dict.copy() d.update(overrides) - return apply(Environment, (), d) + return Environment(**d) def _update(self, dict): self._dict.update(dict) def get_factory(self, factory): @@ -133,7 +132,7 @@ class Environment: def get_scanner(self, scanner_key): return self._dict['SCANNERS'][0] -class Builder: +class Builder(object): def __init__(self, env=None, is_explicit=1): if env is None: env = Environment() self.env = env @@ -167,19 +166,19 @@ class ListBuilder(Builder): target = self.nodes[0] self.status = Builder.execute(self, target, source, env) -class FailBuilder: +class FailBuilder(object): def execute(self, target, source, env): return 1 -class ExceptBuilder: +class ExceptBuilder(object): def execute(self, target, source, env): raise SCons.Errors.BuildError -class ExceptBuilder2: +class ExceptBuilder2(object): def execute(self, target, source, env): - raise "foo" + raise Exception("foo") -class Scanner: +class Scanner(object): called = None def __call__(self, node): self.called = 1 @@ -205,16 +204,19 @@ class MyNode(SCons.Node.Node): def get_found_includes(self, env, scanner, target): return scanner(self) -class Calculator: +class Calculator(object): def __init__(self, val): self.max_drift = 0 - class M: + class M(object): def __init__(self, val): self.val = val def signature(self, args): return self.val def collect(self, args): - return reduce(lambda x, y: x+y, args, self.val) + result = self.val + for a in args: + result += a + return result self.module = M(val) @@ -382,7 +384,7 @@ class NodeTestCase(unittest.TestCase): else: self.fail("did not catch expected AttributeError") - class Builder: + class Builder(object): action = 'act' env = 'env1' overrides = {} @@ -616,7 +618,7 @@ class NodeTestCase(unittest.TestCase): class testNode2(SCons.Node.Node): def __str__(self): return 'null_binfo' - class FS: + class FS(object): pass node = testNode2() node.fs = FS() @@ -625,8 +627,8 @@ class NodeTestCase(unittest.TestCase): assert result is None, result def get_null_info(): - class Null_SConsignEntry: - class Null_BuildInfo: + class Null_SConsignEntry(object): + class Null_BuildInfo(object): def prepare_dependencies(self): pass binfo = Null_BuildInfo() @@ -786,7 +788,7 @@ class NodeTestCase(unittest.TestCase): except: pass else: - raise "did not catch expected exception" + raise Exception("did not catch expected exception") assert node.depends == [zero, one, two, three, four] @@ -818,7 +820,7 @@ class NodeTestCase(unittest.TestCase): except: pass else: - raise "did not catch expected exception" + raise Exception("did not catch expected exception") assert node.sources == [zero, one, two, three, four], node.sources def test_add_ignore(self): @@ -849,7 +851,7 @@ class NodeTestCase(unittest.TestCase): except: pass else: - raise "did not catch expected exception" + raise Exception("did not catch expected exception") assert node.ignore == [zero, one, two, three, four] def test_get_found_includes(self): @@ -889,24 +891,24 @@ class NodeTestCase(unittest.TestCase): d2.found_includes = [e, f] f.found_includes = [g] deps = node.get_implicit_deps(env, s, target) - assert deps == [d1, d2, e, f, g], map(str, deps) + assert deps == [d1, d2, e, f, g], list(map(str, deps)) # Recursive scanning eliminates duplicates e.found_includes = [f] deps = node.get_implicit_deps(env, s, target) - assert deps == [d1, d2, e, f, g], map(str, deps) + assert deps == [d1, d2, e, f, g], list(map(str, deps)) # Scanner method can select specific nodes to recurse def no_fff(nodes): - return filter(lambda n: str(n)[0] != 'f', nodes) + return [n for n in nodes if str(n)[0] != 'f'] s.recurse_nodes = no_fff deps = node.get_implicit_deps(env, s, target) - assert deps == [d1, d2, e, f], map(str, deps) + assert deps == [d1, d2, e, f], list(map(str, deps)) # Scanner method can short-circuit recursing entirely s.recurse_nodes = lambda nodes: [] deps = node.get_implicit_deps(env, s, target) - assert deps == [d1, d2], map(str, deps) + assert deps == [d1, d2], list(map(str, deps)) def test_get_env_scanner(self): """Test fetching the environment scanner for a Node @@ -1102,22 +1104,22 @@ class NodeTestCase(unittest.TestCase): nw = SCons.Node.Walker(n1) assert not nw.is_done() - assert nw.next().name == "n1" + assert nw.get_next().name == "n1" assert nw.is_done() - assert nw.next() is None + assert nw.get_next() is None n2 = MyNode("n2") n3 = MyNode("n3") n1.add_source([n2, n3]) nw = SCons.Node.Walker(n1) - n = nw.next() + n = nw.get_next() assert n.name == "n2", n.name - n = nw.next() + n = nw.get_next() assert n.name == "n3", n.name - n = nw.next() + n = nw.get_next() assert n.name == "n1", n.name - n = nw.next() + n = nw.get_next() assert n is None, n n4 = MyNode("n4") @@ -1128,17 +1130,17 @@ class NodeTestCase(unittest.TestCase): n3.add_dependency([n6, n7]) nw = SCons.Node.Walker(n1) - assert nw.next().name == "n4" - assert nw.next().name == "n5" - assert nw.history.has_key(n2) - assert nw.next().name == "n2" - assert nw.next().name == "n6" - assert nw.next().name == "n7" - assert nw.history.has_key(n3) - assert nw.next().name == "n3" - assert nw.history.has_key(n1) - assert nw.next().name == "n1" - assert nw.next() is None + assert nw.get_next().name == "n4" + assert nw.get_next().name == "n5" + assert n2 in nw.history + assert nw.get_next().name == "n2" + assert nw.get_next().name == "n6" + assert nw.get_next().name == "n7" + assert n3 in nw.history + assert nw.get_next().name == "n3" + assert n1 in nw.history + assert nw.get_next().name == "n1" + assert nw.get_next() is None n8 = MyNode("n8") n8.add_dependency([n3]) @@ -1151,16 +1153,16 @@ class NodeTestCase(unittest.TestCase): global cycle_detected nw = SCons.Node.Walker(n3, cycle_func = cycle) - n = nw.next() + n = nw.get_next() assert n.name == "n6", n.name - n = nw.next() + n = nw.get_next() assert n.name == "n8", n.name assert cycle_detected cycle_detected = None - n = nw.next() + n = nw.get_next() assert n.name == "n7", n.name - n = nw.next() - assert nw.next() is None + n = nw.get_next() + assert nw.get_next() is None def test_abspath(self): """Test the get_abspath() method.""" @@ -1275,16 +1277,9 @@ class NodeListTestCase(unittest.TestCase): nl = SCons.Node.NodeList([n3, n2, n1]) l = [1] - ul = UserList.UserList([2]) - try: - l.extend(ul) - except TypeError: - # An older version of Python (*cough* 1.5.2 *cough*) - # that doesn't allow UserList objects to extend lists. - pass - else: - s = str(nl) - assert s == "['n3', 'n2', 'n1']", s + ul = collections.UserList([2]) + s = str(nl) + assert s == "['n3', 'n2', 'n1']", s r = repr(nl) r = re.sub('at (0[xX])?[0-9a-fA-F]+', 'at 0x', r) @@ -1293,7 +1288,7 @@ class NodeListTestCase(unittest.TestCase): # New-style classes report as "object"; classic classes report # as "instance"... r = re.sub("object", "instance", r) - l = string.join(["<MyNode instance at 0x>"]*3, ", ") + l = ", ".join(["<MyNode instance at 0x>"]*3) assert r == '[%s]' % l, r @@ -1306,7 +1301,7 @@ if __name__ == "__main__": NodeListTestCase ] for tclass in tclasses: names = unittest.getTestCaseNames(tclass, 'test_') - suite.addTests(map(tclass, names)) + suite.addTests(list(map(tclass, names))) if not unittest.TextTestRunner().run(suite).wasSuccessful(): sys.exit(1) diff --git a/src/engine/SCons/Node/Python.py b/src/engine/SCons/Node/Python.py index 53c2c80..be99d28 100644 --- a/src/engine/SCons/Node/Python.py +++ b/src/engine/SCons/Node/Python.py @@ -27,7 +27,7 @@ Python nodes. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Node/Python.py 4720 2010/03/24 03:14:11 jars" +__revision__ = "src/engine/SCons/Node/Python.py 5023 2010/06/14 22:05:46 scons" import SCons.Node @@ -67,7 +67,7 @@ class Value(SCons.Node.Node): def build(self, **kw): if not hasattr(self, 'built_value'): - apply (SCons.Node.Node.build, (self,), kw) + SCons.Node.Node.build(self, **kw) is_up_to_date = SCons.Node.Node.children_are_up_to_date diff --git a/src/engine/SCons/Node/PythonTests.py b/src/engine/SCons/Node/PythonTests.py index dcf39ec..314b940 100644 --- a/src/engine/SCons/Node/PythonTests.py +++ b/src/engine/SCons/Node/PythonTests.py @@ -21,7 +21,7 @@ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Node/PythonTests.py 4720 2010/03/24 03:14:11 jars" +__revision__ = "src/engine/SCons/Node/PythonTests.py 5023 2010/06/14 22:05:46 scons" import sys import unittest @@ -51,7 +51,7 @@ class ValueTestCase(unittest.TestCase): def test_build(self): """Test "building" a Value Node """ - class fake_executor: + class fake_executor(object): def __call__(self, node): node.write('faked') @@ -119,7 +119,7 @@ if __name__ == "__main__": ] for tclass in tclasses: names = unittest.getTestCaseNames(tclass, 'test_') - suite.addTests(map(tclass, names)) + suite.addTests(list(map(tclass, names))) if not unittest.TextTestRunner().run(suite).wasSuccessful(): sys.exit(1) diff --git a/src/engine/SCons/Node/__init__.py b/src/engine/SCons/Node/__init__.py index b0570b0..8d15b58 100644 --- a/src/engine/SCons/Node/__init__.py +++ b/src/engine/SCons/Node/__init__.py @@ -40,14 +40,12 @@ be able to depend on any other type of "thing." # 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__ = "src/engine/SCons/Node/__init__.py 4720 2010/03/24 03:14:11 jars" +__revision__ = "src/engine/SCons/Node/__init__.py 5023 2010/06/14 22:05:46 scons" +import collections import copy -from itertools import chain, izip -import string -import UserList +from itertools import chain from SCons.Debug import logInstanceCreation import SCons.Executor @@ -57,7 +55,7 @@ import SCons.Util from SCons.Debug import Trace def classname(obj): - return string.split(str(obj.__class__), '.')[-1] + return str(obj.__class__).split('.')[-1] # Node states # @@ -99,7 +97,7 @@ Annotate = do_nothing # Classes for signature info for Nodes. -class NodeInfoBase: +class NodeInfoBase(object): """ The generic base class for signature information for a Node. @@ -107,7 +105,7 @@ class NodeInfoBase: logic for dealing with their own Node-specific signature information. """ current_version_id = 1 - def __init__(self, node): + def __init__(self, node=None): # Create an object attribute from the class attribute so it ends up # in the pickled data in the .sconsign file. self._version_id = self.current_version_id @@ -136,8 +134,7 @@ class NodeInfoBase: try: field_list = self.field_list except AttributeError: - field_list = self.__dict__.keys() - field_list.sort() + field_list = sorted(self.__dict__.keys()) fields = [] for field in field_list: try: @@ -150,7 +147,7 @@ class NodeInfoBase: fields.append(f) return fields -class BuildInfoBase: +class BuildInfoBase(object): """ The generic base class for build information for a Node. @@ -161,7 +158,7 @@ class BuildInfoBase: implicit dependencies, and action information. """ current_version_id = 1 - def __init__(self, node): + def __init__(self, node=None): # Create an object attribute from the class attribute so it ends up # in the pickled data in the .sconsign file. self._version_id = self.current_version_id @@ -172,7 +169,7 @@ class BuildInfoBase: def merge(self, other): self.__dict__.update(other.__dict__) -class Node: +class Node(object): """The base Node class, for entities that we know how to build, or use to build other Nodes. """ @@ -182,7 +179,7 @@ class Node: memoizer_counters = [] - class Attrs: + class Attrs(object): pass def __init__(self): @@ -351,12 +348,12 @@ class Node: for d in self.depends: if d.missing(): msg = "Explicit dependency `%s' not found, needed by target `%s'." - raise SCons.Errors.StopError, msg % (d, self) + raise SCons.Errors.StopError(msg % (d, self)) if self.implicit is not None: for i in self.implicit: if i.missing(): msg = "Implicit dependency `%s' not found, needed by target `%s'." - raise SCons.Errors.StopError, msg % (i, self) + raise SCons.Errors.StopError(msg % (i, self)) self.binfo = self.get_binfo() def build(self, **kw): @@ -372,7 +369,7 @@ class Node: """ try: - apply(self.get_executor(), (self,), kw) + self.get_executor()(self, **kw) except SCons.Errors.BuildError, e: e.node = self raise @@ -548,8 +545,7 @@ class Node: deps = [] while nodes: n = nodes.pop(0) - d = filter(lambda x, seen=seen: not seen.has_key(x), - n.get_found_includes(env, scanner, path)) + d = [x for x in n.get_found_includes(env, scanner, path) if x not in seen] if d: deps.extend(d) for n in d: @@ -832,7 +828,7 @@ class Node: except TypeError, e: e = e.args[0] if SCons.Util.is_List(e): - s = map(str, e) + s = list(map(str, e)) else: s = str(e) raise SCons.Errors.UserError("attempted to add a non-Node dependency to %s:\n\t%s is a %s, not a Node" % (str(self), s, type(e))) @@ -849,7 +845,7 @@ class Node: except TypeError, e: e = e.args[0] if SCons.Util.is_List(e): - s = map(str, e) + s = list(map(str, e)) else: s = str(e) raise SCons.Errors.UserError("attempted to ignore a non-Node dependency of %s:\n\t%s is a %s, not a Node" % (str(self), s, type(e))) @@ -863,7 +859,7 @@ class Node: except TypeError, e: e = e.args[0] if SCons.Util.is_List(e): - s = map(str, e) + s = list(map(str, e)) else: s = str(e) raise SCons.Errors.UserError("attempted to add a non-Node as source of %s:\n\t%s is a %s, not a Node" % (str(self), s, type(e))) @@ -1053,7 +1049,7 @@ class Node: if t: Trace(': old %s new %s' % (len(then), len(children))) result = True - for child, prev_ni in izip(children, then): + for child, prev_ni in zip(children, then): if child.changed_since_last_build(self, prev_ni): if t: Trace(': %s changed' % child) result = True @@ -1199,8 +1195,8 @@ class Node: new_bkids = new.bsources + new.bdepends + new.bimplicit new_bkidsigs = new.bsourcesigs + new.bdependsigs + new.bimplicitsigs - osig = dict(izip(old_bkids, old_bkidsigs)) - nsig = dict(izip(new_bkids, new_bkidsigs)) + osig = dict(zip(old_bkids, old_bkidsigs)) + nsig = dict(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 @@ -1215,11 +1211,11 @@ class Node: lines = [] - removed = filter(lambda x, nk=new_bkids: not x in nk, old_bkids) + removed = [x for x in old_bkids if not x in new_bkids] if removed: - removed = map(stringify, removed) + removed = list(map(stringify, removed)) fmt = "`%s' is no longer a dependency\n" - lines.extend(map(lambda s, fmt=fmt: fmt % s, removed)) + lines.extend([fmt % s for s in removed]) for k in new_bkids: if not k in old_bkids: @@ -1229,14 +1225,14 @@ class Node: if len(lines) == 0 and old_bkids != new_bkids: lines.append("the dependency order changed:\n" + - "%sold: %s\n" % (' '*15, map(stringify, old_bkids)) + - "%snew: %s\n" % (' '*15, map(stringify, new_bkids))) + "%sold: %s\n" % (' '*15, list(map(stringify, old_bkids))) + + "%snew: %s\n" % (' '*15, list(map(stringify, new_bkids)))) if len(lines) == 0: def fmt_with_title(title, strlines): - lines = string.split(strlines, '\n') + lines = strlines.split('\n') sep = '\n' + ' '*(15 + len(title)) - return ' '*15 + title + string.join(lines, sep) + '\n' + return ' '*15 + title + sep.join(lines) + '\n' if old.bactsig != new.bactsig: if old.bact == new.bact: lines.append("the contents of the build action changed\n" + @@ -1254,31 +1250,22 @@ class Node: return "%s %s" % (preamble, lines[0]) else: lines = ["%s:\n" % preamble] + lines - return string.join(lines, ' '*11) - -try: - [].extend(UserList.UserList([])) -except TypeError: - # Python 1.5.2 doesn't allow a list to be extended by list-like - # objects (such as UserList instances), so just punt and use - # real lists. - def NodeList(l): - return l -else: - class NodeList(UserList.UserList): - def __str__(self): - return str(map(str, self.data)) + return ( ' '*11).join(lines) + +class NodeList(collections.UserList): + def __str__(self): + return str(list(map(str, self.data))) def get_children(node, parent): return node.children() def ignore_cycle(node, stack): pass def do_nothing(node, parent): pass -class Walker: +class Walker(object): """An iterator for walking a Node tree. This is depth-first, children are visited before the parent. The Walker object can be initialized with any node, and - returns the next node on the descent with each next() call. + returns the next node on the descent with each get_next() call. 'kids_func' is an optional function that will be called to get the children of a node instead of calling 'children'. 'cycle_func' is an optional function that will be called @@ -1298,7 +1285,7 @@ class Walker: self.history = {} # used to efficiently detect and avoid cycles self.history[node] = None - def next(self): + def get_next(self): """Return the next node for this walk of the tree. This function is intentionally iterative, not recursive, @@ -1310,7 +1297,7 @@ class Walker: node = self.stack[-1].wkids.pop(0) if not self.stack[-1].wkids: self.stack[-1].wkids = None - if self.history.has_key(node): + if node in self.history: self.cycle_func(node, self.stack) else: node.wkids = copy.copy(self.kids_func(node, self.stack[-1])) |