Proper type hints in SciPy with `scipy-stubs`

Hi all!

As some of you may already know from scipy/scipy#21614, I’m the author of the scipy-stubs package, and I’d like to give you an update on its current progress.

As the name implies, scipy-stubs provides complete type annotations (stubs) for scipy. It now passes all static type checking tools like stubtest, flake8-pyi, mypy, and pyright, all configured in the strictest of modes. This means that scipy-stubs covers the entire public API of scipy now, and a big part of the private one as well.

If you don’t know much about static typing, or don’t care about it, then that’s not a problem at all. By simply installing scipy-stubs you’ll get better IDE support, so you can expect to get better autocompletions and suggestions for scipy related code

I welcome any feedback or contributions as I work towards improving the current annotations. You can find the package on PyPI and the source code on GitHub. I hope you find scipy-stubs useful in your Python projects!

Let me know if you have any questions.

2 Likes

Thanks a lot for creating this package @jorenham! It’s clear you put a ton of work into it, and it looks quite polished and valuable to SciPy users.

1 Like

To clarify: now that scipy-stubs exist and are in good shape (which is great!), we do not want any inline static typing in the scipy codebase itself? Possibly modulo internal utilities in _lib and _build_utils.

If so, it’d be useful to

  • add some statements to this effect to the developer docs. Also mention the recommended path for contributors (if you add a new function to scipy, consider updating scipy-stubs?)
  • remove bits and pieces of static typing from scipy, transfer good parts to scipy-stubs.

Cheers,

Evgeni

1 Like

Shouldn’t the proper way would be the opposite? (Move type hints into the library proper). This would ensure that type hints are kept in sync with the code, and it would be also easier to inspect the annotations of a particular function when looking at the source.

I think stubs are great for a proof of concept, or when the developers are stubborn and refuse to add type hints (because stubs can be made by third parties), but the end goal would be to merge them into the main repo, IMHO.

1 Like

Yes I considered doing exactly this. In scipy/scipy#21614 I explain in detail why I ended up creating a separate repo instead.
Once scipy-stubs is mature enough, I think that it would indeed for the best to bundle the stubs together with scipy.

Static type checkers give higher priority to stub packages than to other packages with a py.typed marker file. So technically it’s not a problem to keep (or add more) type-hints to scipy itself.

However, it’s very easy to make mistakes when writing writing annotations, especially when dealing with highly dynamic things such as array-likes and dtype-likes. Luckily, we have static type checkers like pyright that can tell us when we do. From experience I know that it’s a lot better to have no type annotations, than to have incorrect ones. That’s because without them, type-checkers can usually do a pretty good job at guessing them. But if there are annotations present, but they are incorrect, then these typing issues will propagate to all users that annotate their code.

And I hate to say it, but the majority annotations I’ve seen within scipy itself aren’t correct. And while that’s not a problem at the moment, it could give the false impression that scipy is actually a typed library, which could cause users to miss out on scipy-stubs.

As much as I love to see interest in typing, I think that for now it would indeed be best to remove the inline annotations and stubs from scipy.

I believe that stubgen already did this when generating the initial skeleton stubs. But if there’s any I missed that aren’t covered yet, then it would certainly help to open an issue or PR for it.

@rgommers suggested something similar a while back in TYP: `scipy-stubs` and the path towards typing scipy · Issue #21614 · scipy/scipy · GitHub, and there I explained some of the issues that might result in.
But even so, I’ll welcome anyone that’s willing to contribute to scipy-stubs – even if it’s your first time writing type-hints.

A large portion of _lib is actually already stubbed: scipy-stubs/scipy-stubs/_lib at master · jorenham/scipy-stubs · GitHub
Many other private modules are also covered, as I thought that the scipy devs could also benefit from using scipy-stubs that way, as wel :slight_smile: