-
Notifications
You must be signed in to change notification settings - Fork 127
Autocompleter #362
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
Autocompleter #362
Conversation
- Fixed a few bugs in AutoCompleter dealing with nargs='+' or nargs='*' - Adjusted some help output dealing with narg ranges - Fixed spacing problem with printing argument help * examples/tab_autocompletion.py - Removed debug code. - Minor changes.
This is to support installation from package managers on older OSes such as Debian 9.
Added more type hinting to AutoCompleter.
…n 3.4 compatibility)
… It works fine when I test by hand.
…ed function arguments. Added example for fully custom completion functions mixed with argparse/AutoCompleter handling - Also demonstrates the ability to pass in a list, tuple, or dict of parameters to append to the custom completion function. Added new test cases exercising the custom completion function calls. Added AutoCompleter and rl_utils to the coverage report.
… prompt. Re-enabled test cases that were failing due to there not being a terminal during unit tests.
Updated AutoCompleter (#349) to match new directory structure from packaging effort.
…constructor parameters in a more concise/general way. May also resolve the weird Mac issue on Python 3.6
Codecov Report
@@ Coverage Diff @@
## master #362 +/- ##
=========================================
+ Coverage 89.33% 91.24% +1.9%
=========================================
Files 2 3 +1
Lines 1876 2273 +397
=========================================
+ Hits 1676 2074 +398
+ Misses 200 199 -1
Continue to review full report at Codecov.
|
tleonhardt
left a comment
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.
Overall a fabulous PR. I love the new feature.
Address my review comments and I'll take a quick look at it again after you do.
main.py
Outdated
|
|
||
| # Set "use_ipython" to True to include the ipy command if IPython is installed, which supports advanced interactive | ||
| # debugging of your application via introspection on self. | ||
| app = Cmd(use_ipython=False) |
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.
As long as no unit tests rely on this, then I would recommend setting use_ipython to True because that can aid debugging.
tests/test_acargparse.py
Outdated
| These are primarily tests related to readline completer functions which handle tab-completion of cmd2/cmd commands, | ||
| file system paths, and shell commands. | ||
|
|
||
| Copyright 2017 Todd Leonhardt <todd.leonhardt@gmail.com> |
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.
You should probably make this Copyright 2018 and yourself ;-)
This comment applies in multiple places.
| @@ -0,0 +1,796 @@ | |||
| # coding=utf-8 | |||
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.
In general module file names within Python packages are named using "snake_case" like auto_completer.py
| [run] | ||
| # Source | ||
| source = cmd2.py | ||
| source = cmd2/ |
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.
Thanks for fixing the code coverage analysis configuration now that cmd2 is a multi-file package
cmd2/AutoCompleter.py
Outdated
| import argparse | ||
| import re as _re | ||
| import sys | ||
| from argparse import OPTIONAL, ZERO_OR_MORE, ONE_OR_MORE, REMAINDER, PARSER, ArgumentError, _ |
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.
I'm assuming the _ at the end of the line is a mistake and should be deleted?
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.
Nope, they have some sort of function called '_' that they use. I had to import it to override their behavior. Bizarre.
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.
Huh ... Well ain't that special ;-) They win the prize for the single worst function name I have ever seen!!!
Maybe add a comment?
| import re as _re | ||
| import sys | ||
| from argparse import OPTIONAL, ZERO_OR_MORE, ONE_OR_MORE, REMAINDER, PARSER, ArgumentError, _ | ||
| from .rl_utils import rl_force_redisplay |
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.
In general I try to order imports like so:
1st: built-in Python modules
2nd: 3rd-party modules
3rd: Our code
(and each section is alphabetical within that).
So recommend moving import from .rl_utils to end.
cmd2/rl_utils.py
Outdated
| pass | ||
|
|
||
|
|
||
| # Check what implementation of readline we are using |
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.
Convert comment before class to docstring after
| pyparsing | ||
| pyperclip | ||
| wcwidth | ||
| colorama |
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.
Thanks for adding this. We need to keep this up-to-date so that the documentation builds correctly on ReadTheDocs
tests/test_autocompletion.py
Outdated
| first_match = complete_tester(text, line, begidx, endidx, cmd2_app) | ||
| assert first_match is not None and \ | ||
| cmd2_app.completion_matches == ['S01E02', 'S01E03', 'S02E01', 'S02E03'] | ||
|
|
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.
Probably don't need quite this many trailing newlines at end of file
| wcwidth | ||
| commands = | ||
| py.test {posargs: -n 2} --cov=cmd2 --cov-report=term-missing --forked | ||
| py.test {posargs: -n 2} --cov --cov-report=term-missing --forked |
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.
Thanks for fixing these
examples/tab_autocompletion.py
Outdated
| def _query_movie_user_library(self): | ||
| return TabCompleteExample.USER_MOVIE_LIBRARY | ||
|
|
||
| def _filter_library(self, text, line, begidx, endidx, full, exclude=[]): |
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.
WARNING: Mutable default arguments in Python behave like static local variables in C - they are forever persistent and if you change the value within the function, you have permanently altered the default for the next time you call the function.
If this is how you intend this function to work, then please document to make it clear.
If this is NOT how you intend this function to work, then use a non-mutable default argument. If a tuple can work for you then that is fine. If you really need that argument to be a list then you can default it to None and then immediately first thing within the function check if it is None and if so assign an empty list to it.
tleonhardt
left a comment
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.
Everything looks good to me. Do you know if Kevin plans on reviewing?
| @@ -0,0 +1,821 @@ | |||
| # coding=utf-8 | |||
| """ | |||
| AutoCompleter interprets the argparse.ArgumentParser internals to automatically | |||
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.
Changes all look good to me.
…ng unit tests due to the lack of a real terminal. Some more comments.
|
No idea if anyone else plans on reviewing this. |
| if not sys.stdout.isatty(): | ||
| return | ||
|
|
||
| if rl_type == RlType.GNU: # pragma: no cover |
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 is covered on macOS when the gnureadline module is installed.
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.
The reason I blocked this out is because it can't be covered by the automated tests because there's isn't a terminal.
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.
I guess it depends on where we care about seeing the coverage.
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.
Oh good point. I think it is reasonable to block it out if we know it won't be hit by any of our CI systems.
tleonhardt
left a comment
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.
Consider removing the "no cover" pragma from the one line which should be covered by our AppVeyor builds.
| display_fixed = ctypes.c_int.in_dll(readline_lib, "rl_display_fixed") | ||
| display_fixed.value = 1 | ||
|
|
||
| elif rl_type == RlType.PYREADLINE: # pragma: no cover |
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 is covered on Windows when the pyreadline module is installed, which is a conditional dependency on Windows so it should be. So this should be covered by our AppVeyor CI builds.
|
@kmvanbrunt I'm good to merge this in whenever. Let me know if you would like to review it or if we should just merge it in. |
This PR addresses most of the feature described in #349 and adds examples and unit tests exercising the new features.
In a future round of changes, cmd2 will be updated to automatically use AutoCompleter for completion on all argparse-driven commands (unless overridden with a custom completion function)