summaryrefslogtreecommitdiffstats
path: root/src/engine/SCons/Executor.py
diff options
context:
space:
mode:
authorSteven Knight <knight@baldmt.com>2004-12-29 21:04:56 (GMT)
committerSteven Knight <knight@baldmt.com>2004-12-29 21:04:56 (GMT)
commita2b119edf2fdd972c426f08f9898fb2efbe36646 (patch)
tree12b6722f049211b37574477e82ab5c49a0521052 /src/engine/SCons/Executor.py
parent9113805b081ef58fdf56bd5b5a9be6afad0b7a41 (diff)
downloadSCons-a2b119edf2fdd972c426f08f9898fb2efbe36646.zip
SCons-a2b119edf2fdd972c426f08f9898fb2efbe36646.tar.gz
SCons-a2b119edf2fdd972c426f08f9898fb2efbe36646.tar.bz2
Add a Memoizer metaclass to collect the logic for caching values in one location. Convert by-hand caching to use of Memoizer. (Kevin Quick)
Diffstat (limited to 'src/engine/SCons/Executor.py')
-rw-r--r--src/engine/SCons/Executor.py127
1 files changed, 69 insertions, 58 deletions
diff --git a/src/engine/SCons/Executor.py b/src/engine/SCons/Executor.py
index 1cb449c..2a19171 100644
--- a/src/engine/SCons/Executor.py
+++ b/src/engine/SCons/Executor.py
@@ -43,7 +43,9 @@ class Executor:
and sources for later processing as needed.
"""
- def __init__(self, action, env=None, overridelist=[],
+ __metaclass__ = SCons.Memoize.Memoized_Metaclass
+
+ def __init__(self, action, env=None, overridelist=[{}],
targets=[], sources=[], builder_kw={}):
if __debug__: logInstanceCreation(self)
if not action:
@@ -58,56 +60,59 @@ class Executor:
def get_build_env(self):
"""Fetch or create the appropriate build Environment
for this Executor.
+ __cacheable__
"""
+ # Create the build environment instance with appropriate
+ # overrides. These get evaluated against the current
+ # environment's construction variables so that users can
+ # add to existing values by referencing the variable in
+ # the expansion.
+ overrides = {}
+ for odict in self.overridelist:
+ overrides.update(odict)
try:
- return self.build_env
- except AttributeError:
- # Create the build environment instance with appropriate
- # overrides. These get evaluated against the current
- # environment's construction variables so that users can
- # add to existing values by referencing the variable in
- # the expansion.
- overrides = {}
- for odict in self.overridelist:
- overrides.update(odict)
- try:
- generate_build_dict = self.targets[0].generate_build_dict
- except (AttributeError, IndexError):
- pass
- else:
- overrides.update(generate_build_dict())
-
- import SCons.Defaults
- env = self.env or SCons.Defaults.DefaultEnvironment()
- self.build_env = env.Override(overrides)
-
- # Update the overrides with the $TARGET/$SOURCE variables for
- # this target+source pair, so that evaluations of arbitrary
- # Python functions have them in the __env__ environment
- # they're passed. Note that the underlying substitution
- # functions also override these with their own $TARGET/$SOURCE
- # expansions, which is *usually* duplicated effort, but covers
- # a corner case where an Action is called directly from within
- # a function action with different target and source lists.
- self.build_env._update(SCons.Util.subst_dict(self.targets,
- self.sources))
- return self.build_env
-
- def do_nothing(self, target, errfunc, **kw):
+ generate_build_dict = self.targets[0].generate_build_dict
+ except (AttributeError, IndexError):
+ pass
+ else:
+ overrides.update(generate_build_dict())
+
+ import SCons.Defaults
+ env = self.env or SCons.Defaults.DefaultEnvironment()
+ build_env = env.Override(overrides)
+
+ # Update the overrides with the $TARGET/$SOURCE variables for
+ # this target+source pair, so that evaluations of arbitrary
+ # Python functions have them in the __env__ environment
+ # they're passed. Note that the underlying substitution
+ # functions also override these with their own $TARGET/$SOURCE
+ # expansions, which is *usually* duplicated effort, but covers
+ # a corner case where an Action is called directly from within
+ # a function action with different target and source lists.
+ build_env._update(SCons.Util.subst_dict(self.targets, self.sources))
+
+ return build_env
+
+ def do_nothing(self, target, errfunc, kw):
pass
- def __call__(self, target, errfunc, **kw):
+ def do_execute(self, target, errfunc, kw):
"""Actually execute the action list."""
kw = kw.copy()
kw.update(self.builder_kw)
apply(self.action, (self.targets, self.sources,
self.get_build_env(), errfunc), kw)
+ # use extra indirection because with new-style objects (Python 2.2
+ # and above) we can't override special methods, and nullify() needs
+ # to be able to do this.
+
+ def __call__(self, target, errfunc, **kw):
+ self.do_execute(target, errfunc, kw)
+
def cleanup(self):
- try:
- del self.build_env
- except AttributeError:
- pass
+ "__reset_cache__"
+ pass
def add_sources(self, sources):
"""Add source files to this Executor's list. This is necessary
@@ -116,34 +121,32 @@ class Executor:
slist = filter(lambda x, s=self.sources: x not in s, sources)
self.sources.extend(slist)
+ # another extra indirection for new-style objects and nullify...
+
+ def my_str(self):
+ return self.action.genstring(self.targets,
+ self.sources,
+ self.get_build_env())
+
def __str__(self):
- try:
- return self.string
- except AttributeError:
- action = self.action
- self.string = action.genstring(self.targets,
- self.sources,
- self.get_build_env())
- return self.string
+ "__cacheable__"
+ return self.my_str()
def nullify(self):
- self.__call__ = self.do_nothing
- self.string = ''
+ "__reset_cache__"
+ self.do_execute = self.do_nothing
+ self.my_str = lambda S=self: ''
def get_contents(self):
"""Fetch the signature contents. This, along with
get_raw_contents(), is the real reason this class exists, so we
can compute this once and cache it regardless of how many target
or source Nodes there are.
+ __cacheable__
"""
- try:
- return self.contents
- except AttributeError:
- action = self.action
- self.contents = action.get_contents(self.targets,
- self.sources,
- self.get_build_env())
- return self.contents
+ return self.action.get_contents(self.targets,
+ self.sources,
+ self.get_build_env())
def get_timestamp(self):
"""Fetch a time stamp for this Executor. We don't have one, of
@@ -151,3 +154,11 @@ class Executor:
timestamp module.
"""
return 0
+
+if not SCons.Memoize.has_metaclass:
+ _Base = Executor
+ class Executor(SCons.Memoize.Memoizer, _Base):
+ def __init__(self, *args, **kw):
+ SCons.Memoize.Memoizer.__init__(self)
+ apply(_Base.__init__, (self,)+args, kw)
+