[Scons-users] Substitution of Literal() broken when using Python 3

Philipp Maierhöfer maiphi.public at gmx.net
Sun May 20 12:54:31 EDT 2018


Hi all,

note: this problem has been discussed on the mailing lists before, see https://pairlist2.pair.net/pipermail/scons-dev/2017-June/004297.html, but as of today it hasn't been fixed in the master branch and I didn't find a corresponding issue in the bug tracker. In the following I propose a fix.

To reproduce the problem, create a SConstruct with the content
"""
Command('PHONY', '', 'echo $_RPATH', RPATH=Literal('\$$ORIGIN'))
"""
and run it with SCons with Python 3 (I tested with 3.6.5). This leads to the error
scons: *** [PHONY] TypeError `unhashable type: 'Literal'' trying to evaluate `${_concat(RPATHPREFIX, RPATH, RPATHSUFFIX, __env__)}'.

Note that with Python 2.7 it works fine.

A solution that works for me is to add a __hash__ method to the class SCons.Subst.Literal:
"""
diff --git a/src/engine/SCons/Subst.py b/src/engine/SCons/Subst.py
index 68d247f8..b0abf613 100644
--- a/src/engine/SCons/Subst.py
+++ b/src/engine/SCons/Subst.py
@@ -78,6 +78,9 @@ class Literal(object):
     def is_literal(self):
         return 1

+    def __hash__(self):
+        return hash(self.lstr)
+
     def __eq__(self, other):
         if not isinstance(other, Literal):
             return False
"""

I don't know why the Literal needs to be hashable in Python 3 but not in Python 2. And I cannot decide if the above patch is a viable solution or if the problem should be addressed somewhere else.

A workaroud on the user side (in your SConstruct) may look like this:
"""
import SCons
class HashableLiteral(SCons.Subst.Literal):
    def __hash__(self):
        return hash(self.lstr)
"""
Then use HashableLiteral instead of Literal.

Cheers,
Philipp


More information about the Scons-users mailing list