-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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 .pyi files to help static type checkers deal with lazy imports #12059
Add .pyi files to help static type checkers deal with lazy imports #12059
Conversation
honestly to me this is too much. Suddenly we added a lot of extra work and complexity for what I consider a very marginal gain. |
I tend to agree with @agramfort. The real culprit is lazy loading though. To me, a little slower import time is not worth the extra hacks. A typical analysis script runs dozens of seconds, if not much longer, so a few seconds spent on import is negligible. |
I agree too. I don't see any advantage for me and most users thanks to lazy imports. Whether my scripts take 1 or 2.5 seconds to start processing is completely irrelevant to my work. And for interactive use, the import is run once at the very beginning and that's it... |
In case @agramfort was not talking about lazy imports per se, but only about the changes in this PR: I don't like lazy imports. They're an obvious and ugly hack as long as they're not a core language feature ... |
To add to the broader discussion about lazy imports, here's the justification as to why PEP 690 – Lazy Imports was rejected. I believe it's an interesting read. The core reason is this:
|
Indeed good points, I think these were discussed at some point during a dev meeting when we originally considered and made a go/no-go decision on #11780. Since we decided at that time to "go" I think we should stick with it a bit longer. If it gets (or continues to be) too onerous or broken for users or devs then we should eventually revert, but I don't think we've exhausted our options for fixing it yet. |
Just to be clear, my comments in #11780 were rather skeptical once I realized that the actual implementation is not ideal (as opposed to the general idea of lazy loading, which is great). It seems like the prospect of adding MNE-Python to the list of SPEC supporters was the driving force behind this discussion/decision rather than the actual technical implications. But OK with me to decide later. Maybe other people can share their thoughts as well here. |
I, too, can live with the changes started in this PR. The imports are redundant but at least the imported names are not strings anymore 😅 so that's at least something! |
I think we should re-evaluate our decision to adopt lazy loading. You can read my general thoughts on the topic here, and here is why I think MNE-Python doesn't need that extra complexity. Before lazy loading, |
There were factors other than just speed taken into account and discussed when we made that decision |
Would you mind reiterating them here? I could only find
But maybe more arguments have been discussed in a dev meeting (where I didn't participate). BTW, I don't think (1) is a good reason because lazy loading should not be a standard (see my comment in the scientific-python repo). And I'd argue that nested imports are less complex (and less prone to unexpected behavior) than lazy loading. |
Funnily enough, even the engineer who originally developed the lazy loading implementation we're using is extremely skeptical of the entire approach now. It's causing headaches for developers downstream. |
Yes those are the two major ones, and so far the un-nesting is a nice addition for contributors and maintainers alike I think.
I'm cautiously optimistic that we've solved most of those headaches now, but we'll see! I agree with eventually reverting if stuff continues to pop up after @drammock's latest PR. At some point the cost is too high. But I'd prefer to wait some more months (maybe a year?) and see if our maintenance burden has net gone up and/or package usability has net gone down. |
@cbrnr your big complaint seems to be with how the ecosystem presents lazy loading to the community. Given that MNE is a large complex package with many submodules, that complaint alone doesn't seem reason enough for us to abandon lazy loading, so I infer that you also have some other gripes... you say here that the speedup is too small to be worth it, but by now the work is already done so I think that point is now moot. Do you have any other substantive objections to it? @hoechenberger I think your chief complaint was to do with Pylance, but that is now working for you again, right? Any other substantive complaints? My personal take is that the "halfway" implementation that we did in #11838 was pretty bad (no code completion and an ugly / hard-to-grok implementation in our |
Yes.
Yes, you are correct in assuming that I don't think it is a good idea. The reasons are mentioned in the rejection of the PEP. It's likely that new corner cases will be discovered. For example, there is a significant conflict between lazy loading and strict type checking discussed here. I also don't like rolling a custom import system with .pyi files and whatnot. Finally, I don't understand why we brush away all arguments made by the Python core developers by saying "nah, we'll just implement it and it'll work". Anyway, it is probably more work to revert now than to wait and see what happens. Edit: And yes, I agree that our |
Hi @drammock, I'm currently on the road and don't have much time for a more elaborate response. But over the course of the past couple of days I read up on lazy loading in Python (including the rejected PEP 690 and the related discussion) and I'm just not convinced this is something we should have unless it becomes part of the stdlib. It also appears that the approach we've adopted now will break downstream projects that use mypy for strict typing. I'm not saying we should revert at this point, but my gut feeling is not a very positive one. In any case I'd like acknowledge and to thank you for all the work you've put into this! |
If I'm correctly interpreting the discussion that @cbrnr linked to (this one from skimage) then what we've done will not break downstream projects that use mypy for strict typing --- that would happen only if we included a |
That's also how I interpreted it @drammock. However, if we ever want to add type annotations to MNE, we will need |
Yes, this is my concern. I had locally tested (a while back, before we moved to lazy importing) adding type annotations for a few classes and functions, which greatly improved usability in some cases. It's really something I'd like to see either being added to MNE upstream or, alternatively, to typeshed someday. But it would require adding py.typed. So I'm a little bit uncertain about future implications here |
please read the skimage thread more carefully. The "downstream problems" arise from adding |
Thanks @drammock, I in fact didn't realize the mypy fix was already around the corner. |
Fixes #12047
This is very much work in progress and I only added the few
.pyi
files I needed to get some immediate work done. I'm not sure if and when I'll have time to complete this for all (sub)modules. Anyone, pleae feel free to help me out here or take over – this PR is really just meant to serve as a demo and starting point. I tested with Pylance and it's working as expected.FWIW I used the following script to generate the
.pyi
file content.cc @drammock