-
Notifications
You must be signed in to change notification settings - Fork 216
Add Literals to lots of function arguments #3904
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
base: main
Are you sure you want to change the base?
Add Literals to lots of function arguments #3904
Conversation
I think you need a from future import annotations for 3.9 :) |
The "|" notation for types was only added in 3.10 (https://peps.python.org/pep-0604/)!! So the following code errors on 3.9: import spikeinterface.full as si
from typing import get_type_hints, get_args
get_type_hints(si.detect_bad_channels) Does annotations help somehow here, @zm711 ?? This notation is used everywhere in the codebase and 3.14 comes out in 5 months, so I'd vote to skip these tests on python < 3.10? |
Yes that's the reason we use that import statement at the top. It allows us to bring in |
Just to be clear it is from __future__ import annotations |
Hello, thanks! Turns out detect_bad_channels_method_literals = get_args(get_type_hints(detect_bad_channels)["method"]) to from typing import Literal
detect_bad_channels_method_literals = get_args(eval(detect_bad_channels.__annotations__['method'])) (the Literal import is needed for the |
Cool, but this becomes moot in 3.10? I think having to run an Or are you saying the |
Yeah. EDIT: Another bad code smell: this method imports Literal but it's only used implicitly. |
@@ -18,6 +21,15 @@ | |||
HAVE_NPIX = False | |||
|
|||
|
|||
def test_literal_hardcoded_values(): |
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 guess if we think about it what is the value of this test? This is basically saying that you don't trust the type hints of python and want to confirm they exist? We wouldn't add this test to every file right?
What is it that you want to test?
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 want to protect against a developer adding a new method and forgetting to add it to the typing.
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 see so this is just a change detector to annoy Sam :P
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.
So after carefully reading your PR discussion + your edits I think this:
EDIT: The steps 1. 2. 3. might be overkill?? Should I just do 1.?
I think we start with just 1 and then if we decide to add a test later we do that. I'm actually fine with 2 as well because it allows us to easily add in a useful error message (ie you have entered x but only [y,z,a,b] are allowed). But 2 just adds so much work and you're right that if we do 2 then if we want to ensure it is enforced we have to do 3, but then that will cause test failures in refactor potentially. So for me 2 and 3 should really be a 1.0 type move when we are saying the API is 100% stable.
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 came to the same conclusion while trying to get to sleep last night. Importantly, if we miss a method from a Literal
, it doesn't mess any of the code up - it just gives the user bad advice via their typing tool
This PR improves the user experience by adding Literals to LOTS of function arguments (eventually...). They are in a few function arguments at the moment.
Allows for auto-complete for string arguments, like so:
Plan is to go through each module and add
Literal
s everywhere. Will be especially helpful forcompute
! Before I do so, thought I'd use one concrete example to generate some discussion. I've added Literals for themethod
argument ofdetect_bad_channels
. To do so, I've done three things:As far I can figure out, Literals have to be hardcoded for static type checkers to pick up on them. To check this hardcoding, I think it's worth adding tests like this for any arguments that might be extended in the future. Any other opinions?
EDIT: The steps 1. 2. 3. might be overkill?? Should I just do 1.?