bpo-31810: Add smelly.py to check exported symbols#4057
Conversation
* Add Tools/scripts/smelly.py: script checking if all symbols exported by libpython start with "Py" or "_Py". * Modify "make smelly" to run smelly.py: the command now fails with a non-zero exit code if libpython leaks a "smelly" symbol. * Travis CI now runs "make smelly"
|
@CuriousLearner proposed a simpler patch which only runs "make smelly" : PR #4054, as I proposed in the BPO. Sadly, I didn't notice that "make smelly" always exits with an exit code 0, even if libpython leaks symbols. @taleinat: Would you mind to review this PR please? |
|
I tested my change manually with this diff: make smelly fails as expected with non-zero exit code: When libpython doesn't leak symbols, "make smelly" succeed: |
Use a blacklist of symbol types rather than a whitelist of symbol
types ("T", "D", "B").
Display the list of ignored symbol types, and add also the symbol
type in the list of smelly symbols.
taleinat
left a comment
There was a problem hiding this comment.
LGTM. I have several minor comments, but they are about style and code readability and can be ignored if preferred.
| - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then ./python Tools/scripts/patchcheck.py --travis $TRAVIS_PULL_REQUEST; fi | ||
| # `-r -w` implicitly provided through `make buildbottest`. | ||
| - make buildbottest TESTOPTS="-j4 -uall,-cpu" | ||
| # Check if all symbols exported by libpython start with "Py" or "_Py" |
There was a problem hiding this comment.
Maybe change "Check if" to "Check that" or "Validate that" for better clarity?
| -exec rm -f {} ';' | ||
|
|
||
| # Check for smelly exported symbols (not starting with Py/_Py) | ||
| # Check if all symbols exported by libpython start with "Py" or "_Py" |
| return stdout | ||
|
|
||
|
|
||
| def get_smelly_symbols(stdout): |
There was a problem hiding this comment.
stdout is not a very informative name here, and somewhat confusing in the body of the function.
There was a problem hiding this comment.
Done, renamed to nm_output.
|
|
||
|
|
||
| def get_smelly_symbols(stdout): | ||
| symbols = [] |
There was a problem hiding this comment.
Why not have this function be a generator and just yield the smelly symbols? Just style preference so feel free to ignore.
| # If lowercase, the symbol is usually local; if uppercase, the symbol | ||
| # is global (external). There are however a few lowercase symbols that | ||
| # are shown for special global symbols ("u", "v" and "w"). | ||
| if symtype.islower() and symtype not in ("u", "v" "w"): |
There was a problem hiding this comment.
Is the lack of comma between 'v' and 'w' intended or is it just a typo ?
There was a problem hiding this comment.
Oops, it's a bug. Fixed.
|
The current "make smelly" rule don't check for these symbol types:
This list seems incomplete. "C" symbols are ignored, whereas there are also exported:
I modified the code to use a blacklist of private symbol types, rather than a whitelist of public symbols. I tested manually: the new modified smelly.py is now able to detect a leaked "C" symbol which doesn't start with Py/_Py. |
| @@ -1,5 +1,5 @@ | |||
| #!/usr/bin/env python | |||
| # Script checking if all symbols exported by libpython start with "Py" or "_Py" | |||
| # Script checking that all symbols exported by libpython start with Py or _Py | |||
There was a problem hiding this comment.
I would use "Py" or "_Py" to keep the same style with others comments
There was a problem hiding this comment.
I tried, but it doesn't fit into 80 characters :-)
There was a problem hiding this comment.
You can write:
# Script checking that all symbols exported by libpython
# start with Py or _Py
Is just a style preference =D
|
Thanks for your reviews @taleinat, @eamanu and @SylvainDe! I merged my PR. |
exported by libpython start with "Py" or "_Py".
non-zero exit code if libpython leaks a "smelly" symbol.
https://bugs.python.org/issue31810