Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ParseConfig can fail when adding to CPPDEFINES #4321

Closed
mwichmann opened this issue Mar 9, 2023 · 14 comments · Fixed by #4322
Closed

ParseConfig can fail when adding to CPPDEFINES #4321

mwichmann opened this issue Mar 9, 2023 · 14 comments · Fixed by #4322
Labels
Append Issues in Append/Prepend + Unique variants bug Version: 4.5.0
Milestone

Comments

@mwichmann
Copy link
Collaborator

mwichmann commented Mar 9, 2023

After the changes in CPPDEFINES handling for SCons 4.5, it is possible for ParseConfig to hit a TypeError. Here is one traceback:

TypeError: sequence index must be integer, not 'slice':
  File "/home/akien/Projects/godot/godot.git/SConstruct", line 539:
    detect.configure(env)
  File "/home/akien/Projects/godot/godot.git/./platform/linuxbsd/detect.py", line 309:
    env.ParseConfig("pkg-config libpulse --cflags --libs")
  File "/home/akien/.local/lib/python3.10/site-packages/SCons/Environment.py", line 1773:
    return function(self, self.backtick(command), unique)
  File "/home/akien/.local/lib/python3.10/site-packages/SCons/Environment.py", line 1767:
    return env.MergeFlags(cmd, unique)
  File "/home/akien/.local/lib/python3.10/site-packages/SCons/Environment.py", line 1095:
    for v in orig[::-1]:

For this condition to trigger, CPPDEFINES in that environment must have previously been converted into the internal deque type. The error actually happens in MergeFlags, which tries to do various complicated things to simulate what the Append routine would do in adding. Since Append and relatives now short-circuits that work in case the key is CPPDEFINES, it seems MergeFlags should do the same.

@mwichmann mwichmann added bug Append Issues in Append/Prepend + Unique variants Version: 4.5.0 labels Mar 9, 2023
@akien-mga
Copy link

Attaching a minimal reproduction project, which reproduces the issue with 4.5.0 and 4.5.1:
scons-ParseConfig-CPPDEFINES-merge.zip

@mwichmann
Copy link
Collaborator Author

I'm seeing another hole here, I think - env.Override(parse_flags={some: dict}) seems to not give an independent value. Investigating - this tripped on an existing testcase after a change for the above.

@bdbaddog bdbaddog added this to the NextRelease milestone Mar 9, 2023
@bdbaddog
Copy link
Contributor

bdbaddog commented Mar 9, 2023

ok. Once we have a fix for both, we can roll a 4.5.2

@mwichmann
Copy link
Collaborator Author

mwichmann commented Mar 9, 2023

Sigh, it looks like (without documenting it), MergeFlags always creates a new item, so my short-circuit means that doesn't happen, and so indeed that opens up a new leak-through

@mwichmann
Copy link
Collaborator Author

@akien-mga - the patch proposed in the PR ended up being different, because of the new problem that one created. Would you be able to test the change from SCons/Environment.py in your setup to make sure it still works for you?

@akien-mga
Copy link

@mwichmann I confirm that #4322 (as of e58b9c3) fixes the bug for me, applied the diff manually on top of pip-installed 4.5.1.

@mwichmann
Copy link
Collaborator Author

Not going to tackle this here, as want to keep this PR as a simple "hotfix", but don't actually see any reason why MergeFlags needs to reimplement the adding logic (it contains the comment The logic here was lifted from part of env.Append() ) - we've already proven here that having it in two places makes it more fragile. So someday... at that point, the caller should end up indicating whether the variables merged into need to be independent (Override case) or the existing environment vars can be safely updated (all other callers, AFAICT).

@mgorny
Copy link
Contributor

mgorny commented Mar 21, 2023

Could you please make a new release with this fix? This is affecting at least godot on Gentoo, and quite likely dxx-rebirth (I haven't confirmed whether it's the same cause).

@bdbaddog
Copy link
Contributor

Could you please make a new release with this fix? This is affecting at least godot on Gentoo, and quite likely dxx-rebirth (I haven't confirmed whether it's the same cause).

IRL issues causing delay. I'll try to get it out today sometime.

@bdbaddog
Copy link
Contributor

4.5.2 released.

@mgorny
Copy link
Contributor

mgorny commented Mar 21, 2023

Thank you!

@arbruijn
Copy link

There's still a deque returned by env['CPPDEFINES'] in 4.5.2 after env.Append with an existing and added list, which can break SConstruct files. The documentation seems to suggest it should result in a list (7.2.10. Appending to the End of Values: the Append Method). Is this an intended change of behavior?

Example that worked before 4.5.0 and breaks since 4.5.0:

env = Environment()
env.Append(CPPDEFINES = ['A'])
env.Append(CPPDEFINES = ['B'])
defs = env['CPPDEFINES'] + ['X']

@mwichmann
Copy link
Collaborator Author

mwichmann commented Mar 21, 2023

It was an intended change. What type it is is supposed to be internal, and works consistently internally, but there's not much to be done if the API methods for amending are not used - adding an object directly using Python syntax. May have to give up on deque (it was chosen because the Prepend methods then work as cleanly as the Append methods without resorting to tricks - one of the instances in the old version, but not all, reversed, added, reversed again to Prepend).

Note that whatever that snip in the user guide says, the internal represntation was never guaranteed, and could change depending on what operations you performed. Using a different pathway of building up CPPDEFINES you could have ended up with a dict, and then your same add would fail (hypothetical example, but I ran through lots of these permutations when I expanded the tests):

emv = Environment()
env.Append(CPPDEFINES={'A': None, 'B': None})
defs = env['CPPDEFINES'] + ['X']

would take an exception

TypeError: unsupported operand type(s) for +: 'dict' and 'list'

@vLKp
Copy link

vLKp commented Mar 22, 2023

Regarding #4321 (comment) :

This is affecting at least godot on Gentoo, and quite likely dxx-rebirth (I haven't confirmed whether it's the same cause).

I think the Rebirth problem was caused by the same SCons change that broke ParseConfig, but the failure mode is different, and I think the change in a4ab466 would not help Rebirth. Rebirth had an expression of the form env.get(name, [])[:], which sought to look up a variable from the construction environment and create a copy of it. When the construction environment returned a Python list, [:] worked. Now that SCons returns a Python deque, the error reported in dxx-rebirth/dxx-rebirth#704 occurs, because deque does not understand using [:] to create a copy. I changed that expression to env.get(name, []).copy(), which works just as well on SCons 4.4. I have not tried it on SCons 4.5 yet (scons is not slotted, and I am not ready to remove SCons 4.4 yet), but I published the change in the hope that it would be useful.

arbruijn added a commit to arbruijn/dxx-rebirth that referenced this issue Mar 22, 2023
env['CPPDEFINES'] may return a deque object in scons 4.5.0+ (see
SCons/scons#4321).
Explicitly convert it to a list where needed.

Tested with scons 4.4.0, 4.5.0, 4.5.1 and 4.5.2.
rpurdie pushed a commit to yoctoproject/poky that referenced this issue Mar 26, 2023
* fixes:
  SCons/scons#4321
  which caused e.g. iotifity to fail in do_compile

(From OE-Core rev: 5b022730053cdf62db57f497014ed85e2f7057b6)

Signed-off-by: Martin Jansa <[email protected]>
Signed-off-by: Alexandre Belloni <[email protected]>
Signed-off-by: Richard Purdie <[email protected]>
halstead pushed a commit to openembedded/openembedded-core that referenced this issue Mar 26, 2023
* fixes:
  SCons/scons#4321
  which caused e.g. iotifity to fail in do_compile

Signed-off-by: Martin Jansa <[email protected]>
Signed-off-by: Alexandre Belloni <[email protected]>
arbruijn added a commit to arbruijn/DXX-Retro that referenced this issue Apr 16, 2023
In scons 4.5+ env['CPPDEFINES'] can sometimes return a deque object.
See SCons/scons#4321
arbruijn added a commit to arbruijn/DXX-Retro that referenced this issue Apr 16, 2023
In scons 4.5+ env['CPPDEFINES'] can sometimes return a deque object
(see SCons/scons#4321). Convert it to a list where needed.
daregit pushed a commit to daregit/yocto-combined that referenced this issue May 22, 2024
* fixes:
  SCons/scons#4321
  which caused e.g. iotifity to fail in do_compile

(From OE-Core rev: 5b022730053cdf62db57f497014ed85e2f7057b6)

Signed-off-by: Martin Jansa <[email protected]>
Signed-off-by: Alexandre Belloni <[email protected]>
Signed-off-by: Richard Purdie <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Append Issues in Append/Prepend + Unique variants bug Version: 4.5.0
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants