- 
                Notifications
    You must be signed in to change notification settings 
- Fork 24
feat: add lazy_context (beware: magic) #12
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
Conversation
| @tlambert03 Hah, fun and clever!  But, indeed, the  | 
| 
 there is a way by patching  | 
| mad respect for the crazy magic | 
| @stefanv you could achieve the same by loading an invalid package, e.g.:  | 
| or really use any exception of your choice to stop the process. actually thinking about this i like that form of magic 😂 for example u could make a function  | 
| For extra confusion, you can use: with lazy_loader.lazy_imports():
    ...
    0//4
    ...
    from . import rank
    from ._fft_based import butterworth
    from ._gabor import gabor, gabor_kernel
    from ._gaussian import difference_of_gaussians, gaussian😄 Maybe more sensibly: with lazy_loader.lazy_imports() as delay_imports:
    delay_imports()
    from . import rank
    from ._fft_based import butterworth
    from ._gabor import gabor, gabor_kernel
    from ._gaussian import difference_of_gaussians, gaussian | 
| 
 Apparently, the assignment to a variable also counts as part of the code inside the  You would want to catch in the  | 
| I still cannot let this syntax go (it is better than stubs). from contextlib import contextmanager
def raise_exc(*args, **kwargs):
    raise ImportError
@contextmanager
def remove_exceptions():
    import builtins
    import_fun = builtins.__import__
    builtins.__import__ = raise_exc
    try:
        yield None
    finally:        
        builtins.__import__ = import_fun
with remove_exceptions:
    from numpy import meanThis approach even allows to remove the magic, letting Python machinery give us the import names themselves!!!: import builtins
from types import SimpleNamespace
class SaveModules():
    def __init__(self):
        self.imports = []
    def __enter__(self):
        self.import_fun = builtins.__import__
        builtins.__import__ = self._my_import
        return None
    def __exit__(self, type, value, tb):
        builtins.__import__ = self.import_fun
        print(self.imports)
    def _my_import(self, name, globals=None, locals=None, fromlist=(), level=0):
        builtins.__import__ = self.import_fun
        self.imports.append({"name": name, "fromlist": fromlist, "level": level})
        builtins.__import__ = self._my_import
        if fromlist:
              return SimpleNamespace(**{k: None for k in fromlist})
        return None
with SaveModules():
    from numpy import mean
    import scipy
    from .. import kk | 
| The advantage of the stubs is that you get type inference, which is more important to a lot of people than I realized. But this is certainly an improvement in syntax over  | 
| Why shouldn't you get type inference with this approach? As far as I know Mypy will assume that the imports work as normal (I haven't tested it) and use their associated types. | 
| Worth a try! | 
| indeed. worth a try! :) | 
I was intrigued by @maurosilber context manager concept from #11 ...
This PR achieves that syntax using some serious ridiculousness 😂
believe it or not, it works! and it makes IDEs happy without any pyi files. It basically parses the source code from the
withblock using the same ast parser from #10 ... and then injects the output into the module globalsThat said, I wouldn't be surprised or offended in the least if you closed this PR immediately and rushed off to take a shower 🛀 Opening this mostly as a proof of principle and record of a little magic exploration :)