blob: 22c90f24a7e46cecbbc87027a319576d7c32c006 [file] [log] [blame]
Brett Cannonb46a1792012-02-27 18:15:42 -05001"""A pure Python implementation of import."""
Antoine Pitrouc541f8e2012-02-20 01:48:16 +01002__all__ = ['__import__', 'import_module', 'invalidate_caches']
Brett Cannon9495f182009-03-12 22:01:40 +00003
Brett Cannon7f400e12009-01-22 22:44:04 +00004# Bootstrap help #####################################################
Nick Coghlanbe7e49f2012-07-20 23:40:09 +10005
6# Until bootstrapping is complete, DO NOT import any modules that attempt
7# to import importlib._bootstrap (directly or indirectly). Since this
8# partially initialised package would be present in sys.modules, those
9# modules would get an uninitialised copy of the source version, instead
10# of a fully initialised version (either the frozen one or the one
11# initialised below if the frozen one is not available).
12import _imp # Just the builtin component, NOT the full Python module
Brett Cannon354c26e2012-02-08 18:50:22 -050013import sys
Brett Cannon7f400e12009-01-22 22:44:04 +000014
Antoine Pitrou48114b92012-06-17 22:33:38 +020015try:
Brett Cannon53089c62012-07-04 14:03:40 -040016 import _frozen_importlib as _bootstrap
17except ImportError:
Antoine Pitrou48114b92012-06-17 22:33:38 +020018 from . import _bootstrap
Nick Coghlanbe7e49f2012-07-20 23:40:09 +100019 _bootstrap._setup(sys, _imp)
Antoine Pitrou48114b92012-06-17 22:33:38 +020020else:
21 # importlib._bootstrap is the built-in import, ensure we don't create
22 # a second copy of the module.
23 _bootstrap.__name__ = 'importlib._bootstrap'
24 _bootstrap.__package__ = 'importlib'
25 _bootstrap.__file__ = __file__.replace('__init__.py', '_bootstrap.py')
26 sys.modules['importlib._bootstrap'] = _bootstrap
27
28# To simplify imports in test code
29_w_long = _bootstrap._w_long
30_r_long = _bootstrap._r_long
Brett Cannon23cbd8a2009-01-18 00:24:28 +000031
Nick Coghlanbe7e49f2012-07-20 23:40:09 +100032# Fully bootstrapped at this point, import whatever you like, circular
33# dependencies and startup overhead minimisation permitting :)
Brett Cannonafccd632009-01-20 02:21:27 +000034
Brett Cannon7f400e12009-01-22 22:44:04 +000035# Public API #########################################################
36
Brett Cannonb46a1792012-02-27 18:15:42 -050037from ._bootstrap import __import__
38
39
40def invalidate_caches():
Brett Cannonf4dc9202012-08-10 12:21:12 -040041 """Call the invalidate_caches() method on all meta path finders stored in
42 sys.meta_path (where implemented)."""
43 for finder in sys.meta_path:
Brett Cannonb46a1792012-02-27 18:15:42 -050044 if hasattr(finder, 'invalidate_caches'):
45 finder.invalidate_caches()
Brett Cannonafccd632009-01-20 02:21:27 +000046
47
Brett Cannonee78a2b2012-05-12 17:43:17 -040048def find_loader(name, path=None):
49 """Find the loader for the specified module.
50
51 First, sys.modules is checked to see if the module was already imported. If
52 so, then sys.modules[name].__loader__ is returned. If that happens to be
53 set to None, then ValueError is raised. If the module is not in
54 sys.modules, then sys.meta_path is searched for a suitable loader with the
55 value of 'path' given to the finders. None is returned if no loader could
56 be found.
57
Brett Cannon56b4ca72012-11-17 09:30:55 -050058 Dotted names do not have their parent packages implicitly imported. You will
59 most likely need to explicitly import all parent packages in the proper
60 order for a submodule to get the correct loader.
Brett Cannonee78a2b2012-05-12 17:43:17 -040061
62 """
63 try:
64 loader = sys.modules[name].__loader__
65 if loader is None:
66 raise ValueError('{}.__loader__ is None'.format(name))
67 else:
68 return loader
69 except KeyError:
70 pass
71 return _bootstrap._find_module(name, path)
72
73
Brett Cannonafccd632009-01-20 02:21:27 +000074def import_module(name, package=None):
75 """Import a module.
76
77 The 'package' argument is required when performing a relative import. It
78 specifies the package to use as the anchor point from which to resolve the
79 relative import to an absolute import.
80
81 """
Brett Cannon2c318a12009-02-07 01:15:27 +000082 level = 0
Brett Cannonafccd632009-01-20 02:21:27 +000083 if name.startswith('.'):
84 if not package:
85 raise TypeError("relative imports require the 'package' argument")
Brett Cannonafccd632009-01-20 02:21:27 +000086 for character in name:
87 if character != '.':
88 break
89 level += 1
Brett Cannon2c318a12009-02-07 01:15:27 +000090 return _bootstrap._gcd_import(name[level:], package, level)