user2821
user2821

Reputation: 1604

When I invoke python script with a print statement in it, SCons generates a corrupt target

I'm a bit confused about how to build from Python script or why SCons doesn't build correctly.

A silly but minimal (not) working example:

I have a Python script, plot.py:

import matplotlib.pyplot as plt

fig, ax = plt.subplots( nrows=1, ncols=1 ) 
ax.plot([0,1,2], [10,20,3])
print 'Doing some stuff...'
fig.savefig('figure.png')   

If I run the script in terminal $ python plot.py it creates a nice image file but if invoke the script from SCons, it creates a corrupt file that can't be opened. However, it seems to have the same size as it should.

import os
env = Environment(ENV = os.environ)
env.Command('figure.png', 'plot.py', 'python $SOURCE > $TARGET')

If I specify target as $ scons figure.png the result is the same. Cleaning and rebuilding (scons -c) doesn't help. I get no Error message.

$ scons
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
python plot.py > figure.png
scons: done building targets.

A debug looks OK, as far as I can tell:

+-.
  +-SConstruct
  +-figure.png
  | +-plot.py
  | +-/Users/tobiasstal/anaconda/bin/python
  +-plot.py

But, interestingly enough, if I remove the print statement it works.

import matplotlib.pyplot as plt
import time

fig, ax = plt.subplots( nrows=1, ncols=1 ) 
ax.plot([0,1,2], [10,20,3])
time.sleep(3)
# print 'Doing some stuff...'
fig.savefig('figure.png')  

Also if I run the Python script above directly in the SConstruct file it saves the figure correctly.

What do I do wrong? How do I invoke a Python script from SCons to generate a working target, even if there is a print statement in the script?

Using OS 10.11.6 Python 2.7 SCons 2.5.0

Upvotes: 0

Views: 505

Answers (1)

bdbaddog
bdbaddog

Reputation: 3509

Given that your python script writes to the target and then you create output which gets redirected to the same target, it's not surprising you get a corrupt file...

import os
env = Environment(ENV = os.environ)
env.Command('figure.png', 'plot.py', 'python $SOURCE > $TARGET')

You can either omit "> $TARGET" from the command string. Or modify your script to take an argument which is the target file and change your SCons logic to be

import os
env = Environment(ENV = os.environ)
env.Command('figure.png', 'plot.py', 'python $SOURCE $TARGET')

Upvotes: 1

Related Questions