Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit e9103d2

Browse files
committed
Last big re-organization of importlib._bootstrap. Should actually be able to find something in the file now.
1 parent ce43ddf commit e9103d2

1 file changed

Lines changed: 173 additions & 172 deletions

File tree

Lib/importlib/_bootstrap.py

Lines changed: 173 additions & 172 deletions
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,13 @@ def inner(self, name, *args, **kwargs):
173173
return inner
174174

175175

176-
# Finders/loaders #############################################################
176+
def _suffix_list(suffix_type):
177+
"""Return a list of file suffixes based on the imp file type."""
178+
return [suffix[0] for suffix in imp.get_suffixes()
179+
if suffix[2] == suffix_type]
180+
181+
182+
# Loaders #####################################################################
177183

178184
class BuiltinImporter:
179185

@@ -241,100 +247,6 @@ def load_module(cls, fullname):
241247
raise
242248

243249

244-
def _chained_path_hook(*path_hooks):
245-
"""Create a closure which sequentially checks path hooks to see which ones
246-
(if any) can work with a path."""
247-
def path_hook(entry):
248-
"""Check to see if 'entry' matches any of the enclosed path hooks."""
249-
finders = []
250-
for hook in path_hooks:
251-
try:
252-
finder = hook(entry)
253-
except ImportError:
254-
continue
255-
else:
256-
finders.append(finder)
257-
if not finders:
258-
raise ImportError("no finder found")
259-
else:
260-
return _ChainedFinder(*finders)
261-
262-
return path_hook
263-
264-
265-
class _ChainedFinder:
266-
267-
"""Finder that sequentially calls other finders."""
268-
269-
def __init__(self, *finders):
270-
self._finders = finders
271-
272-
def find_module(self, fullname, path=None):
273-
for finder in self._finders:
274-
result = finder.find_module(fullname, path)
275-
if result:
276-
return result
277-
else:
278-
return None
279-
280-
281-
282-
class _ExtensionFileLoader:
283-
284-
"""Loader for extension modules.
285-
286-
The constructor is designed to work with FileFinder.
287-
288-
"""
289-
290-
def __init__(self, name, path, is_pkg):
291-
"""Initialize the loader.
292-
293-
If is_pkg is True then an exception is raised as extension modules
294-
cannot be the __init__ module for an extension module.
295-
296-
"""
297-
self._name = name
298-
self._path = path
299-
if is_pkg:
300-
raise ValueError("extension modules cannot be packages")
301-
302-
@_check_name
303-
@set_package
304-
@set_loader
305-
def load_module(self, fullname):
306-
"""Load an extension module."""
307-
is_reload = fullname in sys.modules
308-
try:
309-
return imp.load_dynamic(fullname, self._path)
310-
except:
311-
if not is_reload and fullname in sys.modules:
312-
del sys.modules[fullname]
313-
raise
314-
315-
@_check_name
316-
def is_package(self, fullname):
317-
"""Return False as an extension module can never be a package."""
318-
return False
319-
320-
@_check_name
321-
def get_code(self, fullname):
322-
"""Return None as an extension module cannot create a code object."""
323-
return None
324-
325-
@_check_name
326-
def get_source(self, fullname):
327-
"""Return None as extension modules have no source code."""
328-
return None
329-
330-
331-
def _suffix_list(suffix_type):
332-
"""Return a list of file suffixes based on the imp file type."""
333-
return [suffix[0] for suffix in imp.get_suffixes()
334-
if suffix[2] == suffix_type]
335-
336-
337-
338250
class PyLoader:
339251

340252
"""Loader base class for Python source.
@@ -584,6 +496,136 @@ def write_bytecode(self, name, data):
584496
raise
585497

586498

499+
class _ExtensionFileLoader:
500+
501+
"""Loader for extension modules.
502+
503+
The constructor is designed to work with FileFinder.
504+
505+
"""
506+
507+
def __init__(self, name, path, is_pkg):
508+
"""Initialize the loader.
509+
510+
If is_pkg is True then an exception is raised as extension modules
511+
cannot be the __init__ module for an extension module.
512+
513+
"""
514+
self._name = name
515+
self._path = path
516+
if is_pkg:
517+
raise ValueError("extension modules cannot be packages")
518+
519+
@_check_name
520+
@set_package
521+
@set_loader
522+
def load_module(self, fullname):
523+
"""Load an extension module."""
524+
is_reload = fullname in sys.modules
525+
try:
526+
return imp.load_dynamic(fullname, self._path)
527+
except:
528+
if not is_reload and fullname in sys.modules:
529+
del sys.modules[fullname]
530+
raise
531+
532+
@_check_name
533+
def is_package(self, fullname):
534+
"""Return False as an extension module can never be a package."""
535+
return False
536+
537+
@_check_name
538+
def get_code(self, fullname):
539+
"""Return None as an extension module cannot create a code object."""
540+
return None
541+
542+
@_check_name
543+
def get_source(self, fullname):
544+
"""Return None as extension modules have no source code."""
545+
return None
546+
547+
548+
# Finders #####################################################################
549+
550+
class PathFinder:
551+
552+
"""Meta path finder for sys.(path|path_hooks|path_importer_cache)."""
553+
554+
@classmethod
555+
def _path_hooks(cls, path, hooks=None):
556+
"""Search sequence of hooks for a finder for 'path'.
557+
558+
If 'hooks' is false then use sys.path_hooks.
559+
560+
"""
561+
if not hooks:
562+
hooks = sys.path_hooks
563+
for hook in hooks:
564+
try:
565+
return hook(path)
566+
except ImportError:
567+
continue
568+
else:
569+
raise ImportError("no path hook found for {0}".format(path))
570+
571+
@classmethod
572+
def _path_importer_cache(cls, path, default=None):
573+
"""Get the finder for the path from sys.path_importer_cache.
574+
575+
If the path is not in the cache, find the appropriate finder and cache
576+
it. If None is cached, get the default finder and cache that
577+
(if applicable).
578+
579+
Because of NullImporter, some finder should be returned. The only
580+
explicit fail case is if None is cached but the path cannot be used for
581+
the default hook, for which ImportError is raised.
582+
583+
"""
584+
try:
585+
finder = sys.path_importer_cache[path]
586+
except KeyError:
587+
finder = cls._path_hooks(path)
588+
sys.path_importer_cache[path] = finder
589+
else:
590+
if finder is None and default:
591+
# Raises ImportError on failure.
592+
finder = default(path)
593+
sys.path_importer_cache[path] = finder
594+
return finder
595+
596+
@classmethod
597+
def find_module(cls, fullname, path=None):
598+
"""Find the module on sys.path or 'path'."""
599+
if not path:
600+
path = sys.path
601+
for entry in path:
602+
try:
603+
finder = cls._path_importer_cache(entry)
604+
except ImportError:
605+
continue
606+
loader = finder.find_module(fullname)
607+
if loader:
608+
return loader
609+
else:
610+
return None
611+
612+
613+
class _ChainedFinder:
614+
615+
"""Finder that sequentially calls other finders."""
616+
617+
def __init__(self, *finders):
618+
self._finders = finders
619+
620+
def find_module(self, fullname, path=None):
621+
for finder in self._finders:
622+
result = finder.find_module(fullname, path)
623+
if result:
624+
return result
625+
else:
626+
return None
627+
628+
587629
class FileFinder:
588630

589631
"""Base class for file finders.
@@ -643,20 +685,6 @@ def find_module(self, fullname, path=None):
643685
return None
644686

645687

646-
class ExtensionFileFinder(FileFinder):
647-
648-
"""Importer for extension files."""
649-
650-
_possible_package = False
651-
_loader = _ExtensionFileLoader
652-
653-
def __init__(self, path_entry):
654-
# Assigning to _suffixes here instead of at the class level because
655-
# imp is not imported at the time of class creation.
656-
self._suffixes = _suffix_list(imp.C_EXTENSION)
657-
super().__init__(path_entry)
658-
659-
660688
class PyFileFinder(FileFinder):
661689

662690
"""Importer for source/bytecode files."""
@@ -683,82 +711,43 @@ def __init__(self, path_entry):
683711
self._suffixes += _suffix_list(imp.PY_COMPILED)
684712

685713

686-
class PathFinder:
687714

688-
"""Meta path finder for sys.(path|path_hooks|path_importer_cache)."""
689715

690-
@classmethod
691-
def _path_hooks(cls, path, hooks=None):
692-
"""Search sequence of hooks for a finder for 'path'.
693-
694-
If 'hooks' is false then use sys.path_hooks.
716+
class ExtensionFileFinder(FileFinder):
695717

696-
"""
697-
if not hooks:
698-
hooks = sys.path_hooks
699-
for hook in hooks:
700-
try:
701-
return hook(path)
702-
except ImportError:
703-
continue
704-
else:
705-
raise ImportError("no path hook found for {0}".format(path))
718+
"""Importer for extension files."""
706719

707-
@classmethod
708-
def _path_importer_cache(cls, path, default=None):
709-
"""Get the finder for the path from sys.path_importer_cache.
720+
_possible_package = False
721+
_loader = _ExtensionFileLoader
710722

711-
If the path is not in the cache, find the appropriate finder and cache
712-
it. If None is cached, get the default finder and cache that
713-
(if applicable).
723+
def __init__(self, path_entry):
724+
# Assigning to _suffixes here instead of at the class level because
725+
# imp is not imported at the time of class creation.
726+
self._suffixes = _suffix_list(imp.C_EXTENSION)
727+
super().__init__(path_entry)
714728

715-
Because of NullImporter, some finder should be returned. The only
716-
explicit fail case is if None is cached but the path cannot be used for
717-
the default hook, for which ImportError is raised.
718729

719-
"""
720-
try:
721-
finder = sys.path_importer_cache[path]
722-
except KeyError:
723-
finder = cls._path_hooks(path)
724-
sys.path_importer_cache[path] = finder
725-
else:
726-
if finder is None and default:
727-
# Raises ImportError on failure.
728-
finder = default(path)
729-
sys.path_importer_cache[path] = finder
730-
return finder
730+
# Import itself ###############################################################
731731

732-
@classmethod
733-
def find_module(cls, fullname, path=None):
734-
"""Find the module on sys.path or 'path'."""
735-
if not path:
736-
path = sys.path
737-
for entry in path:
732+
def _chained_path_hook(*path_hooks):
733+
"""Create a closure which sequentially checks path hooks to see which ones
734+
(if any) can work with a path."""
735+
def path_hook(entry):
736+
"""Check to see if 'entry' matches any of the enclosed path hooks."""
737+
finders = []
738+
for hook in path_hooks:
738739
try:
739-
finder = cls._path_importer_cache(entry)
740+
finder = hook(entry)
740741
except ImportError:
741742
continue
742-
loader = finder.find_module(fullname)
743-
if loader:
744-
return loader
743+
else:
744+
finders.append(finder)
745+
if not finders:
746+
raise ImportError("no finder found")
745747
else:
746-
return None
747-
748-
749-
# Import itself ###############################################################
750-
751-
class _ImportLockContext:
752-
753-
"""Context manager for the import lock."""
754-
755-
def __enter__(self):
756-
"""Acquire the import lock."""
757-
imp.acquire_lock()
748+
return _ChainedFinder(*finders)
758749

759-
def __exit__(self, exc_type, exc_value, exc_traceback):
760-
"""Release the import lock regardless of any raised exceptions."""
761-
imp.release_lock()
750+
return path_hook
762751

763752

764753
_DEFAULT_PATH_HOOK = _chained_path_hook(ExtensionFileFinder, PyPycFileFinder)
@@ -784,6 +773,18 @@ def _path_importer_cache(cls, path):
784773
return super()._path_importer_cache(path, _DEFAULT_PATH_HOOK)
785774

786775

776+
class _ImportLockContext:
777+
778+
"""Context manager for the import lock."""
779+
780+
def __enter__(self):
781+
"""Acquire the import lock."""
782+
imp.acquire_lock()
783+
784+
def __exit__(self, exc_type, exc_value, exc_traceback):
785+
"""Release the import lock regardless of any raised exceptions."""
786+
imp.release_lock()
787+
787788

788789
_IMPLICIT_META_PATH = [BuiltinImporter, FrozenImporter, _DefaultPathFinder]
789790

0 commit comments

Comments
 (0)