-
Notifications
You must be signed in to change notification settings - Fork 11
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
Automatic short flags #23
Conversation
Rebased. |
Kindly bumping the issue. |
Thanks for your work on this. I've been intending to get to it but haven't found a large enough block of time to read through it properly. I'll try to review it this weekend. |
No worries. I have been using https://github.com/neithere/argh for most of my projects until recently. I learnt to get around the kinks, but the main problem is that the project is essentially abandoned at that point. I am looking towards switching to defopt, as I think parsing the docstring using a widespread standard (as opposed to, say, docopt) and using standard annotations (rather than attaching ad hoc semantics to them) were very, very good ideas; however, there are some kinks that need to be ironed out before the switch is worth it. |
defopt.py
Outdated
@@ -54,16 +54,18 @@ def run(*funcs, **kwargs): | |||
:param Callable funcs: Function or functions to process and run | |||
:param parsers: Dictionary mapping types to parsers to use for parsing | |||
function arguments. | |||
:type parsers: Dict[type, Callable[[str], type]] | |||
:type parsers: Optional[Dict[type, Callable[[str], type]]] |
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.
Is it necessary to mark this as optional? The documentation for it says "An optional argument with a default needn’t use the Optional qualifier on its type annotation". Is there anything about this argument in particular that distinguishes it from short
or argv
?
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.
seems reasonable, changed
defopt.py
Outdated
count_initials = Counter(name[0] for name in sig.parameters | ||
if name not in positionals) | ||
short = {name.replace('_', '-'): name[0] for name in sig.parameters | ||
if name not in positionals and count_initials[name[0]] == 1} |
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 would prefer to use single letter variable names in list and dictionary comprehensions. This code works fine currently, but the difference in behavior between Python 2 and 3 has caused me some grief in the past. (The variables remain in the current scope in 2, but not in 3).
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.
Switched to using generator expressions, which do not leak variables even on py2.
examples/short.py
Outdated
You can add alternative short flags to arguments by passing a dictionary | ||
to `defopt.run` which maps flag names to single letters. You can | ||
prevent automatic addition of short flags by passing an empty dictionary | ||
as argument. |
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.
These module docstrings are intended to be brief descriptions of what's happening in the example rather than full explanations of the features. Most of this probably belongs under the flags section in features.rst. (I have ended up duplicating a lot of documentation myself, which is not ideal.)
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.
moved to features.rst
I think there are some edge cases where the global short dict you pass in won't be able to replicate exactly what the auto short generation does once more than one command is involved, but I think we can solve that later on if it becomes a problem. There would have to be a more granular way to specify flag names. Perhaps we'll need a decorator-based approach as was proposed in #2 after all. |
What are the edge cases you're thinking about? |
docs/features.rst
Outdated
You can add alternative short flags to arguments by passing a dictionary | ||
to `defopt.run` which maps flag names to single letters. You can | ||
prevent automatic addition of short flags by passing an empty dictionary | ||
as argument:: |
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.
Should this be "as an argument"?
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?
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.
After rereading this section, I think it may need to be reworded - specifically "add alternative short flags" may be taken to imply that the given flags are used in addition to the generated ones, as opposed to overriding them entirely. How about something like this?
You can override these generated short flags by passing a dictionary to
defopt.run
which maps flag names to single letters::[example]
Passing an empty dictionary will suppress automatic short flag generation without adding new flags.
I think the second part belongs after the example is it's not actually demonstrated in there. How does that seem to you?
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.
Sounds good, fixed (with minor rewording).
Consider:
Each of these have a What are your thoughts on this? |
Perhaps |
That would work, but I'm not sure I like encoding information into the strings. Either way, I think we can defer this problem until the need arises. Once the documentation is cleared up I'm happy to merge this. |
Thanks again for your work. Merging. |
See #21. Note that this PR depends on #20 (the first few commits are from that PR).
Turning off automatic generation of short flags can be achieved by replacing the
short = kwargs.pop('short', None)
line byshort = kwargs.pop('short', {})
(and updating the docs). But I'd rather keep it on by default.