diff options
author | Steven Knight <knight@baldmt.com> | 2008-12-30 19:59:43 (GMT) |
---|---|---|
committer | Steven Knight <knight@baldmt.com> | 2008-12-30 19:59:43 (GMT) |
commit | 312f88d4f0daa0aa8ccdad202c76b7e297b605cd (patch) | |
tree | cbc1682df3b74751e0126f55fe16238135e07b86 /src | |
parent | 7b36529d703b12ee4f16c3aa5bd34a002235371d (diff) | |
download | SCons-312f88d4f0daa0aa8ccdad202c76b7e297b605cd.zip SCons-312f88d4f0daa0aa8ccdad202c76b7e297b605cd.tar.gz SCons-312f88d4f0daa0aa8ccdad202c76b7e297b605cd.tar.bz2 |
Issue 1417: Fix use of attributes (${SOURCES.windows}, e.g.) with null
lists of targets and sources.
Diffstat (limited to 'src')
-rw-r--r-- | src/CHANGES.txt | 3 | ||||
-rw-r--r-- | src/engine/SCons/Subst.py | 14 | ||||
-rw-r--r-- | src/engine/SCons/Util.py | 39 |
3 files changed, 30 insertions, 26 deletions
diff --git a/src/CHANGES.txt b/src/CHANGES.txt index 4b759f0..d5e1bf9 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -18,6 +18,9 @@ RELEASE 1.X - XXX - Add a --warn=future-deprecated option for advance warnings about deprecated features that still have warnings hidden by default. + - Fix use of $SOURCE and $SOURCES attributes when there are no + sources specified in the Builder call. + From Arve Knudsen: - Document TestCommon.shobj_prefix variable. diff --git a/src/engine/SCons/Subst.py b/src/engine/SCons/Subst.py index 752bbff..fc9d7d9 100644 --- a/src/engine/SCons/Subst.py +++ b/src/engine/SCons/Subst.py @@ -253,6 +253,12 @@ class Target_or_Source: return repr(nl[0]) return '' +class NullNodeList(SCons.Util.NullSeq): + def __call__(self, *args, **kwargs): return '' + def __str__(self): return '' + +NullNodesList = NullNodeList() + def subst_dict(target, source): """Create a dictionary for substitution of special construction variables. @@ -280,8 +286,8 @@ def subst_dict(target, source): dict['TARGETS'] = Targets_or_Sources(tnl) dict['TARGET'] = Target_or_Source(tnl) else: - dict['TARGETS'] = None - dict['TARGET'] = None + dict['TARGETS'] = NullNodesList + dict['TARGET'] = NullNodesList if source: def get_src_subst_proxy(node): @@ -299,8 +305,8 @@ def subst_dict(target, source): dict['SOURCES'] = Targets_or_Sources(snl) dict['SOURCE'] = Target_or_Source(snl) else: - dict['SOURCES'] = None - dict['SOURCE'] = None + dict['SOURCES'] = NullNodesList + dict['SOURCE'] = NullNodesList return dict diff --git a/src/engine/SCons/Util.py b/src/engine/SCons/Util.py index 641db9c..bbd985d 100644 --- a/src/engine/SCons/Util.py +++ b/src/engine/SCons/Util.py @@ -136,11 +136,6 @@ class NodeList(UserList): return string.join(map(str, self.data)) def __getattr__(self, name): - if not self.data: - # If there is nothing in the list, then we have no attributes to - # pass through, so raise AttributeError for everything. - raise AttributeError, "NodeList has no attribute: %s" % name - # Return a list of the attribute, gotten from every element # in the list attrList = map(lambda x, n=name: getattr(x, n), self.data) @@ -1549,29 +1544,29 @@ def MD5collect(signatures): # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/68205 # ASPN: Python Cookbook: Null Object Design Pattern +# TODO(1.5): +#class Null(object): class Null: - """ Null objects always and reliably "do nothging." """ - + """ Null objects always and reliably "do nothing." """ def __new__(cls, *args, **kwargs): if not '_inst' in vars(cls): #cls._inst = type.__new__(cls, *args, **kwargs) cls._inst = apply(type.__new__, (cls,) + args, kwargs) return cls._inst - def __init__(self, *args, **kwargs): - pass - def __call__(self, *args, **kwargs): - return self - def __repr__(self): - return "Null()" - def __nonzero__(self): - return False - def __getattr__(self, mname): - return self - def __setattr__(self, name, value): - return self - def __delattr__(self, name): - return self - + def __init__(self, *args, **kwargs): pass + def __call__(self, *args, **kwargs): return self + def __repr__(self): return "Null(0x%08X)" % id(self) + def __nonzero__(self): return False + def __getattr__(self, mname): return self + def __setattr__(self, name, value): return self + def __delattr__(self, name): return self + +class NullSeq(Null): + def __len__(self): return 0 + def __iter__(self): return iter(()) + def __getitem__(self, i): return self + def __delitem__(self, i): return self + def __setitem__(self, i, v): return self del __revision__ |