On Wed, Feb 8, 2012 at 20:26, Nick Coghlan <ncogh...@gmail.com> wrote:

> On Thu, Feb 9, 2012 at 2:09 AM, Antoine Pitrou <solip...@pitrou.net>
> wrote:
> > I guess my point was: why is there a function call in that case? The
> > "import" statement could look up sys.modules directly.
> > Or the built-in __import__ could still be written in C, and only defer
> > to importlib when the module isn't found in sys.modules.
> > Practicality beats purity.
>
> I quite like the idea of having builtin __import__ be a *very* thin
> veneer around importlib that just does the "is this in sys.modules
> already so we can just return it from there?" checks and delegates
> other more complex cases to Python code in importlib.
>
> Poking around in importlib.__import__ [1] (as well as
> importlib._gcd_import), I'm thinking what we may want to do is break
> up the logic a bit so that there are multiple helper functions that a
> C version can call back into so that we can optimise certain simple
> code paths to not call back into Python at all, and others to only do
> so selectively.
>
> Step 1: separate out the "fromlist" processing from __import__ into a
> separate helper function
>
>    def _process_fromlist(module, fromlist):
>        # Perform any required imports as per existing code:
>        #
> http://hg.python.org/cpython/file/aba513307f78/Lib/importlib/_bootstrap.py#l987
>
>
Fine by me.


>
> Step 2: separate out the relative import resolution from _gcd_import
> into a separate helper function.
>
>    def _resolve_relative_name(name, package, level):
>        assert hasattr(name, 'rpartition')
>        assert hasattr(package, 'rpartition')
>        assert level > 0
>        name = # Recalculate as per the existing code:
>        #
> http://hg.python.org/cpython/file/aba513307f78/Lib/importlib/_bootstrap.py#l889
>        return name
>

I was actually already thinking of exposing this as
importlib.resolve_name() so breaking it out makes sense.

I also think it might be possible to expose a sort of
importlib.find_module() that does nothing more than find the loader for a
module  (if available).


>
> Step 3: Implement builtin __import__ in C (pseudo-code below):
>
>    def __import__(name, globals={}, locals={}, fromlist=[], level=0):
>        if level > 0:
>            name = importlib._resolve_relative_import(name)
>         try:
>            module = sys.modules[name]
>        except KeyError:
>             # Not cached yet, need to invoke the full import machinery
>            # We already resolved any relative imports though, so
>            # treat it as an absolute import
>            return importlib.__import__(name, globals, locals, fromlist, 0)
>        # Got a hit in the cache, see if there's any more work to do
>        if not fromlist:
>            # Duplicate relevant importlib.__import__ logic as C code
>            # to find the right module to return from sys.modules
>        elif hasattr(module, "__path__"):
>            importlib._process_fromlist(module, fromlist)
>        return module
>
> This would then be similar to the way main.c already works when it
> interacts with runpy - simple cases are handled directly in C, more
> complex cases get handed over to the Python module.
>

I suspect that if people want the case where you load from bytecode is fast
then this will have to expand beyond this to include C functions and/or
classes which can be used as accelerators; while this accelerates the
common case of sys.modules, this (probably) won't make Antoine happy enough
for importing a small module from bytecode (importing large modules like
decimal are already fast enough).
_______________________________________________
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com

Reply via email to