tedana icon indicating copy to clipboard operation
tedana copied to clipboard

Incorporate type hints when possible

Open tsalo opened this issue 3 years ago • 19 comments

Summary

Should we start using type hints, when possible, in our functions?

I believe that it would reduce the amount of argument validation that we do at the beginning of each function. Plus it would make our code more transparent.

One drawback is that, in order to support type hints for numpy arrays (one of our most common argument types), we would probably need an additional dependency like nptyping.

Yea: :+1: Nay: :-1:

Additional Detail

@jbteves has started using type hints in #692, which I quite like. He also brought up style guidelines in this month's developers meeting (see #701), so I thought I'd get the ball rolling with this issue.

Next Steps

  1. Discuss (feel free to weigh in with a vote, but please explain any nays)
  2. Possibly implement

tsalo avatar Mar 20 '21 15:03 tsalo

Just FYI, the types aren't actually checked at runtime unless we add mypy as well. That's why you had to correct one of my type hints in that PR; if they were checked then I would have been getting runtime errors. We can add it if we think it's worth it, however. I included it in that PR mostly to improve documentation and also because frankly I've been using type hints in a different project and forgot we're not using them here 😆 . My view is that we should begin adding type hints in PRs as we modify functions, not do them in one big PR, and add nptyping as a dependency to make that possible. I need to experiment a bit with mypy and npytyping to decide if they're reliable enough to add type-checking to the whole codebase from my point of view.

Thanks for opening @tsalo !

jbteves avatar Mar 22 '21 12:03 jbteves

Just FYI, the types aren't actually checked at runtime unless we add mypy as well.

I did not know that. That's somewhat depressing and simultaneously pretty cool!

My view is that we should begin adding type hints in PRs as we modify functions, not do them in one big PR, and add nptyping as a dependency to make that possible.

My concern about this approach (along with the same approach to reformatting with black or isort) is that there are a number of functions that are very stable, and we may not touch them (and thus get them up to snuff) for a long time. If we want to maintain a coding standard across the package, at some point we'll need to bite the bullet and apply our rules to all of the code, or else we'll eventually have a bit of a Frankenstein's monster situation.

EDIT: Another relevant task is #448, which could be done piecemeal, but hopefully won't be.

tsalo avatar Mar 22 '21 17:03 tsalo

That's somewhat depressing and simultaneously pretty cool!

Intriguingly that's my relationship with Python in a nutshell!

My concern about this approach (along with the same approach to reformatting with black or isort) is that there are a number of functions that are very stable, and we may not touch them (and thus get them up to snuff) for a long time.

I think that's fair. That said, I think that we have enough things going on that adding a major refactor of style is not up at the top of my list. If other developers feel differently, that's worth a discussion, however.

jbteves avatar Mar 22 '21 17:03 jbteves

I may be optimistic, but, IF types are added to the BIDS outputs branch #691, then modularize metrics #591, and then decision tree modularization #592, we'll have covered a substantial portion of the code base. At that point, systematic addition of types to the rest of the code will be annoying, but should be do-able.

handwerkerd avatar Mar 22 '21 18:03 handwerkerd

To clarify my :-1: : I'm for adding type-hints in general -- in that I think they're nice to read -- but I'm against adding dependencies to enforce / check the types. It feels a bit non-pythonic, somehow :)

emdupre avatar Mar 23 '21 16:03 emdupre

Would those additional dependencies have to be general dependencies that all users have to install/import or will they be test dependencies? (... and does that matter in swaying opinions?)

notZaki avatar Mar 23 '21 16:03 notZaki

It's pretty tricky to make them dependencies for only "some" users, though pretty straightforward to make them dependencies for developers only. I personally think that's a recipe for confusion and should be avoided, however.

jbteves avatar Mar 23 '21 16:03 jbteves

I think the main potential benefits would be (1) automatic type checking and (2) automatic type documentation, right? @emdupre I personally like the idea of automatic type checking, but I'm fine not using it. Unfortunately, as far as (2), it doesn't seem like napoleon or numpydoc support type hints automatically, and the Sphinx extensions that support it don't work with numpydoc-style docstrings yet. All of which is to say that if we don't want to actually validate parameter types, I don't know how much type hints will get us with our current documentation structure. 😞

tsalo avatar Mar 25 '21 16:03 tsalo

I am obviously biased but (1) but it helps me when doing things on CLI and (2) coming from strongly typed languages it makes things a little more familiar to me. I doubt (2) is as much of a consideration for others, though. Other users may be using servers where it's difficult to set up some sort of IDE, however, and in that case it's nice to have the hints inline with the parameters.

jbteves avatar Mar 25 '21 17:03 jbteves

The nilearn dev team recently discussed type hints as well. The consensus was (1) the primary benefit is for users/devs using code editors like VSCode, rather than any kind of automatic input validation or documentation, and (2) they would encourage, but not require, type hints in new contributions, but type hints would not be feasible/interpretable for some parts of the library.

Of course, we would still need to add nptyping to include type hints for most of our parameters, and I don't think we could make it a dev-only requirement unless we did a duecredit-like thing and included a dummy module to handle ImportErrors automatically...

EDIT: Also, given the rather limited impact this would have (short of using mypy and figuring out how to support numpydoc with napoleon's type hinting extensions), I'm going to downgrade the impact label for this issue.

tsalo avatar Jul 12 '21 17:07 tsalo

This might be a naive question, but could you clarify what nptying adds over the the numpy typing that's native to Python 3.8 and can be backported to 3.6? https://numpy.org/devdocs/reference/typing.html Can we get most of the benefits of type hints for now without adding another dependency?

handwerkerd avatar Jul 12 '21 19:07 handwerkerd

I didn't know that numpy types were native to 3.8, so that's good news. How can this be backported to 3.6/3.7 though? It looks like we'd need to install typing-extensions.

tsalo avatar Jul 12 '21 19:07 tsalo

I overlooked that typing-extensions isn't a native library & would need to be added. That said, IF this meets our needs, then we can mark it as a dependency only for people running python 3.6 or 3.7 and we'd be able to remove the dependency when we eventually move to requiring 3.8.

handwerkerd avatar Jul 12 '21 20:07 handwerkerd

I think that's a reasonable solution. Does anyone have any issues with adding the typing-extensions package as a dependency?

tsalo avatar Jul 17 '21 15:07 tsalo

I'm still a bit concerned about this. Just to confirm, this can't be done as a dev-only dependency ?

emdupre avatar Jul 18 '21 19:07 emdupre

I guess we could have a fake module like we do for duecredit? Otherwise, I don't think so. The types appear in function definitions, so we can't use try/except ImportError statements.

tsalo avatar Jul 18 '21 20:07 tsalo

Not sure if this changes things, but bokeh already requires the typing-extensions package for Python >= 3.6 (since ~2 years ago). So it won't necessarily be a new dependency.

notZaki avatar Jul 19 '21 07:07 notZaki

Thanks @notZaki! I think we can add typing-extensions without affecting anything then.

tsalo avatar Jul 19 '21 14:07 tsalo

Our minimum Python version is now 3.8, so I don't think we need any extra dependencies. I will open a PR adding a checklist to the PR template with things like "If I edited functions, I included type hints".

tsalo avatar Apr 27 '24 15:04 tsalo