-
Notifications
You must be signed in to change notification settings - Fork 2.4k
Support inverted arguments for BoolParameter #1598
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
a60aa88 to
4e19297
Compare
|
This implementation looks nice and clean. Just some minor inline comments: |
luigi/parameter.py
Outdated
| return bool(value) if value is not None else None | ||
|
|
||
| @staticmethod | ||
| def _parser_action(): |
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.
Can this be deleted now? Is _parser_action() still used anywhere?
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 like it can be since the only place it is overridden is in BoolParameter which does not even call _parser_action any more in _parser_add_arguments.
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.
Ok. Please delete the dead code then :)
|
The reason I like this patch is that I've by now repeatedly told other PR senders that "No, you're not allowed to have True as a default for your BoolParameter". But with this patch we could allow it from now on. |
|
This is a reasonably big change (not in code size), but in what we communicate are good practices to the luigi users. I remember @erikbern saying some time that BoolParameters should always be false by default. But I don't know if he meant that as a "that's good design in general" or "due to current luigi limitations that's the only implementation that works out". |
|
Understood. I agree that existing community usages may have a part to play in whether this PR should be accepted or not. As an anecdotal data point, at my employer, we use Luigi and I have seen our developers confused on multiple occasions by not really being able to set |
|
And this PR is an attempt to improve the API to remove that source of confusion. |
|
I agree with @tdyas on this, as someone who used Luigi heavily while working with @erikbern . It doesn't break the existing semantics, and it does exactly what I had assumed it would have done when I first started using Luigi: adds a --no-xyz argument, which is a de-facto standard for GNU tools and elsewhere. The only reason |
|
i'm fine with this |
|
Adding the --no-xyz arguments seems to confuse argparse's |
|
i'm guessing no argument can be a prefix of another |
|
So I dug in further, and it seems like a bug in argparse. The error occurs during the call to I can get the failing test to pass by renaming the This still brings up an issue about whether this will break Luigi for anybody who has a task with a "n" parameter. |
|
And this issue is known to the Python developers: https://bugs.python.org/issue19814 And apparently only warrants a warning in the documentation. |
|
Please let me know if you need any help. Otherwise I'm patiently waiting for something that builds. :) |
Refactor the add_argument call for adding Parameter's to a ArgumentParser into the Parameter class. This lays the foundation for overriding the default behavior in BoolParameter.
Add two command-line arguments for BoolParameter's instead of one, specifically one to set it to True (e.g, --foo) and another (--no-foo) to set it to False. For cases where an inverted argument does not make sense, the caller should set omit_inverted_argument=True on the BoolParameter. For example, this has been done for --help and --help-all options, as --no-help does not make any sense. This allows BoolParameter's to have a default of True and still be settable to False. Other notes: * Removes Parameter._parser_action as moot. * Merges Parameter._parse_or_no_value into the sole call site and changes the logic to account for None in the value check. * Several tests initially failed with this change because argparse considered --n ambiguous with the --no-FOO style options. This is a known issue with argparse. These options have been renamed to allow the tests to pass. See https://bugs.python.org/issue19814 for details.
e60f5c3 to
2aa25be
Compare
|
As it turns out, the test I added wasn't actually testing whether a I also merged all of the other commits (other than the commit refactoring the add_argument call) into the commit adding the inverted argument support. |
|
There was also a test failure locally for me with |
|
CI tests passed. |
|
I'm still a bit worried about we suddenly dropping support for parameters with names like |
|
Yea I understand this is entirely the fault of some stupid bug in the argparse module (I've also felt the pain). But I'm afraid people are going to start to say their stuff broke and this would need to be reverted in haste if we break compatibility. |
|
apparently python 3.5 added a flag to argparse the correct way would probably be to first change luigi's behavior so that prefix flags throw a deprecation warning for a few months and then an exception btw reminds me – maybe it's time to publish a new version of luigi to pypi? |
|
So the solution for now it seems is to just add a |
|
Yea. I would be more comfortable that way actually @tdyas |
|
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. If closed, you may revisit when your time allows and reopen! Thank you for your contributions. |
|
Resolved by #2427 |
Add two command-line arguments for BoolParameter's instead of one, specifically one to set it to
True(e.g,--foo) and another (--no-foo) to set it toFalse. This is necessary becauseBoolParametercurrently usesargparse's "store_true" action, which does not take a parameter. This change allowsBoolParameter's to have a default ofTrueand still be settable toFalse.For cases where an inverted argument does not make sense, the caller should set
omit_inverted_argument=Trueon theBoolParameter. (For example, this has been done for the--helpand--help-alloptions, as--no-helpis of no help at all.)