From 99a1a3e4c206a7e3aa7d2c0f639a3442c15eece3 Mon Sep 17 00:00:00 2001 From: Steven Knight Date: Fri, 21 Jan 2005 17:01:49 +0000 Subject: Change how Node/__init__.py imports Executor, remove unnecessary has_builder() calls, simply has_explicit_builder(). --- src/engine/SCons/Builder.py | 1 + src/engine/SCons/BuilderTests.py | 5 ++- src/engine/SCons/Environment.py | 10 +++-- src/engine/SCons/Node/NodeTests.py | 4 +- src/engine/SCons/Node/__init__.py | 76 ++++++++++++++++++++++---------------- 5 files changed, 58 insertions(+), 38 deletions(-) diff --git a/src/engine/SCons/Builder.py b/src/engine/SCons/Builder.py index 9ac01fa..584beca 100644 --- a/src/engine/SCons/Builder.py +++ b/src/engine/SCons/Builder.py @@ -341,6 +341,7 @@ def _init_nodes(builder, env, overrides, executor_kw, tlist, slist): t.env_set(env) t.add_source(slist) t.set_executor(executor) + t.set_explicit(builder.is_explicit) class EmitterProxy: """This is a callable class that can act as a diff --git a/src/engine/SCons/BuilderTests.py b/src/engine/SCons/BuilderTests.py index 0d9c2ec..8d60d33 100644 --- a/src/engine/SCons/BuilderTests.py +++ b/src/engine/SCons/BuilderTests.py @@ -143,6 +143,7 @@ class MyNode_without_target_from_source: self.name = name self.sources = [] self.builder = None + self.is_explicit = None self.side_effect = 0 def __str__(self): return self.name @@ -150,8 +151,10 @@ class MyNode_without_target_from_source: self.builder = builder def has_builder(self): return not self.builder is None + def set_explicit(self, is_explicit): + self.is_explicit = is_explicit def has_explicit_builder(self): - return not self.builder is None and self.builder.is_explicit + return self.is_explicit def env_set(self, env, safe=0): self.env = env def add_source(self, source): diff --git a/src/engine/SCons/Environment.py b/src/engine/SCons/Environment.py index fdd9b40..419e4e1 100644 --- a/src/engine/SCons/Environment.py +++ b/src/engine/SCons/Environment.py @@ -1126,11 +1126,13 @@ class Base(SubstitutionEnvironment): result.extend(bld(self, t, source)) return result - action = SCons.Action.Action(action) nkw = self.subst_kw(kw) - nkw['source_factory'] = self.fs.Entry - nkw['multi'] = 1 - nkw['action'] = action + nkw.update({ + 'action' : SCons.Action.Action(action), + 'source_factory' : self.fs.Entry, + 'multi' : 1, + 'is_explicit' : None, + }) bld = apply(SCons.Builder.Builder, (), nkw) # Apply the Builder separately to each target so that the Aliases diff --git a/src/engine/SCons/Node/NodeTests.py b/src/engine/SCons/Node/NodeTests.py index f801963..7d737be 100644 --- a/src/engine/SCons/Node/NodeTests.py +++ b/src/engine/SCons/Node/NodeTests.py @@ -416,9 +416,9 @@ class NodeTestCase(unittest.TestCase): """ n1 = SCons.Node.Node() assert not n1.has_explicit_builder() - n1.builder_set(Builder(is_explicit=1)) + n1.set_explicit(1) assert n1.has_explicit_builder() - n1.builder_set(Builder(is_explicit=None)) + n1.set_explicit(None) assert not n1.has_explicit_builder() def test_get_builder(self): diff --git a/src/engine/SCons/Node/__init__.py b/src/engine/SCons/Node/__init__.py index c20d657..06cb5bf 100644 --- a/src/engine/SCons/Node/__init__.py +++ b/src/engine/SCons/Node/__init__.py @@ -51,6 +51,7 @@ import string import UserList from SCons.Debug import logInstanceCreation +import SCons.Executor import SCons.SConsign import SCons.Util @@ -165,17 +166,39 @@ class Node: except AttributeError: if not create: raise - import SCons.Executor - act = self.builder.action - if self.pre_actions: - act = self.pre_actions + act - if self.post_actions: - act = act + self.post_actions - executor = SCons.Executor.Executor(act, - self.env or self.builder.env, - [self.builder.overrides], - [self], - self.sources) + try: + act = self.builder.action + except AttributeError: + # If there's no builder or action, then return a created + # null Executor with a null build Environment that + # does nothing when the rest of the methods call it. + # We're keeping this here for now because this module is + # the only one using it, and because this whole thing + # may go away in the next step of refactoring this to + # disassociate Builders from Nodes entirely. + class NullExecutor: + def get_build_env(self): + class NullEnvironment: + def get_scanner(self, key): + return None + return NullEnvironment() + def get_build_scanner_path(self): + return None + def __call__(self, *args, **kw): + pass + def cleanup(self): + pass + executor = NullExecutor() + else: + if self.pre_actions: + act = self.pre_actions + act + if self.post_actions: + act = act + self.post_actions + executor = SCons.Executor.Executor(act, + self.env or self.builder.env, + [self.builder.overrides], + [self], + self.sources) self.executor = executor return executor @@ -204,8 +227,6 @@ class Node: so only do thread safe stuff here. Do thread unsafe stuff in built(). """ - if not self.has_builder(): - return def errfunc(stat, node=self): raise SCons.Errors.BuildError(node=node, errstr="Error %d" % stat) executor = self.get_executor() @@ -303,7 +324,6 @@ class Node: and __nonzero__ attributes on instances of our Builder Proxy class(es), generating a bazillion extra calls and slowing things down immensely. - __cacheable__ """ try: b = self.builder @@ -314,6 +334,9 @@ class Node: b = self.builder return not b is None + def set_explicit(self, is_explicit): + self.is_explicit = is_explicit + def has_explicit_builder(self): """Return whether this Node has an explicit builder @@ -321,7 +344,11 @@ class Node: non-explicit, so that it can be overridden by an explicit builder that the user supplies (the canonical example being directories).""" - return self.has_builder() and self.builder.is_explicit + try: + return self.is_explicit + except AttributeError: + self.is_explicit = None + return self.is_explicit def get_builder(self, default_builder=None): """Return the set builder, or a specified default value""" @@ -426,28 +453,15 @@ class Node: This function may be called very often; it attempts to cache the scanner found to improve performance. """ - # Called from scan() for each child (node) of this node - # (self). The scan() may be called multiple times, so this - # gets called a multiple of those times; caching results is - # good. Index results based on the id of the child; can - # ignore build_env parameter for the index because it's passed - # as an optimization of an already-determined value, not as a - # changing parameter. - - if not self.has_builder(): - return None - scanner = None try: scanner = self.builder.source_scanner except AttributeError: pass - - # Not cached, so go look up a scanner from env['SCANNERS'] - # based on the node's scanner key (usually the file - # extension). - if not scanner: + # The builder didn't have an explicit scanner, so go look up + # a scanner from env['SCANNERS'] based on the node's scanner + # key (usually the file extension). scanner = self.get_build_env().get_scanner(node.scanner_key()) if scanner: scanner = scanner.select(node) -- cgit v0.12