-
-
Notifications
You must be signed in to change notification settings - Fork 491
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
Lazy imports based on __import__ #22752
Comments
This comment has been minimized.
This comment has been minimized.
Dependencies: #22755 |
Branch: u/jdemeyer/ticket/22752 |
Upstream: Reported upstream. No feedback yet. |
Commit: |
This comment has been minimized.
This comment has been minimized.
Changed upstream from Reported upstream. No feedback yet. to Fixed upstream, but not in a stable release. |
This comment has been minimized.
This comment has been minimized.
comment:9
I don't think using the context manager is thread safe, and python as a whole doesn't forbid using threads. I'm afraid we're stuck with other, less attractive syntax. I haven't looked into this in detail, but python does have an impressive hooks etc. in the import system (hooks that have changed quite a bit in later versions of 3.* as well ...). If we want to co-opt the
|
comment:10
Different note on lazy imports: Currently we have hundreds of "lazy-import" objects hanging around coming from
and then in module
The problem is that the lazy import object that gets bound to B.XXX still has a pointer to the namespace of A, so every time B.XXX gets called, it will looking at A.XXX. See #16522. If we're going to put hooks into the import system, perhaps we can filter out these issues as well. |
comment:11
I don't like two similar-looking names
Looking at your code, it seems that you chose |
comment:12
Hm. Replacing
what's more, we could also wrap
to check if XXX is a The only offence is that we'd be incompatible with a top-level module "lazy" existing. |
comment:13
Replying to @nbruin:
On the other hard, I would argue that lazy imports are mostly useful during startup, where multi-threading is not likely.
I guess you refer to PEP 302? I did look into that, but it doesn't quite work. It's the wrong level of abstraction. These PEP 302 hooks assume that you actually want to import something (i.e. add a new entry to
Interesting syntax. I guess that would work (not for relative imports, but that is a minor thing). The only problem is that
|
comment:14
Replying to @nbruin:
Funny. I was thinking exactly the same thing after reading your comment [comment:10] |
comment:15
Thinking more about it, I prefer
Only the latter would support relative imports like |
This comment has been minimized.
This comment has been minimized.
comment:17
Nils, you idea doesn't allow passing extra options to
|
This comment has been minimized.
This comment has been minimized.
comment:42
And maybe #21636 too, while you're at it. |
comment:43
...which should eventually lead to a fix for #22747 which I need for OpenDreamKit/OpenDreamKit#87 |
comment:44
Just to know where we stand, let me try to summarize the pros and cons of my approach. I'll try to do this objectively. It will at least allow to compare different approaches. New features compared to the old
Existing features from
Cons:
Finally, let me mention that #21636 is the main reason to work on this, for which in particular proper Cython support for lazy imports is needed. |
comment:46
You wouldn't be manipulating |
comment:47
I think I understand better now how this is really only trying to override the So that takes me back to thinking that some modules should always use some kind of lazy-import mechanism. It's better overall to design things to avoid circular imports in the first place, but it's admittedly tricky for some fundamental modules (like rationals are defined in terms of integers, but operations on integers can return rationals, or need to be able to work with rationals, etc.). That's just one example it it seems to be one of the most pervasive. Now, supporting On a slightly different topic, I don't quite understand why the "deprecation" feature of the existing
this could look something like:
A custom module wrapper would be able handle imports of objects listed in I feel like this is a clearer and more explicit declarative approach to how some attributes of some modules should be handled, rather than mucking with the import system every single time this feature is needed. |
comment:48
Just out of curiosity, I'm going to take a stab at replacing our proxy with |
comment:49
Replying to @embray:
No, it's not. Python is completely fine with circular imports. The problem arises when there is a circular access of module attributes during load time. The problem with "from foo import ..." is that it automatically leads to a module attribute access during load time. Without "from foo import ..." you'd have to write something like
which is very unlikely to happen, since usually at load time only declarations are executed. For that kind of symbols we would basically just need
where forward_binding could be resolved as soon as A is initialized. The proxy doesn't have to hang around until first used, as with lazy-import. I'm not sure we have the right hooks to do this, but if there are I think we could change |
comment:51
Replying to @jdemeyer:
I think there might be a more reliable way: When
i.e., the new import uses a binding in the relevant scope to see if it needs to intercept imports and make them lazy or whether they should be processed as normal. That way, the new import routine would be transparent for scopes where lazy_import isn't being used. Based on that infrastructure, a context would be just fine. It would be about toggling a flag in the relevant scope rather than changing a global variable. It does mean we'd need to have our "import" wrapper in place all the time, because swapping it out would still be sensitive to scoping and threading issues. |
comment:52
I still think that messing so much with imports for what you want to accomplish is overkill. My point in my last comment was that whether you use the You could even make the module wrapper itself a context manager for handling lazy imports. I don't know that this is the clearest syntax but it's an idea:
In this case I think the 'deprecation warning' aspect of My experiment in rewriting |
comment:53
Can we maybe discuss exactly what the use cases are for lazy-import? To me the primary use case--the one that really matters--is just breaking circular imports at startup time. I've never needed something like lazy imports to get around that before, but I admit some of the circular definitions in Sage are vexing and hard to avoid, especially in Cygwin modules where we have less control over the order in which module-level statements are executed with respect to each other. So that's one case. The other two, as far as I can tell, are:
I don't really much see the case for the latter of the two. If the main use case for lazy imports (and note: I'm not necessarily claiming that's the case, that's just my understanding) then who cares if gets resolved at startup time? If it does, any nothing breaks, then it doesn't need to be a lazy import in the first place (having this feature optionally for debugging purposes is nice though). |
comment:54
Or are there also cases where lazy import is used for performance reasons, and if so what are some examples of that? |
comment:55
I would say there are two important use cases:
|
comment:56
Got it--thanks for clarifying. |
comment:57
TODO: discuss lazy imports next week too with @embray. |
comment:58
Good news for myself: I think I can get #22747 to work without requiring this. |
comment:59
Is that the issue you refer to when you mean "works with Cython"? |
Changed upstream from Fixed upstream, but not in a stable release. to none |
Implement lazy imports by overriding import.
To be used as
Unlike the existing lazy import implementation, this supports both Python and Cython.
Depends on #22755
Component: misc
Author: Jeroen Demeyer
Branch/Commit: u/jdemeyer/ticket/22752 @
9e1208b
Issue created by migration from https://trac.sagemath.org/ticket/22752
The text was updated successfully, but these errors were encountered: