[Scons-users] Bug in FunctionAction: not allowing custom get_contents

Jeremy Elson jelson at gmail.com
Sat Sep 19 02:31:37 EDT 2020


Hi! First, let me just say congratulations on making a wonderful build
system. I've been using it to manage a very complex build system and it has
worked wonderfully.

I believe I have found a bug in a somewhat obscure area of scons. I'm
creating a custom Builder with a FunctionAction, i.e. an action that calls
a Python function. I want to override get_contents so that my action can
tell scons when it needs to be re-invoked. There isn't anything in the
documentation on this topic, but from reading the scons sources it appears
I need to make a callable object that has a get_contents attribute, like
this:

class MyCustomAction:
    def __call__(self, env, target, source):
        <....my code that generates targets from source....>

    def get_contents(self, env, target, source):
        <... my code that computes a signature based on relevant parts of
source>

env.Append(BUILDERS={'MyCustomAction': Builder(
    action=MyCustomAction()
)})

This does succeed in generating the targets from source, but scons is not
properly deciding when the target needs to be rebuilt based on the source.
In the course of my debugging, I added "assert(False)" to get_contents and
discovered it was never being called.

I believe the source of the bug is in the scons implementation of
FunctionAction (in Action.py). Specifically, the __init__ function, which I
have quoted in part below. It appears to try to determine the static
contents of the function first, by calling _callable_contents. Only if that
fails does it check if the callable contains its own get_contents function.

Shouldn't the check to see if get_contents is a defined attribute come
first?

        self.execfunction = execfunction
        try:
            self.funccontents = _callable_contents(execfunction)
        except AttributeError:
            try:
                # See if execfunction will do the heavy lifting for us.
                self.gc = execfunction.get_contents
            except AttributeError:
                # This is weird, just do the best we can.
                self.funccontents = _object_contents(execfunction)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://pairlist4.pair.net/pipermail/scons-users/attachments/20200918/cf310e72/attachment.html>


More information about the Scons-users mailing list