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


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

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.

Cheers,
Nick.

[1] http://hg.python.org/cpython/file/default/Lib/importlib/_bootstrap.py#l950

-- 
Nick Coghlan   |   ncogh...@gmail.com   |   Brisbane, Australia
_______________________________________________
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