-
Notifications
You must be signed in to change notification settings - Fork 124
decorator changes for replacing optparse with argparse #249
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
Conversation
new attribute on Cmd2.cmd which defaults to false, but if set true, causes all do_* commands to receive a list of arguments, instead of a string of what the user typed.
Codecov Report
@@ Coverage Diff @@
## master #249 +/- ##
==========================================
- Coverage 96.45% 95.87% -0.59%
==========================================
Files 1 1
Lines 1241 1235 -6
==========================================
- Hits 1197 1184 -13
- Misses 44 51 +7
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.
As discussed in the comments, we can't use the use_argument_list attribute and have it modify onecmd() because that breaks compatibility with methods implemented by the underlying cmd module, most importantly help.
cmd2.py
Outdated
| excludeFromHistory = '''run ru r history histor histo hist his hi h edit edi ed e eof eo eos'''.split() | ||
| exclude_from_help = ['do_eof', 'do_eos'] # Commands to exclude from the help menu | ||
| reserved_words = [] | ||
| use_argument_list = 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.
This class member shouldn't be added. It creates massive backwards compatibility problems with cmd.
cmd2.py
Outdated
| return self.default(statement) | ||
| stop = func(statement) | ||
|
|
||
| if self.use_argument_list: |
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.
We can't do this in onecmd. This breaks any underlying calls which are actually implemented by Python's built-in cmd module which cmd2 extends - most importantly help. With this in place doing a "help history" will throw a "TypeError" exception because the underlying cmd help commands expects a string.
Additionally, if someone tries to upgrade their cmd app to use cmd2, at first none of their commands would work.
cmd2.py
Outdated
| return arg_decorator | ||
|
|
||
|
|
||
| def with_argument_list(func): |
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 like this decorator-based approach for getting cmd2 to pass the do_* methods an argument list instead of an argument string. It is an easy way to alter the default behavior on a per-function basis.
docs/argument_processing.rst
Outdated
| The default behavior of ``cmd2`` is to pass the user input directly to your | ||
| ``do_*`` methods as a string. If you don't want to use the full argument parser support outlined above, you can still have ``cmd2`` apply shell parsing rules to the user input and pass you a list of arguments instead of a string. There are two methods to effect this change. | ||
|
|
||
| The ``use_argument_list`` attribute of a ``cmd2`` class or subclass defaults to ``False``. Set it to ``True`` and all of your ``do_*`` methods will receive a list of arguments parsed by ``shlex.split()`` instead of receiving a string:: |
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.
Update this documentation once the use_argument_list attribute has been removed.
|
On second thought, including the But it is possible that there may be other underlying calls to methods in |
|
So to keep the If this still turns out to be too problematic, perhaps we can try creating a new subclass of str which has a arglist() method. Pass an instance of this new class to the do_ methods where we are currently passing a plain string. Existing code works fine, if you want a list of arguments, call the arglist() method. |
|
Yes, to keep the Many of the do_* methods in # If arguments are being passed as a list instead of as a string
if USE_ARG_LIST:
if arg:
arg = arg[0]
else:
arg = ''@kotfu
|
|
@tleonhardt After looking at some of the do_* methods in Since I think we have to do issue #250 anyway, at this point I'm inclined to try and implement the changes we have discussed to make |
|
@tleonhardt, I don't understand your prior comment: 'Additionally, if someone tries to upgrade their cmd app to use cmd2, at first none of their commands would work.' Can you better explain your concern? |
|
@kotfu Yeah, definitely go forward with the use of As long as the default value of |
This commit converts the following methods: - do_eos() - do_eof() - do_quit() - do_shortcuts() - do_cmdenvironment() - do__relative_load() - do_load() - do_help()
|
While working on Issue #250, I discovered that we will have to discard the |
|
Now that we have a 2nd decorator which simply converts a do_* command so that it gets passed an argument list instead, I'm pretty happy with the decorator approach. That feels to me like a relatively painless, explicit, and self-documenting API. If you can think of a smart and safe alternative to the |
This one depends on the help text for history
|
@kotfu I hope me pushing a few minor fixes doesn't get in the way of what you are doing |
argparse output for invalid option has different text and goes to stderr
It's functionality has been moved inside the set command. The set command now uses an argparse parser.
…sts as a -a/--all option to the set command
…ted @options optparse-based decorator
…was merged into the "history" command awhile back
|
I like how the new and improved history command is behaving. FYI, I think it is "cowardly", not "cowerdly". So now to complete this PR we just need to remove the deprecated run and save commands and remove the command editing capability from the edit command. Random train of thought for another time/PR. Now that history command has the ability both to execute previous commands and to output previous commands to a file, it might be cool to add the capability for it to automatically generate a transcript. I don't know how hard that would be, but if it was easy, that would be a really useful feature to add. |
|
@tleonhardt I think we've got everything done. #252 is completed, and I fixed the spelling. I just updated the changelog, and I think this PR is ready to merge. |
| * The old decorator is still present for now, but should be considered *deprecated* and will eventually be removed | ||
| * See the **Argument Processing** section of the documentation for more information | ||
| * Alternatively, see the **argparse_example.py** example | ||
| * Three new decorators for **do_*** commands to make argument parsing easier |
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 updating the Changelog
Removed usage of and reference to attributes and commands which have now been removed.
| # regexes on prompts just make the trailing space obvious | ||
| (Cmd) set | ||
| abbrev: True | ||
| autorun_on_edit: 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.
My recent commit was just a minor cleanup of documentation and such
This PR adds a new @use_argument_list decorator which converts do_* methods to get passed a list of strings instead of a string. This is in lieu of using the @with_argument_parser decorator for full-blown argparse parsing.
This closes #47
This closes #250
This closes #251
This closes #253
This closes #252