scons icon indicating copy to clipboard operation
scons copied to clipboard

Disallow Cloning() and Override()

Open bdbaddog opened this issue 9 months ago • 2 comments

This is added as a solution to the issue described in PR #4041.

Basically Override()'s are meant to be a light weight deadending copy of an Environment() typically created automatically by SCons when an env var is specialized in a Builder() call.

Here's a possible way to disallow this, from @mwichmann (from: https://github.com/SCons/scons/pull/4041#issuecomment-951359529)

    def __copy__(self):
        from copy import Error

        raise Error("un(shallow)copyable object of type %s" % type(self))

bdbaddog avatar Apr 06 '25 21:04 bdbaddog

FYI, I ran into a similar issue as in that PR when also migrating an old working build script from a python2 to python3 environment, using scons 4.4.0.

In my case, though, I'm not calling Override anywhere in my own scripts. What ended up being the culprit is that it uses MakeBuilder, which performs an env.Clone() inside the message handler, which apparently works in python2 but gets upset in python3:

scons: *** [/workspace/build/cryptopp/libcryptopp.a] KeyError : '__subject'
Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/SCons/Taskmaster.py", line 235, in execute
    self.targets[0].build()
  File "/usr/lib/python3/dist-packages/SCons/Node/__init__.py", line 755, in build
    self.get_executor()(self, **kw)
  File "/usr/lib/python3/dist-packages/SCons/Executor.py", line 384, in __call__
    return _do_execute_map[self._do_execute](self, target, kw)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/SCons/Executor.py", line 117, in execute_action_list
    status = act(*args, **kw)
             ^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/SCons/Action.py", line 684, in __call__
    cmd = self.strfunction(target, source, env, executor)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/workspace/scons/site_scons/site_tools/Make.py", line 73, in message
    myenv = env.Clone()
            ^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/SCons/Environment.py", line 1470, in Clone
    clone = copy.copy(self)
            ^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/copy.py", line 102, in copy
    return _reconstruct(x, None, *rv)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/copy.py", line 272, in _reconstruct
    if hasattr(y, '__setstate__'):
       ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/SCons/Environment.py", line 2411, in __getattr__
    attr = getattr(self.__dict__['__subject'], name)
                   ~~~~~~~~~~~~~^^^^^^^^^^^^^
KeyError: '__subject'
scons: building terminated because of errors.

(FWIW, I also added the executor argument explicitly -- you otherwise get the same error but it's disguised a bit more due to how Action implements the fallback.)

I worked around this by commenting out the message handler, but it would be nice to know a better fix.

gavinltomra avatar May 26 '25 03:05 gavinltomra

@gavinltomra the env.Clone() really isn't needed at all. It seems like it's only used to modify/set MakeTargets, which instead could be passed to env.subst() via the overrides dict it takes as an argument

bdbaddog avatar May 27 '25 00:05 bdbaddog