[Scons-dev] Why we need to release separate SCons3 for Python 3

Evan Driscoll driscoll at cs.wisc.edu
Sat Feb 23 15:49:53 EST 2013

I've sort of read over this thread; here are some of my thoughts as a
user of SCons. I'll a shot at saying what the problem is with end-user
SConstruct/script files (I'll just use "SConstruct" below but I mean
both) and my input on a couple of the suggestions.

I'll refer to an SCons installation that uses Python 2 as scons-py2, and
an SCons installation that uses Python 3 as scons-py3. (I'd prefer these
names to 'scons2' and 'scons3' because I think the latter suggests
versions of SCons rather than versions of Python, and I suspect you
don't want that. (E.g. if you release a version of SCons that works on
both Python versions with the same code base, would you give the Python
2 version of SCons the version number 2.4 or something and the Python 3
version of the exact same code 3.0? :-))

1. Some SConstruct files will work only with scons-py2 (e.g. if they
use a "print" statement not as a function), some not-yet-written
SConstruct files will work only with scons-py3 (e.g. if they use a
print function without a future import), and some will work with
both because they either don't use anything that differs or because
they are written carefully to be compatible with both.

The first and third at least are just a fact; that's just how things
are and basically must be. You can try to minimize the amount of
times the second occurs by stressing in the docs that people should
try to write portable SConstruct files, but for a variety of reasons
people won't listen to you and the second situation will emerge. :-)

2. From the perspective of someone who wants to build software that
uses SCons, think about what this means. Now you have to know what
version of SCons to use -- Python 2 or 3. This isn't a huge deal,
but it is one more step of a process that I feel is already rather
less standardized than what you get with, say, autotools. (That's
said with the disclaimer that I've actually only built one or two
things not written by me that use SCons.)

3. These two things means that detecting the case where the SConstruct
was written for the other version of SCons and giving a helpful
error is highly desirable. I can think of three or four ways in
which an incompatibility can manifest:

* The easy case: syntax errors. For example, someone tries to build
with scons-py3 a program that has an SConstruct that uses 'print'
as a statement, or they try to use scons-py2 to build something
that uses the 'print' function with keyword arguments as a
function without a future import. But see the next point, because
this is NOT actually quite as easy as it sounds.

* A harder case: errors that arise only after processing some of the
SConstruct. For instance, for some reason an SConstruct does as
comparison 'a < b' where, in Python 3, 'a' and 'b' are
incomparable. (E.g. In Python 2 if you say "1 < 'hi'" you'd get
some arbitrary ordering; in Python 3, that's a TypeError.) If this
is discovered during SConstruct processing (not building), you
won't have really started building anything so it's probably fine,
but at the same time the user WILL have had part of his code run
so there is a theoretical chance of bad things happening. (But
maybe not enough to worry about.)

Note that many instances the first case actually appear here. If
the 'SConstruct' file (here I actually mean "SConstruct") calls
SConscript(), and the file it reads then has a syntax error, that
will only be discovered after enough of the SConstruct has been
read that it hits that call to SConscript().

* An even harder case: errors that arise during the building phase.
I think that this can only happen if the user uses a builder that
calls a Python function instead of shelling out to a program --
but it can certainly happen in such a case.

* The hardest case: errors which the SCons engine never sees but
which silently change the behavior of the build. This would happen
if, e.g., the SConscript does division and uses an integer result
differently than a floating point result, or were to do the
'a < b' thing but catch the TypeError that arose and do something

I don't think that all of these are necessarily something you should
necessarily worry about in practice, but it does illustrate that
determining compatibility is something which is not trivial. Even in
the second case it isn't easy -- if the SConstruct throws a
TypeError, is that because you're running with scons-py2 and it
needs scons-py3, or is that just because the SConstruct is buggy?

If you put all of this together, I think it's worthwhile to consider
having some mechanism to suggest to SCons which version of Python is

One potential way would be to have people use an SConstruct.3 file. This
seemed to get a cold reception before, but in the interest of
brainstorming, perhaps this modification of that idea will sound
attractive. scons-py2 looks for SConstruct files named 'SConstruct.2',
'SConstruct', 'Sconstruct.2', 'Sconstruct', 'sconstruct.2', and
'sconstruct', running the first it finds. scons-py3 looks for
'SConstruct.3', 'SConstruct', etc. (The order is up to you, or perhaps
you'd want to give an error if both 'SConstruct.2' and 'SConstruct' are
present, or something like that.) In addition to SCons being able to
better tell what version it should use, that presents a very clear hint
to the user.

Or you could go with this idea:

On 02/23/2013 04:24 AM, anatoly techtonik wrote:

> 3. obligatory #!/usr/bin/env scons3 in SConstruct files that are already

> ported to Python

> (this should be checked by scons 2 binary also, the string can be

> different)

I don't like that string, because it suggests that the SConstruct is
executable on its own, which it isn't. But perhaps something like
"# -*- python3 -*-" to emulate a common editor modeline. (Unfortunately
at least my version of Emacs doesn't recognize that as Python, and you'd
need "# -*- python -*- 3" to get it to.) You could then, before evaling
the SConstruct, check if that line is present by reading it normally.

Finally, you could have something akin to EnsureSConsVersion() that
checks the Python version during evaling of the file. The upside of this
compared to the previous one is that you don't have to do a separate
read of the file. The downside is that, if there are syntax errors, it
won't execute the EnsurePythonVersion() line and you'll be stuck
catching the syntax error (which I didn't check but I would guess is
possible). That's still a very good indication that the Python version
is wrong, but you still have to qualify the "you should use the other
version of Python" message with the statement that maybe it's just
broken. :-)


-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 554 bytes
Desc: OpenPGP digital signature
Url : <http://two.pairlist.net/pipermail/scons-dev/attachments/20130223/d5bcbdf5/attachment.pgp>

More information about the Scons-dev mailing list