[Scons-users] extending build environments (the OO-way)

Julius Ziegler ziegler at atlatec.de
Thu Sep 21 11:57:16 EDT 2017


Thanks for your reply, Gary.

Phew, its more complicated than I was hoping.

You have cleared up my main misunderstanding, that was that "Program" is 
a member function, while it actually is an object that has the __call__ 
function overloaded (am I right)?

After reading your message I was trying a bit to monkey patch the 
Program builder, like this:

def print_message( self, *args, **kwargs ):
     print "MESSAGE"
     self.old_call( *args, **kwargs )

env.Program.old_call = env.Program.__call__
env.Program.__call__ = print_message

Does that make sense?

I found out that this can not work directly, according to [1]

Maybe someone else has a better idea?

[1] 
https://stackoverflow.com/questions/38541015/how-to-monkey-patch-a-call-method



On 09/21/2017 05:09 PM, Gary Granger wrote:
> Here's something about the current solution to this we use, but I don't
> know if it would be considered a "best practice".  You're right that the
> methods on the Environment class which are builders are not treated like
> regular methods.  So to "wrap" a builder method, you can wrap the actual
> builder instance and replace that instance with your own, something like
> this:
>
> from SCons.Builder import BuilderBase
> from SCons.Builder import _null
>
> class MyProgramBuilder(BuilderBase):
>     def __init__(self, builder):
>         BuilderBase.__init__(self,
>                              action=builder.action,
>                              emitter=builder.emitter,
>                              prefix=builder.prefix,
>                              suffix=builder.suffix,
>                              src_suffix=builder.src_suffix,
>                              src_builder=builder.src_builder)
>
>     def __call__(self, env, target=None, source=None, chdir=_null, **kw):
>         ret = BuilderBase.__call__(self, env, target, source, chdir, **kw)
> 	print("Registered program %s" % (str(source[0]))
>         return ret
>
> ...
>
> env['BUILDERS']['Program'] = MyProgramBuilder(env['BUILDERS']['Program'])
>
> It could be a little fragile because the wrapper passes all the
> parameters up to BuilderBase, and the parameters needed by a Program
> builder instance could change.  Anyway, maybe that helps, or maybe
> someone knows a better way.
>
> Gary
>
> On 09/19/2017 03:20 AM, Julius Ziegler wrote:
>> Dear all,
>>
>> I am trying to extend what an environment does by inheritance.
>>
>> Here is an example of what I try to achive. Expected result is that
>> whenever I schedule build of a "Program" with a  MyEnv, a message gets
>> printed to stdout:
>>
>> class MyEnv( Environment ):
>>   def Program( self, *args, **kwargs ):
>>     print "REGISTERED PROGRAM TARGET", args[0]
>>     super().Program( *args, **kwargs )
>>
>> ...but this code seems to do nothing. It looks like the original
>> Environment overloads the class attribute access or something like
>> this. I am not a hardcore python programmer and it is really hard for
>> me to figure out what is going on.
>>
>> Is there a best practice to achieve something similar?
>>
>> Thanks!
>> Julius
>>
>

-- 
Dr.-Ing. Julius Ziegler

Phone:  +49 151 722 026 63
E-Mail: ziegler at atlatec.de
Web:    www.atlatec.de

Atlatec GmbH
Haid- und Neu-Strasse 7
D-76131 Karlsruhe

Sitz der Gesellschaft: Karlsruhe | Registergericht Mannheim
Handelsregisternummer: HRB 718673 | USt-IdNr. DE293003755
Geschäftsführer: Dr. Henning Lategahn


More information about the Scons-users mailing list