summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWilliam Deegan <bill@baddogconsulting.com>2017-03-10 16:19:42 -0500
committerWilliam Deegan <bill@baddogconsulting.com>2017-03-10 16:19:42 -0500
commitf6f2d97258aaee87385b8b867804f97ea1bd2bde (patch)
tree710e9174db9e253d079f7f8bd98bbddbd7f9f9d2
parent2349f35f3a91afb9e078b30f6e2ab0831f6804c5 (diff)
downloadscons-f6f2d97258aaee87385b8b867804f97ea1bd2bde.tar.gz
Fixing SConsValues to work with py2/3. Turns out because in py2 optparse.Values is a classic class deepcopy works different than in py3 when it's a modern class (no more classic classes). The net of which is deepcopy will look for various methods to copy the objects state, __deepcopy__, something else, then __setstate__. When it checks for __setstate__ it trys on a blank SConsValue instance which doesn't have __defaults__ and so SConsValues ends up throwing a KeyError exception. deepcopy is looking for an AttributeError exception to know that __setstate__ is not available. Once it receives the appropriate exception, it then properly copies the object and scons interactive mode works with py3
-rw-r--r--src/engine/SCons/Script/SConsOptions.py15
1 files changed, 14 insertions, 1 deletions
diff --git a/src/engine/SCons/Script/SConsOptions.py b/src/engine/SCons/Script/SConsOptions.py
index 501e4cef..288a7a5a 100644
--- a/src/engine/SCons/Script/SConsOptions.py
+++ b/src/engine/SCons/Script/SConsOptions.py
@@ -63,6 +63,7 @@ def diskcheck_convert(value):
raise ValueError(v)
return result
+
class SConsValues(optparse.Values):
"""
Holder class for uniform access to SCons options, regardless
@@ -112,7 +113,18 @@ class SConsValues(optparse.Values):
try:
return self.__dict__['__SConscript_settings__'][attr]
except KeyError:
- return getattr(self.__dict__['__defaults__'], attr)
+ try:
+ return getattr(self.__dict__['__defaults__'], attr)
+ except KeyError:
+ # Added because with py3 this is a new class,
+ # not a classic class, and due to the way
+ # In that case it will create an object without
+ # __defaults__, and then query for __setstate__
+ # which will throw an exception of KeyError
+ # deepcopy() is expecting AttributeError if __setstate__
+ # is not available.
+ raise AttributeError(attr)
+
settable = [
'clean',
@@ -186,6 +198,7 @@ class SConsValues(optparse.Values):
self.__SConscript_settings__[name] = value
+
class SConsOption(optparse.Option):
def convert_value(self, opt, value):
if value is not None: