-
-
Notifications
You must be signed in to change notification settings - Fork 311
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
Some fixes to sconsign #3238
Some fixes to sconsign #3238
Conversation
The previous fix changed a failing line that printed something that could be bytes in Py3 to do a decode. But it turned out that value can be either str or bytes and the change failed the sconsign tests. Use a try block instead of unconditionally calling decode. Signed-off-by: Mats Wichmann <mats@linux.com>
src/script/sconsign.py
Outdated
try: | ||
bkids = entry.bsources + entry.bdepends + entry.bimplicit | ||
bkidsigs = entry.bsourcesigs + entry.bdependsigs + entry.bimplicitsigs | ||
except AttributeError: | ||
return None | ||
result = [] | ||
for i in range(len(bkids)): | ||
result.append(nodeinfo_string(bkids[i], bkidsigs[i], " ")) | ||
for bkid, bkidsig in zip(bkids, bkidsigs): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could be list comprehension.. (which is faster than for loop.. ;)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done... though I don't think this is a performance critial place, as it's outputting a bunch of strings to stdout and won't ever do anything with results beyond that....
Signed-off-by: Mats Wichmann <mats@linux.com>
@staticmethod | ||
def printentries(dir, val): | ||
try: | ||
print('=== ' + dir + ':') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For clarity, this problem turned up on a nearly empty sconsign file, which on Python2, which did not error, displayed this way:
=== .:
help: None 0 0
Using Python 3, it threw an exception:
print('=== ' + dir + ':')
TypeError: must be str, not bytes
src/script/sconsign.py
Outdated
result = [] | ||
for i in range(len(bkids)): | ||
result.append(nodeinfo_string(bkids[i], bkidsigs[i], " ")) | ||
result = [nodeinfo_string(bkid, bkidsig, " ") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This problem turned up after a complex build, sconsign file is 2404476 bytes. thows an IndexError because bkidsigs
is zero length, so indexing into it inside the loop failed. There are multiple instances in our build of this problem seen if we cause it not to error, but all come from the same sconscript/environment. This change causes sconsign not to error out but does not address why signatures are missing - it follows the manpage comment of "the lines are simply omitted" since in these cases the function will return an empty list aka None.
doc/man/sconsign.xml
Outdated
is assumed to be a traditional | ||
<markup>.sconsign</markup> | ||
file containing the signature entries | ||
for a single directory. | ||
If neither of those is true, | ||
<command>sconsign</command> | ||
attempts to guess the format (but will |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove will probably get it wrong..
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No problem, but it's true. sconsign doesn't seem to know how to recognize the default sconsign "dblite" format in any meaningful way, it only recognizes the presence of the file extension. If not found, the effort is passed on to python's whichdb, which didn't seem to be able to guess. The sentence was intended to lead into the (existing) next sentence, which is that you can specify the format with an argument.
Signed-off-by: Mats Wichmann <mats@linux.com>
So what is needed to make this workable? The main issue here is "fails on bad data"... probaby claiming that should be fixed is non-controversial, but the solution may not be. Around line 286, the change does what code in the engine does - zip the two lists so "extras" are dropped. That can be seen as masking the problem, rather than fixing the generation of the problem data in the engine. |
I think likely the right thing to do is issue and error and exit. Also perhaps a flag to keep going regardless...? (and or to just issue a warning instead of error and exit?) Or just issue an error for each and keep going? |
Well, in my case, it's one specific area it breaks on, so I'm happy enough for it to continue. Since the sconsign file problem doesn't seem to keep the project from building it seems it should be non-fatal to the sconsign program too. Any preferences on what the warning message should be? |
So this is an example from our build with a message added, to prompt discussion about how it could be more informative:
|
Maybe add a warning count at bottom of output? |
Regarding warnings, is there a way to make SCons warnings fatal? If not, I'd suggest adding such a feature, maybe called |
I pursued this for a while a few months ago, when I found out calling a missing sconscript didn't fail the build. In the end, something specific to the sconscript topic went in; I still have a patch for my alternative approach sitting around, which was to add a |
Two locations which attempt to directly print an item tipped over on py3, so they now decode(). There seem to be cases where implicit dependencies do not have signatures, so instead of looping through the dep list and indexing into the signature list (IndexError), the two lists are now zipped, which means nothing is printed, but sconsign does not die (the zip technique is used in FS.py in the engine). Minor PEP8 changes: spaces around operators; shorter lines; two-blanks rule around classes/functions. Also unused args changed to _ to show it was intentional. Manpage updated slightly - the internal whichdb function explicitly looks for the .dblite suffix, so the claim that if it's not .dbm it is assumed to be dblite was not true. sconsign still will not work on a dblite file which is not suffixed .dblite, but that is an existing problem, not a newly introduced one. Signed-off-by: Mats Wichmann <mats@linux.com>
The previous fix changed a failing line that printed something that could be bytes in Py3 to do a decode. But it turned out that value can be either str or bytes and the change failed the sconsign tests. Use a try block instead of unconditionally calling decode. Signed-off-by: Mats Wichmann <mats@linux.com>
Signed-off-by: Mats Wichmann <mats@linux.com>
Signed-off-by: Mats Wichmann <mats@linux.com>
Rather than just silently moving on, emit warning messages if id count does not match signature count; summarize at the end if there were any warnings. Signed-off-by: Mats Wichmann <mats@linux.com>
afa1b65
to
1c7b5c0
Compare
@mwichmann - Sounds like a good approach though. Did it ever make it to a PR? |
No, but I can push one up if it's interesting. |
Is there any reasonable way to test this? |
test what? sconsign printing warnings? maybe there's a way to dummy up an sconsign file with the issue - there's already a test for a corrupt file. Not sure I know enough to build an artificial file. Meanwhile, until I fix our mess, we're able to reliably create a sconsign file that crashes unpatches sconsign. |
ok. Merging. |
@mwichmann - I'd definitely be interested in your work to add |
published as #3250 |
Two locations which attempt to directly print an item tipped over on py3, so they now decode().
There seem to be cases where implicit dependencies do not have signatures, so instead of looping through the dep list and indexing into the signature list (IndexError), the two lists are now zipped, which means nothing is printed, but sconsign does not die (the zip technique is used in FS.py in the engine).
Minor PEP8 changes: spaces around operators; shorter lines; two-blanks rule around classes/functions. Also unused args changed to _ to show it was intentional.
Manpage updated slightly - the internal whichdb function explicitly looks for the .dblite suffix, so the claim that if it's not .dbm it is assumed to be dblite was not true.
sconsign still will not work on a dblite file which is not suffixed .dblite, but that is an existing problem, not a newly introduced one.
Signed-off-by: Mats Wichmann mats@linux.com
Contributor Checklist:
master/src/CHANGES.txt
directory (and read theREADME.txt
in that directory)