| 
									
										
										
										
											2009-01-18 00:24:28 +00:00
										 |  |  | """Core implementation of import.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | This module is NOT meant to be directly imported! It has been designed such | 
					
						
							|  |  |  | that it can be bootstrapped into Python as the implementation of import. As | 
					
						
							|  |  |  | such it requires the injection of specific modules and attributes in order to | 
					
						
							|  |  |  | work. One should use importlib as the public-facing version of this module. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | """
 | 
					
						
							| 
									
										
										
										
											2012-04-25 10:54:48 +02:00
										 |  |  | # | 
					
						
							|  |  |  | # IMPORTANT: Whenever making changes to this module, be sure to run | 
					
						
							|  |  |  | # a top-level make in order to get the frozen version of the module | 
					
						
							| 
									
										
										
										
											2014-05-30 14:55:29 -04:00
										 |  |  | # updated. Not doing so will result in the Makefile to fail for | 
					
						
							| 
									
										
										
										
											2012-04-25 10:54:48 +02:00
										 |  |  | # all others who don't have a ./python around to freeze the module | 
					
						
							|  |  |  | # in the early stages of compilation. | 
					
						
							|  |  |  | # | 
					
						
							| 
									
										
										
										
											2009-01-18 00:24:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-20 21:19:53 -04:00
										 |  |  | # See importlib._setup() for what is injected into the global namespace. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-18 00:24:28 +00:00
										 |  |  | # When editing this code be aware that code executed at import time CANNOT | 
					
						
							|  |  |  | # reference any injected objects! This includes not only global code but also | 
					
						
							|  |  |  | # anything specified at the class level. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-12 22:28:55 +00:00
										 |  |  | # Bootstrap-related code ###################################################### | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-04 13:52:49 -04:00
										 |  |  | _CASE_INSENSITIVE_PLATFORMS = 'win', 'cygwin', 'darwin' | 
					
						
							| 
									
										
										
										
											2012-01-26 19:03:52 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-20 13:52:47 +01:00
										 |  |  | def _make_relax_case(): | 
					
						
							| 
									
										
										
										
											2012-05-04 13:52:49 -04:00
										 |  |  |     if sys.platform.startswith(_CASE_INSENSITIVE_PLATFORMS): | 
					
						
							| 
									
										
										
										
											2012-02-20 01:48:16 +01:00
										 |  |  |         def _relax_case(): | 
					
						
							| 
									
										
										
										
											2012-02-20 15:06:35 -05:00
										 |  |  |             """True if filenames must be checked case-insensitively.""" | 
					
						
							| 
									
										
										
										
											2013-09-03 19:43:49 -05:00
										 |  |  |             return b'PYTHONCASEOK' in _os.environ | 
					
						
							| 
									
										
										
										
											2012-01-26 19:03:52 -05:00
										 |  |  |     else: | 
					
						
							| 
									
										
										
										
											2012-02-20 01:48:16 +01:00
										 |  |  |         def _relax_case(): | 
					
						
							| 
									
										
										
										
											2012-02-20 15:06:35 -05:00
										 |  |  |             """True if filenames must be checked case-insensitively.""" | 
					
						
							| 
									
										
										
										
											2012-02-20 01:48:16 +01:00
										 |  |  |             return False | 
					
						
							|  |  |  |     return _relax_case | 
					
						
							| 
									
										
										
										
											2012-01-26 19:03:52 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-25 18:58:03 -05:00
										 |  |  | def _w_long(x): | 
					
						
							| 
									
										
										
										
											2013-05-28 18:35:54 -04:00
										 |  |  |     """Convert a 32-bit integer to little-endian.""" | 
					
						
							| 
									
										
										
										
											2013-02-25 17:10:11 -05:00
										 |  |  |     return (int(x) & 0xFFFFFFFF).to_bytes(4, 'little') | 
					
						
							| 
									
										
										
										
											2012-01-25 18:58:03 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def _r_long(int_bytes): | 
					
						
							| 
									
										
										
										
											2013-05-28 18:35:54 -04:00
										 |  |  |     """Convert 4 bytes in little-endian to an integer.""" | 
					
						
							| 
									
										
										
										
											2013-02-25 15:40:33 +02:00
										 |  |  |     return int.from_bytes(int_bytes, 'little') | 
					
						
							| 
									
										
										
										
											2012-01-25 18:58:03 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-22 11:45:07 -04:00
										 |  |  | def _path_join(*path_parts): | 
					
						
							| 
									
										
										
										
											2012-04-20 21:19:53 -04:00
										 |  |  |     """Replacement for os.path.join().""" | 
					
						
							| 
									
										
										
										
											2013-02-25 15:40:33 +02:00
										 |  |  |     return path_sep.join([part.rstrip(path_separators) | 
					
						
							|  |  |  |                           for part in path_parts if part]) | 
					
						
							| 
									
										
										
										
											2012-04-20 21:19:53 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def _path_split(path): | 
					
						
							|  |  |  |     """Replacement for os.path.split().""" | 
					
						
							| 
									
										
										
										
											2013-02-25 15:40:33 +02:00
										 |  |  |     if len(path_separators) == 1: | 
					
						
							|  |  |  |         front, _, tail = path.rpartition(path_sep) | 
					
						
							|  |  |  |         return front, tail | 
					
						
							| 
									
										
										
										
											2012-04-20 21:19:53 -04:00
										 |  |  |     for x in reversed(path): | 
					
						
							|  |  |  |         if x in path_separators: | 
					
						
							| 
									
										
										
										
											2013-02-25 17:10:11 -05:00
										 |  |  |             front, tail = path.rsplit(x, maxsplit=1) | 
					
						
							| 
									
										
										
										
											2013-02-25 15:40:33 +02:00
										 |  |  |             return front, tail | 
					
						
							|  |  |  |     return '', path | 
					
						
							| 
									
										
										
										
											2009-01-18 00:24:28 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-01 14:04:24 -04:00
										 |  |  | def _path_stat(path): | 
					
						
							|  |  |  |     """Stat the path.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Made a separate function to make it easier to override in experiments | 
					
						
							|  |  |  |     (e.g. cache stat results). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     return _os.stat(path) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-18 00:24:28 +00:00
										 |  |  | def _path_is_mode_type(path, mode): | 
					
						
							|  |  |  |     """Test whether the path is the specified mode type.""" | 
					
						
							|  |  |  |     try: | 
					
						
							| 
									
										
										
										
											2013-11-01 14:04:24 -04:00
										 |  |  |         stat_info = _path_stat(path) | 
					
						
							| 
									
										
										
										
											2009-01-18 00:24:28 +00:00
										 |  |  |     except OSError: | 
					
						
							|  |  |  |         return False | 
					
						
							|  |  |  |     return (stat_info.st_mode & 0o170000) == mode | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def _path_isfile(path): | 
					
						
							|  |  |  |     """Replacement for os.path.isfile.""" | 
					
						
							|  |  |  |     return _path_is_mode_type(path, 0o100000) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def _path_isdir(path): | 
					
						
							|  |  |  |     """Replacement for os.path.isdir.""" | 
					
						
							| 
									
										
										
										
											2010-07-03 21:48:25 +00:00
										 |  |  |     if not path: | 
					
						
							|  |  |  |         path = _os.getcwd() | 
					
						
							| 
									
										
										
										
											2009-01-18 00:24:28 +00:00
										 |  |  |     return _path_is_mode_type(path, 0o040000) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-08-24 18:32:40 +10:00
										 |  |  | def _write_atomic(path, data, mode=0o666): | 
					
						
							| 
									
										
										
										
											2012-02-22 21:03:09 +01:00
										 |  |  |     """Best-effort function to write data to a path atomically.
 | 
					
						
							|  |  |  |     Be prepared to handle a FileExistsError if concurrent writing of the | 
					
						
							|  |  |  |     temporary file is attempted."""
 | 
					
						
							| 
									
										
										
										
											2011-11-15 19:15:19 +01:00
										 |  |  |     # id() is used to generate a pseudo-random filename. | 
					
						
							|  |  |  |     path_tmp = '{}.{}'.format(path, id(path)) | 
					
						
							| 
									
										
										
										
											2012-08-24 18:32:40 +10:00
										 |  |  |     fd = _os.open(path_tmp, | 
					
						
							|  |  |  |                   _os.O_EXCL | _os.O_CREAT | _os.O_WRONLY, mode & 0o666) | 
					
						
							| 
									
										
										
										
											2011-11-15 19:15:19 +01:00
										 |  |  |     try: | 
					
						
							| 
									
										
										
										
											2012-02-17 09:26:53 -05:00
										 |  |  |         # We first write data to a temporary file, and then use os.replace() to | 
					
						
							|  |  |  |         # perform an atomic rename. | 
					
						
							| 
									
										
										
										
											2011-11-15 19:15:19 +01:00
										 |  |  |         with _io.FileIO(fd, 'wb') as file: | 
					
						
							|  |  |  |             file.write(data) | 
					
						
							| 
									
										
										
										
											2012-02-17 09:26:53 -05:00
										 |  |  |         _os.replace(path_tmp, path) | 
					
						
							| 
									
										
										
										
											2011-11-15 19:15:19 +01:00
										 |  |  |     except OSError: | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             _os.unlink(path_tmp) | 
					
						
							| 
									
										
										
										
											2011-10-17 19:28:44 +02:00
										 |  |  |         except OSError: | 
					
						
							| 
									
										
										
										
											2011-11-15 19:15:19 +01:00
										 |  |  |             pass | 
					
						
							|  |  |  |         raise | 
					
						
							| 
									
										
										
										
											2011-10-17 19:28:44 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-12 22:07:17 +00:00
										 |  |  | def _wrap(new, old): | 
					
						
							| 
									
										
										
										
											2012-07-07 13:16:44 +02:00
										 |  |  |     """Simple substitute for functools.update_wrapper.""" | 
					
						
							| 
									
										
										
										
											2011-12-14 22:53:13 -06:00
										 |  |  |     for replace in ['__module__', '__name__', '__qualname__', '__doc__']: | 
					
						
							| 
									
										
										
										
											2012-02-08 18:44:14 -05:00
										 |  |  |         if hasattr(old, replace): | 
					
						
							|  |  |  |             setattr(new, replace, getattr(old, replace)) | 
					
						
							| 
									
										
										
										
											2009-02-07 02:13:28 +00:00
										 |  |  |     new.__dict__.update(old.__dict__) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-22 09:05:39 -07:00
										 |  |  | def _new_module(name): | 
					
						
							|  |  |  |     return type(sys)(name) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-04 13:52:49 -04:00
										 |  |  | _code_type = type(_wrap.__code__) | 
					
						
							| 
									
										
										
										
											2010-07-03 21:48:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-15 16:08:47 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-29 11:00:11 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | class _ManageReload: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     """Manages the possible clean-up of sys.modules for load_module().""" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def __init__(self, name): | 
					
						
							|  |  |  |         self._name = name | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def __enter__(self): | 
					
						
							|  |  |  |         self._is_reload = self._name in sys.modules | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def __exit__(self, *args): | 
					
						
							|  |  |  |         if any(arg is not None for arg in args) and not self._is_reload: | 
					
						
							|  |  |  |             try: | 
					
						
							|  |  |  |                 del sys.modules[self._name] | 
					
						
							|  |  |  |             except KeyError: | 
					
						
							|  |  |  |                 pass | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-17 18:55:59 +02:00
										 |  |  | # Module-level locking ######################################################## | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # A dict mapping module names to weakrefs of _ModuleLock instances | 
					
						
							|  |  |  | _module_locks = {} | 
					
						
							|  |  |  | # A dict mapping thread ids to _ModuleLock instances | 
					
						
							|  |  |  | _blocking_on = {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class _DeadlockError(RuntimeError): | 
					
						
							|  |  |  |     pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class _ModuleLock: | 
					
						
							|  |  |  |     """A recursive lock implementation which is able to detect deadlocks
 | 
					
						
							|  |  |  |     (e.g. thread 1 trying to take locks A then B, and thread 2 trying to | 
					
						
							|  |  |  |     take locks B then A). | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def __init__(self, name): | 
					
						
							|  |  |  |         self.lock = _thread.allocate_lock() | 
					
						
							|  |  |  |         self.wakeup = _thread.allocate_lock() | 
					
						
							|  |  |  |         self.name = name | 
					
						
							|  |  |  |         self.owner = None | 
					
						
							|  |  |  |         self.count = 0 | 
					
						
							|  |  |  |         self.waiters = 0 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def has_deadlock(self): | 
					
						
							|  |  |  |         # Deadlock avoidance for concurrent circular imports. | 
					
						
							|  |  |  |         me = _thread.get_ident() | 
					
						
							|  |  |  |         tid = self.owner | 
					
						
							|  |  |  |         while True: | 
					
						
							|  |  |  |             lock = _blocking_on.get(tid) | 
					
						
							|  |  |  |             if lock is None: | 
					
						
							|  |  |  |                 return False | 
					
						
							|  |  |  |             tid = lock.owner | 
					
						
							|  |  |  |             if tid == me: | 
					
						
							|  |  |  |                 return True | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def acquire(self): | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         Acquire the module lock.  If a potential deadlock is detected, | 
					
						
							|  |  |  |         a _DeadlockError is raised. | 
					
						
							|  |  |  |         Otherwise, the lock is always acquired and True is returned. | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         tid = _thread.get_ident() | 
					
						
							|  |  |  |         _blocking_on[tid] = self | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             while True: | 
					
						
							|  |  |  |                 with self.lock: | 
					
						
							|  |  |  |                     if self.count == 0 or self.owner == tid: | 
					
						
							|  |  |  |                         self.owner = tid | 
					
						
							|  |  |  |                         self.count += 1 | 
					
						
							|  |  |  |                         return True | 
					
						
							|  |  |  |                     if self.has_deadlock(): | 
					
						
							| 
									
										
										
										
											2013-07-12 11:04:23 -04:00
										 |  |  |                         raise _DeadlockError('deadlock detected by %r' % self) | 
					
						
							| 
									
										
										
										
											2012-05-17 18:55:59 +02:00
										 |  |  |                     if self.wakeup.acquire(False): | 
					
						
							|  |  |  |                         self.waiters += 1 | 
					
						
							|  |  |  |                 # Wait for a release() call | 
					
						
							|  |  |  |                 self.wakeup.acquire() | 
					
						
							|  |  |  |                 self.wakeup.release() | 
					
						
							|  |  |  |         finally: | 
					
						
							|  |  |  |             del _blocking_on[tid] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def release(self): | 
					
						
							|  |  |  |         tid = _thread.get_ident() | 
					
						
							|  |  |  |         with self.lock: | 
					
						
							|  |  |  |             if self.owner != tid: | 
					
						
							| 
									
										
										
										
											2013-07-12 11:04:23 -04:00
										 |  |  |                 raise RuntimeError('cannot release un-acquired lock') | 
					
						
							| 
									
										
										
										
											2012-05-17 18:55:59 +02:00
										 |  |  |             assert self.count > 0 | 
					
						
							|  |  |  |             self.count -= 1 | 
					
						
							|  |  |  |             if self.count == 0: | 
					
						
							|  |  |  |                 self.owner = None | 
					
						
							|  |  |  |                 if self.waiters: | 
					
						
							|  |  |  |                     self.waiters -= 1 | 
					
						
							|  |  |  |                     self.wakeup.release() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def __repr__(self): | 
					
						
							| 
									
										
										
										
											2013-07-12 11:04:23 -04:00
										 |  |  |         return '_ModuleLock({!r}) at {}'.format(self.name, id(self)) | 
					
						
							| 
									
										
										
										
											2012-05-17 18:55:59 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class _DummyModuleLock: | 
					
						
							|  |  |  |     """A simple _ModuleLock equivalent for Python builds without
 | 
					
						
							|  |  |  |     multi-threading support."""
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def __init__(self, name): | 
					
						
							|  |  |  |         self.name = name | 
					
						
							|  |  |  |         self.count = 0 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def acquire(self): | 
					
						
							|  |  |  |         self.count += 1 | 
					
						
							|  |  |  |         return True | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def release(self): | 
					
						
							|  |  |  |         if self.count == 0: | 
					
						
							| 
									
										
										
										
											2013-07-12 11:04:23 -04:00
										 |  |  |             raise RuntimeError('cannot release un-acquired lock') | 
					
						
							| 
									
										
										
										
											2012-05-17 18:55:59 +02:00
										 |  |  |         self.count -= 1 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def __repr__(self): | 
					
						
							| 
									
										
										
										
											2013-07-12 11:04:23 -04:00
										 |  |  |         return '_DummyModuleLock({!r}) at {}'.format(self.name, id(self)) | 
					
						
							| 
									
										
										
										
											2012-05-17 18:55:59 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-22 09:05:39 -07:00
										 |  |  | class _ModuleLockManager: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def __init__(self, name): | 
					
						
							|  |  |  |         self._name = name | 
					
						
							|  |  |  |         self._lock = None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def __enter__(self): | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             self._lock = _get_module_lock(self._name) | 
					
						
							|  |  |  |         finally: | 
					
						
							|  |  |  |             _imp.release_lock() | 
					
						
							|  |  |  |         self._lock.acquire() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def __exit__(self, *args, **kwargs): | 
					
						
							|  |  |  |         self._lock.release() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-17 18:55:59 +02:00
										 |  |  | # The following two functions are for consumption by Python/import.c. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def _get_module_lock(name): | 
					
						
							|  |  |  |     """Get or create the module lock for a given module name.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Should only be called with the import lock taken."""
 | 
					
						
							|  |  |  |     lock = None | 
					
						
							| 
									
										
										
										
											2012-08-28 00:24:52 +02:00
										 |  |  |     try: | 
					
						
							| 
									
										
										
										
											2012-05-17 18:55:59 +02:00
										 |  |  |         lock = _module_locks[name]() | 
					
						
							| 
									
										
										
										
											2012-08-28 00:24:52 +02:00
										 |  |  |     except KeyError: | 
					
						
							|  |  |  |         pass | 
					
						
							| 
									
										
										
										
											2012-05-17 18:55:59 +02:00
										 |  |  |     if lock is None: | 
					
						
							|  |  |  |         if _thread is None: | 
					
						
							|  |  |  |             lock = _DummyModuleLock(name) | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             lock = _ModuleLock(name) | 
					
						
							|  |  |  |         def cb(_): | 
					
						
							|  |  |  |             del _module_locks[name] | 
					
						
							|  |  |  |         _module_locks[name] = _weakref.ref(lock, cb) | 
					
						
							|  |  |  |     return lock | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def _lock_unlock_module(name): | 
					
						
							|  |  |  |     """Release the global import lock, and acquires then release the
 | 
					
						
							|  |  |  |     module lock for a given module name. | 
					
						
							|  |  |  |     This is used to ensure a module is completely initialized, in the | 
					
						
							|  |  |  |     event it is being imported by another thread. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Should only be called with the import lock taken."""
 | 
					
						
							|  |  |  |     lock = _get_module_lock(name) | 
					
						
							|  |  |  |     _imp.release_lock() | 
					
						
							|  |  |  |     try: | 
					
						
							|  |  |  |         lock.acquire() | 
					
						
							|  |  |  |     except _DeadlockError: | 
					
						
							|  |  |  |         # Concurrent circular import, we'll accept a partially initialized | 
					
						
							|  |  |  |         # module object. | 
					
						
							|  |  |  |         pass | 
					
						
							|  |  |  |     else: | 
					
						
							|  |  |  |         lock.release() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-07-31 21:14:18 +10:00
										 |  |  | # Frame stripping magic ############################################### | 
					
						
							| 
									
										
										
										
											2012-05-17 18:55:59 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-07-31 21:14:18 +10:00
										 |  |  | def _call_with_frames_removed(f, *args, **kwds): | 
					
						
							|  |  |  |     """remove_importlib_frames in import.c will always remove sequences
 | 
					
						
							|  |  |  |     of importlib frames that end with a call to this function | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Use it instead of a normal call in places where including the importlib | 
					
						
							|  |  |  |     frames introduces unwanted noise into the traceback (e.g. when executing | 
					
						
							|  |  |  |     module code) | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     return f(*args, **kwds) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # Finder/loader utility code ############################################### | 
					
						
							| 
									
										
										
										
											2009-03-12 22:28:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-26 01:11:54 +01:00
										 |  |  | # Magic word to reject .pyc files generated by other Python versions. | 
					
						
							|  |  |  | # It should change for each incompatible change to the bytecode. | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # The value of CR and LF is incorporated so if you ever read or write | 
					
						
							|  |  |  | # a .pyc file in text mode the magic number will be wrong; also, the | 
					
						
							|  |  |  | # Apple MPW compiler swaps their values, botching string constants. | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # The magic numbers must be spaced apart at least 2 values, as the | 
					
						
							|  |  |  | # -U interpeter flag will cause MAGIC+1 being used. They have been | 
					
						
							|  |  |  | # odd numbers for some time now. | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # There were a variety of old schemes for setting the magic number. | 
					
						
							|  |  |  | # The current working scheme is to increment the previous value by | 
					
						
							|  |  |  | # 10. | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # Starting with the adoption of PEP 3147 in Python 3.2, every bump in magic | 
					
						
							|  |  |  | # number also includes a new "magic tag", i.e. a human readable string used | 
					
						
							|  |  |  | # to represent the magic number in __pycache__ directories.  When you change | 
					
						
							|  |  |  | # the magic number, you must also set a new unique magic tag.  Generally this | 
					
						
							|  |  |  | # can be named after the Python major version of the magic number bump, but | 
					
						
							|  |  |  | # it can really be anything, as long as it's different than anything else | 
					
						
							|  |  |  | # that's come before.  The tags are included in the following table, starting | 
					
						
							|  |  |  | # with Python 3.2a0. | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # Known values: | 
					
						
							|  |  |  | #  Python 1.5:   20121 | 
					
						
							|  |  |  | #  Python 1.5.1: 20121 | 
					
						
							|  |  |  | #     Python 1.5.2: 20121 | 
					
						
							|  |  |  | #     Python 1.6:   50428 | 
					
						
							|  |  |  | #     Python 2.0:   50823 | 
					
						
							|  |  |  | #     Python 2.0.1: 50823 | 
					
						
							|  |  |  | #     Python 2.1:   60202 | 
					
						
							|  |  |  | #     Python 2.1.1: 60202 | 
					
						
							|  |  |  | #     Python 2.1.2: 60202 | 
					
						
							|  |  |  | #     Python 2.2:   60717 | 
					
						
							|  |  |  | #     Python 2.3a0: 62011 | 
					
						
							|  |  |  | #     Python 2.3a0: 62021 | 
					
						
							|  |  |  | #     Python 2.3a0: 62011 (!) | 
					
						
							|  |  |  | #     Python 2.4a0: 62041 | 
					
						
							|  |  |  | #     Python 2.4a3: 62051 | 
					
						
							|  |  |  | #     Python 2.4b1: 62061 | 
					
						
							|  |  |  | #     Python 2.5a0: 62071 | 
					
						
							|  |  |  | #     Python 2.5a0: 62081 (ast-branch) | 
					
						
							|  |  |  | #     Python 2.5a0: 62091 (with) | 
					
						
							|  |  |  | #     Python 2.5a0: 62092 (changed WITH_CLEANUP opcode) | 
					
						
							|  |  |  | #     Python 2.5b3: 62101 (fix wrong code: for x, in ...) | 
					
						
							|  |  |  | #     Python 2.5b3: 62111 (fix wrong code: x += yield) | 
					
						
							|  |  |  | #     Python 2.5c1: 62121 (fix wrong lnotab with for loops and | 
					
						
							|  |  |  | #                          storing constants that should have been removed) | 
					
						
							|  |  |  | #     Python 2.5c2: 62131 (fix wrong code: for x, in ... in listcomp/genexp) | 
					
						
							|  |  |  | #     Python 2.6a0: 62151 (peephole optimizations and STORE_MAP opcode) | 
					
						
							|  |  |  | #     Python 2.6a1: 62161 (WITH_CLEANUP optimization) | 
					
						
							|  |  |  | #     Python 2.7a0: 62171 (optimize list comprehensions/change LIST_APPEND) | 
					
						
							|  |  |  | #     Python 2.7a0: 62181 (optimize conditional branches: | 
					
						
							|  |  |  | #                          introduce POP_JUMP_IF_FALSE and POP_JUMP_IF_TRUE) | 
					
						
							|  |  |  | #     Python 2.7a0  62191 (introduce SETUP_WITH) | 
					
						
							|  |  |  | #     Python 2.7a0  62201 (introduce BUILD_SET) | 
					
						
							|  |  |  | #     Python 2.7a0  62211 (introduce MAP_ADD and SET_ADD) | 
					
						
							|  |  |  | #     Python 3000:   3000 | 
					
						
							|  |  |  | #                    3010 (removed UNARY_CONVERT) | 
					
						
							|  |  |  | #                    3020 (added BUILD_SET) | 
					
						
							|  |  |  | #                    3030 (added keyword-only parameters) | 
					
						
							|  |  |  | #                    3040 (added signature annotations) | 
					
						
							|  |  |  | #                    3050 (print becomes a function) | 
					
						
							|  |  |  | #                    3060 (PEP 3115 metaclass syntax) | 
					
						
							|  |  |  | #                    3061 (string literals become unicode) | 
					
						
							|  |  |  | #                    3071 (PEP 3109 raise changes) | 
					
						
							|  |  |  | #                    3081 (PEP 3137 make __file__ and __name__ unicode) | 
					
						
							|  |  |  | #                    3091 (kill str8 interning) | 
					
						
							|  |  |  | #                    3101 (merge from 2.6a0, see 62151) | 
					
						
							|  |  |  | #                    3103 (__file__ points to source file) | 
					
						
							|  |  |  | #     Python 3.0a4: 3111 (WITH_CLEANUP optimization). | 
					
						
							|  |  |  | #     Python 3.0a5: 3131 (lexical exception stacking, including POP_EXCEPT) | 
					
						
							|  |  |  | #     Python 3.1a0: 3141 (optimize list, set and dict comprehensions: | 
					
						
							|  |  |  | #             change LIST_APPEND and SET_ADD, add MAP_ADD) | 
					
						
							|  |  |  | #     Python 3.1a0: 3151 (optimize conditional branches: | 
					
						
							|  |  |  | #             introduce POP_JUMP_IF_FALSE and POP_JUMP_IF_TRUE) | 
					
						
							|  |  |  | #     Python 3.2a0: 3160 (add SETUP_WITH) | 
					
						
							|  |  |  | #                   tag: cpython-32 | 
					
						
							|  |  |  | #     Python 3.2a1: 3170 (add DUP_TOP_TWO, remove DUP_TOPX and ROT_FOUR) | 
					
						
							|  |  |  | #                   tag: cpython-32 | 
					
						
							|  |  |  | #     Python 3.2a2  3180 (add DELETE_DEREF) | 
					
						
							|  |  |  | #     Python 3.3a0  3190 __class__ super closure changed | 
					
						
							|  |  |  | #     Python 3.3a0  3200 (__qualname__ added) | 
					
						
							|  |  |  | #                      3210 (added size modulo 2**32 to the pyc header) | 
					
						
							|  |  |  | #     Python 3.3a1  3220 (changed PEP 380 implementation) | 
					
						
							|  |  |  | #     Python 3.3a4  3230 (revert changes to implicit __class__ closure) | 
					
						
							|  |  |  | #     Python 3.4a1  3250 (evaluate positional default arguments before | 
					
						
							|  |  |  | #                        keyword-only defaults) | 
					
						
							| 
									
										
										
										
											2013-04-30 09:41:40 -04:00
										 |  |  | #     Python 3.4a1  3260 (add LOAD_CLASSDEREF; allow locals of class to override | 
					
						
							|  |  |  | #                        free vars) | 
					
						
							| 
									
										
										
										
											2013-06-11 17:22:39 -04:00
										 |  |  | #     Python 3.4a1  3270 (various tweaks to the __class__ closure) | 
					
						
							| 
									
										
										
										
											2013-05-16 14:37:25 -05:00
										 |  |  | #     Python 3.4a1  3280 (remove implicit class argument) | 
					
						
							| 
									
										
										
										
											2013-10-19 16:01:13 -04:00
										 |  |  | #     Python 3.4a4  3290 (changes to __qualname__ computation) | 
					
						
							| 
									
										
										
										
											2013-10-20 17:50:28 -04:00
										 |  |  | #     Python 3.4a4  3300 (more changes to __qualname__ computation) | 
					
						
							| 
									
										
										
										
											2014-02-19 18:05:36 -05:00
										 |  |  | #     Python 3.4rc2 3310 (alter __qualname__ computation) | 
					
						
							| 
									
										
										
										
											2014-04-09 23:55:56 -04:00
										 |  |  | #     Python 3.5a0  3320 (matrix multiplication operator) | 
					
						
							| 
									
										
										
										
											2013-03-26 01:11:54 +01:00
										 |  |  | # | 
					
						
							|  |  |  | # MAGIC must change whenever the bytecode emitted by the compiler may no | 
					
						
							|  |  |  | # longer be understood by older implementations of the eval loop (usually | 
					
						
							|  |  |  | # due to the addition of new opcodes). | 
					
						
							| 
									
										
										
										
											2012-07-09 16:09:00 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-09 23:55:56 -04:00
										 |  |  | MAGIC_NUMBER = (3320).to_bytes(2, 'little') + b'\r\n' | 
					
						
							| 
									
										
										
										
											2013-06-14 19:02:34 -04:00
										 |  |  | _RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little')  # For import.c | 
					
						
							| 
									
										
										
										
											2012-07-09 16:09:00 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-04 13:52:49 -04:00
										 |  |  | _PYCACHE = '__pycache__' | 
					
						
							| 
									
										
										
										
											2012-04-20 21:44:46 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-11 12:58:42 -04:00
										 |  |  | SOURCE_SUFFIXES = ['.py']  # _setup() adds .pyw as needed. | 
					
						
							| 
									
										
										
										
											2012-04-21 18:52:52 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-11 12:58:42 -04:00
										 |  |  | DEBUG_BYTECODE_SUFFIXES = ['.pyc'] | 
					
						
							|  |  |  | OPTIMIZED_BYTECODE_SUFFIXES = ['.pyo'] | 
					
						
							| 
									
										
										
										
											2012-04-20 21:44:46 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-04 13:52:49 -04:00
										 |  |  | def cache_from_source(path, debug_override=None): | 
					
						
							| 
									
										
										
										
											2012-04-20 21:44:46 -04:00
										 |  |  |     """Given the path to a .py file, return the path to its .pyc/.pyo file.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     The .py file does not need to exist; this simply returns the path to the | 
					
						
							|  |  |  |     .pyc/.pyo file calculated as if the .py file were imported.  The extension | 
					
						
							| 
									
										
										
										
											2012-09-25 11:22:59 -04:00
										 |  |  |     will be .pyc unless sys.flags.optimize is non-zero, then it will be .pyo. | 
					
						
							| 
									
										
										
										
											2012-04-20 21:44:46 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-26 00:25:10 -04:00
										 |  |  |     If debug_override is not None, then it must be a boolean and is used in | 
					
						
							|  |  |  |     place of sys.flags.optimize. | 
					
						
							| 
									
										
										
										
											2012-04-20 21:44:46 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-07-09 13:58:07 -04:00
										 |  |  |     If sys.implementation.cache_tag is None then NotImplementedError is raised. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-20 21:44:46 -04:00
										 |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2012-09-25 11:22:59 -04:00
										 |  |  |     debug = not sys.flags.optimize if debug_override is None else debug_override | 
					
						
							| 
									
										
										
										
											2012-05-11 12:58:42 -04:00
										 |  |  |     if debug: | 
					
						
							|  |  |  |         suffixes = DEBUG_BYTECODE_SUFFIXES | 
					
						
							|  |  |  |     else: | 
					
						
							|  |  |  |         suffixes = OPTIMIZED_BYTECODE_SUFFIXES | 
					
						
							| 
									
										
										
										
											2012-04-20 21:44:46 -04:00
										 |  |  |     head, tail = _path_split(path) | 
					
						
							| 
									
										
										
										
											2014-12-01 17:10:10 -05:00
										 |  |  |     base, sep, rest = tail.rpartition('.') | 
					
						
							| 
									
										
										
										
											2012-07-09 13:58:07 -04:00
										 |  |  |     tag = sys.implementation.cache_tag | 
					
						
							|  |  |  |     if tag is None: | 
					
						
							|  |  |  |         raise NotImplementedError('sys.implementation.cache_tag is None') | 
					
						
							| 
									
										
										
										
											2014-12-01 17:10:10 -05:00
										 |  |  |     filename = ''.join([(base if base else rest), sep, tag, suffixes[0]]) | 
					
						
							| 
									
										
										
										
											2012-05-04 13:52:49 -04:00
										 |  |  |     return _path_join(head, _PYCACHE, filename) | 
					
						
							| 
									
										
										
										
											2012-04-20 21:44:46 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-07-13 13:57:03 -04:00
										 |  |  | def source_from_cache(path): | 
					
						
							|  |  |  |     """Given the path to a .pyc./.pyo file, return the path to its .py file.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     The .pyc/.pyo file does not need to exist; this simply returns the path to | 
					
						
							|  |  |  |     the .py file calculated to correspond to the .pyc/.pyo file.  If path does | 
					
						
							|  |  |  |     not conform to PEP 3147 format, ValueError will be raised. If | 
					
						
							|  |  |  |     sys.implementation.cache_tag is None then NotImplementedError is raised. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     if sys.implementation.cache_tag is None: | 
					
						
							|  |  |  |         raise NotImplementedError('sys.implementation.cache_tag is None') | 
					
						
							|  |  |  |     head, pycache_filename = _path_split(path) | 
					
						
							|  |  |  |     head, pycache = _path_split(head) | 
					
						
							|  |  |  |     if pycache != _PYCACHE: | 
					
						
							|  |  |  |         raise ValueError('{} not bottom-level directory in ' | 
					
						
							|  |  |  |                          '{!r}'.format(_PYCACHE, path)) | 
					
						
							|  |  |  |     if pycache_filename.count('.') != 2: | 
					
						
							|  |  |  |         raise ValueError('expected only 2 dots in ' | 
					
						
							|  |  |  |                          '{!r}'.format(pycache_filename)) | 
					
						
							|  |  |  |     base_filename = pycache_filename.partition('.')[0] | 
					
						
							|  |  |  |     return _path_join(head, base_filename + SOURCE_SUFFIXES[0]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def _get_sourcefile(bytecode_path): | 
					
						
							|  |  |  |     """Convert a bytecode file path to a source path (if possible).
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     This function exists purely for backwards-compatibility for | 
					
						
							|  |  |  |     PyImport_ExecCodeModuleWithFilenames() in the C API. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     if len(bytecode_path) == 0: | 
					
						
							|  |  |  |         return None | 
					
						
							| 
									
										
										
										
											2013-07-06 17:56:43 -04:00
										 |  |  |     rest, _, extension = bytecode_path.rpartition('.') | 
					
						
							|  |  |  |     if not rest or extension.lower()[-3:-1] != 'py': | 
					
						
							| 
									
										
										
										
											2012-07-13 13:57:03 -04:00
										 |  |  |         return bytecode_path | 
					
						
							|  |  |  |     try: | 
					
						
							|  |  |  |         source_path = source_from_cache(bytecode_path) | 
					
						
							|  |  |  |     except (NotImplementedError, ValueError): | 
					
						
							| 
									
										
										
										
											2013-07-06 17:56:43 -04:00
										 |  |  |         source_path = bytecode_path[:-1] | 
					
						
							|  |  |  |     return source_path if _path_isfile(source_path) else bytecode_path | 
					
						
							| 
									
										
										
										
											2012-07-13 13:57:03 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-14 12:48:15 -04:00
										 |  |  | def _calc_mode(path): | 
					
						
							|  |  |  |     """Calculate the mode permissions for a bytecode file.""" | 
					
						
							|  |  |  |     try: | 
					
						
							| 
									
										
										
										
											2013-11-01 14:04:24 -04:00
										 |  |  |         mode = _path_stat(path).st_mode | 
					
						
							| 
									
										
										
										
											2013-04-14 12:48:15 -04:00
										 |  |  |     except OSError: | 
					
						
							|  |  |  |         mode = 0o666 | 
					
						
							|  |  |  |     # We always ensure write access so we can update cached files | 
					
						
							|  |  |  |     # later even when the source files are read-only on Windows (#6074) | 
					
						
							|  |  |  |     mode |= 0o200 | 
					
						
							|  |  |  |     return mode | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-01 13:10:51 -04:00
										 |  |  | def _verbose_message(message, *args, verbosity=1): | 
					
						
							| 
									
										
										
										
											2012-04-14 14:10:13 -04:00
										 |  |  |     """Print the message to stderr if -v/PYTHONVERBOSE is turned on.""" | 
					
						
							| 
									
										
										
										
											2013-04-01 13:10:51 -04:00
										 |  |  |     if sys.flags.verbose >= verbosity: | 
					
						
							| 
									
										
										
										
											2012-04-15 12:21:32 -07:00
										 |  |  |         if not message.startswith(('#', 'import ')): | 
					
						
							| 
									
										
										
										
											2012-04-14 14:10:13 -04:00
										 |  |  |             message = '# ' + message | 
					
						
							|  |  |  |         print(message.format(*args), file=sys.stderr) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-20 01:48:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-12 22:28:55 +00:00
										 |  |  | def _check_name(method): | 
					
						
							|  |  |  |     """Decorator to verify that the module being requested matches the one the
 | 
					
						
							|  |  |  |     loader can handle. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     The first argument (self) must define _name which the second argument is | 
					
						
							| 
									
										
										
										
											2011-03-15 05:18:48 +02:00
										 |  |  |     compared against. If the comparison fails then ImportError is raised. | 
					
						
							| 
									
										
										
										
											2009-03-12 22:28:55 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2012-05-11 14:48:41 -04:00
										 |  |  |     def _check_name_wrapper(self, name=None, *args, **kwargs): | 
					
						
							|  |  |  |         if name is None: | 
					
						
							|  |  |  |             name = self.name | 
					
						
							|  |  |  |         elif self.name != name: | 
					
						
							| 
									
										
										
										
											2013-07-12 11:04:23 -04:00
										 |  |  |             raise ImportError('loader cannot handle %s' % name, name=name) | 
					
						
							| 
									
										
										
										
											2009-03-12 22:28:55 +00:00
										 |  |  |         return method(self, name, *args, **kwargs) | 
					
						
							| 
									
										
										
										
											2012-01-16 11:46:22 -05:00
										 |  |  |     _wrap(_check_name_wrapper, method) | 
					
						
							|  |  |  |     return _check_name_wrapper | 
					
						
							| 
									
										
										
										
											2009-03-12 22:28:55 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-15 01:41:33 +00:00
										 |  |  | def _requires_builtin(fxn): | 
					
						
							|  |  |  |     """Decorator to verify the named module is built-in.""" | 
					
						
							| 
									
										
										
										
											2012-01-16 11:46:22 -05:00
										 |  |  |     def _requires_builtin_wrapper(self, fullname): | 
					
						
							| 
									
										
										
										
											2009-03-15 01:41:33 +00:00
										 |  |  |         if fullname not in sys.builtin_module_names: | 
					
						
							| 
									
										
										
										
											2013-11-22 14:52:36 -05:00
										 |  |  |             raise ImportError('{!r} is not a built-in module'.format(fullname), | 
					
						
							| 
									
										
										
										
											2012-04-12 21:09:01 -04:00
										 |  |  |                               name=fullname) | 
					
						
							| 
									
										
										
										
											2009-03-15 01:41:33 +00:00
										 |  |  |         return fxn(self, fullname) | 
					
						
							| 
									
										
										
										
											2012-01-16 11:46:22 -05:00
										 |  |  |     _wrap(_requires_builtin_wrapper, fxn) | 
					
						
							|  |  |  |     return _requires_builtin_wrapper | 
					
						
							| 
									
										
										
										
											2009-03-15 01:41:33 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-15 02:20:16 +00:00
										 |  |  | def _requires_frozen(fxn): | 
					
						
							|  |  |  |     """Decorator to verify the named module is frozen.""" | 
					
						
							| 
									
										
										
										
											2012-01-16 11:46:22 -05:00
										 |  |  |     def _requires_frozen_wrapper(self, fullname): | 
					
						
							| 
									
										
										
										
											2012-04-15 16:08:47 -04:00
										 |  |  |         if not _imp.is_frozen(fullname): | 
					
						
							| 
									
										
										
										
											2013-11-22 14:52:36 -05:00
										 |  |  |             raise ImportError('{!r} is not a frozen module'.format(fullname), | 
					
						
							| 
									
										
										
										
											2012-04-12 21:09:01 -04:00
										 |  |  |                               name=fullname) | 
					
						
							| 
									
										
										
										
											2009-03-15 02:20:16 +00:00
										 |  |  |         return fxn(self, fullname) | 
					
						
							| 
									
										
										
										
											2012-01-16 11:46:22 -05:00
										 |  |  |     _wrap(_requires_frozen_wrapper, fxn) | 
					
						
							|  |  |  |     return _requires_frozen_wrapper | 
					
						
							| 
									
										
										
										
											2009-03-15 02:20:16 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-08-10 17:41:23 -04:00
										 |  |  | def _find_module_shim(self, fullname): | 
					
						
							|  |  |  |     """Try to find a loader for the specified module by delegating to
 | 
					
						
							| 
									
										
										
										
											2014-01-06 20:49:04 -07:00
										 |  |  |     self.find_loader(). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     This method is deprecated in favor of finder.find_spec(). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2012-08-10 17:41:23 -04:00
										 |  |  |     # Call find_loader(). If it returns a string (indicating this | 
					
						
							|  |  |  |     # is a namespace package portion), generate a warning and | 
					
						
							|  |  |  |     # return None. | 
					
						
							|  |  |  |     loader, portions = self.find_loader(fullname) | 
					
						
							|  |  |  |     if loader is None and len(portions): | 
					
						
							| 
									
										
										
										
											2013-07-12 11:04:23 -04:00
										 |  |  |         msg = 'Not importing directory {}: missing __init__' | 
					
						
							| 
									
										
										
										
											2012-08-10 17:41:23 -04:00
										 |  |  |         _warnings.warn(msg.format(portions[0]), ImportWarning) | 
					
						
							|  |  |  |     return loader | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-30 16:28:00 -04:00
										 |  |  | # Typically used by loader classes as a method replacement. | 
					
						
							|  |  |  | def _load_module_shim(self, fullname): | 
					
						
							| 
									
										
										
										
											2014-01-06 20:49:04 -07:00
										 |  |  |     """Load the specified module into sys.modules and return it.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     This method is deprecated.  Use loader.exec_module instead. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2014-05-30 16:28:00 -04:00
										 |  |  |     spec = spec_from_loader(fullname, self) | 
					
						
							| 
									
										
										
										
											2013-11-22 09:05:39 -07:00
										 |  |  |     if fullname in sys.modules: | 
					
						
							|  |  |  |         module = sys.modules[fullname] | 
					
						
							| 
									
										
										
										
											2014-05-30 14:55:29 -04:00
										 |  |  |         _exec(spec, module) | 
					
						
							| 
									
										
										
										
											2013-11-22 09:05:39 -07:00
										 |  |  |         return sys.modules[fullname] | 
					
						
							|  |  |  |     else: | 
					
						
							| 
									
										
										
										
											2014-05-30 14:55:29 -04:00
										 |  |  |         return _load(spec) | 
					
						
							| 
									
										
										
										
											2013-11-22 09:05:39 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-11 18:09:25 -05:00
										 |  |  | def _validate_bytecode_header(data, source_stats=None, name=None, path=None): | 
					
						
							|  |  |  |     """Validate the header of the passed-in bytecode against source_stats (if
 | 
					
						
							|  |  |  |     given) and returning the bytecode that can be compiled by compile(). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     All other arguments are used to enhance error reporting. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ImportError is raised when the magic number is incorrect or the bytecode is | 
					
						
							|  |  |  |     found to be stale. EOFError is raised when the data is found to be | 
					
						
							|  |  |  |     truncated. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     exc_details = {} | 
					
						
							|  |  |  |     if name is not None: | 
					
						
							|  |  |  |         exc_details['name'] = name | 
					
						
							|  |  |  |     else: | 
					
						
							|  |  |  |         # To prevent having to make all messages have a conditional name. | 
					
						
							| 
									
										
										
										
											2013-01-25 13:49:19 -05:00
										 |  |  |         name = '<bytecode>' | 
					
						
							| 
									
										
										
										
											2013-01-11 18:09:25 -05:00
										 |  |  |     if path is not None: | 
					
						
							|  |  |  |         exc_details['path'] = path | 
					
						
							|  |  |  |     magic = data[:4] | 
					
						
							|  |  |  |     raw_timestamp = data[4:8] | 
					
						
							|  |  |  |     raw_size = data[8:12] | 
					
						
							| 
									
										
										
										
											2013-06-14 19:02:34 -04:00
										 |  |  |     if magic != MAGIC_NUMBER: | 
					
						
							| 
									
										
										
										
											2013-04-01 13:25:40 -04:00
										 |  |  |         message = 'bad magic number in {!r}: {!r}'.format(name, magic) | 
					
						
							|  |  |  |         _verbose_message(message) | 
					
						
							|  |  |  |         raise ImportError(message, **exc_details) | 
					
						
							| 
									
										
										
										
											2013-01-11 18:09:25 -05:00
										 |  |  |     elif len(raw_timestamp) != 4: | 
					
						
							| 
									
										
										
										
											2013-06-05 18:37:50 -04:00
										 |  |  |         message = 'reached EOF while reading timestamp in {!r}'.format(name) | 
					
						
							| 
									
										
										
										
											2013-01-11 18:09:25 -05:00
										 |  |  |         _verbose_message(message) | 
					
						
							|  |  |  |         raise EOFError(message) | 
					
						
							|  |  |  |     elif len(raw_size) != 4: | 
					
						
							| 
									
										
										
										
											2013-06-05 18:37:50 -04:00
										 |  |  |         message = 'reached EOF while reading size of source in {!r}'.format(name) | 
					
						
							| 
									
										
										
										
											2013-01-11 18:09:25 -05:00
										 |  |  |         _verbose_message(message) | 
					
						
							|  |  |  |         raise EOFError(message) | 
					
						
							|  |  |  |     if source_stats is not None: | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             source_mtime = int(source_stats['mtime']) | 
					
						
							|  |  |  |         except KeyError: | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             if _r_long(raw_timestamp) != source_mtime: | 
					
						
							|  |  |  |                 message = 'bytecode is stale for {!r}'.format(name) | 
					
						
							|  |  |  |                 _verbose_message(message) | 
					
						
							|  |  |  |                 raise ImportError(message, **exc_details) | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             source_size = source_stats['size'] & 0xFFFFFFFF | 
					
						
							|  |  |  |         except KeyError: | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             if _r_long(raw_size) != source_size: | 
					
						
							| 
									
										
										
										
											2013-07-12 11:04:23 -04:00
										 |  |  |                 raise ImportError('bytecode is stale for {!r}'.format(name), | 
					
						
							| 
									
										
										
										
											2013-01-11 18:09:25 -05:00
										 |  |  |                                   **exc_details) | 
					
						
							|  |  |  |     return data[12:] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def _compile_bytecode(data, name=None, bytecode_path=None, source_path=None): | 
					
						
							|  |  |  |     """Compile bytecode as returned by _validate_bytecode_header().""" | 
					
						
							|  |  |  |     code = marshal.loads(data) | 
					
						
							|  |  |  |     if isinstance(code, _code_type): | 
					
						
							|  |  |  |         _verbose_message('code object from {!r}', bytecode_path) | 
					
						
							|  |  |  |         if source_path is not None: | 
					
						
							|  |  |  |             _imp._fix_co_filename(code, source_path) | 
					
						
							|  |  |  |         return code | 
					
						
							|  |  |  |     else: | 
					
						
							| 
									
										
										
										
											2013-07-12 11:04:23 -04:00
										 |  |  |         raise ImportError('Non-code object in {!r}'.format(bytecode_path), | 
					
						
							| 
									
										
										
										
											2013-01-11 18:09:25 -05:00
										 |  |  |                           name=name, path=bytecode_path) | 
					
						
							| 
									
										
										
										
											2012-08-10 17:41:23 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-26 08:48:36 -05:00
										 |  |  | def _code_to_bytecode(code, mtime=0, source_size=0): | 
					
						
							|  |  |  |     """Compile a code object into bytecode for writing out to a byte-compiled
 | 
					
						
							|  |  |  |     file."""
 | 
					
						
							| 
									
										
										
										
											2013-06-14 19:02:34 -04:00
										 |  |  |     data = bytearray(MAGIC_NUMBER) | 
					
						
							| 
									
										
										
										
											2013-01-26 08:48:36 -05:00
										 |  |  |     data.extend(_w_long(mtime)) | 
					
						
							|  |  |  |     data.extend(_w_long(source_size)) | 
					
						
							|  |  |  |     data.extend(marshal.dumps(code)) | 
					
						
							|  |  |  |     return data | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-08-10 17:41:23 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-16 18:37:53 -04:00
										 |  |  | def decode_source(source_bytes): | 
					
						
							|  |  |  |     """Decode bytes representing source code and return the string.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Universal newline support is used in the decoding. | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     import tokenize  # To avoid bootstrap issues. | 
					
						
							|  |  |  |     source_bytes_readline = _io.BytesIO(source_bytes).readline | 
					
						
							|  |  |  |     encoding = tokenize.detect_encoding(source_bytes_readline) | 
					
						
							|  |  |  |     newline_decoder = _io.IncrementalNewlineDecoder(None, True) | 
					
						
							|  |  |  |     return newline_decoder.decode(source_bytes.decode(encoding[0])) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-22 09:05:39 -07:00
										 |  |  | # Module specifications ####################################################### | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def _module_repr(module): | 
					
						
							|  |  |  |     # The implementation of ModuleType__repr__(). | 
					
						
							|  |  |  |     loader = getattr(module, '__loader__', None) | 
					
						
							|  |  |  |     if hasattr(loader, 'module_repr'): | 
					
						
							| 
									
										
										
										
											2014-01-06 20:49:04 -07:00
										 |  |  |         # As soon as BuiltinImporter, FrozenImporter, and NamespaceLoader | 
					
						
							|  |  |  |         # drop their implementations for module_repr. we can add a | 
					
						
							|  |  |  |         # deprecation warning here. | 
					
						
							| 
									
										
										
										
											2013-11-22 09:05:39 -07:00
										 |  |  |         try: | 
					
						
							|  |  |  |             return loader.module_repr(module) | 
					
						
							|  |  |  |         except Exception: | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  |     try: | 
					
						
							|  |  |  |         spec = module.__spec__ | 
					
						
							|  |  |  |     except AttributeError: | 
					
						
							|  |  |  |         pass | 
					
						
							|  |  |  |     else: | 
					
						
							|  |  |  |         if spec is not None: | 
					
						
							| 
									
										
										
										
											2014-05-30 14:55:29 -04:00
										 |  |  |             return _module_repr_from_spec(spec) | 
					
						
							| 
									
										
										
										
											2013-11-22 09:05:39 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # We could use module.__class__.__name__ instead of 'module' in the | 
					
						
							|  |  |  |     # various repr permutations. | 
					
						
							|  |  |  |     try: | 
					
						
							|  |  |  |         name = module.__name__ | 
					
						
							|  |  |  |     except AttributeError: | 
					
						
							|  |  |  |         name = '?' | 
					
						
							|  |  |  |     try: | 
					
						
							|  |  |  |         filename = module.__file__ | 
					
						
							|  |  |  |     except AttributeError: | 
					
						
							|  |  |  |         if loader is None: | 
					
						
							|  |  |  |             return '<module {!r}>'.format(name) | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             return '<module {!r} ({!r})>'.format(name, loader) | 
					
						
							|  |  |  |     else: | 
					
						
							|  |  |  |         return '<module {!r} from {!r}>'.format(name, filename) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class _installed_safely: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def __init__(self, module): | 
					
						
							|  |  |  |         self._module = module | 
					
						
							|  |  |  |         self._spec = module.__spec__ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def __enter__(self): | 
					
						
							|  |  |  |         # This must be done before putting the module in sys.modules | 
					
						
							|  |  |  |         # (otherwise an optimization shortcut in import.c becomes | 
					
						
							|  |  |  |         # wrong) | 
					
						
							|  |  |  |         self._spec._initializing = True | 
					
						
							|  |  |  |         sys.modules[self._spec.name] = self._module | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def __exit__(self, *args): | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             spec = self._spec | 
					
						
							|  |  |  |             if any(arg is not None for arg in args): | 
					
						
							|  |  |  |                 try: | 
					
						
							|  |  |  |                     del sys.modules[spec.name] | 
					
						
							|  |  |  |                 except KeyError: | 
					
						
							|  |  |  |                     pass | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 _verbose_message('import {!r} # {!r}', spec.name, spec.loader) | 
					
						
							|  |  |  |         finally: | 
					
						
							|  |  |  |             self._spec._initializing = False | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class ModuleSpec: | 
					
						
							|  |  |  |     """The specification for a module, used for loading.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     A module's spec is the source for information about the module.  For | 
					
						
							|  |  |  |     data associated with the module, including source, use the spec's | 
					
						
							|  |  |  |     loader. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     `name` is the absolute name of the module.  `loader` is the loader | 
					
						
							|  |  |  |     to use when loading the module.  `parent` is the name of the | 
					
						
							|  |  |  |     package the module is in.  The parent is derived from the name. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     `is_package` determines if the module is considered a package or | 
					
						
							|  |  |  |     not.  On modules this is reflected by the `__path__` attribute. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     `origin` is the specific location used by the loader from which to | 
					
						
							|  |  |  |     load the module, if that information is available.  When filename is | 
					
						
							|  |  |  |     set, origin will match. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     `has_location` indicates that a spec's "origin" reflects a location. | 
					
						
							|  |  |  |     When this is True, `__file__` attribute of the module is set. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     `cached` is the location of the cached bytecode file, if any.  It | 
					
						
							|  |  |  |     corresponds to the `__cached__` attribute. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     `submodule_search_locations` is the sequence of path entries to | 
					
						
							|  |  |  |     search when importing submodules.  If set, is_package should be | 
					
						
							|  |  |  |     True--and False otherwise. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Packages are simply modules that (may) have submodules.  If a spec | 
					
						
							|  |  |  |     has a non-None value in `submodule_search_locations`, the import | 
					
						
							|  |  |  |     system will consider modules loaded from the spec as packages. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Only finders (see importlib.abc.MetaPathFinder and | 
					
						
							|  |  |  |     importlib.abc.PathEntryFinder) should modify ModuleSpec instances. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def __init__(self, name, loader, *, origin=None, loader_state=None, | 
					
						
							|  |  |  |                  is_package=None): | 
					
						
							|  |  |  |         self.name = name | 
					
						
							|  |  |  |         self.loader = loader | 
					
						
							|  |  |  |         self.origin = origin | 
					
						
							|  |  |  |         self.loader_state = loader_state | 
					
						
							|  |  |  |         self.submodule_search_locations = [] if is_package else None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # file-location attributes | 
					
						
							|  |  |  |         self._set_fileattr = False | 
					
						
							|  |  |  |         self._cached = None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def __repr__(self): | 
					
						
							|  |  |  |         args = ['name={!r}'.format(self.name), | 
					
						
							|  |  |  |                 'loader={!r}'.format(self.loader)] | 
					
						
							|  |  |  |         if self.origin is not None: | 
					
						
							|  |  |  |             args.append('origin={!r}'.format(self.origin)) | 
					
						
							|  |  |  |         if self.submodule_search_locations is not None: | 
					
						
							|  |  |  |             args.append('submodule_search_locations={}' | 
					
						
							|  |  |  |                         .format(self.submodule_search_locations)) | 
					
						
							|  |  |  |         return '{}({})'.format(self.__class__.__name__, ', '.join(args)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def __eq__(self, other): | 
					
						
							|  |  |  |         smsl = self.submodule_search_locations | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             return (self.name == other.name and | 
					
						
							|  |  |  |                     self.loader == other.loader and | 
					
						
							|  |  |  |                     self.origin == other.origin and | 
					
						
							|  |  |  |                     smsl == other.submodule_search_locations and | 
					
						
							|  |  |  |                     self.cached == other.cached and | 
					
						
							|  |  |  |                     self.has_location == other.has_location) | 
					
						
							|  |  |  |         except AttributeError: | 
					
						
							|  |  |  |             return False | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @property | 
					
						
							|  |  |  |     def cached(self): | 
					
						
							|  |  |  |         if self._cached is None: | 
					
						
							|  |  |  |             if self.origin is not None and self._set_fileattr: | 
					
						
							|  |  |  |                 filename = self.origin | 
					
						
							|  |  |  |                 if filename.endswith(tuple(SOURCE_SUFFIXES)): | 
					
						
							|  |  |  |                     try: | 
					
						
							|  |  |  |                         self._cached = cache_from_source(filename) | 
					
						
							|  |  |  |                     except NotImplementedError: | 
					
						
							|  |  |  |                         pass | 
					
						
							|  |  |  |                 elif filename.endswith(tuple(BYTECODE_SUFFIXES)): | 
					
						
							|  |  |  |                     self._cached = filename | 
					
						
							|  |  |  |         return self._cached | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @cached.setter | 
					
						
							|  |  |  |     def cached(self, cached): | 
					
						
							|  |  |  |         self._cached = cached | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @property | 
					
						
							|  |  |  |     def parent(self): | 
					
						
							|  |  |  |         """The name of the module's parent.""" | 
					
						
							|  |  |  |         if self.submodule_search_locations is None: | 
					
						
							|  |  |  |             return self.name.rpartition('.')[0] | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             return self.name | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @property | 
					
						
							|  |  |  |     def has_location(self): | 
					
						
							|  |  |  |         return self._set_fileattr | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-10 22:16:41 -07:00
										 |  |  |     @has_location.setter | 
					
						
							|  |  |  |     def has_location(self, value): | 
					
						
							|  |  |  |         self._set_fileattr = bool(value) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-22 09:05:39 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | def spec_from_loader(name, loader, *, origin=None, is_package=None): | 
					
						
							|  |  |  |     """Return a module spec based on various loader methods.""" | 
					
						
							|  |  |  |     if hasattr(loader, 'get_filename'): | 
					
						
							|  |  |  |         if is_package is None: | 
					
						
							|  |  |  |             return spec_from_file_location(name, loader=loader) | 
					
						
							|  |  |  |         search = [] if is_package else None | 
					
						
							|  |  |  |         return spec_from_file_location(name, loader=loader, | 
					
						
							|  |  |  |                                        submodule_search_locations=search) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if is_package is None: | 
					
						
							|  |  |  |         if hasattr(loader, 'is_package'): | 
					
						
							|  |  |  |             try: | 
					
						
							|  |  |  |                 is_package = loader.is_package(name) | 
					
						
							|  |  |  |             except ImportError: | 
					
						
							|  |  |  |                 is_package = None  # aka, undefined | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             # the default | 
					
						
							|  |  |  |             is_package = False | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return ModuleSpec(name, loader, origin=origin, is_package=is_package) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | _POPULATE = object() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def spec_from_file_location(name, location=None, *, loader=None, | 
					
						
							|  |  |  |                             submodule_search_locations=_POPULATE): | 
					
						
							|  |  |  |     """Return a module spec based on a file location.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     To indicate that the module is a package, set | 
					
						
							|  |  |  |     submodule_search_locations to a list of directory paths.  An | 
					
						
							|  |  |  |     empty list is sufficient, though its not otherwise useful to the | 
					
						
							|  |  |  |     import system. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     The loader must take a spec as its only __init__() arg. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     if location is None: | 
					
						
							|  |  |  |         # The caller may simply want a partially populated location- | 
					
						
							|  |  |  |         # oriented spec.  So we set the location to a bogus value and | 
					
						
							|  |  |  |         # fill in as much as we can. | 
					
						
							|  |  |  |         location = '<unknown>' | 
					
						
							|  |  |  |         if hasattr(loader, 'get_filename'): | 
					
						
							|  |  |  |             # ExecutionLoader | 
					
						
							|  |  |  |             try: | 
					
						
							|  |  |  |                 location = loader.get_filename(name) | 
					
						
							|  |  |  |             except ImportError: | 
					
						
							|  |  |  |                 pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # If the location is on the filesystem, but doesn't actually exist, | 
					
						
							|  |  |  |     # we could return None here, indicating that the location is not | 
					
						
							|  |  |  |     # valid.  However, we don't have a good way of testing since an | 
					
						
							|  |  |  |     # indirect location (e.g. a zip file or URL) will look like a | 
					
						
							|  |  |  |     # non-existent file relative to the filesystem. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     spec = ModuleSpec(name, loader, origin=location) | 
					
						
							|  |  |  |     spec._set_fileattr = True | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Pick a loader if one wasn't provided. | 
					
						
							|  |  |  |     if loader is None: | 
					
						
							|  |  |  |         for loader_class, suffixes in _get_supported_file_loaders(): | 
					
						
							|  |  |  |             if location.endswith(tuple(suffixes)): | 
					
						
							|  |  |  |                 loader = loader_class(name, location) | 
					
						
							|  |  |  |                 spec.loader = loader | 
					
						
							|  |  |  |                 break | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             return None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Set submodule_search_paths appropriately. | 
					
						
							|  |  |  |     if submodule_search_locations is _POPULATE: | 
					
						
							|  |  |  |         # Check the loader. | 
					
						
							|  |  |  |         if hasattr(loader, 'is_package'): | 
					
						
							|  |  |  |             try: | 
					
						
							|  |  |  |                 is_package = loader.is_package(name) | 
					
						
							|  |  |  |             except ImportError: | 
					
						
							|  |  |  |                 pass | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 if is_package: | 
					
						
							|  |  |  |                     spec.submodule_search_locations = [] | 
					
						
							|  |  |  |     else: | 
					
						
							|  |  |  |         spec.submodule_search_locations = submodule_search_locations | 
					
						
							|  |  |  |     if spec.submodule_search_locations == []: | 
					
						
							|  |  |  |         if location: | 
					
						
							|  |  |  |             dirname = _path_split(location)[0] | 
					
						
							|  |  |  |             spec.submodule_search_locations.append(dirname) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return spec | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def _spec_from_module(module, loader=None, origin=None): | 
					
						
							|  |  |  |     # This function is meant for use in _setup(). | 
					
						
							|  |  |  |     try: | 
					
						
							|  |  |  |         spec = module.__spec__ | 
					
						
							|  |  |  |     except AttributeError: | 
					
						
							|  |  |  |         pass | 
					
						
							|  |  |  |     else: | 
					
						
							|  |  |  |         if spec is not None: | 
					
						
							|  |  |  |             return spec | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     name = module.__name__ | 
					
						
							|  |  |  |     if loader is None: | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             loader = module.__loader__ | 
					
						
							|  |  |  |         except AttributeError: | 
					
						
							|  |  |  |             # loader will stay None. | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  |     try: | 
					
						
							|  |  |  |         location = module.__file__ | 
					
						
							|  |  |  |     except AttributeError: | 
					
						
							|  |  |  |         location = None | 
					
						
							|  |  |  |     if origin is None: | 
					
						
							|  |  |  |         if location is None: | 
					
						
							|  |  |  |             try: | 
					
						
							|  |  |  |                 origin = loader._ORIGIN | 
					
						
							|  |  |  |             except AttributeError: | 
					
						
							|  |  |  |                 origin = None | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             origin = location | 
					
						
							|  |  |  |     try: | 
					
						
							|  |  |  |         cached = module.__cached__ | 
					
						
							|  |  |  |     except AttributeError: | 
					
						
							|  |  |  |         cached = None | 
					
						
							|  |  |  |     try: | 
					
						
							|  |  |  |         submodule_search_locations = list(module.__path__) | 
					
						
							|  |  |  |     except AttributeError: | 
					
						
							|  |  |  |         submodule_search_locations = None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     spec = ModuleSpec(name, loader, origin=origin) | 
					
						
							|  |  |  |     spec._set_fileattr = False if location is None else True | 
					
						
							|  |  |  |     spec.cached = cached | 
					
						
							|  |  |  |     spec.submodule_search_locations = submodule_search_locations | 
					
						
							|  |  |  |     return spec | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-30 14:55:29 -04:00
										 |  |  | def _init_module_attrs(spec, module, *, override=False): | 
					
						
							|  |  |  |     # The passed-in module may be not support attribute assignment, | 
					
						
							|  |  |  |     # in which case we simply don't set the attributes. | 
					
						
							|  |  |  |     # __name__ | 
					
						
							|  |  |  |     if (override or getattr(module, '__name__', None) is None): | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             module.__name__ = spec.name | 
					
						
							|  |  |  |         except AttributeError: | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  |     # __loader__ | 
					
						
							|  |  |  |     if override or getattr(module, '__loader__', None) is None: | 
					
						
							|  |  |  |         loader = spec.loader | 
					
						
							|  |  |  |         if loader is None: | 
					
						
							|  |  |  |             # A backward compatibility hack. | 
					
						
							|  |  |  |             if spec.submodule_search_locations is not None: | 
					
						
							|  |  |  |                 loader = _NamespaceLoader.__new__(_NamespaceLoader) | 
					
						
							|  |  |  |                 loader._path = spec.submodule_search_locations | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             module.__loader__ = loader | 
					
						
							|  |  |  |         except AttributeError: | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  |     # __package__ | 
					
						
							|  |  |  |     if override or getattr(module, '__package__', None) is None: | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             module.__package__ = spec.parent | 
					
						
							|  |  |  |         except AttributeError: | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  |     # __spec__ | 
					
						
							|  |  |  |     try: | 
					
						
							|  |  |  |         module.__spec__ = spec | 
					
						
							|  |  |  |     except AttributeError: | 
					
						
							|  |  |  |         pass | 
					
						
							|  |  |  |     # __path__ | 
					
						
							|  |  |  |     if override or getattr(module, '__path__', None) is None: | 
					
						
							|  |  |  |         if spec.submodule_search_locations is not None: | 
					
						
							| 
									
										
										
										
											2013-11-22 09:05:39 -07:00
										 |  |  |             try: | 
					
						
							| 
									
										
										
										
											2014-05-30 14:55:29 -04:00
										 |  |  |                 module.__path__ = spec.submodule_search_locations | 
					
						
							| 
									
										
										
										
											2013-11-22 09:05:39 -07:00
										 |  |  |             except AttributeError: | 
					
						
							|  |  |  |                 pass | 
					
						
							| 
									
										
										
										
											2014-05-30 14:55:29 -04:00
										 |  |  |     # __file__/__cached__ | 
					
						
							|  |  |  |     if spec.has_location: | 
					
						
							|  |  |  |         if override or getattr(module, '__file__', None) is None: | 
					
						
							| 
									
										
										
										
											2013-11-22 09:05:39 -07:00
										 |  |  |             try: | 
					
						
							| 
									
										
										
										
											2014-05-30 14:55:29 -04:00
										 |  |  |                 module.__file__ = spec.origin | 
					
						
							| 
									
										
										
										
											2013-11-22 09:05:39 -07:00
										 |  |  |             except AttributeError: | 
					
						
							|  |  |  |                 pass | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-30 14:55:29 -04:00
										 |  |  |         if override or getattr(module, '__cached__', None) is None: | 
					
						
							|  |  |  |             if spec.cached is not None: | 
					
						
							| 
									
										
										
										
											2013-11-22 09:05:39 -07:00
										 |  |  |                 try: | 
					
						
							| 
									
										
										
										
											2014-05-30 14:55:29 -04:00
										 |  |  |                     module.__cached__ = spec.cached | 
					
						
							| 
									
										
										
										
											2013-11-22 09:05:39 -07:00
										 |  |  |                 except AttributeError: | 
					
						
							|  |  |  |                     pass | 
					
						
							| 
									
										
										
										
											2014-05-30 14:55:29 -04:00
										 |  |  |     return module | 
					
						
							| 
									
										
										
										
											2013-11-22 09:05:39 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-30 14:55:29 -04:00
										 |  |  | def module_from_spec(spec): | 
					
						
							|  |  |  |     """Create a module based on the provided spec.""" | 
					
						
							|  |  |  |     # Typically loaders will not implement create_module(). | 
					
						
							|  |  |  |     module = None | 
					
						
							|  |  |  |     if hasattr(spec.loader, 'create_module'): | 
					
						
							|  |  |  |         # If create_module() returns `None` then it means default | 
					
						
							|  |  |  |         # module creation should be used. | 
					
						
							|  |  |  |         module = spec.loader.create_module(spec) | 
					
						
							| 
									
										
										
										
											2015-01-09 11:39:21 -05:00
										 |  |  |     elif hasattr(spec.loader, 'exec_module'): | 
					
						
							|  |  |  |         _warnings.warn('starting in Python 3.6, loaders defining exec_module() ' | 
					
						
							|  |  |  |                        'must also define create_module()', | 
					
						
							|  |  |  |                        DeprecationWarning, stacklevel=2) | 
					
						
							| 
									
										
										
										
											2014-05-30 14:55:29 -04:00
										 |  |  |     if module is None: | 
					
						
							|  |  |  |         module = _new_module(spec.name) | 
					
						
							|  |  |  |     _init_module_attrs(spec, module) | 
					
						
							|  |  |  |     return module | 
					
						
							| 
									
										
										
										
											2013-11-22 09:05:39 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-30 14:55:29 -04:00
										 |  |  | def _module_repr_from_spec(spec): | 
					
						
							|  |  |  |     """Return the repr to use for the module.""" | 
					
						
							|  |  |  |     # We mostly replicate _module_repr() using the spec attributes. | 
					
						
							|  |  |  |     name = '?' if spec.name is None else spec.name | 
					
						
							|  |  |  |     if spec.origin is None: | 
					
						
							|  |  |  |         if spec.loader is None: | 
					
						
							|  |  |  |             return '<module {!r}>'.format(name) | 
					
						
							| 
									
										
										
										
											2013-11-22 09:05:39 -07:00
										 |  |  |         else: | 
					
						
							| 
									
										
										
										
											2014-05-30 14:55:29 -04:00
										 |  |  |             return '<module {!r} ({!r})>'.format(name, spec.loader) | 
					
						
							|  |  |  |     else: | 
					
						
							|  |  |  |         if spec.has_location: | 
					
						
							|  |  |  |             return '<module {!r} from {!r}>'.format(name, spec.origin) | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             return '<module {!r} ({})>'.format(spec.name, spec.origin) | 
					
						
							| 
									
										
										
										
											2013-11-22 09:05:39 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-30 14:55:29 -04:00
										 |  |  | # Used by importlib.reload() and _load_module_shim(). | 
					
						
							|  |  |  | def _exec(spec, module): | 
					
						
							|  |  |  |     """Execute the spec in an existing module's namespace.""" | 
					
						
							|  |  |  |     name = spec.name | 
					
						
							|  |  |  |     _imp.acquire_lock() | 
					
						
							|  |  |  |     with _ModuleLockManager(name): | 
					
						
							|  |  |  |         if sys.modules.get(name) is not module: | 
					
						
							|  |  |  |             msg = 'module {!r} not in sys.modules'.format(name) | 
					
						
							|  |  |  |             raise ImportError(msg, name=name) | 
					
						
							|  |  |  |         if spec.loader is None: | 
					
						
							|  |  |  |             if spec.submodule_search_locations is None: | 
					
						
							|  |  |  |                 raise ImportError('missing loader', name=spec.name) | 
					
						
							|  |  |  |             # namespace package | 
					
						
							|  |  |  |             _init_module_attrs(spec, module, override=True) | 
					
						
							|  |  |  |             return module | 
					
						
							|  |  |  |         _init_module_attrs(spec, module, override=True) | 
					
						
							|  |  |  |         if not hasattr(spec.loader, 'exec_module'): | 
					
						
							|  |  |  |             # (issue19713) Once BuiltinImporter and ExtensionFileLoader | 
					
						
							|  |  |  |             # have exec_module() implemented, we can add a deprecation | 
					
						
							|  |  |  |             # warning here. | 
					
						
							|  |  |  |             spec.loader.load_module(name) | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             spec.loader.exec_module(module) | 
					
						
							|  |  |  |     return sys.modules[name] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def _load_backward_compatible(spec): | 
					
						
							|  |  |  |     # (issue19713) Once BuiltinImporter and ExtensionFileLoader | 
					
						
							|  |  |  |     # have exec_module() implemented, we can add a deprecation | 
					
						
							|  |  |  |     # warning here. | 
					
						
							|  |  |  |     spec.loader.load_module(spec.name) | 
					
						
							|  |  |  |     # The module must be in sys.modules at this point! | 
					
						
							|  |  |  |     module = sys.modules[spec.name] | 
					
						
							|  |  |  |     if getattr(module, '__loader__', None) is None: | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             module.__loader__ = spec.loader | 
					
						
							|  |  |  |         except AttributeError: | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  |     if getattr(module, '__package__', None) is None: | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             # Since module.__path__ may not line up with | 
					
						
							|  |  |  |             # spec.submodule_search_paths, we can't necessarily rely | 
					
						
							|  |  |  |             # on spec.parent here. | 
					
						
							|  |  |  |             module.__package__ = module.__name__ | 
					
						
							|  |  |  |             if not hasattr(module, '__path__'): | 
					
						
							|  |  |  |                 module.__package__ = spec.name.rpartition('.')[0] | 
					
						
							|  |  |  |         except AttributeError: | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  |     if getattr(module, '__spec__', None) is None: | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             module.__spec__ = spec | 
					
						
							|  |  |  |         except AttributeError: | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  |     return module | 
					
						
							| 
									
										
										
										
											2013-11-22 09:05:39 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-30 14:55:29 -04:00
										 |  |  | def _load_unlocked(spec): | 
					
						
							|  |  |  |     # A helper for direct use by the import system. | 
					
						
							|  |  |  |     if spec.loader is not None: | 
					
						
							|  |  |  |         # not a namespace package | 
					
						
							|  |  |  |         if not hasattr(spec.loader, 'exec_module'): | 
					
						
							|  |  |  |             return _load_backward_compatible(spec) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     module = module_from_spec(spec) | 
					
						
							|  |  |  |     with _installed_safely(module): | 
					
						
							|  |  |  |         if spec.loader is None: | 
					
						
							|  |  |  |             if spec.submodule_search_locations is None: | 
					
						
							|  |  |  |                 raise ImportError('missing loader', name=spec.name) | 
					
						
							|  |  |  |             # A namespace package so do nothing. | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             spec.loader.exec_module(module) | 
					
						
							| 
									
										
										
										
											2013-11-22 09:05:39 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-30 14:55:29 -04:00
										 |  |  |     # We don't ensure that the import-related module attributes get | 
					
						
							|  |  |  |     # set in the sys.modules replacement case.  Such modules are on | 
					
						
							|  |  |  |     # their own. | 
					
						
							|  |  |  |     return sys.modules[spec.name] | 
					
						
							| 
									
										
										
										
											2013-11-22 09:05:39 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-30 14:55:29 -04:00
										 |  |  | # A method used during testing of _load_unlocked() and by | 
					
						
							|  |  |  | # _load_module_shim(). | 
					
						
							|  |  |  | def _load(spec): | 
					
						
							|  |  |  |     """Return a new module object, loaded by the spec's loader.
 | 
					
						
							| 
									
										
										
										
											2013-11-22 09:05:39 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-30 14:55:29 -04:00
										 |  |  |     The module is not added to its parent. | 
					
						
							| 
									
										
										
										
											2013-11-22 09:05:39 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-30 14:55:29 -04:00
										 |  |  |     If a module is already in sys.modules, that existing module gets | 
					
						
							|  |  |  |     clobbered. | 
					
						
							| 
									
										
										
										
											2013-11-22 09:05:39 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-30 14:55:29 -04:00
										 |  |  |     """
 | 
					
						
							|  |  |  |     _imp.acquire_lock() | 
					
						
							|  |  |  |     with _ModuleLockManager(spec.name): | 
					
						
							|  |  |  |         return _load_unlocked(spec) | 
					
						
							| 
									
										
										
										
											2013-11-22 09:05:39 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-12 17:54:55 -06:00
										 |  |  | def _fix_up_module(ns, name, pathname, cpathname=None): | 
					
						
							|  |  |  |     # This function is used by PyImport_ExecCodeModuleObject(). | 
					
						
							|  |  |  |     loader = ns.get('__loader__') | 
					
						
							|  |  |  |     spec = ns.get('__spec__') | 
					
						
							|  |  |  |     if not loader: | 
					
						
							|  |  |  |         if spec: | 
					
						
							|  |  |  |             loader = spec.loader | 
					
						
							|  |  |  |         elif pathname == cpathname: | 
					
						
							|  |  |  |             loader = SourcelessFileLoader(name, pathname) | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             loader = SourceFileLoader(name, pathname) | 
					
						
							|  |  |  |     if not spec: | 
					
						
							|  |  |  |         spec = spec_from_file_location(name, pathname, loader=loader) | 
					
						
							|  |  |  |     try: | 
					
						
							|  |  |  |         ns['__spec__'] = spec | 
					
						
							|  |  |  |         ns['__loader__'] = loader | 
					
						
							|  |  |  |         ns['__file__'] = pathname | 
					
						
							|  |  |  |         ns['__cached__'] = cpathname | 
					
						
							|  |  |  |     except Exception: | 
					
						
							|  |  |  |         # Not important enough to report. | 
					
						
							|  |  |  |         pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-12 22:37:06 +00:00
										 |  |  | # Loaders ##################################################################### | 
					
						
							| 
									
										
										
										
											2009-03-12 22:28:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-22 22:43:07 +00:00
										 |  |  | class BuiltinImporter: | 
					
						
							| 
									
										
										
										
											2009-01-18 00:24:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-15 00:53:05 +00:00
										 |  |  |     """Meta path import for built-in modules.
 | 
					
						
							| 
									
										
										
										
											2009-01-18 00:24:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-15 00:53:05 +00:00
										 |  |  |     All methods are either class or static methods to avoid the need to | 
					
						
							|  |  |  |     instantiate the class. | 
					
						
							| 
									
										
										
										
											2009-01-18 00:24:28 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-22 09:05:39 -07:00
										 |  |  |     @staticmethod | 
					
						
							|  |  |  |     def module_repr(module): | 
					
						
							| 
									
										
										
										
											2014-01-06 20:49:04 -07:00
										 |  |  |         """Return repr for the module.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         The method is deprecated.  The import machinery does the job itself. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2013-07-12 11:04:23 -04:00
										 |  |  |         return '<module {!r} (built-in)>'.format(module.__name__) | 
					
						
							| 
									
										
										
										
											2012-05-24 20:21:04 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-22 09:05:39 -07:00
										 |  |  |     @classmethod | 
					
						
							|  |  |  |     def find_spec(cls, fullname, path=None, target=None): | 
					
						
							|  |  |  |         if path is not None: | 
					
						
							|  |  |  |             return None | 
					
						
							|  |  |  |         if _imp.is_builtin(fullname): | 
					
						
							|  |  |  |             return spec_from_loader(fullname, cls, origin='built-in') | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             return None | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-22 22:43:07 +00:00
										 |  |  |     @classmethod | 
					
						
							|  |  |  |     def find_module(cls, fullname, path=None): | 
					
						
							| 
									
										
										
										
											2009-03-15 00:53:05 +00:00
										 |  |  |         """Find the built-in module.
 | 
					
						
							| 
									
										
										
										
											2009-01-18 00:24:28 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         If 'path' is ever specified then the search is considered a failure. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-06 20:49:04 -07:00
										 |  |  |         This method is deprecated.  Use find_spec() instead. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-18 00:24:28 +00:00
										 |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2013-11-22 09:05:39 -07:00
										 |  |  |         spec = cls.find_spec(fullname, path) | 
					
						
							|  |  |  |         return spec.loader if spec is not None else None | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-25 04:56:30 +00:00
										 |  |  |     @classmethod | 
					
						
							| 
									
										
										
										
											2013-11-29 11:00:11 -05:00
										 |  |  |     @_requires_builtin | 
					
						
							| 
									
										
										
										
											2009-01-25 04:56:30 +00:00
										 |  |  |     def load_module(cls, fullname): | 
					
						
							| 
									
										
										
										
											2009-01-18 00:24:28 +00:00
										 |  |  |         """Load a built-in module.""" | 
					
						
							| 
									
										
										
										
											2014-01-06 20:49:04 -07:00
										 |  |  |         # Once an exec_module() implementation is added we can also | 
					
						
							|  |  |  |         # add a deprecation warning here. | 
					
						
							| 
									
										
										
										
											2013-11-29 11:00:11 -05:00
										 |  |  |         with _ManageReload(fullname): | 
					
						
							|  |  |  |             module = _call_with_frames_removed(_imp.init_builtin, fullname) | 
					
						
							|  |  |  |         module.__loader__ = cls | 
					
						
							|  |  |  |         module.__package__ = '' | 
					
						
							|  |  |  |         return module | 
					
						
							| 
									
										
										
										
											2009-01-18 00:24:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-15 01:41:33 +00:00
										 |  |  |     @classmethod | 
					
						
							|  |  |  |     @_requires_builtin | 
					
						
							|  |  |  |     def get_code(cls, fullname): | 
					
						
							|  |  |  |         """Return None as built-in modules do not have code objects.""" | 
					
						
							|  |  |  |         return None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @classmethod | 
					
						
							|  |  |  |     @_requires_builtin | 
					
						
							|  |  |  |     def get_source(cls, fullname): | 
					
						
							|  |  |  |         """Return None as built-in modules do not have source code.""" | 
					
						
							|  |  |  |         return None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @classmethod | 
					
						
							|  |  |  |     @_requires_builtin | 
					
						
							|  |  |  |     def is_package(cls, fullname): | 
					
						
							| 
									
										
										
										
											2012-07-07 13:16:44 +02:00
										 |  |  |         """Return False as built-in modules are never packages.""" | 
					
						
							| 
									
										
										
										
											2009-03-15 01:41:33 +00:00
										 |  |  |         return False | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-18 00:24:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-22 22:43:07 +00:00
										 |  |  | class FrozenImporter: | 
					
						
							| 
									
										
										
										
											2009-01-18 00:24:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-15 00:53:05 +00:00
										 |  |  |     """Meta path import for frozen modules.
 | 
					
						
							| 
									
										
										
										
											2009-01-18 00:24:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-15 00:53:05 +00:00
										 |  |  |     All methods are either class or static methods to avoid the need to | 
					
						
							|  |  |  |     instantiate the class. | 
					
						
							| 
									
										
										
										
											2009-01-18 00:24:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-22 22:43:07 +00:00
										 |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2009-01-18 00:24:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-22 09:05:39 -07:00
										 |  |  |     @staticmethod | 
					
						
							|  |  |  |     def module_repr(m): | 
					
						
							| 
									
										
										
										
											2014-01-06 20:49:04 -07:00
										 |  |  |         """Return repr for the module.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         The method is deprecated.  The import machinery does the job itself. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2013-07-12 11:04:23 -04:00
										 |  |  |         return '<module {!r} (frozen)>'.format(m.__name__) | 
					
						
							| 
									
										
										
										
											2012-05-24 20:21:04 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-22 09:05:39 -07:00
										 |  |  |     @classmethod | 
					
						
							|  |  |  |     def find_spec(cls, fullname, path=None, target=None): | 
					
						
							|  |  |  |         if _imp.is_frozen(fullname): | 
					
						
							|  |  |  |             return spec_from_loader(fullname, cls, origin='frozen') | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             return None | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-22 22:43:07 +00:00
										 |  |  |     @classmethod | 
					
						
							|  |  |  |     def find_module(cls, fullname, path=None): | 
					
						
							| 
									
										
										
										
											2014-01-06 20:49:04 -07:00
										 |  |  |         """Find a frozen module.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         This method is deprecated.  Use find_spec() instead. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2012-04-15 16:08:47 -04:00
										 |  |  |         return cls if _imp.is_frozen(fullname) else None | 
					
						
							| 
									
										
										
										
											2009-01-18 00:24:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-09 11:39:21 -05:00
										 |  |  |     @classmethod | 
					
						
							|  |  |  |     def create_module(cls, spec): | 
					
						
							|  |  |  |         """Use default semantics for module creation.""" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-22 09:05:39 -07:00
										 |  |  |     @staticmethod | 
					
						
							|  |  |  |     def exec_module(module): | 
					
						
							|  |  |  |         name = module.__spec__.name | 
					
						
							|  |  |  |         if not _imp.is_frozen(name): | 
					
						
							| 
									
										
										
										
											2013-11-22 14:52:36 -05:00
										 |  |  |             raise ImportError('{!r} is not a frozen module'.format(name), | 
					
						
							| 
									
										
										
										
											2013-11-22 09:05:39 -07:00
										 |  |  |                               name=name) | 
					
						
							|  |  |  |         code = _call_with_frames_removed(_imp.get_frozen_object, name) | 
					
						
							|  |  |  |         exec(code, module.__dict__) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-22 22:43:07 +00:00
										 |  |  |     @classmethod | 
					
						
							|  |  |  |     def load_module(cls, fullname): | 
					
						
							| 
									
										
										
										
											2014-01-06 20:49:04 -07:00
										 |  |  |         """Load a frozen module.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         This method is deprecated.  Use exec_module() instead. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2013-11-22 09:05:39 -07:00
										 |  |  |         return _load_module_shim(cls, fullname) | 
					
						
							| 
									
										
										
										
											2009-01-18 00:24:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-15 02:20:16 +00:00
										 |  |  |     @classmethod | 
					
						
							|  |  |  |     @_requires_frozen | 
					
						
							|  |  |  |     def get_code(cls, fullname): | 
					
						
							|  |  |  |         """Return the code object for the frozen module.""" | 
					
						
							| 
									
										
										
										
											2012-04-15 16:08:47 -04:00
										 |  |  |         return _imp.get_frozen_object(fullname) | 
					
						
							| 
									
										
										
										
											2009-03-15 02:20:16 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     @classmethod | 
					
						
							|  |  |  |     @_requires_frozen | 
					
						
							|  |  |  |     def get_source(cls, fullname): | 
					
						
							|  |  |  |         """Return None as frozen modules do not have source code.""" | 
					
						
							|  |  |  |         return None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @classmethod | 
					
						
							|  |  |  |     @_requires_frozen | 
					
						
							|  |  |  |     def is_package(cls, fullname): | 
					
						
							| 
									
										
										
										
											2012-08-10 16:21:35 -07:00
										 |  |  |         """Return True if the frozen module is a package.""" | 
					
						
							| 
									
										
										
										
											2012-04-15 16:08:47 -04:00
										 |  |  |         return _imp.is_frozen_package(fullname) | 
					
						
							| 
									
										
										
										
											2009-03-15 02:20:16 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-18 00:24:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-08-02 21:45:24 +10:00
										 |  |  | class WindowsRegistryFinder: | 
					
						
							| 
									
										
										
										
											2012-07-28 21:33:05 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-22 09:05:39 -07:00
										 |  |  |     """Meta path finder for modules declared in the Windows registry.""" | 
					
						
							| 
									
										
										
										
											2012-07-28 21:33:05 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     REGISTRY_KEY = ( | 
					
						
							| 
									
										
										
										
											2013-07-12 11:04:23 -04:00
										 |  |  |         'Software\\Python\\PythonCore\\{sys_version}' | 
					
						
							|  |  |  |         '\\Modules\\{fullname}') | 
					
						
							| 
									
										
										
										
											2012-07-28 21:33:05 +02:00
										 |  |  |     REGISTRY_KEY_DEBUG = ( | 
					
						
							| 
									
										
										
										
											2013-07-12 11:04:23 -04:00
										 |  |  |         'Software\\Python\\PythonCore\\{sys_version}' | 
					
						
							|  |  |  |         '\\Modules\\{fullname}\\Debug') | 
					
						
							| 
									
										
										
										
											2012-07-28 21:33:05 +02:00
										 |  |  |     DEBUG_BUILD = False  # Changed in _setup() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @classmethod | 
					
						
							|  |  |  |     def _open_registry(cls, key): | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             return _winreg.OpenKey(_winreg.HKEY_CURRENT_USER, key) | 
					
						
							| 
									
										
										
										
											2012-12-19 14:33:35 +02:00
										 |  |  |         except OSError: | 
					
						
							| 
									
										
										
										
											2012-07-28 21:33:05 +02:00
										 |  |  |             return _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, key) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @classmethod | 
					
						
							|  |  |  |     def _search_registry(cls, fullname): | 
					
						
							|  |  |  |         if cls.DEBUG_BUILD: | 
					
						
							|  |  |  |             registry_key = cls.REGISTRY_KEY_DEBUG | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             registry_key = cls.REGISTRY_KEY | 
					
						
							|  |  |  |         key = registry_key.format(fullname=fullname, | 
					
						
							|  |  |  |                                   sys_version=sys.version[:3]) | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             with cls._open_registry(key) as hkey: | 
					
						
							| 
									
										
										
										
											2013-07-12 11:04:23 -04:00
										 |  |  |                 filepath = _winreg.QueryValue(hkey, '') | 
					
						
							| 
									
										
										
										
											2012-12-19 14:33:35 +02:00
										 |  |  |         except OSError: | 
					
						
							| 
									
										
										
										
											2012-07-28 21:33:05 +02:00
										 |  |  |             return None | 
					
						
							|  |  |  |         return filepath | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @classmethod | 
					
						
							| 
									
										
										
										
											2013-11-22 09:05:39 -07:00
										 |  |  |     def find_spec(cls, fullname, path=None, target=None): | 
					
						
							| 
									
										
										
										
											2012-07-28 21:33:05 +02:00
										 |  |  |         filepath = cls._search_registry(fullname) | 
					
						
							|  |  |  |         if filepath is None: | 
					
						
							|  |  |  |             return None | 
					
						
							|  |  |  |         try: | 
					
						
							| 
									
										
										
										
											2013-11-01 14:04:24 -04:00
										 |  |  |             _path_stat(filepath) | 
					
						
							| 
									
										
										
										
											2012-07-28 21:33:05 +02:00
										 |  |  |         except OSError: | 
					
						
							|  |  |  |             return None | 
					
						
							| 
									
										
										
										
											2013-10-03 12:08:55 -06:00
										 |  |  |         for loader, suffixes in _get_supported_file_loaders(): | 
					
						
							| 
									
										
										
										
											2012-07-28 21:33:05 +02:00
										 |  |  |             if filepath.endswith(tuple(suffixes)): | 
					
						
							| 
									
										
										
										
											2013-11-22 09:05:39 -07:00
										 |  |  |                 spec = spec_from_loader(fullname, loader(fullname, filepath), | 
					
						
							|  |  |  |                                         origin=filepath) | 
					
						
							|  |  |  |                 return spec | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @classmethod | 
					
						
							|  |  |  |     def find_module(cls, fullname, path=None): | 
					
						
							| 
									
										
										
										
											2014-01-06 20:49:04 -07:00
										 |  |  |         """Find module named in the registry.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         This method is deprecated.  Use exec_module() instead. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2014-01-02 22:25:00 -07:00
										 |  |  |         spec = cls.find_spec(fullname, path) | 
					
						
							| 
									
										
										
										
											2013-11-22 09:05:39 -07:00
										 |  |  |         if spec is not None: | 
					
						
							|  |  |  |             return spec.loader | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             return None | 
					
						
							| 
									
										
										
										
											2012-07-28 21:33:05 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-03 21:48:25 +00:00
										 |  |  | class _LoaderBasics: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     """Base class of common code needed by both SourceLoader and
 | 
					
						
							| 
									
										
										
										
											2012-04-22 19:58:33 -04:00
										 |  |  |     SourcelessFileLoader."""
 | 
					
						
							| 
									
										
										
										
											2010-07-03 21:48:25 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def is_package(self, fullname): | 
					
						
							|  |  |  |         """Concrete implementation of InspectLoader.is_package by checking if
 | 
					
						
							|  |  |  |         the path returned by get_filename has a filename of '__init__.py'."""
 | 
					
						
							| 
									
										
										
										
											2012-04-20 21:19:53 -04:00
										 |  |  |         filename = _path_split(self.get_filename(fullname))[1] | 
					
						
							| 
									
										
										
										
											2012-06-15 20:00:53 -04:00
										 |  |  |         filename_base = filename.rsplit('.', 1)[0] | 
					
						
							|  |  |  |         tail_name = fullname.rpartition('.')[2] | 
					
						
							|  |  |  |         return filename_base == '__init__' and tail_name != '__init__' | 
					
						
							| 
									
										
										
										
											2010-07-03 21:48:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-09 11:39:21 -05:00
										 |  |  |     def create_module(self, spec): | 
					
						
							|  |  |  |         """Use default semantics for module creation.""" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-22 09:05:39 -07:00
										 |  |  |     def exec_module(self, module): | 
					
						
							|  |  |  |         """Execute the module.""" | 
					
						
							|  |  |  |         code = self.get_code(module.__name__) | 
					
						
							|  |  |  |         if code is None: | 
					
						
							|  |  |  |             raise ImportError('cannot load module {!r} when get_code() ' | 
					
						
							|  |  |  |                               'returns None'.format(module.__name__)) | 
					
						
							|  |  |  |         _call_with_frames_removed(exec, code, module.__dict__) | 
					
						
							| 
									
										
										
										
											2013-05-31 18:56:47 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-22 09:05:39 -07:00
										 |  |  |     load_module = _load_module_shim | 
					
						
							| 
									
										
										
										
											2010-07-03 21:48:25 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class SourceLoader(_LoaderBasics): | 
					
						
							| 
									
										
										
										
											2010-06-28 04:57:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-13 02:31:25 +00:00
										 |  |  |     def path_mtime(self, path): | 
					
						
							| 
									
										
										
										
											2011-01-13 19:08:04 +00:00
										 |  |  |         """Optional method that returns the modification time (an int) for the
 | 
					
						
							|  |  |  |         specified path, where path is a str. | 
					
						
							| 
									
										
										
										
											2013-04-09 16:59:39 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |         Raises IOError when the path cannot be handled. | 
					
						
							| 
									
										
										
										
											2012-01-13 18:52:16 +01:00
										 |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2013-04-09 16:59:39 -04:00
										 |  |  |         raise IOError | 
					
						
							| 
									
										
										
										
											2010-06-28 04:57:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-13 18:52:16 +01:00
										 |  |  |     def path_stats(self, path): | 
					
						
							|  |  |  |         """Optional method returning a metadata dict for the specified path
 | 
					
						
							|  |  |  |         to by the path (str). | 
					
						
							|  |  |  |         Possible keys: | 
					
						
							|  |  |  |         - 'mtime' (mandatory) is the numeric timestamp of last source | 
					
						
							|  |  |  |           code modification; | 
					
						
							|  |  |  |         - 'size' (optional) is the size in bytes of the source code. | 
					
						
							| 
									
										
										
										
											2010-06-28 04:57:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-13 18:52:16 +01:00
										 |  |  |         Implementing this method allows the loader to read bytecode files. | 
					
						
							| 
									
										
										
										
											2013-04-09 16:59:39 -04:00
										 |  |  |         Raises IOError when the path cannot be handled. | 
					
						
							| 
									
										
										
										
											2010-06-28 04:57:24 +00:00
										 |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2012-01-13 18:52:16 +01:00
										 |  |  |         return {'mtime': self.path_mtime(path)} | 
					
						
							| 
									
										
										
										
											2010-06-28 04:57:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-08-24 18:32:40 +10:00
										 |  |  |     def _cache_bytecode(self, source_path, cache_path, data): | 
					
						
							|  |  |  |         """Optional method which writes data (bytes) to a file path (a str).
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         Implementing this method allows for the writing of bytecode files. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         The source path is needed in order to correctly transfer permissions | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         # For backwards compatibility, we delegate to set_data() | 
					
						
							|  |  |  |         return self.set_data(cache_path, data) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-13 02:31:25 +00:00
										 |  |  |     def set_data(self, path, data): | 
					
						
							| 
									
										
										
										
											2011-01-13 19:08:04 +00:00
										 |  |  |         """Optional method which writes data (bytes) to a file path (a str).
 | 
					
						
							| 
									
										
										
										
											2010-06-28 04:57:24 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         Implementing this method allows for the writing of bytecode files. | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def get_source(self, fullname): | 
					
						
							|  |  |  |         """Concrete implementation of InspectLoader.get_source.""" | 
					
						
							|  |  |  |         path = self.get_filename(fullname) | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             source_bytes = self.get_data(path) | 
					
						
							| 
									
										
										
										
											2012-12-25 16:47:37 +02:00
										 |  |  |         except OSError as exc: | 
					
						
							| 
									
										
										
										
											2013-07-12 11:04:23 -04:00
										 |  |  |             raise ImportError('source not available through get_data()', | 
					
						
							| 
									
										
										
										
											2012-07-15 22:12:14 +10:00
										 |  |  |                               name=fullname) from exc | 
					
						
							| 
									
										
										
										
											2013-06-16 18:37:53 -04:00
										 |  |  |         return decode_source(source_bytes) | 
					
						
							| 
									
										
										
										
											2010-06-28 04:57:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-26 08:48:36 -05:00
										 |  |  |     def source_to_code(self, data, path, *, _optimize=-1): | 
					
						
							| 
									
										
										
										
											2012-11-18 10:03:31 -05:00
										 |  |  |         """Return the code object compiled from source.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         The 'data' argument can be any object type that compile() supports. | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         return _call_with_frames_removed(compile, data, path, 'exec', | 
					
						
							| 
									
										
										
										
											2013-01-26 08:48:36 -05:00
										 |  |  |                                         dont_inherit=True, optimize=_optimize) | 
					
						
							| 
									
										
										
										
											2012-11-18 10:03:31 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-28 04:57:24 +00:00
										 |  |  |     def get_code(self, fullname): | 
					
						
							|  |  |  |         """Concrete implementation of InspectLoader.get_code.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-13 18:52:16 +01:00
										 |  |  |         Reading of bytecode requires path_stats to be implemented. To write | 
					
						
							| 
									
										
										
										
											2010-06-28 04:57:24 +00:00
										 |  |  |         bytecode, set_data must also be implemented. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         source_path = self.get_filename(fullname) | 
					
						
							|  |  |  |         source_mtime = None | 
					
						
							| 
									
										
										
										
											2012-07-09 13:58:07 -04:00
										 |  |  |         try: | 
					
						
							|  |  |  |             bytecode_path = cache_from_source(source_path) | 
					
						
							|  |  |  |         except NotImplementedError: | 
					
						
							|  |  |  |             bytecode_path = None | 
					
						
							|  |  |  |         else: | 
					
						
							| 
									
										
										
										
											2010-06-28 04:57:24 +00:00
										 |  |  |             try: | 
					
						
							| 
									
										
										
										
											2012-01-13 18:52:16 +01:00
										 |  |  |                 st = self.path_stats(source_path) | 
					
						
							| 
									
										
										
										
											2013-04-09 16:59:39 -04:00
										 |  |  |             except IOError: | 
					
						
							| 
									
										
										
										
											2010-06-28 04:57:24 +00:00
										 |  |  |                 pass | 
					
						
							|  |  |  |             else: | 
					
						
							| 
									
										
										
										
											2012-01-13 18:52:16 +01:00
										 |  |  |                 source_mtime = int(st['mtime']) | 
					
						
							| 
									
										
										
										
											2010-06-28 04:57:24 +00:00
										 |  |  |                 try: | 
					
						
							|  |  |  |                     data = self.get_data(bytecode_path) | 
					
						
							| 
									
										
										
										
											2012-12-25 16:47:37 +02:00
										 |  |  |                 except OSError: | 
					
						
							| 
									
										
										
										
											2010-06-28 04:57:24 +00:00
										 |  |  |                     pass | 
					
						
							|  |  |  |                 else: | 
					
						
							| 
									
										
										
										
											2010-07-03 21:48:25 +00:00
										 |  |  |                     try: | 
					
						
							| 
									
										
										
										
											2013-01-11 18:09:25 -05:00
										 |  |  |                         bytes_data = _validate_bytecode_header(data, | 
					
						
							|  |  |  |                                 source_stats=st, name=fullname, | 
					
						
							|  |  |  |                                 path=bytecode_path) | 
					
						
							| 
									
										
										
										
											2010-07-03 21:48:25 +00:00
										 |  |  |                     except (ImportError, EOFError): | 
					
						
							|  |  |  |                         pass | 
					
						
							|  |  |  |                     else: | 
					
						
							| 
									
										
										
										
											2012-05-04 13:52:49 -04:00
										 |  |  |                         _verbose_message('{} matches {}', bytecode_path, | 
					
						
							| 
									
										
										
										
											2012-04-14 14:10:13 -04:00
										 |  |  |                                         source_path) | 
					
						
							| 
									
										
										
										
											2013-01-11 18:09:25 -05:00
										 |  |  |                         return _compile_bytecode(bytes_data, name=fullname, | 
					
						
							|  |  |  |                                                  bytecode_path=bytecode_path, | 
					
						
							|  |  |  |                                                  source_path=source_path) | 
					
						
							| 
									
										
										
										
											2010-06-28 04:57:24 +00:00
										 |  |  |         source_bytes = self.get_data(source_path) | 
					
						
							| 
									
										
										
										
											2012-12-04 23:43:43 -08:00
										 |  |  |         code_object = self.source_to_code(source_bytes, source_path) | 
					
						
							| 
									
										
										
										
											2012-05-04 13:52:49 -04:00
										 |  |  |         _verbose_message('code object from {}', source_path) | 
					
						
							| 
									
										
										
										
											2010-06-28 04:57:24 +00:00
										 |  |  |         if (not sys.dont_write_bytecode and bytecode_path is not None and | 
					
						
							| 
									
										
										
										
											2013-01-26 08:48:36 -05:00
										 |  |  |                 source_mtime is not None): | 
					
						
							|  |  |  |             data = _code_to_bytecode(code_object, source_mtime, | 
					
						
							|  |  |  |                     len(source_bytes)) | 
					
						
							| 
									
										
										
										
											2010-06-28 04:57:24 +00:00
										 |  |  |             try: | 
					
						
							| 
									
										
										
										
											2012-08-24 18:32:40 +10:00
										 |  |  |                 self._cache_bytecode(source_path, bytecode_path, data) | 
					
						
							| 
									
										
										
										
											2012-05-04 13:52:49 -04:00
										 |  |  |                 _verbose_message('wrote {!r}', bytecode_path) | 
					
						
							| 
									
										
										
										
											2010-06-28 04:57:24 +00:00
										 |  |  |             except NotImplementedError: | 
					
						
							|  |  |  |                 pass | 
					
						
							|  |  |  |         return code_object | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-22 19:58:33 -04:00
										 |  |  | class FileLoader: | 
					
						
							| 
									
										
										
										
											2010-06-28 04:57:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-03 21:48:25 +00:00
										 |  |  |     """Base file loader class which implements the loader protocol methods that
 | 
					
						
							|  |  |  |     require file system usage."""
 | 
					
						
							| 
									
										
										
										
											2010-06-28 04:57:24 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def __init__(self, fullname, path): | 
					
						
							| 
									
										
										
										
											2010-07-03 21:48:25 +00:00
										 |  |  |         """Cache the module name and the path to the file found by the
 | 
					
						
							|  |  |  |         finder."""
 | 
					
						
							| 
									
										
										
										
											2012-04-22 19:58:33 -04:00
										 |  |  |         self.name = fullname | 
					
						
							|  |  |  |         self.path = path | 
					
						
							| 
									
										
										
										
											2010-06-28 04:57:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-04 15:06:49 -07:00
										 |  |  |     def __eq__(self, other): | 
					
						
							|  |  |  |         return (self.__class__ == other.__class__ and | 
					
						
							|  |  |  |                 self.__dict__ == other.__dict__) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def __hash__(self): | 
					
						
							|  |  |  |         return hash(self.name) ^ hash(self.path) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-11 14:48:41 -04:00
										 |  |  |     @_check_name | 
					
						
							|  |  |  |     def load_module(self, fullname): | 
					
						
							| 
									
										
										
										
											2014-01-06 20:49:04 -07:00
										 |  |  |         """Load a module from a file.
 | 
					
						
							| 
									
										
										
										
											2013-11-22 09:05:39 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-06 20:49:04 -07:00
										 |  |  |         This method is deprecated.  Use exec_module() instead. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         # The only reason for this method is for the name check. | 
					
						
							| 
									
										
										
										
											2013-11-22 09:05:39 -07:00
										 |  |  |         # Issue #14857: Avoid the zero-argument form of super so the implementation | 
					
						
							| 
									
										
										
										
											2012-05-27 17:49:58 +10:00
										 |  |  |         # of that form can be updated without breaking the frozen module | 
					
						
							|  |  |  |         return super(FileLoader, self).load_module(fullname) | 
					
						
							| 
									
										
										
										
											2012-05-11 14:48:41 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-28 04:57:24 +00:00
										 |  |  |     @_check_name | 
					
						
							|  |  |  |     def get_filename(self, fullname): | 
					
						
							|  |  |  |         """Return the path to the source file as found by the finder.""" | 
					
						
							| 
									
										
										
										
											2012-04-22 19:58:33 -04:00
										 |  |  |         return self.path | 
					
						
							| 
									
										
										
										
											2010-06-28 04:57:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-03 21:48:25 +00:00
										 |  |  |     def get_data(self, path): | 
					
						
							|  |  |  |         """Return the data from path as raw bytes.""" | 
					
						
							| 
									
										
										
										
											2010-09-03 19:55:26 +00:00
										 |  |  |         with _io.FileIO(path, 'r') as file: | 
					
						
							| 
									
										
										
										
											2010-07-03 21:48:25 +00:00
										 |  |  |             return file.read() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-22 19:58:33 -04:00
										 |  |  | class SourceFileLoader(FileLoader, SourceLoader): | 
					
						
							| 
									
										
										
										
											2010-07-03 21:48:25 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     """Concrete implementation of SourceLoader using the file system.""" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-13 18:52:16 +01:00
										 |  |  |     def path_stats(self, path): | 
					
						
							| 
									
										
										
										
											2012-08-10 16:21:35 -07:00
										 |  |  |         """Return the metadata for the path.""" | 
					
						
							| 
									
										
										
										
											2013-11-01 14:04:24 -04:00
										 |  |  |         st = _path_stat(path) | 
					
						
							| 
									
										
										
										
											2012-01-13 18:52:16 +01:00
										 |  |  |         return {'mtime': st.st_mtime, 'size': st.st_size} | 
					
						
							| 
									
										
										
										
											2010-06-28 04:57:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-08-24 18:32:40 +10:00
										 |  |  |     def _cache_bytecode(self, source_path, bytecode_path, data): | 
					
						
							|  |  |  |         # Adapt between the two APIs | 
					
						
							| 
									
										
										
										
											2013-04-14 12:48:15 -04:00
										 |  |  |         mode = _calc_mode(source_path) | 
					
						
							| 
									
										
										
										
											2012-08-24 13:48:39 -04:00
										 |  |  |         return self.set_data(bytecode_path, data, _mode=mode) | 
					
						
							| 
									
										
										
										
											2012-08-24 18:32:40 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-08-24 13:48:39 -04:00
										 |  |  |     def set_data(self, path, data, *, _mode=0o666): | 
					
						
							| 
									
										
										
										
											2010-06-28 04:57:24 +00:00
										 |  |  |         """Write bytes data to a file.""" | 
					
						
							| 
									
										
										
										
											2012-04-20 21:19:53 -04:00
										 |  |  |         parent, filename = _path_split(path) | 
					
						
							| 
									
										
										
										
											2010-08-22 22:19:11 +00:00
										 |  |  |         path_parts = [] | 
					
						
							|  |  |  |         # Figure out what directories are missing. | 
					
						
							|  |  |  |         while parent and not _path_isdir(parent): | 
					
						
							| 
									
										
										
										
											2012-04-20 21:19:53 -04:00
										 |  |  |             parent, part = _path_split(parent) | 
					
						
							| 
									
										
										
										
											2010-08-22 22:19:11 +00:00
										 |  |  |             path_parts.append(part) | 
					
						
							|  |  |  |         # Create needed directories. | 
					
						
							|  |  |  |         for part in reversed(path_parts): | 
					
						
							|  |  |  |             parent = _path_join(parent, part) | 
					
						
							|  |  |  |             try: | 
					
						
							|  |  |  |                 _os.mkdir(parent) | 
					
						
							| 
									
										
										
										
											2011-10-28 16:06:23 +02:00
										 |  |  |             except FileExistsError: | 
					
						
							| 
									
										
										
										
											2010-08-22 22:19:11 +00:00
										 |  |  |                 # Probably another Python process already created the dir. | 
					
						
							| 
									
										
										
										
											2011-10-28 16:06:23 +02:00
										 |  |  |                 continue | 
					
						
							| 
									
										
										
										
											2012-10-16 07:47:34 -04:00
										 |  |  |             except OSError as exc: | 
					
						
							|  |  |  |                 # Could be a permission error, read-only filesystem: just forget | 
					
						
							|  |  |  |                 # about writing the data. | 
					
						
							|  |  |  |                 _verbose_message('could not create {!r}: {!r}', parent, exc) | 
					
						
							| 
									
										
										
										
											2011-10-28 16:06:23 +02:00
										 |  |  |                 return | 
					
						
							| 
									
										
										
										
											2010-06-28 04:57:24 +00:00
										 |  |  |         try: | 
					
						
							| 
									
										
										
										
											2012-08-24 13:48:39 -04:00
										 |  |  |             _write_atomic(path, data, _mode) | 
					
						
							| 
									
										
										
										
											2012-05-04 13:52:49 -04:00
										 |  |  |             _verbose_message('created {!r}', path) | 
					
						
							| 
									
										
										
										
											2012-10-16 07:47:34 -04:00
										 |  |  |         except OSError as exc: | 
					
						
							|  |  |  |             # Same as above: just don't write the bytecode. | 
					
						
							|  |  |  |             _verbose_message('could not create {!r}: {!r}', path, exc) | 
					
						
							| 
									
										
										
										
											2010-06-28 04:57:24 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-25 02:31:37 +02:00
										 |  |  | class SourcelessFileLoader(FileLoader, _LoaderBasics): | 
					
						
							| 
									
										
										
										
											2009-02-21 05:41:15 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-03 21:48:25 +00:00
										 |  |  |     """Loader which handles sourceless file imports.""" | 
					
						
							| 
									
										
										
										
											2009-02-21 05:41:15 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def get_code(self, fullname): | 
					
						
							| 
									
										
										
										
											2010-07-03 21:48:25 +00:00
										 |  |  |         path = self.get_filename(fullname) | 
					
						
							|  |  |  |         data = self.get_data(path) | 
					
						
							| 
									
										
										
										
											2013-01-11 18:09:25 -05:00
										 |  |  |         bytes_data = _validate_bytecode_header(data, name=fullname, path=path) | 
					
						
							|  |  |  |         return _compile_bytecode(bytes_data, name=fullname, bytecode_path=path) | 
					
						
							| 
									
										
										
										
											2009-01-18 00:24:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-03 21:48:25 +00:00
										 |  |  |     def get_source(self, fullname): | 
					
						
							|  |  |  |         """Return None as there is no source code.""" | 
					
						
							|  |  |  |         return None | 
					
						
							| 
									
										
										
										
											2009-01-18 00:24:28 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-08-10 13:47:54 -04:00
										 |  |  | # Filled in by _setup(). | 
					
						
							|  |  |  | EXTENSION_SUFFIXES = [] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-22 19:58:33 -04:00
										 |  |  | class ExtensionFileLoader: | 
					
						
							| 
									
										
										
										
											2009-03-12 22:37:06 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     """Loader for extension modules.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     The constructor is designed to work with FileFinder. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-03 21:48:25 +00:00
										 |  |  |     def __init__(self, name, path): | 
					
						
							| 
									
										
										
										
											2012-04-22 19:58:33 -04:00
										 |  |  |         self.name = name | 
					
						
							|  |  |  |         self.path = path | 
					
						
							| 
									
										
										
										
											2009-03-12 22:37:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-04 15:06:49 -07:00
										 |  |  |     def __eq__(self, other): | 
					
						
							|  |  |  |         return (self.__class__ == other.__class__ and | 
					
						
							|  |  |  |                 self.__dict__ == other.__dict__) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def __hash__(self): | 
					
						
							|  |  |  |         return hash(self.name) ^ hash(self.path) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-12 22:37:06 +00:00
										 |  |  |     @_check_name | 
					
						
							|  |  |  |     def load_module(self, fullname): | 
					
						
							|  |  |  |         """Load an extension module.""" | 
					
						
							| 
									
										
										
										
											2014-01-06 20:49:04 -07:00
										 |  |  |         # Once an exec_module() implementation is added we can also | 
					
						
							|  |  |  |         # add a deprecation warning here. | 
					
						
							| 
									
										
										
										
											2013-11-29 11:00:11 -05:00
										 |  |  |         with _ManageReload(fullname): | 
					
						
							|  |  |  |             module = _call_with_frames_removed(_imp.load_dynamic, | 
					
						
							|  |  |  |                                                fullname, self.path) | 
					
						
							|  |  |  |         _verbose_message('extension module loaded from {!r}', self.path) | 
					
						
							|  |  |  |         is_package = self.is_package(fullname) | 
					
						
							|  |  |  |         if is_package and not hasattr(module, '__path__'): | 
					
						
							|  |  |  |             module.__path__ = [_path_split(self.path)[0]] | 
					
						
							|  |  |  |         module.__loader__ = self | 
					
						
							|  |  |  |         module.__package__ = module.__name__ | 
					
						
							|  |  |  |         if not is_package: | 
					
						
							|  |  |  |             module.__package__ = module.__package__.rpartition('.')[0] | 
					
						
							|  |  |  |         return module | 
					
						
							| 
									
										
										
										
											2009-03-12 22:37:06 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def is_package(self, fullname): | 
					
						
							| 
									
										
										
										
											2012-08-10 16:21:35 -07:00
										 |  |  |         """Return True if the extension module is a package.""" | 
					
						
							| 
									
										
										
										
											2012-08-10 13:47:54 -04:00
										 |  |  |         file_name = _path_split(self.path)[1] | 
					
						
							| 
									
										
										
										
											2012-08-10 11:53:54 -07:00
										 |  |  |         return any(file_name == '__init__' + suffix | 
					
						
							|  |  |  |                    for suffix in EXTENSION_SUFFIXES) | 
					
						
							| 
									
										
										
										
											2009-03-12 22:37:06 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def get_code(self, fullname): | 
					
						
							|  |  |  |         """Return None as an extension module cannot create a code object.""" | 
					
						
							|  |  |  |         return None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def get_source(self, fullname): | 
					
						
							|  |  |  |         """Return None as extension modules have no source code.""" | 
					
						
							|  |  |  |         return None | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-03 12:08:55 -06:00
										 |  |  |     @_check_name | 
					
						
							|  |  |  |     def get_filename(self, fullname): | 
					
						
							|  |  |  |         """Return the path to the source file as found by the finder.""" | 
					
						
							|  |  |  |         return self.path | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-12 22:37:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-24 20:21:04 -04:00
										 |  |  | class _NamespacePath: | 
					
						
							|  |  |  |     """Represents a namespace package's path.  It uses the module name
 | 
					
						
							|  |  |  |     to find its parent module, and from there it looks up the parent's | 
					
						
							|  |  |  |     __path__.  When this changes, the module's own path is recomputed, | 
					
						
							| 
									
										
										
										
											2012-11-12 16:48:17 -05:00
										 |  |  |     using path_finder.  For top-level modules, the parent module's path | 
					
						
							| 
									
										
										
										
											2012-05-24 20:21:04 -04:00
										 |  |  |     is sys.path."""
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def __init__(self, name, path, path_finder): | 
					
						
							|  |  |  |         self._name = name | 
					
						
							|  |  |  |         self._path = path | 
					
						
							|  |  |  |         self._last_parent_path = tuple(self._get_parent_path()) | 
					
						
							|  |  |  |         self._path_finder = path_finder | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def _find_parent_path_names(self): | 
					
						
							|  |  |  |         """Returns a tuple of (parent-module-name, parent-path-attr-name)""" | 
					
						
							|  |  |  |         parent, dot, me = self._name.rpartition('.') | 
					
						
							|  |  |  |         if dot == '': | 
					
						
							|  |  |  |             # This is a top-level module. sys.path contains the parent path. | 
					
						
							|  |  |  |             return 'sys', 'path' | 
					
						
							|  |  |  |         # Not a top-level module. parent-module.__path__ contains the | 
					
						
							|  |  |  |         #  parent path. | 
					
						
							|  |  |  |         return parent, '__path__' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def _get_parent_path(self): | 
					
						
							|  |  |  |         parent_module_name, path_attr_name = self._find_parent_path_names() | 
					
						
							|  |  |  |         return getattr(sys.modules[parent_module_name], path_attr_name) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def _recalculate(self): | 
					
						
							|  |  |  |         # If the parent's path has changed, recalculate _path | 
					
						
							|  |  |  |         parent_path = tuple(self._get_parent_path()) # Make a copy | 
					
						
							|  |  |  |         if parent_path != self._last_parent_path: | 
					
						
							| 
									
										
										
										
											2013-11-22 09:05:39 -07:00
										 |  |  |             spec = self._path_finder(self._name, parent_path) | 
					
						
							| 
									
										
										
										
											2012-05-24 20:21:04 -04:00
										 |  |  |             # Note that no changes are made if a loader is returned, but we | 
					
						
							|  |  |  |             #  do remember the new parent path | 
					
						
							| 
									
										
										
										
											2013-11-22 09:05:39 -07:00
										 |  |  |             if spec is not None and spec.loader is None: | 
					
						
							|  |  |  |                 if spec.submodule_search_locations: | 
					
						
							|  |  |  |                     self._path = spec.submodule_search_locations | 
					
						
							| 
									
										
										
										
											2012-05-24 20:21:04 -04:00
										 |  |  |             self._last_parent_path = parent_path     # Save the copy | 
					
						
							|  |  |  |         return self._path | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def __iter__(self): | 
					
						
							|  |  |  |         return iter(self._recalculate()) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def __len__(self): | 
					
						
							|  |  |  |         return len(self._recalculate()) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def __repr__(self): | 
					
						
							| 
									
										
										
										
											2013-07-12 11:04:23 -04:00
										 |  |  |         return '_NamespacePath({!r})'.format(self._path) | 
					
						
							| 
									
										
										
										
											2012-05-24 20:21:04 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def __contains__(self, item): | 
					
						
							|  |  |  |         return item in self._recalculate() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def append(self, item): | 
					
						
							|  |  |  |         self._path.append(item) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-30 14:55:29 -04:00
										 |  |  | # We use this exclusively in module_from_spec() for backward-compatibility. | 
					
						
							| 
									
										
										
										
											2013-11-22 09:05:39 -07:00
										 |  |  | class _NamespaceLoader: | 
					
						
							| 
									
										
										
										
											2012-05-24 20:21:04 -04:00
										 |  |  |     def __init__(self, name, path, path_finder): | 
					
						
							|  |  |  |         self._path = _NamespacePath(name, path, path_finder) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @classmethod | 
					
						
							|  |  |  |     def module_repr(cls, module): | 
					
						
							| 
									
										
										
										
											2014-01-06 20:49:04 -07:00
										 |  |  |         """Return repr for the module.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         The method is deprecated.  The import machinery does the job itself. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2013-07-12 11:04:23 -04:00
										 |  |  |         return '<module {!r} (namespace)>'.format(module.__name__) | 
					
						
							| 
									
										
										
										
											2012-05-24 20:21:04 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-16 14:56:58 -04:00
										 |  |  |     def is_package(self, fullname): | 
					
						
							|  |  |  |         return True | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def get_source(self, fullname): | 
					
						
							|  |  |  |         return '' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def get_code(self, fullname): | 
					
						
							|  |  |  |         return compile('', '<string>', 'exec', dont_inherit=True) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-09 11:39:21 -05:00
										 |  |  |     def create_module(self, spec): | 
					
						
							|  |  |  |         """Use default semantics for module creation.""" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-06 20:49:04 -07:00
										 |  |  |     def exec_module(self, module): | 
					
						
							|  |  |  |         pass | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-31 18:56:47 -04:00
										 |  |  |     def load_module(self, fullname): | 
					
						
							| 
									
										
										
										
											2014-01-06 20:49:04 -07:00
										 |  |  |         """Load a namespace module.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         This method is deprecated.  Use exec_module() instead. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         # The import system never calls this method. | 
					
						
							| 
									
										
										
										
											2012-05-24 20:21:04 -04:00
										 |  |  |         _verbose_message('namespace module loaded with path {!r}', self._path) | 
					
						
							| 
									
										
										
										
											2013-11-22 09:05:39 -07:00
										 |  |  |         return _load_module_shim(self, fullname) | 
					
						
							| 
									
										
										
										
											2012-05-24 20:21:04 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-12 22:37:06 +00:00
										 |  |  | # Finders ##################################################################### | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class PathFinder: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-08-02 23:03:58 +10:00
										 |  |  |     """Meta path finder for sys.path and package __path__ attributes.""" | 
					
						
							| 
									
										
										
										
											2009-03-12 22:37:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-08-10 12:21:12 -04:00
										 |  |  |     @classmethod | 
					
						
							|  |  |  |     def invalidate_caches(cls): | 
					
						
							|  |  |  |         """Call the invalidate_caches() method on all path entry finders
 | 
					
						
							|  |  |  |         stored in sys.path_importer_caches (where implemented)."""
 | 
					
						
							|  |  |  |         for finder in sys.path_importer_cache.values(): | 
					
						
							|  |  |  |             if hasattr(finder, 'invalidate_caches'): | 
					
						
							|  |  |  |                 finder.invalidate_caches() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-12 22:37:06 +00:00
										 |  |  |     @classmethod | 
					
						
							| 
									
										
										
										
											2012-04-25 20:54:04 -04:00
										 |  |  |     def _path_hooks(cls, path): | 
					
						
							| 
									
										
										
										
											2009-03-12 22:37:06 +00:00
										 |  |  |         """Search sequence of hooks for a finder for 'path'.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         If 'hooks' is false then use sys.path_hooks. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2014-10-10 10:54:28 -04:00
										 |  |  |         if sys.path_hooks is not None and not sys.path_hooks: | 
					
						
							| 
									
										
										
										
											2012-04-25 20:54:04 -04:00
										 |  |  |             _warnings.warn('sys.path_hooks is empty', ImportWarning) | 
					
						
							|  |  |  |         for hook in sys.path_hooks: | 
					
						
							| 
									
										
										
										
											2009-03-12 22:37:06 +00:00
										 |  |  |             try: | 
					
						
							|  |  |  |                 return hook(path) | 
					
						
							|  |  |  |             except ImportError: | 
					
						
							|  |  |  |                 continue | 
					
						
							|  |  |  |         else: | 
					
						
							| 
									
										
										
										
											2012-04-27 15:30:58 -04:00
										 |  |  |             return None | 
					
						
							| 
									
										
										
										
											2009-03-12 22:37:06 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     @classmethod | 
					
						
							| 
									
										
										
										
											2012-04-25 20:54:04 -04:00
										 |  |  |     def _path_importer_cache(cls, path): | 
					
						
							| 
									
										
										
										
											2012-08-02 23:03:58 +10:00
										 |  |  |         """Get the finder for the path entry from sys.path_importer_cache.
 | 
					
						
							| 
									
										
										
										
											2009-03-12 22:37:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-08-02 23:03:58 +10:00
										 |  |  |         If the path entry is not in the cache, find the appropriate finder | 
					
						
							|  |  |  |         and cache it. If no finder is available, store None. | 
					
						
							| 
									
										
										
										
											2009-03-12 22:37:06 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2012-02-16 18:12:00 -05:00
										 |  |  |         if path == '': | 
					
						
							| 
									
										
										
										
											2014-11-21 12:19:28 -05:00
										 |  |  |             try: | 
					
						
							|  |  |  |                 path = _os.getcwd() | 
					
						
							|  |  |  |             except FileNotFoundError: | 
					
						
							|  |  |  |                 # Don't cache the failure as the cwd can easily change to | 
					
						
							|  |  |  |                 # a valid directory later on. | 
					
						
							|  |  |  |                 return None | 
					
						
							| 
									
										
										
										
											2009-03-12 22:37:06 +00:00
										 |  |  |         try: | 
					
						
							|  |  |  |             finder = sys.path_importer_cache[path] | 
					
						
							|  |  |  |         except KeyError: | 
					
						
							| 
									
										
										
										
											2012-02-16 18:12:00 -05:00
										 |  |  |             finder = cls._path_hooks(path) | 
					
						
							| 
									
										
										
										
											2009-03-12 22:37:06 +00:00
										 |  |  |             sys.path_importer_cache[path] = finder | 
					
						
							|  |  |  |         return finder | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-24 20:21:04 -04:00
										 |  |  |     @classmethod | 
					
						
							| 
									
										
										
										
											2013-11-22 09:05:39 -07:00
										 |  |  |     def _legacy_get_spec(cls, fullname, finder): | 
					
						
							| 
									
										
										
										
											2014-01-06 20:49:04 -07:00
										 |  |  |         # This would be a good place for a DeprecationWarning if | 
					
						
							|  |  |  |         # we ended up going that route. | 
					
						
							| 
									
										
										
										
											2013-11-22 09:05:39 -07:00
										 |  |  |         if hasattr(finder, 'find_loader'): | 
					
						
							|  |  |  |             loader, portions = finder.find_loader(fullname) | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             loader = finder.find_module(fullname) | 
					
						
							| 
									
										
										
										
											2014-02-26 18:26:49 -05:00
										 |  |  |             portions = [] | 
					
						
							| 
									
										
										
										
											2013-11-22 09:05:39 -07:00
										 |  |  |         if loader is not None: | 
					
						
							|  |  |  |             return spec_from_loader(fullname, loader) | 
					
						
							|  |  |  |         spec = ModuleSpec(fullname, None) | 
					
						
							|  |  |  |         spec.submodule_search_locations = portions | 
					
						
							|  |  |  |         return spec | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @classmethod | 
					
						
							|  |  |  |     def _get_spec(cls, fullname, path, target=None): | 
					
						
							| 
									
										
										
										
											2012-05-24 20:21:04 -04:00
										 |  |  |         """Find the loader or namespace_path for this module/package name.""" | 
					
						
							|  |  |  |         # If this ends up being a namespace package, namespace_path is | 
					
						
							|  |  |  |         #  the list of paths that will become its __path__ | 
					
						
							|  |  |  |         namespace_path = [] | 
					
						
							|  |  |  |         for entry in path: | 
					
						
							| 
									
										
										
										
											2012-11-20 15:22:51 -05:00
										 |  |  |             if not isinstance(entry, (str, bytes)): | 
					
						
							|  |  |  |                 continue | 
					
						
							| 
									
										
										
										
											2012-05-24 20:21:04 -04:00
										 |  |  |             finder = cls._path_importer_cache(entry) | 
					
						
							|  |  |  |             if finder is not None: | 
					
						
							| 
									
										
										
										
											2013-11-22 09:05:39 -07:00
										 |  |  |                 if hasattr(finder, 'find_spec'): | 
					
						
							|  |  |  |                     spec = finder.find_spec(fullname, target) | 
					
						
							| 
									
										
										
										
											2012-05-24 20:21:04 -04:00
										 |  |  |                 else: | 
					
						
							| 
									
										
										
										
											2013-11-22 09:05:39 -07:00
										 |  |  |                     spec = cls._legacy_get_spec(fullname, finder) | 
					
						
							|  |  |  |                 if spec is None: | 
					
						
							|  |  |  |                     continue | 
					
						
							|  |  |  |                 if spec.loader is not None: | 
					
						
							|  |  |  |                     return spec | 
					
						
							|  |  |  |                 portions = spec.submodule_search_locations | 
					
						
							|  |  |  |                 if portions is None: | 
					
						
							|  |  |  |                     raise ImportError('spec missing loader') | 
					
						
							| 
									
										
										
										
											2012-05-24 20:21:04 -04:00
										 |  |  |                 # This is possibly part of a namespace package. | 
					
						
							|  |  |  |                 #  Remember these path entries (if any) for when we | 
					
						
							|  |  |  |                 #  create a namespace package, and continue iterating | 
					
						
							|  |  |  |                 #  on path. | 
					
						
							|  |  |  |                 namespace_path.extend(portions) | 
					
						
							|  |  |  |         else: | 
					
						
							| 
									
										
										
										
											2013-11-22 09:05:39 -07:00
										 |  |  |             spec = ModuleSpec(fullname, None) | 
					
						
							|  |  |  |             spec.submodule_search_locations = namespace_path | 
					
						
							|  |  |  |             return spec | 
					
						
							| 
									
										
										
										
											2012-05-24 20:21:04 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-12 22:37:06 +00:00
										 |  |  |     @classmethod | 
					
						
							| 
									
										
										
										
											2013-11-22 09:05:39 -07:00
										 |  |  |     def find_spec(cls, fullname, path=None, target=None): | 
					
						
							|  |  |  |         """find the module on sys.path or 'path' based on sys.path_hooks and
 | 
					
						
							| 
									
										
										
										
											2009-03-15 00:53:05 +00:00
										 |  |  |         sys.path_importer_cache."""
 | 
					
						
							| 
									
										
										
										
											2012-04-17 21:41:35 -04:00
										 |  |  |         if path is None: | 
					
						
							| 
									
										
										
										
											2009-03-12 22:37:06 +00:00
										 |  |  |             path = sys.path | 
					
						
							| 
									
										
										
										
											2013-11-22 09:05:39 -07:00
										 |  |  |         spec = cls._get_spec(fullname, path, target) | 
					
						
							|  |  |  |         if spec is None: | 
					
						
							|  |  |  |             return None | 
					
						
							|  |  |  |         elif spec.loader is None: | 
					
						
							|  |  |  |             namespace_path = spec.submodule_search_locations | 
					
						
							| 
									
										
										
										
											2012-05-24 20:21:04 -04:00
										 |  |  |             if namespace_path: | 
					
						
							|  |  |  |                 # We found at least one namespace path.  Return a | 
					
						
							| 
									
										
										
										
											2013-11-22 09:05:39 -07:00
										 |  |  |                 #  spec which can create the namespace package. | 
					
						
							|  |  |  |                 spec.origin = 'namespace' | 
					
						
							|  |  |  |                 spec.submodule_search_locations = _NamespacePath(fullname, namespace_path, cls._get_spec) | 
					
						
							|  |  |  |                 return spec | 
					
						
							| 
									
										
										
										
											2012-05-24 20:21:04 -04:00
										 |  |  |             else: | 
					
						
							|  |  |  |                 return None | 
					
						
							| 
									
										
										
										
											2013-11-22 09:05:39 -07:00
										 |  |  |         else: | 
					
						
							|  |  |  |             return spec | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @classmethod | 
					
						
							|  |  |  |     def find_module(cls, fullname, path=None): | 
					
						
							|  |  |  |         """find the module on sys.path or 'path' based on sys.path_hooks and
 | 
					
						
							| 
									
										
										
										
											2014-01-06 20:49:04 -07:00
										 |  |  |         sys.path_importer_cache. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         This method is deprecated.  Use find_spec() instead. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2013-11-22 09:05:39 -07:00
										 |  |  |         spec = cls.find_spec(fullname, path) | 
					
						
							|  |  |  |         if spec is None: | 
					
						
							|  |  |  |             return None | 
					
						
							|  |  |  |         return spec.loader | 
					
						
							| 
									
										
										
										
											2009-03-12 22:37:06 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-22 19:58:33 -04:00
										 |  |  | class FileFinder: | 
					
						
							| 
									
										
										
										
											2009-01-18 00:24:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-03 21:48:25 +00:00
										 |  |  |     """File-based finder.
 | 
					
						
							| 
									
										
										
										
											2009-01-18 00:24:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-22 19:58:33 -04:00
										 |  |  |     Interactions with the file system are cached for performance, being | 
					
						
							|  |  |  |     refreshed when the directory the finder is handling has been modified. | 
					
						
							| 
									
										
										
										
											2009-01-18 00:24:28 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-16 19:06:55 -04:00
										 |  |  |     def __init__(self, path, *loader_details): | 
					
						
							| 
									
										
										
										
											2012-04-22 19:58:33 -04:00
										 |  |  |         """Initialize with the path to search on and a variable number of
 | 
					
						
							| 
									
										
										
										
											2013-02-16 22:23:48 -07:00
										 |  |  |         2-tuples containing the loader and the file suffixes the loader | 
					
						
							|  |  |  |         recognizes."""
 | 
					
						
							| 
									
										
										
										
											2012-08-10 13:47:54 -04:00
										 |  |  |         loaders = [] | 
					
						
							| 
									
										
										
										
											2013-06-16 19:06:55 -04:00
										 |  |  |         for loader, suffixes in loader_details: | 
					
						
							| 
									
										
										
										
											2012-08-10 13:47:54 -04:00
										 |  |  |             loaders.extend((suffix, loader) for suffix in suffixes) | 
					
						
							|  |  |  |         self._loaders = loaders | 
					
						
							| 
									
										
										
										
											2012-02-20 01:48:16 +01:00
										 |  |  |         # Base (directory) path | 
					
						
							| 
									
										
										
										
											2013-11-01 10:37:57 -04:00
										 |  |  |         self.path = path or '.' | 
					
						
							| 
									
										
										
										
											2012-02-20 01:48:16 +01:00
										 |  |  |         self._path_mtime = -1 | 
					
						
							|  |  |  |         self._path_cache = set() | 
					
						
							| 
									
										
										
										
											2012-02-20 22:06:59 +01:00
										 |  |  |         self._relaxed_path_cache = set() | 
					
						
							| 
									
										
										
										
											2012-02-27 18:15:42 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def invalidate_caches(self): | 
					
						
							|  |  |  |         """Invalidate the directory mtime.""" | 
					
						
							|  |  |  |         self._path_mtime = -1 | 
					
						
							| 
									
										
										
										
											2010-07-03 21:48:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-08-10 17:41:23 -04:00
										 |  |  |     find_module = _find_module_shim | 
					
						
							| 
									
										
										
										
											2012-05-24 20:21:04 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def find_loader(self, fullname): | 
					
						
							| 
									
										
										
										
											2013-11-22 09:05:39 -07:00
										 |  |  |         """Try to find a loader for the specified module, or the namespace
 | 
					
						
							| 
									
										
										
										
											2014-01-06 20:49:04 -07:00
										 |  |  |         package portions. Returns (loader, list-of-portions). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         This method is deprecated.  Use find_spec() instead. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2013-11-22 09:05:39 -07:00
										 |  |  |         spec = self.find_spec(fullname) | 
					
						
							|  |  |  |         if spec is None: | 
					
						
							|  |  |  |             return None, [] | 
					
						
							|  |  |  |         return spec.loader, spec.submodule_search_locations or [] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-18 23:35:15 -07:00
										 |  |  |     def _get_spec(self, loader_class, fullname, path, smsl, target): | 
					
						
							| 
									
										
										
										
											2013-11-22 09:05:39 -07:00
										 |  |  |         loader = loader_class(fullname, path) | 
					
						
							| 
									
										
										
										
											2013-12-18 23:35:15 -07:00
										 |  |  |         return spec_from_file_location(fullname, path, loader=loader, | 
					
						
							|  |  |  |                                        submodule_search_locations=smsl) | 
					
						
							| 
									
										
										
										
											2013-11-22 09:05:39 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def find_spec(self, fullname, target=None): | 
					
						
							| 
									
										
										
										
											2012-05-24 20:21:04 -04:00
										 |  |  |         """Try to find a loader for the specified module, or the namespace
 | 
					
						
							|  |  |  |         package portions. Returns (loader, list-of-portions)."""
 | 
					
						
							| 
									
										
										
										
											2012-06-24 19:13:55 -04:00
										 |  |  |         is_namespace = False | 
					
						
							| 
									
										
										
										
											2009-02-21 03:15:37 +00:00
										 |  |  |         tail_module = fullname.rpartition('.')[2] | 
					
						
							| 
									
										
										
										
											2012-02-20 01:48:16 +01:00
										 |  |  |         try: | 
					
						
							| 
									
										
										
										
											2013-11-01 14:04:24 -04:00
										 |  |  |             mtime = _path_stat(self.path or _os.getcwd()).st_mtime | 
					
						
							| 
									
										
										
										
											2012-02-20 01:48:16 +01:00
										 |  |  |         except OSError: | 
					
						
							|  |  |  |             mtime = -1 | 
					
						
							| 
									
										
										
										
											2012-02-27 18:15:42 -05:00
										 |  |  |         if mtime != self._path_mtime: | 
					
						
							| 
									
										
										
										
											2012-02-20 01:48:16 +01:00
										 |  |  |             self._fill_cache() | 
					
						
							|  |  |  |             self._path_mtime = mtime | 
					
						
							| 
									
										
										
										
											2012-02-20 22:06:59 +01:00
										 |  |  |         # tail_module keeps the original casing, for __file__ and friends | 
					
						
							|  |  |  |         if _relax_case(): | 
					
						
							|  |  |  |             cache = self._relaxed_path_cache | 
					
						
							|  |  |  |             cache_module = tail_module.lower() | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             cache = self._path_cache | 
					
						
							|  |  |  |             cache_module = tail_module | 
					
						
							| 
									
										
										
										
											2012-04-14 18:37:07 -04:00
										 |  |  |         # Check if the module is the name of a directory (and thus a package). | 
					
						
							| 
									
										
										
										
											2012-02-20 22:06:59 +01:00
										 |  |  |         if cache_module in cache: | 
					
						
							| 
									
										
										
										
											2012-02-20 01:48:16 +01:00
										 |  |  |             base_path = _path_join(self.path, tail_module) | 
					
						
							| 
									
										
										
										
											2013-11-22 09:05:39 -07:00
										 |  |  |             for suffix, loader_class in self._loaders: | 
					
						
							| 
									
										
										
										
											2013-10-18 13:24:13 -04:00
										 |  |  |                 init_filename = '__init__' + suffix | 
					
						
							|  |  |  |                 full_path = _path_join(base_path, init_filename) | 
					
						
							|  |  |  |                 if _path_isfile(full_path): | 
					
						
							| 
									
										
										
										
											2013-11-22 09:05:39 -07:00
										 |  |  |                     return self._get_spec(loader_class, fullname, full_path, [base_path], target) | 
					
						
							| 
									
										
										
										
											2013-10-18 13:24:13 -04:00
										 |  |  |             else: | 
					
						
							|  |  |  |                 # If a namespace package, return the path if we don't | 
					
						
							|  |  |  |                 #  find a module in the next section. | 
					
						
							|  |  |  |                 is_namespace = _path_isdir(base_path) | 
					
						
							| 
									
										
										
										
											2012-04-14 18:37:07 -04:00
										 |  |  |         # Check for a file w/ a proper suffix exists. | 
					
						
							| 
									
										
										
										
											2013-11-22 09:05:39 -07:00
										 |  |  |         for suffix, loader_class in self._loaders: | 
					
						
							| 
									
										
										
										
											2013-04-01 13:10:51 -04:00
										 |  |  |             full_path = _path_join(self.path, tail_module + suffix) | 
					
						
							|  |  |  |             _verbose_message('trying {}'.format(full_path), verbosity=2) | 
					
						
							| 
									
										
										
										
											2012-02-20 22:06:59 +01:00
										 |  |  |             if cache_module + suffix in cache: | 
					
						
							| 
									
										
										
										
											2012-02-20 01:48:16 +01:00
										 |  |  |                 if _path_isfile(full_path): | 
					
						
							| 
									
										
										
										
											2013-11-22 09:05:39 -07:00
										 |  |  |                     return self._get_spec(loader_class, fullname, full_path, None, target) | 
					
						
							| 
									
										
										
										
											2012-06-24 19:13:55 -04:00
										 |  |  |         if is_namespace: | 
					
						
							| 
									
										
										
										
											2013-04-01 13:10:51 -04:00
										 |  |  |             _verbose_message('possible namespace for {}'.format(base_path)) | 
					
						
							| 
									
										
										
										
											2013-11-22 09:05:39 -07:00
										 |  |  |             spec = ModuleSpec(fullname, None) | 
					
						
							|  |  |  |             spec.submodule_search_locations = [base_path] | 
					
						
							|  |  |  |             return spec | 
					
						
							|  |  |  |         return None | 
					
						
							| 
									
										
										
										
											2009-02-21 03:31:35 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-20 01:48:16 +01:00
										 |  |  |     def _fill_cache(self): | 
					
						
							|  |  |  |         """Fill the cache of potential modules and packages for this directory.""" | 
					
						
							|  |  |  |         path = self.path | 
					
						
							| 
									
										
										
										
											2012-08-20 13:18:15 +10:00
										 |  |  |         try: | 
					
						
							| 
									
										
										
										
											2013-10-18 12:01:06 -04:00
										 |  |  |             contents = _os.listdir(path or _os.getcwd()) | 
					
						
							| 
									
										
										
										
											2013-01-11 15:40:12 -05:00
										 |  |  |         except (FileNotFoundError, PermissionError, NotADirectoryError): | 
					
						
							|  |  |  |             # Directory has either been removed, turned into a file, or made | 
					
						
							|  |  |  |             # unreadable. | 
					
						
							| 
									
										
										
										
											2012-08-20 13:18:15 +10:00
										 |  |  |             contents = [] | 
					
						
							| 
									
										
										
										
											2012-02-20 22:06:59 +01:00
										 |  |  |         # We store two cached versions, to handle runtime changes of the | 
					
						
							|  |  |  |         # PYTHONCASEOK environment variable. | 
					
						
							| 
									
										
										
										
											2012-04-20 12:53:14 -04:00
										 |  |  |         if not sys.platform.startswith('win'): | 
					
						
							|  |  |  |             self._path_cache = set(contents) | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             # Windows users can import modules with case-insensitive file | 
					
						
							|  |  |  |             # suffixes (for legacy reasons). Make the suffix lowercase here | 
					
						
							|  |  |  |             # so it's done once instead of for every import. This is safe as | 
					
						
							|  |  |  |             # the specified suffixes to check against are always specified in a | 
					
						
							|  |  |  |             # case-sensitive manner. | 
					
						
							|  |  |  |             lower_suffix_contents = set() | 
					
						
							|  |  |  |             for item in contents: | 
					
						
							|  |  |  |                 name, dot, suffix = item.partition('.') | 
					
						
							|  |  |  |                 if dot: | 
					
						
							|  |  |  |                     new_name = '{}.{}'.format(name, suffix.lower()) | 
					
						
							|  |  |  |                 else: | 
					
						
							|  |  |  |                     new_name = name | 
					
						
							|  |  |  |                 lower_suffix_contents.add(new_name) | 
					
						
							|  |  |  |             self._path_cache = lower_suffix_contents | 
					
						
							| 
									
										
										
										
											2012-05-04 13:52:49 -04:00
										 |  |  |         if sys.platform.startswith(_CASE_INSENSITIVE_PLATFORMS): | 
					
						
							| 
									
										
										
										
											2013-02-25 15:40:33 +02:00
										 |  |  |             self._relaxed_path_cache = {fn.lower() for fn in contents} | 
					
						
							| 
									
										
										
										
											2012-02-20 01:48:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-22 19:58:33 -04:00
										 |  |  |     @classmethod | 
					
						
							|  |  |  |     def path_hook(cls, *loader_details): | 
					
						
							|  |  |  |         """A class method which returns a closure to use on sys.path_hook
 | 
					
						
							|  |  |  |         which will return an instance using the specified loaders and the path | 
					
						
							|  |  |  |         called on the closure. | 
					
						
							| 
									
										
										
										
											2012-02-20 01:48:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-22 19:58:33 -04:00
										 |  |  |         If the path called on the closure is not a directory, ImportError is | 
					
						
							|  |  |  |         raised. | 
					
						
							| 
									
										
										
										
											2009-02-02 19:19:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-22 19:58:33 -04:00
										 |  |  |         """
 | 
					
						
							|  |  |  |         def path_hook_for_FileFinder(path): | 
					
						
							|  |  |  |             """Path hook for importlib.machinery.FileFinder.""" | 
					
						
							|  |  |  |             if not _path_isdir(path): | 
					
						
							| 
									
										
										
										
											2013-07-12 11:04:23 -04:00
										 |  |  |                 raise ImportError('only directories are supported', path=path) | 
					
						
							| 
									
										
										
										
											2012-04-22 19:58:33 -04:00
										 |  |  |             return cls(path, *loader_details) | 
					
						
							| 
									
										
										
										
											2009-02-02 19:19:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-22 19:58:33 -04:00
										 |  |  |         return path_hook_for_FileFinder | 
					
						
							| 
									
										
										
										
											2009-02-02 19:19:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-06-23 02:12:56 +02:00
										 |  |  |     def __repr__(self): | 
					
						
							| 
									
										
										
										
											2013-07-12 11:04:23 -04:00
										 |  |  |         return 'FileFinder({!r})'.format(self.path) | 
					
						
							| 
									
										
										
										
											2009-02-02 19:19:36 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-12 22:37:06 +00:00
										 |  |  | # Import itself ############################################################### | 
					
						
							| 
									
										
										
										
											2009-02-02 19:19:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-12 22:37:06 +00:00
										 |  |  | class _ImportLockContext: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     """Context manager for the import lock.""" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def __enter__(self): | 
					
						
							|  |  |  |         """Acquire the import lock.""" | 
					
						
							| 
									
										
										
										
											2012-04-15 16:08:47 -04:00
										 |  |  |         _imp.acquire_lock() | 
					
						
							| 
									
										
										
										
											2009-03-12 22:37:06 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def __exit__(self, exc_type, exc_value, exc_traceback): | 
					
						
							|  |  |  |         """Release the import lock regardless of any raised exceptions.""" | 
					
						
							| 
									
										
										
										
											2012-04-15 16:08:47 -04:00
										 |  |  |         _imp.release_lock() | 
					
						
							| 
									
										
										
										
											2009-03-12 22:37:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-18 00:24:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-16 13:43:41 -05:00
										 |  |  | def _resolve_name(name, package, level): | 
					
						
							|  |  |  |     """Resolve a relative module name to an absolute one.""" | 
					
						
							| 
									
										
										
										
											2012-02-24 21:48:17 -08:00
										 |  |  |     bits = package.rsplit('.', level - 1) | 
					
						
							| 
									
										
										
										
											2012-02-24 11:20:54 -05:00
										 |  |  |     if len(bits) < level: | 
					
						
							|  |  |  |         raise ValueError('attempted relative import beyond top-level package') | 
					
						
							|  |  |  |     base = bits[0] | 
					
						
							| 
									
										
										
										
											2012-07-07 13:16:44 +02:00
										 |  |  |     return '{}.{}'.format(base, name) if name else base | 
					
						
							| 
									
										
										
										
											2012-02-16 13:43:41 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-06 20:49:04 -07:00
										 |  |  | def _find_spec_legacy(finder, name, path): | 
					
						
							|  |  |  |     # This would be a good place for a DeprecationWarning if | 
					
						
							|  |  |  |     # we ended up going that route. | 
					
						
							|  |  |  |     loader = finder.find_module(name, path) | 
					
						
							|  |  |  |     if loader is None: | 
					
						
							|  |  |  |         return None | 
					
						
							|  |  |  |     return spec_from_loader(name, loader) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-22 09:05:39 -07:00
										 |  |  | def _find_spec(name, path, target=None): | 
					
						
							| 
									
										
										
										
											2012-02-16 13:43:41 -05:00
										 |  |  |     """Find a module's loader.""" | 
					
						
							| 
									
										
										
										
											2014-10-10 10:54:28 -04:00
										 |  |  |     if sys.meta_path is not None and not sys.meta_path: | 
					
						
							| 
									
										
										
										
											2012-04-27 14:01:58 -04:00
										 |  |  |         _warnings.warn('sys.meta_path is empty', ImportWarning) | 
					
						
							| 
									
										
										
										
											2013-11-22 09:05:39 -07:00
										 |  |  |     # We check sys.modules here for the reload case.  While a passed-in | 
					
						
							|  |  |  |     # target will usually indicate a reload there is no guarantee, whereas | 
					
						
							|  |  |  |     # sys.modules provides one. | 
					
						
							| 
									
										
										
										
											2013-10-31 22:22:15 -06:00
										 |  |  |     is_reload = name in sys.modules | 
					
						
							| 
									
										
										
										
											2012-04-27 14:01:58 -04:00
										 |  |  |     for finder in sys.meta_path: | 
					
						
							| 
									
										
										
										
											2012-05-17 18:55:59 +02:00
										 |  |  |         with _ImportLockContext(): | 
					
						
							| 
									
										
										
										
											2013-11-22 09:05:39 -07:00
										 |  |  |             try: | 
					
						
							|  |  |  |                 find_spec = finder.find_spec | 
					
						
							|  |  |  |             except AttributeError: | 
					
						
							| 
									
										
										
										
											2014-01-06 20:49:04 -07:00
										 |  |  |                 spec = _find_spec_legacy(finder, name, path) | 
					
						
							|  |  |  |                 if spec is None: | 
					
						
							| 
									
										
										
										
											2013-11-22 09:05:39 -07:00
										 |  |  |                     continue | 
					
						
							| 
									
										
										
										
											2012-02-16 13:43:41 -05:00
										 |  |  |             else: | 
					
						
							| 
									
										
										
										
											2013-11-22 09:05:39 -07:00
										 |  |  |                 spec = find_spec(name, path, target) | 
					
						
							|  |  |  |         if spec is not None: | 
					
						
							|  |  |  |             # The parent import may have already imported this module. | 
					
						
							|  |  |  |             if not is_reload and name in sys.modules: | 
					
						
							|  |  |  |                 module = sys.modules[name] | 
					
						
							| 
									
										
										
										
											2013-10-31 22:22:15 -06:00
										 |  |  |                 try: | 
					
						
							| 
									
										
										
										
											2013-11-22 09:05:39 -07:00
										 |  |  |                     __spec__ = module.__spec__ | 
					
						
							| 
									
										
										
										
											2013-10-31 22:22:15 -06:00
										 |  |  |                 except AttributeError: | 
					
						
							| 
									
										
										
										
											2013-11-22 09:05:39 -07:00
										 |  |  |                     # We use the found spec since that is the one that | 
					
						
							|  |  |  |                     # we would have used if the parent module hadn't | 
					
						
							|  |  |  |                     # beaten us to the punch. | 
					
						
							|  |  |  |                     return spec | 
					
						
							|  |  |  |                 else: | 
					
						
							|  |  |  |                     if __spec__ is None: | 
					
						
							|  |  |  |                         return spec | 
					
						
							|  |  |  |                     else: | 
					
						
							|  |  |  |                         return __spec__ | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 return spec | 
					
						
							| 
									
										
										
										
											2012-02-16 13:43:41 -05:00
										 |  |  |     else: | 
					
						
							|  |  |  |         return None | 
					
						
							| 
									
										
										
										
											2009-02-15 05:48:13 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-11-18 03:03:04 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-16 13:43:41 -05:00
										 |  |  | def _sanity_check(name, package, level): | 
					
						
							|  |  |  |     """Verify arguments are "sane".""" | 
					
						
							| 
									
										
										
										
											2012-02-23 18:18:48 -05:00
										 |  |  |     if not isinstance(name, str): | 
					
						
							| 
									
										
										
										
											2013-07-12 11:04:23 -04:00
										 |  |  |         raise TypeError('module name must be str, not {}'.format(type(name))) | 
					
						
							| 
									
										
										
										
											2012-02-22 18:33:05 -05:00
										 |  |  |     if level < 0: | 
					
						
							|  |  |  |         raise ValueError('level must be >= 0') | 
					
						
							| 
									
										
										
										
											2009-02-07 01:15:27 +00:00
										 |  |  |     if package: | 
					
						
							| 
									
										
										
										
											2012-02-23 18:18:48 -05:00
										 |  |  |         if not isinstance(package, str): | 
					
						
							| 
									
										
										
										
											2013-07-12 11:04:23 -04:00
										 |  |  |             raise TypeError('__package__ not set to a string') | 
					
						
							| 
									
										
										
										
											2009-02-07 01:15:27 +00:00
										 |  |  |         elif package not in sys.modules: | 
					
						
							| 
									
										
										
										
											2013-07-12 11:04:23 -04:00
										 |  |  |             msg = ('Parent module {!r} not loaded, cannot perform relative ' | 
					
						
							|  |  |  |                    'import') | 
					
						
							| 
									
										
										
										
											2009-02-07 01:15:27 +00:00
										 |  |  |             raise SystemError(msg.format(package)) | 
					
						
							|  |  |  |     if not name and level == 0: | 
					
						
							| 
									
										
										
										
											2013-07-12 11:04:23 -04:00
										 |  |  |         raise ValueError('Empty module name') | 
					
						
							| 
									
										
										
										
											2012-02-16 13:43:41 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-06 14:48:18 -04:00
										 |  |  | _ERR_MSG_PREFIX = 'No module named ' | 
					
						
							|  |  |  | _ERR_MSG = _ERR_MSG_PREFIX + '{!r}' | 
					
						
							| 
									
										
										
										
											2012-02-16 13:43:41 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-17 18:55:59 +02:00
										 |  |  | def _find_and_load_unlocked(name, import_): | 
					
						
							| 
									
										
										
										
											2012-02-16 13:43:41 -05:00
										 |  |  |     path = None | 
					
						
							|  |  |  |     parent = name.rpartition('.')[0] | 
					
						
							|  |  |  |     if parent: | 
					
						
							|  |  |  |         if parent not in sys.modules: | 
					
						
							| 
									
										
										
										
											2012-07-31 21:14:18 +10:00
										 |  |  |             _call_with_frames_removed(import_, parent) | 
					
						
							| 
									
										
										
										
											2012-04-02 20:33:56 -04:00
										 |  |  |         # Crazy side-effects! | 
					
						
							|  |  |  |         if name in sys.modules: | 
					
						
							|  |  |  |             return sys.modules[name] | 
					
						
							| 
									
										
										
										
											2012-02-16 13:43:41 -05:00
										 |  |  |         parent_module = sys.modules[parent] | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             path = parent_module.__path__ | 
					
						
							|  |  |  |         except AttributeError: | 
					
						
							| 
									
										
										
										
											2013-11-22 14:52:36 -05:00
										 |  |  |             msg = (_ERR_MSG + '; {!r} is not a package').format(name, parent) | 
					
						
							| 
									
										
										
										
											2014-11-21 20:33:57 +02:00
										 |  |  |             raise ImportError(msg, name=name) from None | 
					
						
							| 
									
										
										
										
											2013-11-22 09:05:39 -07:00
										 |  |  |     spec = _find_spec(name, path) | 
					
						
							|  |  |  |     if spec is None: | 
					
						
							| 
									
										
										
										
											2013-07-06 14:48:18 -04:00
										 |  |  |         raise ImportError(_ERR_MSG.format(name), name=name) | 
					
						
							| 
									
										
										
										
											2013-11-22 09:05:39 -07:00
										 |  |  |     else: | 
					
						
							| 
									
										
										
										
											2014-05-30 14:55:29 -04:00
										 |  |  |         module = _load_unlocked(spec) | 
					
						
							| 
									
										
										
										
											2012-02-22 18:33:05 -05:00
										 |  |  |     if parent: | 
					
						
							|  |  |  |         # Set the module as an attribute on its parent. | 
					
						
							|  |  |  |         parent_module = sys.modules[parent] | 
					
						
							|  |  |  |         setattr(parent_module, name.rpartition('.')[2], module) | 
					
						
							|  |  |  |     return module | 
					
						
							| 
									
										
										
										
											2012-02-16 13:43:41 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-17 18:55:59 +02:00
										 |  |  | def _find_and_load(name, import_): | 
					
						
							|  |  |  |     """Find and load the module, and release the import lock.""" | 
					
						
							| 
									
										
										
										
											2013-11-22 09:05:39 -07:00
										 |  |  |     with _ModuleLockManager(name): | 
					
						
							| 
									
										
										
										
											2012-05-17 18:55:59 +02:00
										 |  |  |         return _find_and_load_unlocked(name, import_) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-16 13:43:41 -05:00
										 |  |  | def _gcd_import(name, package=None, level=0): | 
					
						
							|  |  |  |     """Import and return the module based on its name, the package the call is
 | 
					
						
							|  |  |  |     being made from, and the level adjustment. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     This function represents the greatest common denominator of functionality | 
					
						
							|  |  |  |     between import_module and __import__. This includes setting __package__ if | 
					
						
							|  |  |  |     the loader did not. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     _sanity_check(name, package, level) | 
					
						
							| 
									
										
										
										
											2009-02-06 02:47:33 +00:00
										 |  |  |     if level > 0: | 
					
						
							| 
									
										
										
										
											2012-02-16 13:43:41 -05:00
										 |  |  |         name = _resolve_name(name, package, level) | 
					
						
							| 
									
										
										
										
											2012-05-17 18:55:59 +02:00
										 |  |  |     _imp.acquire_lock() | 
					
						
							|  |  |  |     if name not in sys.modules: | 
					
						
							| 
									
										
										
										
											2012-02-22 18:33:05 -05:00
										 |  |  |         return _find_and_load(name, _gcd_import) | 
					
						
							| 
									
										
										
										
											2012-05-17 18:55:59 +02:00
										 |  |  |     module = sys.modules[name] | 
					
						
							|  |  |  |     if module is None: | 
					
						
							|  |  |  |         _imp.release_lock() | 
					
						
							| 
									
										
										
										
											2013-07-12 11:04:23 -04:00
										 |  |  |         message = ('import of {} halted; ' | 
					
						
							|  |  |  |                    'None in sys.modules'.format(name)) | 
					
						
							| 
									
										
										
										
											2013-07-04 17:48:16 -04:00
										 |  |  |         raise ImportError(message, name=name) | 
					
						
							| 
									
										
										
										
											2012-05-17 18:55:59 +02:00
										 |  |  |     _lock_unlock_module(name) | 
					
						
							|  |  |  |     return module | 
					
						
							| 
									
										
										
										
											2009-02-06 02:47:33 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-23 20:47:57 -05:00
										 |  |  | def _handle_fromlist(module, fromlist, import_): | 
					
						
							| 
									
										
										
										
											2012-02-16 13:43:41 -05:00
										 |  |  |     """Figure out what __import__ should return.
 | 
					
						
							| 
									
										
										
										
											2009-01-18 00:24:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-16 13:43:41 -05:00
										 |  |  |     The import_ parameter is a callable which takes the name of module to | 
					
						
							|  |  |  |     import. It is required to decouple the function from assuming importlib's | 
					
						
							|  |  |  |     import implementation is desired. | 
					
						
							| 
									
										
										
										
											2009-01-18 00:24:28 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2009-02-07 01:15:27 +00:00
										 |  |  |     # The hell that is fromlist ... | 
					
						
							| 
									
										
										
										
											2012-02-23 20:47:57 -05:00
										 |  |  |     # If a package was imported, try to import stuff from fromlist. | 
					
						
							|  |  |  |     if hasattr(module, '__path__'): | 
					
						
							| 
									
										
										
										
											2012-07-10 10:05:00 -04:00
										 |  |  |         if '*' in fromlist: | 
					
						
							| 
									
										
										
										
											2012-02-23 20:47:57 -05:00
										 |  |  |             fromlist = list(fromlist) | 
					
						
							|  |  |  |             fromlist.remove('*') | 
					
						
							| 
									
										
										
										
											2012-07-10 10:05:00 -04:00
										 |  |  |             if hasattr(module, '__all__'): | 
					
						
							|  |  |  |                 fromlist.extend(module.__all__) | 
					
						
							| 
									
										
										
										
											2012-07-07 13:16:44 +02:00
										 |  |  |         for x in fromlist: | 
					
						
							|  |  |  |             if not hasattr(module, x): | 
					
						
							| 
									
										
										
										
											2012-10-10 19:03:46 -04:00
										 |  |  |                 from_name = '{}.{}'.format(module.__name__, x) | 
					
						
							| 
									
										
										
										
											2012-08-17 13:21:16 -04:00
										 |  |  |                 try: | 
					
						
							| 
									
										
										
										
											2012-10-10 19:03:46 -04:00
										 |  |  |                     _call_with_frames_removed(import_, from_name) | 
					
						
							| 
									
										
										
										
											2013-07-04 17:51:50 -04:00
										 |  |  |                 except ImportError as exc: | 
					
						
							| 
									
										
										
										
											2012-08-17 13:21:16 -04:00
										 |  |  |                     # Backwards-compatibility dictates we ignore failed | 
					
						
							| 
									
										
										
										
											2012-08-24 18:25:59 -04:00
										 |  |  |                     # imports triggered by fromlist for modules that don't | 
					
						
							|  |  |  |                     # exist. | 
					
						
							| 
									
										
										
										
											2013-07-06 14:48:18 -04:00
										 |  |  |                     if str(exc).startswith(_ERR_MSG_PREFIX): | 
					
						
							| 
									
										
										
										
											2013-07-04 17:51:50 -04:00
										 |  |  |                         if exc.name == from_name: | 
					
						
							|  |  |  |                             continue | 
					
						
							| 
									
										
										
										
											2012-10-10 19:03:46 -04:00
										 |  |  |                     raise | 
					
						
							| 
									
										
										
										
											2012-02-23 20:47:57 -05:00
										 |  |  |     return module | 
					
						
							| 
									
										
										
										
											2012-02-08 18:50:22 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-16 13:43:41 -05:00
										 |  |  | def _calc___package__(globals): | 
					
						
							|  |  |  |     """Calculate what __package__ should be.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     __package__ is not guaranteed to be defined or could be set to None | 
					
						
							|  |  |  |     to represent that its proper value is unknown. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     package = globals.get('__package__') | 
					
						
							|  |  |  |     if package is None: | 
					
						
							|  |  |  |         package = globals['__name__'] | 
					
						
							|  |  |  |         if '__path__' not in globals: | 
					
						
							|  |  |  |             package = package.rpartition('.')[0] | 
					
						
							|  |  |  |     return package | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-07-28 21:33:05 +02:00
										 |  |  | def _get_supported_file_loaders(): | 
					
						
							|  |  |  |     """Returns a list of file-based module loaders.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-03 12:08:55 -06:00
										 |  |  |     Each item is a tuple (loader, suffixes). | 
					
						
							| 
									
										
										
										
											2012-07-28 21:33:05 +02:00
										 |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2012-08-10 13:47:54 -04:00
										 |  |  |     extensions = ExtensionFileLoader, _imp.extension_suffixes() | 
					
						
							|  |  |  |     source = SourceFileLoader, SOURCE_SUFFIXES | 
					
						
							|  |  |  |     bytecode = SourcelessFileLoader, BYTECODE_SUFFIXES | 
					
						
							| 
									
										
										
										
											2012-07-28 21:33:05 +02:00
										 |  |  |     return [extensions, source, bytecode] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-08-06 16:34:44 -04:00
										 |  |  | def __import__(name, globals=None, locals=None, fromlist=(), level=0): | 
					
						
							| 
									
										
										
										
											2012-02-16 13:43:41 -05:00
										 |  |  |     """Import a module.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     The 'globals' argument is used to infer where the import is occuring from | 
					
						
							|  |  |  |     to handle relative imports. The 'locals' argument is ignored. The | 
					
						
							|  |  |  |     'fromlist' argument specifies what should exist as attributes on the module | 
					
						
							|  |  |  |     being imported (e.g. ``from module import <fromlist>``).  The 'level' | 
					
						
							|  |  |  |     argument represents the package location to import from in a relative | 
					
						
							|  |  |  |     import (e.g. ``from ..pkg import mod`` would have a 'level' of 2). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     if level == 0: | 
					
						
							|  |  |  |         module = _gcd_import(name) | 
					
						
							|  |  |  |     else: | 
					
						
							| 
									
										
										
										
											2012-08-06 16:34:44 -04:00
										 |  |  |         globals_ = globals if globals is not None else {} | 
					
						
							|  |  |  |         package = _calc___package__(globals_) | 
					
						
							| 
									
										
										
										
											2012-02-16 13:43:41 -05:00
										 |  |  |         module = _gcd_import(name, package, level) | 
					
						
							| 
									
										
										
										
											2012-02-23 20:47:57 -05:00
										 |  |  |     if not fromlist: | 
					
						
							|  |  |  |         # Return up to the first dot in 'name'. This is complicated by the fact | 
					
						
							|  |  |  |         # that 'name' may be relative. | 
					
						
							|  |  |  |         if level == 0: | 
					
						
							| 
									
										
										
										
											2012-05-07 21:41:59 +02:00
										 |  |  |             return _gcd_import(name.partition('.')[0]) | 
					
						
							| 
									
										
										
										
											2012-02-23 20:47:57 -05:00
										 |  |  |         elif not name: | 
					
						
							|  |  |  |             return module | 
					
						
							|  |  |  |         else: | 
					
						
							| 
									
										
										
										
											2012-09-28 16:41:39 -04:00
										 |  |  |             # Figure out where to slice the module's name up to the first dot | 
					
						
							|  |  |  |             # in 'name'. | 
					
						
							| 
									
										
										
										
											2012-02-23 20:47:57 -05:00
										 |  |  |             cut_off = len(name) - len(name.partition('.')[0]) | 
					
						
							| 
									
										
										
										
											2012-09-28 16:41:39 -04:00
										 |  |  |             # Slice end needs to be positive to alleviate need to special-case | 
					
						
							|  |  |  |             # when ``'.' not in name``. | 
					
						
							| 
									
										
										
										
											2012-04-14 21:50:00 -04:00
										 |  |  |             return sys.modules[module.__name__[:len(module.__name__)-cut_off]] | 
					
						
							| 
									
										
										
										
											2012-02-23 20:47:57 -05:00
										 |  |  |     else: | 
					
						
							|  |  |  |         return _handle_fromlist(module, fromlist, _gcd_import) | 
					
						
							| 
									
										
										
										
											2012-02-16 13:43:41 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-22 09:05:39 -07:00
										 |  |  | def _builtin_from_name(name): | 
					
						
							|  |  |  |     spec = BuiltinImporter.find_spec(name) | 
					
						
							| 
									
										
										
										
											2013-11-22 11:58:17 -05:00
										 |  |  |     if spec is None: | 
					
						
							|  |  |  |         raise ImportError('no built-in module named ' + name) | 
					
						
							| 
									
										
										
										
											2014-05-30 14:55:29 -04:00
										 |  |  |     return _load_unlocked(spec) | 
					
						
							| 
									
										
										
										
											2013-11-22 09:05:39 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-20 18:04:03 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-15 16:08:47 -04:00
										 |  |  | def _setup(sys_module, _imp_module): | 
					
						
							| 
									
										
										
										
											2012-02-08 18:50:22 -05:00
										 |  |  |     """Setup importlib by importing needed built-in modules and injecting them
 | 
					
						
							|  |  |  |     into the global namespace. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-15 16:08:47 -04:00
										 |  |  |     As sys is needed for sys.modules access and _imp is needed to load built-in | 
					
						
							| 
									
										
										
										
											2012-02-14 18:38:11 -05:00
										 |  |  |     modules, those two modules must be explicitly passed in. | 
					
						
							| 
									
										
										
										
											2012-02-08 18:50:22 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2012-09-25 11:22:59 -04:00
										 |  |  |     global _imp, sys, BYTECODE_SUFFIXES | 
					
						
							| 
									
										
										
										
											2012-04-15 16:08:47 -04:00
										 |  |  |     _imp = _imp_module | 
					
						
							| 
									
										
										
										
											2012-02-08 18:50:22 -05:00
										 |  |  |     sys = sys_module | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-25 11:22:59 -04:00
										 |  |  |     if sys.flags.optimize: | 
					
						
							|  |  |  |         BYTECODE_SUFFIXES = OPTIMIZED_BYTECODE_SUFFIXES | 
					
						
							|  |  |  |     else: | 
					
						
							|  |  |  |         BYTECODE_SUFFIXES = DEBUG_BYTECODE_SUFFIXES | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-22 09:05:39 -07:00
										 |  |  |     # Set up the spec for existing builtin/frozen modules. | 
					
						
							| 
									
										
										
										
											2013-02-01 14:04:12 -05:00
										 |  |  |     module_type = type(sys) | 
					
						
							| 
									
										
										
										
											2013-02-01 15:31:49 -05:00
										 |  |  |     for name, module in sys.modules.items(): | 
					
						
							| 
									
										
										
										
											2013-02-01 14:04:12 -05:00
										 |  |  |         if isinstance(module, module_type): | 
					
						
							| 
									
										
										
										
											2013-11-22 09:05:39 -07:00
										 |  |  |             if name in sys.builtin_module_names: | 
					
						
							|  |  |  |                 loader = BuiltinImporter | 
					
						
							|  |  |  |             elif _imp.is_frozen(name): | 
					
						
							|  |  |  |                 loader = FrozenImporter | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 continue | 
					
						
							|  |  |  |             spec = _spec_from_module(module, loader) | 
					
						
							| 
									
										
										
										
											2014-05-30 14:55:29 -04:00
										 |  |  |             _init_module_attrs(spec, module) | 
					
						
							| 
									
										
										
										
											2012-02-08 18:50:22 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-22 09:05:39 -07:00
										 |  |  |     # Directly load built-in modules needed during bootstrap. | 
					
						
							| 
									
										
										
										
											2012-02-08 18:50:22 -05:00
										 |  |  |     self_module = sys.modules[__name__] | 
					
						
							|  |  |  |     for builtin_name in ('_io', '_warnings', 'builtins', 'marshal'): | 
					
						
							|  |  |  |         if builtin_name not in sys.modules: | 
					
						
							| 
									
										
										
										
											2013-11-22 09:05:39 -07:00
										 |  |  |             builtin_module = _builtin_from_name(builtin_name) | 
					
						
							| 
									
										
										
										
											2012-02-08 18:50:22 -05:00
										 |  |  |         else: | 
					
						
							|  |  |  |             builtin_module = sys.modules[builtin_name] | 
					
						
							|  |  |  |         setattr(self_module, builtin_name, builtin_module) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-22 09:05:39 -07:00
										 |  |  |     # Directly load the os module (needed during bootstrap). | 
					
						
							| 
									
										
										
										
											2012-10-05 03:15:39 +02:00
										 |  |  |     os_details = ('posix', ['/']), ('nt', ['\\', '/']) | 
					
						
							| 
									
										
										
										
											2012-04-20 21:19:53 -04:00
										 |  |  |     for builtin_os, path_separators in os_details: | 
					
						
							| 
									
										
										
										
											2012-04-22 11:45:07 -04:00
										 |  |  |         # Assumption made in _path_join() | 
					
						
							|  |  |  |         assert all(len(sep) == 1 for sep in path_separators) | 
					
						
							| 
									
										
										
										
											2012-04-20 21:19:53 -04:00
										 |  |  |         path_sep = path_separators[0] | 
					
						
							| 
									
										
										
										
											2012-02-08 18:50:22 -05:00
										 |  |  |         if builtin_os in sys.modules: | 
					
						
							|  |  |  |             os_module = sys.modules[builtin_os] | 
					
						
							|  |  |  |             break | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             try: | 
					
						
							| 
									
										
										
										
											2013-11-22 09:05:39 -07:00
										 |  |  |                 os_module = _builtin_from_name(builtin_os) | 
					
						
							| 
									
										
										
										
											2012-02-08 18:50:22 -05:00
										 |  |  |                 break | 
					
						
							|  |  |  |             except ImportError: | 
					
						
							|  |  |  |                 continue | 
					
						
							|  |  |  |     else: | 
					
						
							|  |  |  |         raise ImportError('importlib requires posix or nt') | 
					
						
							| 
									
										
										
										
											2013-11-22 09:05:39 -07:00
										 |  |  |     setattr(self_module, '_os', os_module) | 
					
						
							|  |  |  |     setattr(self_module, 'path_sep', path_sep) | 
					
						
							|  |  |  |     setattr(self_module, 'path_separators', ''.join(path_separators)) | 
					
						
							| 
									
										
										
										
											2012-05-17 18:55:59 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-22 09:05:39 -07:00
										 |  |  |     # Directly load the _thread module (needed during bootstrap). | 
					
						
							| 
									
										
										
										
											2012-05-17 18:55:59 +02:00
										 |  |  |     try: | 
					
						
							| 
									
										
										
										
											2013-11-22 09:05:39 -07:00
										 |  |  |         thread_module = _builtin_from_name('_thread') | 
					
						
							| 
									
										
										
										
											2012-05-17 18:55:59 +02:00
										 |  |  |     except ImportError: | 
					
						
							|  |  |  |         # Python was built without threads | 
					
						
							|  |  |  |         thread_module = None | 
					
						
							| 
									
										
										
										
											2013-11-22 09:05:39 -07:00
										 |  |  |     setattr(self_module, '_thread', thread_module) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Directly load the _weakref module (needed during bootstrap). | 
					
						
							|  |  |  |     weakref_module = _builtin_from_name('_weakref') | 
					
						
							|  |  |  |     setattr(self_module, '_weakref', weakref_module) | 
					
						
							| 
									
										
										
										
											2012-05-17 18:55:59 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-22 09:05:39 -07:00
										 |  |  |     # Directly load the winreg module (needed during bootstrap). | 
					
						
							| 
									
										
										
										
											2012-07-28 21:33:05 +02:00
										 |  |  |     if builtin_os == 'nt': | 
					
						
							| 
									
										
										
										
											2013-11-22 09:05:39 -07:00
										 |  |  |         winreg_module = _builtin_from_name('winreg') | 
					
						
							| 
									
										
										
										
											2012-07-28 21:33:05 +02:00
										 |  |  |         setattr(self_module, '_winreg', winreg_module) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-20 01:48:16 +01:00
										 |  |  |     # Constants | 
					
						
							| 
									
										
										
										
											2012-02-20 13:52:47 +01:00
										 |  |  |     setattr(self_module, '_relax_case', _make_relax_case()) | 
					
						
							| 
									
										
										
										
											2012-08-10 13:47:54 -04:00
										 |  |  |     EXTENSION_SUFFIXES.extend(_imp.extension_suffixes()) | 
					
						
							| 
									
										
										
										
											2012-04-21 18:52:52 -04:00
										 |  |  |     if builtin_os == 'nt': | 
					
						
							| 
									
										
										
										
											2012-05-11 12:58:42 -04:00
										 |  |  |         SOURCE_SUFFIXES.append('.pyw') | 
					
						
							| 
									
										
										
										
											2012-08-10 13:47:54 -04:00
										 |  |  |         if '_d.pyd' in EXTENSION_SUFFIXES: | 
					
						
							| 
									
										
										
										
											2012-08-02 21:45:24 +10:00
										 |  |  |             WindowsRegistryFinder.DEBUG_BUILD = True | 
					
						
							| 
									
										
										
										
											2012-02-17 09:46:48 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-14 18:38:11 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-15 16:08:47 -04:00
										 |  |  | def _install(sys_module, _imp_module): | 
					
						
							| 
									
										
										
										
											2012-05-04 16:47:54 -04:00
										 |  |  |     """Install importlib as the implementation of import.""" | 
					
						
							| 
									
										
										
										
											2012-04-15 16:08:47 -04:00
										 |  |  |     _setup(sys_module, _imp_module) | 
					
						
							| 
									
										
										
										
											2012-07-28 21:33:05 +02:00
										 |  |  |     supported_loaders = _get_supported_file_loaders() | 
					
						
							| 
									
										
										
										
											2012-04-27 15:30:58 -04:00
										 |  |  |     sys.path_hooks.extend([FileFinder.path_hook(*supported_loaders)]) | 
					
						
							| 
									
										
										
										
											2012-07-28 21:33:05 +02:00
										 |  |  |     sys.meta_path.append(BuiltinImporter) | 
					
						
							|  |  |  |     sys.meta_path.append(FrozenImporter) | 
					
						
							|  |  |  |     if _os.__name__ == 'nt': | 
					
						
							| 
									
										
										
										
											2012-08-02 21:45:24 +10:00
										 |  |  |         sys.meta_path.append(WindowsRegistryFinder) | 
					
						
							| 
									
										
										
										
											2012-07-28 21:33:05 +02:00
										 |  |  |     sys.meta_path.append(PathFinder) |