Idea: Import Auto: Optional Automatic Imports for Modules

I can think of this import auto as equivalent to “lazy import all standard library modules” as a future extension to PEP 810.

import auto is definitely not intended to be used in production code, but like star imports (from some_module import *) it is harmful but too temptingly convenient :upside_down_face: that I can see many command-line stuff, REPL and throwaway scripts will be using it. Readability will be a problem outside of small scripts, and I think linters should always flag the use of import auto as an issue — if you are already using an IDE or linter, you might as well just let it explicitly spell out the imports you actually need.

Overall I’m -0 on this. It’s very convenient in some situations, but it masks potential typos. Given the general unwelcomedness of star imports I don’t think our standards should be any different here.

I don’t particularly dislike this proposal with it limited to the standard library, but I’d prefer this be a functionality of IDLE or the repl if needed, not the language itself.

I might use it as proposed in quick prototyping or off-the-cuff testing at the command line, though I have supplanted a lot of what I used to do that way with a local Jupyter environment, as I’ve found lately that having a persistent reference to how I got to a solution makes writing the corresponding internal documentation easier. I recognize I’m probably not representative of the person this would help, as I also have a shell alias that starts up a Python REPL with a customized site module and pre-imports various things I use frequently when just quickly hacking up a prototype.

I’m not worried about import auto being used in a production situation in a way that can be harmful if implemented as proposed. It’s limited to the standard library, and I don’t have any concerns about confusability creating a sneaky exploit. As for non-security concerns, this is something that not doing can be handled by conventions/consenting adults principles.

It might be more palatable to some people if we were in a future where all stdlib modules where namespaced under a top level std as presumably an import of a standard library module then wouldn’t ever clobber other uses of a name.

2 Likes

Thanks for your view. I understand what you mean when you say it shouldn’t be put into the language but keep it in the IDLE or the REPL.

But I do still believe there is a use in having a standard way to do it , but I think starting it off as a REPL feature would be a good start.

In fact, I think this would become redundant if (when?) that happens, as from std import * would do basically the same thing.

In fact, couldn’t this be implemented right now as a 3rd party package that just implemented all of the stdlib?

2 Likes

You can do this with ipython profiles. You just create a profile that does a bunch of import x, y at startup.

Also add the code that make the name available in the main code

With the small gotcha that importing all the stdlib[1] will print the Zen in your terminal and open a comic in your web browser :smile:


  1. according to sys.stdlib_module_names ↩︎

9 Likes

Yes, though it’s likely a few modules should not be imported by default, but use a module __getattr__ (this is a clear one, so is antigravity). They should also avoid using the name std for such a package given the public interest, but no concrete proposal as of yet to have such a standard top level namespace.

I think automatically importing stdlib modules could be useful in educational contexts.

You could do this today by setting the environment variable PYTHONSTARTUP=/path/to/add_stdlib_modules_to_builtins.py. That can be done in the command line, in an IDE, or in a shell profile.

The script referenced would then import stdlib modules of interest and add them as attributes of the builtins module.

It could definitely be implemented that way, but a lot of names overlap (e.g. operator.abs vs. builtins.abs). I suppose that means that they’ll still need to be implemented in submodules (or as classes).

???

All I meant was:

mystdlib.py

import math
import sys
import os
import pathlib
# etc...

Then, in your code,

from mystdlib import *
# ...

No way does importing every name from every stdlib module, with no qualifiers or namespacing, make sense. There would be so many name clashes it would be a disaster.

Nor do I think that’s what the OP was asking for…

2 Likes

Oh, then i suppose i just missunderstood you, sorry for the confusion.

Eagerly importing almost all standard library modules is too expensive. We can make an easy way to lazily import stdlib modules if PEP 810 is accepted, and I think this would be actually one of the use cases of essentially cost-free lazy import (at the moment the cost still hasn’t been decided, but I think it’s not unreasonable to allow standard library modules to skip module spec checking).

Another possible solution is to allow easy hooking of the global and builtin lookup process before raising NameError (I don’t think monkey-patching builtins such as ModuleType.__getattr__ is possible yet). With a hook we are not limited to importing stdlib modules, we can import other modules or even return other objects whenever a name lookup would fail. Performance shouldn’t be an issue as this hook is intended to be a backstop, so it shouldn’t be in the happy path of normal name lookup. Though, how useful such a feature will be outside of specific cases remains to be justified.