Fixed issues with rbtools argument parsing on Python 3 when running '--help'
Review Request #10856 — Created Jan. 24, 2020 and submitted
On python 2, running
rbt --help <command>andrbt <command> --help
are equivalent. However, runningrbt <command> --helpdoes not work
on python 3. This happens because byte strings are utilized in the
code to see if--helpor-hare passed in as arguments. They are
never found because the code is trying to findb'--help' orb'-h'.
In python 2,b'--help'is equivalent to'--help', but in python 3,
this is not the case.To fix this issue, the byte strings
b'--help'andb’-h’have been
changed to python 3 compatible strings (i.e.--helpand-h). Unit
tests have also been added to ensure that all possible positions and
cases of the 'help' argument work for rbtools.(ex.rbt —help <command>,
rbt <command> -h,rbt help <command>, etc.).All tests were run using both python 2.7.17 and python 3.7.6.
Test cases run on python 2.7.17 and 3.7.6:
Test case whererbt help <command>is run
Test case whererbt <command> --helporrbt <command> -his run
Test case whererbt --help <command>orrbt -h <command>is run
Test case where an invalid rbt command is run withhelp
Test case where multiple arguments are entered
| Description | From | Last Updated |
|---|---|---|
|
Can you also detail which versions of Python all your tests have been run under? We need to ensure full … |
|
|
|
Can you wrap the change description at 79 columns? It would also be nice to use backticks whenever you're showing … |
|
|
|
E501 line too long (91 > 79 characters) |
|
|
|
E501 line too long (91 > 79 characters) |
|
|
|
E501 line too long (91 > 79 characters) |
|
|
|
E501 line too long (94 > 79 characters) |
|
|
|
E501 line too long (80 > 79 characters) |
|
|
|
E501 line too long (92 > 79 characters) |
|
|
|
E501 line too long (92 > 79 characters) |
|
|
|
E501 line too long (92 > 79 characters) |
|
|
|
E501 line too long (82 > 79 characters) |
|
|
|
E501 line too long (88 > 79 characters) |
|
|
|
E501 line too long (80 > 79 characters) |
|
|
|
E501 line too long (92 > 79 characters) |
|
|
|
E501 line too long (92 > 79 characters) |
|
|
|
E501 line too long (92 > 79 characters) |
|
|
|
E501 line too long (82 > 79 characters) |
|
|
|
E501 line too long (88 > 79 characters) |
|
|
|
E501 line too long (80 > 79 characters) |
|
|
|
E501 line too long (82 > 79 characters) |
|
|
|
I think this docstring and file could be named in a more descriptive way eg. Tests for RBTools help command … |
|
|
|
Similar issue about naming here - I think something like HelpCommandTests would be better |
|
|
|
I think this could be better named as test_help_command. Ordering it that way would make it more consistent with the … |
|
|
|
Maybe this could be pulled out into a function since you use it a few times |
|
|
|
This snippet feels like it could also be a function since you use it a few times. Also, maybe command_string … |
|
|
|
Same as above |
|
|
|
Minor but maybe naming test_help to be test_command would be better here to be more consistent with your first test … |
|
|
|
Same as above |
|
|
|
Same as above |
|
|
|
Same as above |
|
|
|
Since you're testing help already, it might be a good idea to add tests for when there are more than … |
|
|
|
W293 blank line contains whitespace |
|
|
|
W293 blank line contains whitespace |
|
|
|
W293 blank line contains whitespace |
|
|
|
W293 blank line contains whitespace |
|
|
|
W391 blank line at end of file |
|
|
|
This is wrapping way too early. Can you make sure it wraps at 79 characters? Same with docstrings below. |
|
|
|
I think you can go ahead and just use these strings inline. It results in less code, and is easier … |
|
|
|
Blank line between blocks/statements. Same below. |
|
|
|
Docstring summaries are limited to one line. Same below. |
|
|
|
The string type is going to be required. Should be unicode. Same below. |
|
|
|
"Returns" blocks are in the form of: Returns: type: description So probably unicode for the type. |
|
|
|
We use %-formatting, instead of .format(). It's technically faster. |
|
|
|
Blank line between each argument. |
|
|
|
bool |
|
|
|
bool |
|
|
|
W291 trailing whitespace |
|
|
|
W291 trailing whitespace |
|
|
|
W291 trailing whitespace |
|
|
|
W291 trailing whitespace |
|
|
|
I've been thinking about these code blocks, which are almost universal in your code. I think what would be better … |
|
|
|
How about making this one statement? Same below. |
|
|
|
This could be one line now. Same with ones below. |
|
|
|
Sorry, I wasn't clear in my description above. We'd want a blank line when separating blocks on the same indentation … |
|
|
|
This can be one statement. |
|
|
|
Here, and below, it'll be a lot easier to debug if we're passing in the command directly to _check_help_output. The … |
|
|
|
This should be "Check". We use a form of "Do this, do that" rather than "Does this, does that." in … |
|
|
|
The type should be (bool, optional), since it's not required. |
|
|
|
True should be shown as a literal, using double-backticks. |
|
|
|
Functions that don't return a value shouldn't have a Returns section. |
|
|
|
This seems fragile. I'm not wild about it. The idea is to have a version of command that didn't have … |
|
|
|
Rather than defining the variable, you can move the assertIn into those if statements. |
|
|
|
This is only here for the execute command, right? In this case, let's only wrap as much as we need … |
|
- Change Summary:
-
Fixed linting issues
- Testing Done:
-
~ Testing Done:
~ * Test case where 'rbt help <command>' is run ~ * Test case where 'rbt <command> --help' or 'rbt <command> -h' is run ~ * Test case where 'rbt --help <command>' or 'rbt -h <command>' is run ~ * Test case where an invalid rbt command is run with 'help' ~ Testing Done:
~ Test case where 'rbt help <command>' is run ~ Test case where 'rbt <command> --help' or 'rbt <command> -h' is run ~ Test case where 'rbt --help <command>' or 'rbt -h <command>' is run ~ Test case where an invalid rbt command is run with 'help' - Commit:
-
f436426d2b9f182dd24ca32d2d27096881265c15a7f62a85769b8ca6fac60ae945edec61c742c533
Checks run (2 succeeded)
-
-
I think this docstring and file could be named in a more descriptive way eg.
Tests for RBTools help commandandtest_help.py. That way it's also consistent with the other test file I see in that directory (test_post.py). -
-
I think this could be better named as
test_help_command. Ordering it that way would make it more consistent with the couple of other tests with a similar pattern in the name intest_post.py -
-
This snippet feels like it could also be a function since you use it a few times.
Also, maybe
command_stringandtestcould be renamed to something more descriptive, such asexpected_command_stringandtest_result- it wasn't very clear to me thattestcontained the output of executing the commands. -
-
Minor but maybe naming
test_helpto betest_commandwould be better here to be more consistent with your first test where you referred to a single command astest_commandor changing the first one totest_help(but imotest_commandis easier to understand) -
-
-
-
Since you're testing
helpalready, it might be a good idea to add tests for when there are more than than three arguments eg.rbt help alias abcdand also less than eg.rbt help
- Change Summary:
-
Addressed review changes and added a new test case
- Testing Done:
-
Testing Done:
Test case where 'rbt help <command>' is run Test case where 'rbt <command> --help' or 'rbt <command> -h' is run Test case where 'rbt --help <command>' or 'rbt -h <command>' is run ~ Test case where an invalid rbt command is run with 'help' ~ Test case where an invalid rbt command is run with 'help' + Test case where multiple arguments are entered - Commit:
-
a7f62a85769b8ca6fac60ae945edec61c742c533883fd61c35b3699bdeced4956cf8d3f739ea5ac6
- Commit:
-
883fd61c35b3699bdeced4956cf8d3f739ea5ac6382d4bb8d8b664d107f8267aff468ba33986084c
Checks run (2 succeeded)
-
First pass, addressing some of the syntax and standards stuff.
-
Can you also detail which versions of Python all your tests have been run under? We need to ensure full coverage.
-
Can you wrap the change description at 79 columns?
It would also be nice to use backticks whenever you're showing commands, arguments, or Python code, to help readability.
-
This is wrapping way too early. Can you make sure it wraps at 79 characters?
Same with docstrings below.
-
I think you can go ahead and just use these strings inline. It results in less code, and is easier to read through and understand.
Same with tests below.
-
-
-
-
-
-
-
-
- Change Summary:
-
Addressed syntax and styling reviews
- Description:
-
~ On python 2, running 'rbt --help <command>' and 'rbt <command> --help' are equivalent. However, running
~ 'rbt <command> --help' does not work on python 3. This happens because byte strings are utilized in the code to see if ~ '--help' or '-h' are passed in as arguments. However, '--help' and 'h' are never found because the code is trying to find ~ b'--help' or b'-h'. In python 2, b'--help' is equivalent to '--help', but in python 3, this is not the case. ~ On python 2, running
rbt --help <command>andrbt <command> --help~ are equivalent. However, running rbt <command> --helpdoes not work~ on python 3. This happens because byte strings are utilized in the ~ code to see if --helpor-hare passed in as arguments. They are+ never found because the code is trying to find b'--help' orb'-h'.+ In python 2, b'--help'is equivalent to'--help', but in python 3,+ this is not the case. ~ To fix this issue, the byte strings b'--help' and b’-h’ have been changed to python 3 compatible strings (i.e. '--help' and ‘-h’).
~ Unit tests have also been added to ensure that all possible positions and cases of the 'help' argument work for rbtools. ~ (ex. 'rbt —help <command>', 'rbt <command> -h', 'rbt help <command>', etc. ) ~ To fix this issue, the byte strings
b'--help'andb’-h’have been~ changed to python 3 compatible strings (i.e. --helpand-h). Unit~ tests have also been added to ensure that all possible positions and + cases of the 'help' argument work for rbtools.(ex. rbt —help <command>,+ rbt <command> -h,rbt help <command>, etc.).+ + All tests were run using both python 2.7.17 and python 3.7.6.
- Testing Done:
-
~ Testing Done:
~ Test case where 'rbt help <command>' is run ~ Test case where 'rbt <command> --help' or 'rbt <command> -h' is run ~ Test case where 'rbt --help <command>' or 'rbt -h <command>' is run ~ Test case where an invalid rbt command is run with 'help' ~ Test cases run on python 2.7.17 and 3.7.6:
~ Test case where rbt help <command>is run~ Test case where rbt <command> --helporrbt <command> -his run~ Test case where rbt --help <command>orrbt -h <command>is run~ Test case where an invalid rbt command is run with helpTest case where multiple arguments are entered - Commit:
-
382d4bb8d8b664d107f8267aff468ba33986084cfbdc829ff4b1d6c0ea256a75a9bc59ea473a2687
- Change Summary:
-
Removed trailing whitespaces
- Commit:
-
fbdc829ff4b1d6c0ea256a75a9bc59ea473a26871fce31258b1216379b42dc5759259f8681dbadf9
Checks run (2 succeeded)
- Change Summary:
-
Replaced variables 'invalid_rbt_command' with strings 'invalid'
- Commit:
-
1fce31258b1216379b42dc5759259f8681dbadf9ba444c99cbf615c716ba3c58dc50b6a385cc949e
Checks run (2 succeeded)
-
-
I've been thinking about these code blocks, which are almost universal in your code. I think what would be better would be to have a single command that takes care of executing these tests. Something like a
_check_help_output()method, which takes the command to run and theinvalidparameter.That would take care of the
try/execute/exceptblock, would take care of creating the fail message (you could just roll that logic up into this method), and the assertion.The assertion itself can then become an
assertIn, rather than anassertTrue(... in ...), which is what it basically is today. That allows us to leverage the standard behavior in unit tests for checking for a needle in a haystack, taking advantage of the enhanced failure information that provides.This would simplify the tests greatly. Each test for a command would basically be a call. You could remove the
forloops and just call this with each variant (which really helps when debugging test failures -- it's harder when loops are involved). -
-
-
Sorry, I wasn't clear in my description above. We'd want a blank line when separating blocks on the same indentation level, but you wouldn't have one between the start of a block and that block's first statement.
This is fine:
test_rbt_commands = [ ... ] for test_command in test_rbt_commands: try: ...
- Change Summary:
-
Refactored code to be simplified
- Commit:
-
ba444c99cbf615c716ba3c58dc50b6a385cc949ed06066f5d11f28a571fadd2fb44f6ee97af8a6cf
Checks run (2 succeeded)
-
-
-
Here, and below, it'll be a lot easier to debug if we're passing in the command directly to
_check_help_output. The list doesn't benefit us in any way, since we unrolled the loops, and can actually lead to future copy/paste bugs (if we skip an index or miss an item in the list). -
This should be "Check". We use a form of "Do this, do that" rather than "Does this, does that." in the summary.
-
-
-
-
This seems fragile. I'm not wild about it. The idea is to have a version of
commandthat didn't have a--helpvariant in it, right?It's best when making a unit test helper function to not have to guess too much about the caller's intention. I think this should simply take another parameter specifying the RBTools subcommand name.
subcommand_nameshould be fine. You can then just pass that into the output strings, and avoid the guessing here. -
-
This is only here for the
executecommand, right? In this case, let's only wrap as much as we need to in thetry/except. We should only require theexecuteto be wrapped.
- Change Summary:
-
More refactoring
- Commit:
-
d06066f5d11f28a571fadd2fb44f6ee97af8a6cf392c0509e6981b9680df340fa36434e5b89c305f