diff --git a/CHANGES.txt b/CHANGES.txt
index 45a195d533..d5cf6bc497 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -9,6 +9,10 @@ NOTE: 4.3.0 now requires Python 3.6.0 and above. Python 3.5.x is no longer suppo
RELEASE VERSION/DATE TO BE FILLED IN LATER
+ From Thaddeus Crews:
+ - GetSConsVersion() to grab the latest SCons version without needing to
+ access SCons internals.
+
From Raymond Li:
- Fix issue #3935: OSErrors are now no longer hidden during execution of
Actions. All exceptions during the execution of an Action are now
diff --git a/RELEASE.txt b/RELEASE.txt
index 661cddf968..92e10e2e81 100644
--- a/RELEASE.txt
+++ b/RELEASE.txt
@@ -16,7 +16,7 @@ Here is a summary of the changes since 4.7.0:
NEW FUNCTIONALITY
-----------------
-- List new features (presumably why a checkpoint is being released)
+- GetSConsVersion() added to retrieve the SCons version.
DEPRECATED FUNCTIONALITY
------------------------
diff --git a/SCons/Script/SConscript.py b/SCons/Script/SConscript.py
index 85070ab053..a2ef3b9d57 100644
--- a/SCons/Script/SConscript.py
+++ b/SCons/Script/SConscript.py
@@ -45,6 +45,7 @@
import sys
import traceback
import time
+from typing import Tuple
class SConscriptReturn(Exception):
pass
@@ -385,7 +386,7 @@ class SConsEnvironment(SCons.Environment.Base):
# Private methods of an SConsEnvironment.
#
@staticmethod
- def _get_major_minor_revision(version_string):
+ def _get_major_minor_revision(version_string: str) -> Tuple[int, int, int]:
"""Split a version string into major, minor and (optionally)
revision parts.
@@ -484,15 +485,22 @@ def Default(self, *targets) -> None:
SCons.Script._Set_Default_Targets(self, targets)
@staticmethod
- def EnsureSConsVersion(major, minor, revision: int=0) -> None:
+ def GetSConsVersion() -> Tuple[int, int, int]:
+ """Return the current SCons version.
+
+ .. versionadded:: 4.8.0
+ """
+ return SConsEnvironment._get_major_minor_revision(SCons.__version__)
+
+ @staticmethod
+ def EnsureSConsVersion(major: int, minor: int, revision: int = 0) -> None:
"""Exit abnormally if the SCons version is not late enough."""
# split string to avoid replacement during build process
if SCons.__version__ == '__' + 'VERSION__':
SCons.Warnings.warn(SCons.Warnings.DevelopmentVersionWarning,
"EnsureSConsVersion is ignored for development version")
return
- scons_ver = SConsEnvironment._get_major_minor_revision(SCons.__version__)
- if scons_ver < (major, minor, revision):
+ if SConsEnvironment.GetSConsVersion() < (major, minor, revision):
if revision:
scons_ver_string = '%d.%d.%d' % (major, minor, revision)
else:
diff --git a/SCons/Script/SConscript.xml b/SCons/Script/SConscript.xml
index 3c729947f4..a201c969e0 100644
--- a/SCons/Script/SConscript.xml
+++ b/SCons/Script/SConscript.xml
@@ -136,6 +136,19 @@ EnsureSConsVersion(0,96,90)
+
+
+()
+
+
+
+Returns the current SCons version in the form of a Tuple[int, int, int],
+representing the major, minor, and revision values respectively.
+Added in 4.7.1.
+
+
+
+
([value])
diff --git a/SCons/Script/__init__.py b/SCons/Script/__init__.py
index a62650f7f6..ce0105573c 100644
--- a/SCons/Script/__init__.py
+++ b/SCons/Script/__init__.py
@@ -297,6 +297,7 @@ def Variables(files=None, args=ARGUMENTS):
#
# Static functions that do not trigger initialization of
# DefaultEnvironment() and don't use its state.
+GetSConsVersion = _SConscript.SConsEnvironment.GetSConsVersion
EnsureSConsVersion = _SConscript.SConsEnvironment.EnsureSConsVersion
EnsurePythonVersion = _SConscript.SConsEnvironment.EnsurePythonVersion
Exit = _SConscript.SConsEnvironment.Exit
diff --git a/doc/generated/functions.mod b/doc/generated/functions.mod
index 7273aababf..0fb4a354ee 100644
--- a/doc/generated/functions.mod
+++ b/doc/generated/functions.mod
@@ -50,6 +50,7 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT.
GetBuildPath">
GetLaunchDir">
GetOption">
+GetSConsVersion">
Glob">
Help">
Ignore">
@@ -132,6 +133,7 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT.
env.GetBuildPath">
env.GetLaunchDir">
env.GetOption">
+env.GetSConsVersion">
env.Glob">
env.Help">
env.Ignore">
@@ -220,6 +222,7 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT.
GetBuildPath">
GetLaunchDir">
GetOption">
+GetSConsVersion">
Glob">
Help">
Ignore">
@@ -302,6 +305,7 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT.
env.GetBuildPath">
env.GetLaunchDir">
env.GetOption">
+env.GetSConsVersion">
env.Glob">
env.Help">
env.Ignore">
diff --git a/doc/scons.mod b/doc/scons.mod
index d44cfbdaa7..938886ba99 100644
--- a/doc/scons.mod
+++ b/doc/scons.mod
@@ -214,6 +214,7 @@
EnumVariable">
EnsurePythonVersion">
EnsureSConsVersion">
+GetSConsVersion">
Environment">
Execute">
Exit">
diff --git a/doc/user/misc.xml b/doc/user/misc.xml
index ef2e4ca1d6..7d1448d5f5 100644
--- a/doc/user/misc.xml
+++ b/doc/user/misc.xml
@@ -177,6 +177,32 @@ SCons 1.0 or greater required, but you have SCons 0.98.5
+
+ Accessing SCons Version: the &GetSConsVersion; Function
+
+
+
+ While &EnsureSConsVersion; is acceptable for most cases, there
+ are times where the user will want to support multiple SCons versions
+ simultaneously. In this scenario, it's beneficial to retrieve version
+ information of the currently executing SCons directly. This was previously
+ only possible by accessing SCons internals. From SCons4.8 onwards, it's now possible
+ to instead call &GetSConsVersion; to recieve a tuple containing the
+ major, minor, and revision values of the current version.
+
+
+
+
+if GetSConsVersion() >= (4, 9):
+ # Some function got a new argument in 4.9 that we want to take advantage of
+ SomeFunc(arg1, arg2, arg3)
+else:
+ # Can't use the extended syntax, but it doesn't warrant exiting prematurely
+ SomeFunc(arg1, arg2)
+
+
+
+
Explicitly Terminating &SCons; While Reading &SConscript; Files: the &Exit; Function
diff --git a/test/EnsureSConsVersion.py b/test/EnsureSConsVersion.py
index 7eae2ad9cd..efdc17f767 100644
--- a/test/EnsureSConsVersion.py
+++ b/test/EnsureSConsVersion.py
@@ -63,6 +63,23 @@
test.run(status=2)
+ test.write('SConstruct', """\
+env = Environment()
+env.EnsureSConsVersion(*env.GetSConsVersion())
+Exit(0)
+""")
+
+ test.run()
+
+ test.write('SConstruct', """\
+env = Environment()
+ver = env.GetSConsVersion()
+env.EnsureSConsVersion(ver[0], ver[1], ver[2])
+Exit(0)
+""")
+
+ test.run()
+
test.write('SConstruct', """\
@@ -121,6 +138,20 @@
test.run(status=2)
+test.write('SConstruct', """\
+import SCons
+EnsureSConsVersion(*GetSConsVersion())
+""")
+
+test.run()
+
+test.write('SConstruct', """\
+import SCons
+ver = GetSConsVersion()
+EnsureSConsVersion(ver[0], ver[1], ver[2])
+""")
+
+test.run()
test.pass_test()