diff options
author | Steven Knight <knight@baldmt.com> | 2002-01-08 16:20:33 (GMT) |
---|---|---|
committer | Steven Knight <knight@baldmt.com> | 2002-01-08 16:20:33 (GMT) |
commit | 5e8c9967abc27764f333927804f5e7e4ebedffce (patch) | |
tree | 1b78b5b634ef66f60dda6b1c96bdcf75c13650e2 | |
parent | 2064826de2beaee83636183dae605270830a4f9e (diff) | |
download | SCons-5e8c9967abc27764f333927804f5e7e4ebedffce.zip SCons-5e8c9967abc27764f333927804f5e7e4ebedffce.tar.gz SCons-5e8c9967abc27764f333927804f5e7e4ebedffce.tar.bz2 |
Collect common type-checking logic in SCons.Util.
-rw-r--r-- | src/CHANGES.txt | 3 | ||||
-rw-r--r-- | src/engine/SCons/Builder.py | 70 | ||||
-rw-r--r-- | src/engine/SCons/Environment.py | 9 | ||||
-rw-r--r-- | src/engine/SCons/Util.py | 44 | ||||
-rw-r--r-- | src/engine/SCons/UtilTests.py | 25 |
5 files changed, 93 insertions, 58 deletions
diff --git a/src/CHANGES.txt b/src/CHANGES.txt index e83724c..31763f5 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -37,6 +37,9 @@ RELEASE 0.03 - the user's environment variables to executed commands; how to build variants in multiple BuildDirs. + - Collect String, Dict, and List type-checking in common utility + routines so we can accept User{String,Dict,List}s all over. + From Anthony Roach: - Add a "duplicate" keyword argument to BuildDir() that can be set diff --git a/src/engine/SCons/Builder.py b/src/engine/SCons/Builder.py index f47e3a7..796af0a 100644 --- a/src/engine/SCons/Builder.py +++ b/src/engine/SCons/Builder.py @@ -33,21 +33,13 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" import os import os.path -import SCons.Node.FS -from SCons.Util import PathList, scons_str2nodes, scons_subst, scons_subst_list, autogenerate import string import sys import types -from UserList import UserList -from UserDict import UserDict from Errors import UserError -try: - from UserString import UserString -except ImportError: - class UserString: - pass - +import SCons.Node.FS +import SCons.Util exitvalmap = { 2 : 127, @@ -81,7 +73,7 @@ elif os.name == 'nt': if os.path.isabs(cmd): if not os.path.exists(cmd): exts = env['PATHEXT'] - if type(exts) != type([]): + if not SCons.Util.is_List(exts): exts = string.split(exts, os.pathsep) for e in exts: f = cmd + e @@ -89,10 +81,10 @@ elif os.name == 'nt': return f else: path = env['PATH'] - if type(path) != type([]): + if not SCons.Util.is_List(path): path = string.split(path, os.pathsep) exts = env['PATHEXT'] - if type(exts) != type([]): + if not SCons.Util.is_List(exts): exts = string.split(exts, os.pathsep) pairs = [] for dir in path: @@ -122,8 +114,7 @@ elif os.name == 'nt': def Builder(**kw): """A factory for builder objects.""" - if kw.has_key('action') and (type(kw['action']) is types.DictType or - isinstance(kw['action'], UserDict)): + if kw.has_key('action') and SCons.Util.is_Dict(kw['action']): return apply(CompositeBuilder, (), kw) elif kw.has_key('src_builder'): return apply(MultiStepBuilder, (), kw) @@ -165,12 +156,12 @@ class BuilderBase: """ def adjustixes(files, pre, suf): ret = [] - if type(files) is types.StringType or isinstance(files, UserString): + if SCons.Util.is_String(files): files = string.split(files) - if not type(files) is type([]): + if not SCons.Util.is_List(files): files = [files] for f in files: - if type(f) is types.StringType or isinstance(f, UserString): + if SCons.Util.is_String(f): if pre and f[:len(pre)] != pre: path, fn = os.path.split(os.path.normpath(f)) f = os.path.join(path, pre + fn) @@ -180,15 +171,15 @@ class BuilderBase: ret.append(f) return ret - tlist = scons_str2nodes(adjustixes(target, - env.subst(self.prefix), - env.subst(self.suffix)), - self.node_factory) + tlist = SCons.Util.scons_str2nodes(adjustixes(target, + env.subst(self.prefix), + env.subst(self.suffix)), + self.node_factory) - slist = scons_str2nodes(adjustixes(source, - None, - env.subst(self.src_suffix)), - self.node_factory) + slist = SCons.Util.scons_str2nodes(adjustixes(source, + None, + env.subst(self.src_suffix)), + self.node_factory) return tlist, slist def _init_nodes(self, env, tlist, slist): @@ -258,7 +249,7 @@ class MultiStepBuilder(BuilderBase): self.src_builder = src_builder def __call__(self, env, target = None, source = None): - slist = scons_str2nodes(source, self.node_factory) + slist = SCons.Util.scons_str2nodes(source, self.node_factory) final_sources = [] src_suffix = env.subst(self.src_suffix) for snode in slist: @@ -266,7 +257,7 @@ class MultiStepBuilder(BuilderBase): if not src_suffix or ext != src_suffix: tgt = self.src_builder(env, target = [ path ], source=snode) - if not type(tgt) is types.ListType: + if not SCons.Util.is_List(tgt): final_sources.append(tgt) else: final_sources.extend(tgt) @@ -292,7 +283,7 @@ class CompositeBuilder(BuilderBase): src_builder = []): BuilderBase.__init__(self, name=name, prefix=prefix, suffix=suffix) - if src_builder and not type(src_builder) is types.ListType: + if src_builder and not SCons.Util.is_List(src_builder): src_builder = [src_builder] self.src_builder = src_builder self.builder_dict = {} @@ -353,9 +344,9 @@ def Action(act): """A factory for action objects.""" if callable(act): return FunctionAction(act) - elif type(act) == types.StringType or isinstance(act, UserString): + elif SCons.Util.is_String(act): return CommandAction(act) - elif type(act) == types.ListType or isinstance(act, UserList): + elif SCons.Util.is_List(act): return ListAction(act) else: return None @@ -407,27 +398,27 @@ class ActionBase: if kw.has_key('target'): t = kw['target'] del kw['target'] - if not type(t) is types.ListType and not isinstance(t, UserList): + if not SCons.Util.is_List(t): t = [t] try: cwd = t[0].cwd except AttributeError: pass - dict['TARGETS'] = PathList(map(os.path.normpath, map(str, t))) + dict['TARGETS'] = SCons.Util.PathList(map(os.path.normpath, map(str, t))) if dict['TARGETS']: dict['TARGET'] = dict['TARGETS'][0] if kw.has_key('source'): s = kw['source'] del kw['source'] - if not type(s) is types.ListType: + if not SCons.Util.is_List(s): s = [s] - dict['SOURCES'] = PathList(map(os.path.normpath, map(str, s))) + dict['SOURCES'] = SCons.Util.PathList(map(os.path.normpath, map(str, s))) dict.update(kw) # Autogenerate necessary construction variables. - autogenerate(dict, dir = cwd) + SCons.Util.autogenerate(dict, dir = cwd) return dict @@ -437,8 +428,9 @@ class CommandAction(ActionBase): self.command = string def execute(self, **kw): + import SCons.Util dict = apply(self.subst_dict, (), kw) - cmd_list = scons_subst_list(self.command, dict, {}) + cmd_list = SCons.Util.scons_subst_list(self.command, dict, {}) for cmd_line in cmd_list: if len(cmd_line): if print_actions: @@ -465,7 +457,7 @@ class CommandAction(ActionBase): kw['target'] = ['__t1__', '__t2__'] kw['source'] = ['__s1__', '__s2__'] dict = apply(self.subst_dict, (), kw) - return scons_subst(self.command, dict, {}) + return SCons.Util.scons_subst(self.command, dict, {}) class FunctionAction(ActionBase): """Class for Python function actions.""" @@ -477,7 +469,7 @@ class FunctionAction(ActionBase): # XXX: WHAT SHOULD WE PRINT HERE? if execute_actions: if kw.has_key('target'): - if type(kw['target']) is types.ListType: + if SCons.Util.is_List(kw['target']): kw['target'] = map(str, kw['target']) else: kw['target'] = str(kw['target']) diff --git a/src/engine/SCons/Environment.py b/src/engine/SCons/Environment.py index ad92dfd..6f77354 100644 --- a/src/engine/SCons/Environment.py +++ b/src/engine/SCons/Environment.py @@ -39,7 +39,6 @@ import SCons.Util import SCons.Builder import SCons.Defaults from SCons.Errors import UserError -from UserList import UserList import SCons.Node.FS import sys import shutil @@ -73,11 +72,11 @@ def InstallAs(): def our_deepcopy(x): """deepcopy lists and dictionaries, and just copy the reference for everything else.""" - if type(x) is type({}): + if SCons.Util.is_Dict(x): copy = {} for key in x.keys(): copy[key] = our_deepcopy(x[key]) - elif type(x) is type([]): + elif SCons.Util.is_List(x): copy = map(our_deepcopy, x) else: copy = x @@ -130,10 +129,10 @@ class Environment: """ self._dict.update(our_deepcopy(kw)) if self._dict.has_key('BUILDERS') and \ - type(self._dict['BUILDERS']) != type([]): + not SCons.Util.is_List(self._dict['BUILDERS']): self._dict['BUILDERS'] = [self._dict['BUILDERS']] if self._dict.has_key('SCANNERS') and \ - type(self._dict['SCANNERS']) != type([]): + not SCons.Util.is_List(self._dict['SCANNERS']): self._dict['SCANNERS'] = [self._dict['SCANNERS']] class BuilderWrapper: diff --git a/src/engine/SCons/Util.py b/src/engine/SCons/Util.py index a517407..e6ebd06 100644 --- a/src/engine/SCons/Util.py +++ b/src/engine/SCons/Util.py @@ -30,14 +30,22 @@ Various utility functions go here. __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" +import copy import os.path -import types -import string import re -from UserList import UserList -import SCons.Node.FS -import copy +import string +import types +import UserDict +import UserList + +try: + from UserString import UserString +except ImportError: + class UserString: + pass + import SCons.Node +import SCons.Node.FS def scons_str2nodes(arg, node_factory=SCons.Node.FS.default_fs.File): """This function converts a string or list into a list of Node instances. @@ -51,14 +59,14 @@ def scons_str2nodes(arg, node_factory=SCons.Node.FS.default_fs.File): In all cases, the function returns a list of Node instances.""" narg = arg - if type(arg) is types.StringType: + if is_String(arg): narg = string.split(arg) - elif type(arg) is not types.ListType: + elif not is_List(arg): narg = [arg] nodes = [] for v in narg: - if type(v) is types.StringType: + if is_String(v): nodes.append(node_factory(v)) # Do we enforce the following restriction? Maybe, but it # also restricts what we can do for allowing people to @@ -74,7 +82,7 @@ def scons_str2nodes(arg, node_factory=SCons.Node.FS.default_fs.File): return nodes -class PathList(UserList): +class PathList(UserList.UserList): """This class emulates the behavior of a list, but also implements the special "path dissection" attributes we can use to find suffixes, base names, etc. of the paths in the list. @@ -91,7 +99,7 @@ class PathList(UserList): 'bar foo' """ def __init__(self, seq = []): - UserList.__init__(self, seq) + UserList.UserList.__init__(self, seq) def __getattr__(self, name): # This is how we implement the "special" attributes @@ -157,7 +165,7 @@ class PathList(UserList): # We must do this to ensure that single items returned # by index access have the special attributes such as # suffix and basepath. - return self.__class__([ UserList.__getitem__(self, item), ]) + return self.__class__([ UserList.UserList.__getitem__(self, item), ]) _cv = re.compile(r'\$([_a-zA-Z]\w*|{[^}]*})') _space_sep = re.compile(r'[\t ]+(?![^{]*})') @@ -189,8 +197,7 @@ def scons_subst_list(strSubst, locals, globals): e = eval(key, locals, globals) if not e: s = '' - elif type(e) is types.ListType or \ - isinstance(e, UserList): + elif is_List(e): s = string.join(map(str, e), '\0') else: s = _space_sep.sub('\0', str(e)) @@ -282,7 +289,7 @@ class VarInterpolator: def prepareSrc(self, dict): src = dict[self.src] - if not type(src) is types.ListType and not isinstance(src, UserList): + if not is_List(src): src = [ src ] def prepare(x, dict=dict): @@ -409,3 +416,12 @@ def render_tree(root, child_func, margin=[0], visited={}): margin.pop() return retval + +def is_Dict(e): + return type(e) is types.DictType or isinstance(e, UserDict.UserDict) + +def is_List(e): + return type(e) is types.ListType or isinstance(e, UserList.UserList) + +def is_String(e): + return type(e) is types.StringType or isinstance(e, UserString) diff --git a/src/engine/SCons/UtilTests.py b/src/engine/SCons/UtilTests.py index 784c84d..5d7d52e 100644 --- a/src/engine/SCons/UtilTests.py +++ b/src/engine/SCons/UtilTests.py @@ -243,6 +243,31 @@ class UtilTestCase(unittest.TestCase): actual = render_tree(foo, get_children) assert expect == actual, (expect, actual) + def test_is_Dict(self): + assert is_Dict({}) + import UserDict + assert is_Dict(UserDict.UserDict()) + assert not is_Dict([]) + assert not is_Dict("") + + def test_is_List(self): + assert is_List([]) + import UserList + assert is_List(UserList.UserList()) + assert not is_List({}) + assert not is_List("") + + def test_is_String(self): + assert is_String("") + try: + import UserString + except: + pass + else: + assert is_String(UserString.UserString()) + assert not is_String({}) + assert not is_String([]) + if __name__ == "__main__": suite = unittest.makeSuite(UtilTestCase, 'test_') if not unittest.TextTestRunner().run(suite).wasSuccessful(): |