On 2019-11-08 18:09, Brett Cannon wrote:
On Fri, Nov 8, 2019 at 10:01 AM Ricky Teachey
mailto:ricky@teachey.org> wrote: throwing this idea out there, no idea if it is practical but it might be pretty nice/easily understood syntax.
could a context manager be created such that anything imported under it is guaranteed to be imported from the standard library, and produce an error otherwise? perhaps by adding a level keyword argument to the __import__ built in.
__import__ already has a 'level' argument.
something like:
with __import__(level="std"): # imports guaranteed to fail of not in the standard library from pathlib import Path from sys import argv
with __import__(level="package"): # imports guaranteed to fail of not in the current package import mod1 import mod2
with __import__(level="local"): # imports guaranteed to fail of not in the local directory import mod1 import mod2
with __import__(level="site"): # imports guaranteed to fail if not in site-packages, or some other definition that makes sense import numpy as np
Not without frame inspection to know what import statements are in the context manager's block.
This can all be done with code which calls importlib.import_module() and checks __spec__.origin to see where the module came from. Basically if you're willing to give up the syntax support of 'import' statements (which are just calls to __import__ with some assignments afterwards to bind things to names) you can have this protection today without adding syntax (which is always a massive ask).
If we were to add syntax, the best I think I can come up with is: # imports guaranteed to fail of not in the standard library from pathlib in std import Path from sys in std import argv # imports guaranteed to fail of not in the current package import mod1 in package import mod2 in package # imports guaranteed to fail of not in the local directory import mod1 in local import mod2 in local # imports guaranteed to fail if not in site-packages, or some other definition that makes sense import numpy in site as np