-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
Add coercion/normalization of Choice values #1277
Comments
It appears #887 already added this. |
Never mind, this is about what value gets returned, that was about what got matched. |
Sounds like you should just be handling things in all-lowercase? #887 set things to return the Reading #1278, it seems this is about allowing Unless there's some other rationale, I don't think this is well-justified. It adds another parameter to I'm not saying there isn't a reason! In #569 I argued that I really have a use-case where case-sensitivity is driven by external constraints. But I'd need to know what the use-case is before agreeing that this should be part of I'm reminded of this comment on the initial request for case_sensitive. If there is a clear use-case here, it's worth considering a generic parameter which changes the |
@sirosen, yes, #1278 retains the original (not necessarily title) case specified by the choices. It seems to me this may have been a better approach to begin with as opposed having case insensitivity force the introduction of a third casing (lower as opposed to original choice and user-entered). But, for backwards compatibility I introduced this as an option with default behavior remaining as it is now. My actual use case is in https://github.com/altendky/romp where I have choices for platform and Python interpreter (and more, but specifically those). I stuck a copy of the modified choice in there which I am using for now. vm_images = collections.OrderedDict((
('Linux', 'ubuntu-16.04'),
('macOS', 'macOS-10.13'),
('Windows', 'vs2017-win2016'),
))
all_platforms = tuple(vm_images.keys())
As mentioned above it's not clear to me yet that the present functionality of 'returning' the lower case form is actually good over returning original or user entered. Is there a reason it is beyond (the sufficient) backwards compatibility? Thanks for your time and feedback. |
Thanks for linking the original/relevant source of this issue. I was kind of guessing this might be a matter of having a source of data where case is important, then being fed into the CLI opts. I may have to take a break from click for the moment, but will try to circle back and look again later this week -- but I can answer one question:
Maybe those who reviewed it have a different take, but as the author of #887, no, there's no reason. 😅 My use case was that I wanted We could argue that changing this behavior would be a backwards incompatible change -- demanding that it be saved for v8.0 -- or we could make the case that, as I noted that "the doc for case_sensitive should be improved", the behavior is unspecified. I would be okay with saying Realistically, most callers using Making the new behavior in #1278 the only behavior would almost definitely make I want to just change it in v7.1 and field any complaints. But if we do that and someone is relying on the lowercasing and gets broken, I'm sure I'll catch some grief for taking that stance... |
@sirosen, I can certainly make another PR to implement the 'fix' rather than the 'feature addition' in #1278. For the people banking on the forced lowercase result I guess they would get whatever misc failures in their code and the fix would be No rush on this on my behalf. I've got my workaround in place for now and can remove it whenever. |
The best path on that sort of thing is to define a specialized decorator which applies your option with desired params. The def common_options(cmd):
def _lower_callback(ctx, param, value):
if value is None:
return value
else:
return value.lower()
cmd = click.option('--x', callback=_lower_callback)(cmd)
cmd = click.option('--foo', callback=_lower_callback)(cmd)
return cmd If you're comfortable with letting this wait around a little, I'd like to hear someone else's input (e.g. @davidism if he can spare the time) on whether or not it's okay to simply change the behavior and say it was unspecified in 7.0 and will be specified in 7.1 . |
Just to be clear, the new proposal is to make |
@davidism, I believe so. Where 'exact' refers to 'as passed to |
Seems fine for 7.1, along with clarifying the documentation of the option, it would be good to add an example of normalizing to lowercase if there's not one already. |
@davdism, for the additional example, you are referring to Note that 7.0 returns the normed value not the exact value passed to To have the list handy, and in case I missed something, here is the documentation for
|
I think the best thing to do for the examples is to write a command which takes a choice like The token normalize function and use of
To clarify, you're distinguishing
I think the easiest behavior to explain is that it returns the original string passed to Also, something we haven't discussed is that I think it's fine for such behavior to remain undefined, but, if possible, I'd like to take the first or last matching choice in a consistent way. |
Yes, that is the value I'm referring to. Or maybe raise an exception on creation of a non-unique case-insensitive list? |
I think these are the two open questions. Questions:
|
I think so. My rationale is based on looking at the diff for #887 . Prior to that, the choice value which was matched, without passing through So not applying
I'm fine with any of the options you put forth. |
#1318 merged so the issue should be resolved. |
I want my CLI to be case insensitive for certain
Choice
options but I don't want to deal with that variability internally as it has no meaning. I think an option likecoerce_case
ornormalize_case
would be a reasonable addition.PR to follow.
The text was updated successfully, but these errors were encountered: