-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Add _check_option function #5958
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
|
+1 from me |
mne/utils/check.py
Outdated
|
|
||
|
|
||
| def _check_option(parameter, value, allowed_values, error=ValueError): | ||
| """Checks a the value of a parameter against a list of valid options. |
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.
a the -> the
|
can you use/integrate this code anywhere? Let's clean at the same time. |
|
+1000 I found myself refactoring again here https://github.com/mne-tools/mne-python/pull/5836/files#diff-d8a578281e14fb43fe3a386a41036b8fR794 So if you had not opened this PR I would have done it. I would put the word |
| assert list(range(7, 10)) == picks | ||
|
|
||
|
|
||
| def test_check_option(): |
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 a good usecase to use pytest.mark.parametrize
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 pointing me to this function. However, using pytest.mark.parametrize ended up not being any shorter nor clearer than these four lines. A little too much changes across each line.
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.
...or I just don't understand the parametrize function too well. If you have some clever refactoring in mind, please share :)
(I think you meant I totally see how that is good practice. But in this case, all the functions in the |
I'll put in a few use cases in this PR. But shall we leave be big cleanup for a separate PR that will strictly be a search and replace? |
|
git grep "Got " should help find some places you can use this new check function I would favor to do the clean up in this PR. But others can help by pushing to the PR directly. Just saying :) |
Then you got it! |
|
then I go for it or you go for it?
|
|
Lets both go for it! There are plenty of cases to cover I guess :) And I'm still on paternity leave so my working time is spotty. |
Codecov Report
@@ Coverage Diff @@
## master #5958 +/- ##
==========================================
+ Coverage 88.83% 88.92% +0.08%
==========================================
Files 401 401
Lines 72874 72810 -64
Branches 12179 12108 -71
==========================================
+ Hits 64741 64745 +4
+ Misses 5215 5180 -35
+ Partials 2918 2885 -33 |
|
Looking at the API I would prefer something like this: def _check_option(*, option, accepted_values, error):
raise ...
my_var = None
_check_option(option=my_var, accepted_values=[Ture, False], error=ValueError) and that it prints (We can allow for not passing option name If you don't find it useful, we can let it for someone who wants to drill in a rainy day. (here's a stack overflow) |
|
I prefer it the way it is currently. It's really an expert/dev option and I don't find all the extra chars in our repo will be helpful in the long run. Extra verbosity can hurt readability sometimes, it's a trade-off. Here I think the first is better for something that is meant to be a time-saver anyway. |
mne/utils/check.py
Outdated
| Returns | ||
| ------- | ||
| is_valid : bool | ||
| Whether the value was valid or not. |
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.
if its not valid, you are not returning. I'm not sure if we should say it. or just say return True
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.
Good point.
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 remove the "Returns" section as it returns None or raises a ValueError.
besides LGTM
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.
@wmvanvliet this last one please
|
API of private function is fine with me as is. Let's use it as much as possible everywhere now. |
|
That's filenames stating with A-E done. Lots more to do. |
b2e529d to
973289d
Compare
|
This pull request introduces 1 alert when merging 692fca1 into 5418605 - view on LGTM.com new alerts:
Comment posted by LGTM.com |
| options = 'Allowed values are ' | ||
| options += ', '.join(['%r' % v for v in allowed_values[:-1]]) | ||
| options += ' and %r' % allowed_values[-1] | ||
| raise ValueError(msg.format(parameter=parameter, options=options, |
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.
are you sure that it will always be a ValueError? I'm fine with the change and change it back if a TypeError appears.
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.
Scratch that. Actually to check if an option is a subclass of the allowed_values the function should be quite different:
def _check_option(option_name, option_val, allowed_values, type_of_check='one of', ...):and allow for type_of_check='sublcass', etc..
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.
Why would I want to check whether an option is a subclass of allowed_values?
I've gone through the entire codebase now. This function only has to deal with str, None, True and False. It also only ever needs to throw ValueError, hence I removed the code for throwing other types of errors.
The reason this function doesn't need to be more complicated than this, is that all it really does is form a very specific error message that just happens to be a very common one. When a different kind of check is required, the error message is likely to be different as well and you're better off not bending over just to use this function but just write the if-statement and throw yourself.
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 agree. Let’s not be too smart here. @wmvanvliet can you just see why CIs complain ?
|
I think I'm done here. Ready for merge! |
larsoner
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.
LGTM, let's merge once the CIs come back happy
|
Thanks @wmvanvliet ! |
|
THX @wmvanvliet |
* Add _check_option function * Start putting _check_option to use * More usage of _check_option * Fixes * Simplify _check_option function * More _check_option usage * fix * Last batch of _check_option usage * fix * Fixes * Update _check_option doc
As @massich noted in #5946, the following snippet is a common occurrence in our codebase:
Generating a good error message takes a bit more work. You can either do:
or go just write it all out if you don't like the list-like formatting of the valid options:
It's a little bit of a hassle and we're not very consistent across the code base in how we generate such errors.
This PR adds a private
_check_optionfunction that you can use to perform such a check and generate a friendly error message in a single line:Small QOL improvement or unnecessary bloat? You be the judge :)
If we agree that we want this function, I'll open a follow-up PR that changes the bulk of the occurrences of this pattern in our codebase.