Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(16193)

Delta Between Two Patch Sets: Lib/importlib/_bootstrap.py

Issue 18864: Implementation for PEP 451 (importlib.machinery.ModuleSpec)
Left Patch Set: Created 5 years, 7 months ago
Right Patch Set: Created 5 years, 5 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « Doc/library/importlib.rst ('k') | Lib/test/test_importlib/test_spec.py » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 """Core implementation of import. 1 """Core implementation of import.
2 2
3 This module is NOT meant to be directly imported! It has been designed such 3 This module is NOT meant to be directly imported! It has been designed such
4 that it can be bootstrapped into Python as the implementation of import. As 4 that it can be bootstrapped into Python as the implementation of import. As
5 such it requires the injection of specific modules and attributes in order to 5 such it requires the injection of specific modules and attributes in order to
6 work. One should use importlib as the public-facing version of this module. 6 work. One should use importlib as the public-facing version of this module.
7 7
8 """ 8 """
9 # 9 #
10 # IMPORTANT: Whenever making changes to this module, be sure to run 10 # IMPORTANT: Whenever making changes to this module, be sure to run
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
58 if len(path_separators) == 1: 58 if len(path_separators) == 1:
59 front, _, tail = path.rpartition(path_sep) 59 front, _, tail = path.rpartition(path_sep)
60 return front, tail 60 return front, tail
61 for x in reversed(path): 61 for x in reversed(path):
62 if x in path_separators: 62 if x in path_separators:
63 front, tail = path.rsplit(x, maxsplit=1) 63 front, tail = path.rsplit(x, maxsplit=1)
64 return front, tail 64 return front, tail
65 return '', path 65 return '', path
66 66
67 67
68 def _path_stat(path):
69 """Stat the path.
70
71 Made a separate function to make it easier to override in experiments
72 (e.g. cache stat results).
73
74 """
75 return _os.stat(path)
76
77
68 def _path_is_mode_type(path, mode): 78 def _path_is_mode_type(path, mode):
69 """Test whether the path is the specified mode type.""" 79 """Test whether the path is the specified mode type."""
70 try: 80 try:
71 stat_info = _os.stat(path) 81 stat_info = _path_stat(path)
72 except OSError: 82 except OSError:
73 return False 83 return False
74 return (stat_info.st_mode & 0o170000) == mode 84 return (stat_info.st_mode & 0o170000) == mode
75 85
76 86
77 # XXX Could also expose Modules/getpath.c:isfile()
78 def _path_isfile(path): 87 def _path_isfile(path):
79 """Replacement for os.path.isfile.""" 88 """Replacement for os.path.isfile."""
80 return _path_is_mode_type(path, 0o100000) 89 return _path_is_mode_type(path, 0o100000)
81 90
82 91
83 # XXX Could also expose Modules/getpath.c:isdir()
84 def _path_isdir(path): 92 def _path_isdir(path):
85 """Replacement for os.path.isdir.""" 93 """Replacement for os.path.isdir."""
86 if not path: 94 if not path:
87 path = _os.getcwd() 95 path = _os.getcwd()
88 return _path_is_mode_type(path, 0o040000) 96 return _path_is_mode_type(path, 0o040000)
89 97
90 98
91 def _write_atomic(path, data, mode=0o666): 99 def _write_atomic(path, data, mode=0o666):
92 """Best-effort function to write data to a path atomically. 100 """Best-effort function to write data to a path atomically.
93 Be prepared to handle a FileExistsError if concurrent writing of the 101 Be prepared to handle a FileExistsError if concurrent writing of the
(...skipping 17 matching lines...) Expand all
111 119
112 120
113 def _wrap(new, old): 121 def _wrap(new, old):
114 """Simple substitute for functools.update_wrapper.""" 122 """Simple substitute for functools.update_wrapper."""
115 for replace in ['__module__', '__name__', '__qualname__', '__doc__']: 123 for replace in ['__module__', '__name__', '__qualname__', '__doc__']:
116 if hasattr(old, replace): 124 if hasattr(old, replace):
117 setattr(new, replace, getattr(old, replace)) 125 setattr(new, replace, getattr(old, replace))
118 new.__dict__.update(old.__dict__) 126 new.__dict__.update(old.__dict__)
119 127
120 128
129 def _new_module(name):
130 return type(sys)(name)
131
132
121 _code_type = type(_wrap.__code__) 133 _code_type = type(_wrap.__code__)
122 134
135
136
137 class _ManageReload:
138
139 """Manages the possible clean-up of sys.modules for load_module()."""
140
141 def __init__(self, name):
142 self._name = name
143
144 def __enter__(self):
145 self._is_reload = self._name in sys.modules
146
147 def __exit__(self, *args):
148 if any(arg is not None for arg in args) and not self._is_reload:
149 try:
150 del sys.modules[self._name]
151 except KeyError:
152 pass
123 153
124 # Module-level locking ######################################################## 154 # Module-level locking ########################################################
125 155
126 # A dict mapping module names to weakrefs of _ModuleLock instances 156 # A dict mapping module names to weakrefs of _ModuleLock instances
127 _module_locks = {} 157 _module_locks = {}
128 # A dict mapping thread ids to _ModuleLock instances 158 # A dict mapping thread ids to _ModuleLock instances
129 _blocking_on = {} 159 _blocking_on = {}
130 160
131 161
132 class _DeadlockError(RuntimeError): 162 class _DeadlockError(RuntimeError):
(...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after
468 try: 498 try:
469 source_path = source_from_cache(bytecode_path) 499 source_path = source_from_cache(bytecode_path)
470 except (NotImplementedError, ValueError): 500 except (NotImplementedError, ValueError):
471 source_path = bytecode_path[:-1] 501 source_path = bytecode_path[:-1]
472 return source_path if _path_isfile(source_path) else bytecode_path 502 return source_path if _path_isfile(source_path) else bytecode_path
473 503
474 504
475 def _calc_mode(path): 505 def _calc_mode(path):
476 """Calculate the mode permissions for a bytecode file.""" 506 """Calculate the mode permissions for a bytecode file."""
477 try: 507 try:
478 mode = _os.stat(path).st_mode 508 mode = _path_stat(path).st_mode
479 except OSError: 509 except OSError:
480 mode = 0o666 510 mode = 0o666
481 # We always ensure write access so we can update cached files 511 # We always ensure write access so we can update cached files
482 # later even when the source files are read-only on Windows (#6074) 512 # later even when the source files are read-only on Windows (#6074)
483 mode |= 0o200 513 mode |= 0o200
484 return mode 514 return mode
485 515
486 516
487 def _verbose_message(message, *args, verbosity=1): 517 def _verbose_message(message, *args, verbosity=1):
488 """Print the message to stderr if -v/PYTHONVERBOSE is turned on.""" 518 """Print the message to stderr if -v/PYTHONVERBOSE is turned on."""
489 if sys.flags.verbose >= verbosity: 519 if sys.flags.verbose >= verbosity:
490 if not message.startswith(('#', 'import ')): 520 if not message.startswith(('#', 'import ')):
491 message = '# ' + message 521 message = '# ' + message
492 print(message.format(*args), file=sys.stderr) 522 print(message.format(*args), file=sys.stderr)
493
494
495 # XXX Remove.
496 class _ManageReload:
497
498 def __init__(self, name):
499 self._name = name
500
501 def __enter__(self):
502 self._is_reload = self._name in sys.modules
503
504 def __exit__(self, *args):
505 if any(arg is not None for arg in args) and not self._is_reload:
506 try:
507 del sys.modules[self._name]
508 except KeyError:
509 pass
510
511
512 # XXX Remove.
513 # Written as a class only because contextlib is not available.
514 class _ModuleManager(_ManageReload):
515
516 """Context manager which returns the module to be loaded.
517
518 Does the proper unloading from sys.modules upon failure.
519
520 """
521
522 def __init__(self, name, *, reset_name=True):
523 """Prepare the context manager.
524
525 The reset_name argument specifies whether to unconditionally reset
526 the __name__ attribute if the module is found to be a reload.
527 """
528 super().__init__(name)
529 self._reset_name = reset_name
530
531 def __enter__(self):
532 super().__enter__()
533 self._module = sys.modules.get(self._name)
534 if not self._is_reload:
535 # This must be done before open() is called as the 'io' module
536 # implicitly imports 'locale' and would otherwise trigger an
537 # infinite loop.
538 self._module = type(_io)(self._name)
539 # This must be done before putting the module in sys.modules
540 # (otherwise an optimization shortcut in import.c becomes wrong)
541 self._module.__initializing__ = True
542 sys.modules[self._name] = self._module
543 elif self._reset_name:
544 try:
545 self._module.__name__ = self._name
546 except AttributeError:
547 pass
548 return self._module
549
550 def __exit__(self, *args):
551 self._module.__initializing__ = False
552 del self._module
553 super().__exit__(*args)
554
555
556 # XXX Remove.
557 def module_to_load(name, *, reset_name=True):
558 """Return a context manager which provides the module object to load.
559
560 If reset_name is true, reset the module's __name__ to 'name'.
561 """
562 # Hiding _ModuleManager behind a function for better naming.
563 return _ModuleManager(name, reset_name=reset_name)
564
565
566 # XXX Remove.
567 def _init_package_attrs(loader, module):
568 """Set __package__ and __path__ based on what loader.is_package() says."""
569 name = module.__name__
570 try:
571 is_package = loader.is_package(name)
572 except ImportError:
573 pass
574 else:
575 if is_package:
576 module.__package__ = name
577 module.__path__ = []
578 else:
579 module.__package__ = name.rpartition('.')[0]
580
581
582 # XXX Remove.
583 def _init_file_attrs(loader, module):
584 """Set __file__ and __path__ based on loader.get_filename()."""
585 try:
586 module.__file__ = loader.get_filename(module.__name__)
587 except ImportError:
588 pass
589 else:
590 if module.__name__ == module.__package__:
591 module.__path__.append(_path_split(module.__file__)[0])
592
593
594 # XXX Can be moved to importlib.util (and deprecated).
595 def set_package(fxn):
596 """Set __package__ on the returned module."""
597 def set_package_wrapper(*args, **kwargs):
598 module = fxn(*args, **kwargs)
599 if getattr(module, '__package__', None) is None:
600 module.__package__ = module.__name__
601 if not hasattr(module, '__path__'):
602 module.__package__ = module.__package__.rpartition('.')[0]
603 return module
604 _wrap(set_package_wrapper, fxn)
605 return set_package_wrapper
606
607
608 # XXX Can be moved to importlib.util (and deprecated).
609 def set_loader(fxn):
610 """Set __loader__ on the returned module."""
611 def set_loader_wrapper(self, *args, **kwargs):
612 module = fxn(self, *args, **kwargs)
613 if getattr(module, '__loader__', None) is None:
614 module.__loader__ = self
615 return module
616 _wrap(set_loader_wrapper, fxn)
617 return set_loader_wrapper
618 523
619 524
620 def _check_name(method): 525 def _check_name(method):
621 """Decorator to verify that the module being requested matches the one the 526 """Decorator to verify that the module being requested matches the one the
622 loader can handle. 527 loader can handle.
623 528
624 The first argument (self) must define _name which the second argument is 529 The first argument (self) must define _name which the second argument is
625 compared against. If the comparison fails then ImportError is raised. 530 compared against. If the comparison fails then ImportError is raised.
626 531
627 """ 532 """
628 def _check_name_wrapper(self, name=None, *args, **kwargs): 533 def _check_name_wrapper(self, name=None, *args, **kwargs):
629 if name is None: 534 if name is None:
630 name = self.name 535 name = self.name
631 elif self.name != name: 536 elif self.name != name:
632 raise ImportError('loader cannot handle %s' % name, name=name) 537 raise ImportError('loader cannot handle %s' % name, name=name)
633 return method(self, name, *args, **kwargs) 538 return method(self, name, *args, **kwargs)
634 _wrap(_check_name_wrapper, method) 539 _wrap(_check_name_wrapper, method)
635 return _check_name_wrapper 540 return _check_name_wrapper
636 541
637 542
638 def _requires_builtin(fxn): 543 def _requires_builtin(fxn):
639 """Decorator to verify the named module is built-in.""" 544 """Decorator to verify the named module is built-in."""
640 def _requires_builtin_wrapper(self, fullname): 545 def _requires_builtin_wrapper(self, fullname):
641 if fullname not in sys.builtin_module_names: 546 if fullname not in sys.builtin_module_names:
642 raise ImportError('{} is not a built-in module'.format(fullname), 547 raise ImportError('{!r} is not a built-in module'.format(fullname),
643 name=fullname) 548 name=fullname)
644 return fxn(self, fullname) 549 return fxn(self, fullname)
645 _wrap(_requires_builtin_wrapper, fxn) 550 _wrap(_requires_builtin_wrapper, fxn)
646 return _requires_builtin_wrapper 551 return _requires_builtin_wrapper
647 552
648 553
649 def _requires_frozen(fxn): 554 def _requires_frozen(fxn):
650 """Decorator to verify the named module is frozen.""" 555 """Decorator to verify the named module is frozen."""
651 def _requires_frozen_wrapper(self, fullname): 556 def _requires_frozen_wrapper(self, fullname):
652 if not _imp.is_frozen(fullname): 557 if not _imp.is_frozen(fullname):
653 raise ImportError('{} is not a frozen module'.format(fullname), 558 raise ImportError('{!r} is not a frozen module'.format(fullname),
654 name=fullname) 559 name=fullname)
655 return fxn(self, fullname) 560 return fxn(self, fullname)
656 _wrap(_requires_frozen_wrapper, fxn) 561 _wrap(_requires_frozen_wrapper, fxn)
657 return _requires_frozen_wrapper 562 return _requires_frozen_wrapper
658 563
659 564
660 def _find_module_shim(self, fullname): 565 def _find_module_shim(self, fullname):
661 """Try to find a loader for the specified module by delegating to 566 """Try to find a loader for the specified module by delegating to
662 self.find_loader().""" 567 self.find_loader()."""
663 # Call find_loader(). If it returns a string (indicating this 568 # Call find_loader(). If it returns a string (indicating this
664 # is a namespace package portion), generate a warning and 569 # is a namespace package portion), generate a warning and
665 # return None. 570 # return None.
666 loader, portions = self.find_loader(fullname) 571 loader, portions = self.find_loader(fullname)
667 if loader is None and len(portions): 572 if loader is None and len(portions):
668 msg = 'Not importing directory {}: missing __init__' 573 msg = 'Not importing directory {}: missing __init__'
669 _warnings.warn(msg.format(portions[0]), ImportWarning) 574 _warnings.warn(msg.format(portions[0]), ImportWarning)
670 return loader 575 return loader
576
577
578 def _load_module_shim(self, fullname):
579 """Load the specified module into sys.modules and return it."""
580 # XXX Deprecation Warning here...
581 spec = spec_from_loader(fullname, self)
582 methods = _SpecMethods(spec)
583 if fullname in sys.modules:
584 module = sys.modules[fullname]
585 methods.exec(module)
586 return sys.modules[fullname]
587 else:
588 return methods.load()
671 589
672 590
673 def _validate_bytecode_header(data, source_stats=None, name=None, path=None): 591 def _validate_bytecode_header(data, source_stats=None, name=None, path=None):
674 """Validate the header of the passed-in bytecode against source_stats (if 592 """Validate the header of the passed-in bytecode against source_stats (if
675 given) and returning the bytecode that can be compiled by compile(). 593 given) and returning the bytecode that can be compiled by compile().
676 594
677 All other arguments are used to enhance error reporting. 595 All other arguments are used to enhance error reporting.
678 596
679 ImportError is raised when the magic number is incorrect or the bytecode is 597 ImportError is raised when the magic number is incorrect or the bytecode is
680 found to be stale. EOFError is raised when the data is found to be 598 found to be stale. EOFError is raised when the data is found to be
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
766 loader = getattr(module, '__loader__', None) 684 loader = getattr(module, '__loader__', None)
767 if hasattr(loader, 'module_repr'): 685 if hasattr(loader, 'module_repr'):
768 # XXX Deprecation Warning here... 686 # XXX Deprecation Warning here...
769 try: 687 try:
770 return loader.module_repr(module) 688 return loader.module_repr(module)
771 except Exception: 689 except Exception:
772 pass 690 pass
773 try: 691 try:
774 spec = module.__spec__ 692 spec = module.__spec__
775 except AttributeError: 693 except AttributeError:
776 # XXX Use module.__class__.__name__ instead of 'module'? 694 pass
777 try:
778 name = module.__name__
779 except AttributeError:
780 name = '?'
781 try:
782 filename = module.__file__
783 except AttributeError:
784 if loader is None:
785 return '<module {!r}>'.format(name)
786 else:
787 return '<module {!r} ({!r})>'.format(name, loader)
788 else:
789 return '<module {!r} from {!r}>'.format(name, filename)
790 else: 695 else:
791 return _SpecMethods(spec).module_repr() 696 if spec is not None:
697 return _SpecMethods(spec).module_repr()
698
699 # We could use module.__class__.__name__ instead of 'module' in the
700 # various repr permutations.
701 try:
702 name = module.__name__
703 except AttributeError:
704 name = '?'
705 try:
706 filename = module.__file__
707 except AttributeError:
708 if loader is None:
709 return '<module {!r}>'.format(name)
710 else:
711 return '<module {!r} ({!r})>'.format(name, loader)
712 else:
713 return '<module {!r} from {!r}>'.format(name, filename)
792 714
793 715
794 class _installed_safely: 716 class _installed_safely:
795 717
796 def __init__(self, module): 718 def __init__(self, module):
797 self._module = module 719 self._module = module
798 self._spec = module.__spec__ 720 self._spec = module.__spec__
799 721
800 def __enter__(self): 722 def __enter__(self):
801 # This must be done before putting the module in sys.modules 723 # This must be done before putting the module in sys.modules
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
869 791
870 def __repr__(self): 792 def __repr__(self):
871 args = ['name={!r}'.format(self.name), 793 args = ['name={!r}'.format(self.name),
872 'loader={!r}'.format(self.loader)] 794 'loader={!r}'.format(self.loader)]
873 if self.origin is not None: 795 if self.origin is not None:
874 args.append('origin={!r}'.format(self.origin)) 796 args.append('origin={!r}'.format(self.origin))
875 if self.submodule_search_locations is not None: 797 if self.submodule_search_locations is not None:
876 args.append('submodule_search_locations={}' 798 args.append('submodule_search_locations={}'
877 .format(self.submodule_search_locations)) 799 .format(self.submodule_search_locations))
878 return '{}({})'.format(self.__class__.__name__, ', '.join(args)) 800 return '{}({})'.format(self.__class__.__name__, ', '.join(args))
801
802 def __eq__(self, other):
803 smsl = self.submodule_search_locations
804 try:
805 return (self.name == other.name and
806 self.loader == other.loader and
807 self.origin == other.origin and
808 smsl == other.submodule_search_locations and
809 self.cached == other.cached and
810 self.has_location == other.has_location)
811 except AttributeError:
812 return False
879 813
880 @property 814 @property
881 def cached(self): 815 def cached(self):
882 if self._cached is None: 816 if self._cached is None:
883 if self.origin is not None and self._set_fileattr: 817 if self.origin is not None and self._set_fileattr:
884 filename = self.origin 818 filename = self.origin
885 if filename.endswith(tuple(SOURCE_SUFFIXES)): 819 if filename.endswith(tuple(SOURCE_SUFFIXES)):
886 try: 820 try:
887 self._cached = cache_from_source(filename) 821 self._cached = cache_from_source(filename)
888 except NotImplementedError: 822 except NotImplementedError:
(...skipping 11 matching lines...) Expand all
900 """The name of the module's parent.""" 834 """The name of the module's parent."""
901 if self.submodule_search_locations is None: 835 if self.submodule_search_locations is None:
902 return self.name.rpartition('.')[0] 836 return self.name.rpartition('.')[0]
903 else: 837 else:
904 return self.name 838 return self.name
905 839
906 @property 840 @property
907 def has_location(self): 841 def has_location(self):
908 return self._set_fileattr 842 return self._set_fileattr
909 843
844 @has_location.setter
845 def has_location(self, value):
846 self._set_fileattr = bool(value)
847
910 848
911 def spec_from_loader(name, loader, *, origin=None, is_package=None): 849 def spec_from_loader(name, loader, *, origin=None, is_package=None):
912 """Return a module spec based on various loader methods.""" 850 """Return a module spec based on various loader methods."""
913
914 # if hasattr(loader, 'get_data'):
915 if hasattr(loader, 'get_filename'): 851 if hasattr(loader, 'get_filename'):
916 if is_package is None: 852 if is_package is None:
917 return spec_from_file_location(name, loader=loader) 853 return spec_from_file_location(name, loader=loader)
918 search = [] if is_package else None 854 search = [] if is_package else None
919 return spec_from_file_location(name, loader=loader, 855 return spec_from_file_location(name, loader=loader,
920 submodule_search_locations=search) 856 submodule_search_locations=search)
921 857
922 if is_package is None: 858 if is_package is None:
923 if hasattr(loader, 'is_package'): 859 if hasattr(loader, 'is_package'):
924 try: 860 try:
(...skipping 16 matching lines...) Expand all
941 877
942 To indicate that the module is a package, set 878 To indicate that the module is a package, set
943 submodule_search_locations to a list of directory paths. An 879 submodule_search_locations to a list of directory paths. An
944 empty list is sufficient, though its not otherwise useful to the 880 empty list is sufficient, though its not otherwise useful to the
945 import system. 881 import system.
946 882
947 The loader must take a spec as its only __init__() arg. 883 The loader must take a spec as its only __init__() arg.
948 884
949 """ 885 """
950 if location is None: 886 if location is None:
887 # The caller may simply want a partially populated location-
888 # oriented spec. So we set the location to a bogus value and
889 # fill in as much as we can.
890 location = '<unknown>'
951 if hasattr(loader, 'get_filename'): 891 if hasattr(loader, 'get_filename'):
892 # ExecutionLoader
952 try: 893 try:
953 location = loader.get_filename(name) 894 location = loader.get_filename(name)
954 except ImportError: 895 except ImportError:
955 # XXX Return None? 896 pass
956 location = '<unknown>' 897
957 else: 898 # If the location is on the filesystem, but doesn't actually exist,
958 # XXX Return None? 899 # we could return None here, indicating that the location is not
959 location = '<unknown>' 900 # valid. However, we don't have a good way of testing since an
960 # XXX This breaks for zipimport (and any indirect location). 901 # indirect location (e.g. a zip file or URL) will look like a
961 #try: 902 # non-existent file relative to the filesystem.
962 # _os.stat(location)
963 #except OSError:
964 # return None
965 903
966 spec = ModuleSpec(name, loader, origin=location) 904 spec = ModuleSpec(name, loader, origin=location)
967 spec._set_fileattr = True 905 spec._set_fileattr = True
968 906
969 # Pick a loader if one wasn't provided. 907 # Pick a loader if one wasn't provided.
970 if loader is None: 908 if loader is None:
971 for loader_class, suffixes in _get_supported_file_loaders(): 909 for loader_class, suffixes in _get_supported_file_loaders():
972 if location.endswith(tuple(suffixes)): 910 if location.endswith(tuple(suffixes)):
973 loader = loader_class(name, location) 911 loader = loader_class(name, location)
974 spec.loader = loader 912 spec.loader = loader
975 break 913 break
976 else: 914 else:
977 return None 915 return None
978 916
979 # Set submodule_search_paths appropriately. 917 # Set submodule_search_paths appropriately.
980 if submodule_search_locations is _POPULATE: 918 if submodule_search_locations is _POPULATE:
981 # Check the loader. 919 # Check the loader.
982 if hasattr(loader, 'is_package'): 920 if hasattr(loader, 'is_package'):
983 try: 921 try:
984 is_package = loader.is_package(name) 922 is_package = loader.is_package(name)
985 except ImportError: 923 except ImportError:
986 pass 924 pass
987 else: 925 else:
988 if is_package: 926 if is_package:
989 spec.submodule_search_locations = [] 927 spec.submodule_search_locations = []
990 else: 928 else:
991 spec.submodule_search_locations = submodule_search_locations 929 spec.submodule_search_locations = submodule_search_locations
992 if spec.submodule_search_locations == []: 930 if spec.submodule_search_locations == []:
993 # if location: 931 if location:
994 dirname = _path_split(location)[0] 932 dirname = _path_split(location)[0]
995 spec.submodule_search_locations.append(dirname) 933 spec.submodule_search_locations.append(dirname)
996 934
997 return spec 935 return spec
998 936
999 937
1000 def _spec_from_module(module, loader=None, origin=None): 938 def _spec_from_module(module, loader=None, origin=None):
939 # This function is meant for use in _setup().
1001 try: 940 try:
1002 return module.__spec__ 941 spec = module.__spec__
1003 except AttributeError: 942 except AttributeError:
1004 pass 943 pass
944 else:
945 if spec is not None:
946 return spec
1005 947
1006 name = module.__name__ 948 name = module.__name__
1007 if loader is None: 949 if loader is None:
1008 try: 950 try:
1009 loader = module.__loader__ 951 loader = module.__loader__
1010 except AttributeError: 952 except AttributeError:
1011 loader = None 953 # loader will stay None.
Jim.J.Jewett 2013/10/30 03:32:01 If I'm reading this correctly, loader was None (or
eric.snow 2013/11/01 01:07:38 I think it's just a holdover from an earlier versi
954 pass
1012 try: 955 try:
1013 location = module.__file__ 956 location = module.__file__
1014 except AttributeError: 957 except AttributeError:
1015 location = None 958 location = None
1016 if origin is None: 959 if origin is None:
1017 if location is None: 960 if location is None:
1018 try: 961 try:
1019 origin = loader._ORIGIN 962 origin = loader._ORIGIN
1020 except AttributeError: 963 except AttributeError:
1021 origin = None 964 origin = None
(...skipping 10 matching lines...) Expand all
1032 975
1033 spec = ModuleSpec(name, loader, origin=origin) 976 spec = ModuleSpec(name, loader, origin=origin)
1034 spec._set_fileattr = False if location is None else True 977 spec._set_fileattr = False if location is None else True
1035 spec.cached = cached 978 spec.cached = cached
1036 spec.submodule_search_locations = submodule_search_locations 979 spec.submodule_search_locations = submodule_search_locations
1037 return spec 980 return spec
1038 981
1039 982
1040 class _SpecMethods: 983 class _SpecMethods:
1041 984
985 """Convenience wrapper around spec objects to provide spec-specific
986 methods."""
987
988 def __init__(self, spec):
989 self.spec = spec
990
1042 @classmethod 991 @classmethod
1043 def from_module(cls, module): 992 def from_module(cls, module):
993 """Create a spec from a module's attributes."""
1044 try: 994 try:
1045 spec = module.__spec__ 995 spec = module.__spec__
1046 except AttributeError: 996 except AttributeError:
1047 try: 997 try:
1048 loader = spec.__loader__ 998 loader = spec.__loader__
1049 except AttributeError: 999 except AttributeError:
1050 spec = _find_spec(module.__name__) 1000 spec = _find_spec(module.__name__)
1001 if spec is None:
1002 spec = spec_from_loader(module.__name__, loader)
1051 else: 1003 else:
1052 spec = spec_from_loader(module.__name__, loader) 1004 spec = spec_from_loader(module.__name__, loader)
1053 return cls(spec) 1005 return cls(spec)
1054
1055 def __init__(self, spec):
1056 self.spec = spec
1057 1006
1058 def module_repr(self): 1007 def module_repr(self):
1059 """Return the repr to use for the module.""" 1008 """Return the repr to use for the module."""
1060 # We mostly replicate _module_repr() using the spec attributes. 1009 # We mostly replicate _module_repr() using the spec attributes.
1061 spec = self.spec 1010 spec = self.spec
1062 name = '?' if spec.name is None else spec.name 1011 name = '?' if spec.name is None else spec.name
1063 if spec.origin is None: 1012 if spec.origin is None:
1064 if spec.loader is None: 1013 if spec.loader is None:
1065 return '<module {!r}>'.format(name) 1014 return '<module {!r}>'.format(name)
1066 else: 1015 else:
(...skipping 14 matching lines...) Expand all
1081 spec.loader -> module.__loader__ 1030 spec.loader -> module.__loader__
1082 spec.parent -> module.__package__ 1031 spec.parent -> module.__package__
1083 spec -> module.__spec__ 1032 spec -> module.__spec__
1084 1033
1085 Optional: 1034 Optional:
1086 spec.origin -> module.__file__ (if spec.set_fileattr is true) 1035 spec.origin -> module.__file__ (if spec.set_fileattr is true)
1087 spec.cached -> module.__cached__ (if __file__ also set) 1036 spec.cached -> module.__cached__ (if __file__ also set)
1088 spec.submodule_search_locations -> module.__path__ (if set) 1037 spec.submodule_search_locations -> module.__path__ (if set)
1089 1038
1090 """ 1039 """
1091 # XXX Make _override public?
1092 spec = self.spec 1040 spec = self.spec
1093 1041
1094 # The passed in module may be not support attribute assignment, 1042 # The passed in module may be not support attribute assignment,
1095 # in which case we simply don't set the attributes. 1043 # in which case we simply don't set the attributes.
1096 1044
1097 # __name__ 1045 # __name__
1098 if (_override or _force_name or 1046 if (_override or _force_name or
1099 getattr(module, '__name__', None) is None): 1047 getattr(module, '__name__', None) is None):
1100 try: 1048 try:
1101 module.__name__ = spec.name 1049 module.__name__ = spec.name
1102 except AttributeError: 1050 except AttributeError:
1103 pass 1051 pass
1104 1052
1105 # __loader__ 1053 # __loader__
1106 if _override or getattr(module, '__loader__', None) is None: 1054 if _override or getattr(module, '__loader__', None) is None:
1055 loader = spec.loader
1056 if loader is None:
1057 # A backward compatibility hack.
1058 if spec.submodule_search_locations is not None:
1059 loader = _NamespaceLoader.__new__(_NamespaceLoader)
1060 loader._path = spec.submodule_search_locations
1107 try: 1061 try:
1108 module.__loader__ = spec.loader 1062 module.__loader__ = loader
1109 except AttributeError: 1063 except AttributeError:
1110 pass 1064 pass
1111 1065
1112 # __package__ 1066 # __package__
1113 if _override or getattr(module, '__package__', None) is None: 1067 if _override or getattr(module, '__package__', None) is None:
1114 try: 1068 try:
1115 module.__package__ = spec.parent 1069 module.__package__ = spec.parent
1116 except AttributeError: 1070 except AttributeError:
1117 pass 1071 pass
1118 1072
(...skipping 20 matching lines...) Expand all
1139 pass 1093 pass
1140 1094
1141 # __cached__ 1095 # __cached__
1142 if _override or getattr(module, '__cached__', None) is None: 1096 if _override or getattr(module, '__cached__', None) is None:
1143 if spec.cached is not None: 1097 if spec.cached is not None:
1144 try: 1098 try:
1145 module.__cached__ = spec.cached 1099 module.__cached__ = spec.cached
1146 except AttributeError: 1100 except AttributeError:
1147 pass 1101 pass
1148 1102
1149 def _update_module_attrs(self, module, limited=True):
1150 try:
1151 cached.__name__ = name
1152 except AttributeError:
1153 pass
1154 if not hasattr(cached, '__spec__'):
1155 try:
1156 cached.__spec__ = self.spec
1157 except AttributeError:
1158 pass
1159 if not limited:
1160 raise NotImplementedError
1161
1162 # Under normal circumstances _create(), _exec(), _load_unlocked(),
1163 # _load(), and # _reload() should not be called directly. So they
1164 # have underscore # names (a.k.a. private API).
1165
Jim.J.Jewett 2013/10/30 03:32:01 I think the above comment is out of date, as I don
eric.snow 2013/11/01 01:07:38 I'll yank it. They used to be methods on ModuleSp
1166 def create(self): 1103 def create(self):
1167 """Return a new module to be loaded. 1104 """Return a new module to be loaded.
1168 1105
1169 The import-related module attributes are also set with the 1106 The import-related module attributes are also set with the
1170 appropriate values from the spec. 1107 appropriate values from the spec.
1171 1108
1172 """ 1109 """
1173 spec = self.spec 1110 spec = self.spec
1174 # Typically loaders will not implement create_module(). 1111 # Typically loaders will not implement create_module().
1175 if hasattr(spec.loader, 'create_module'): 1112 if hasattr(spec.loader, 'create_module'):
1176 # If create_module() returns `None` it means the default 1113 # If create_module() returns `None` it means the default
1177 # module creation should be used. 1114 # module creation should be used.
1178 module = spec.loader.create_module(spec) 1115 module = spec.loader.create_module(spec)
1179 else: 1116 else:
1180 module = None 1117 module = None
1181 if module is None: 1118 if module is None:
1182 # This must be done before open() is ever called as the 'io' 1119 # This must be done before open() is ever called as the 'io'
1183 # module implicitly imports 'locale' and would otherwise 1120 # module implicitly imports 'locale' and would otherwise
1184 # trigger an infinite loop. 1121 # trigger an infinite loop.
1185 module = type(_io)(spec.name) 1122 module = _new_module(spec.name)
1186 self.init_module_attrs(module) 1123 self.init_module_attrs(module)
1187 return module 1124 return module
1188 1125
1189 def _exec(self, module): 1126 def _exec(self, module):
1190 """Do everything necessary to execute the module. 1127 """Do everything necessary to execute the module.
1191 1128
1192 The namespace of `module` is used as the target of execution. 1129 The namespace of `module` is used as the target of execution.
1193 This method uses the loader's `exec_module()` method. 1130 This method uses the loader's `exec_module()` method.
1194 1131
1195 """ 1132 """
1196 if self.spec.loader is None:
1197 # namespace package
1198 return
1199 self.spec.loader.exec_module(module) 1133 self.spec.loader.exec_module(module)
1200 1134
1135 # Used by importlib.reload() and _load_module_shim().
1201 def exec(self, module): 1136 def exec(self, module):
1202 """Execute the spec in an existing module's namespace.""" 1137 """Execute the spec in an existing module's namespace."""
1203 name = self.spec.name 1138 name = self.spec.name
1204 _imp.acquire_lock() 1139 _imp.acquire_lock()
1205 with _ModuleLockManager(name): 1140 with _ModuleLockManager(name):
1141 if sys.modules.get(name) is not module:
1142 msg = 'module {!r} not in sys.modules'.format(name)
1143 raise ImportError(msg, name=name)
1206 if self.spec.loader is None: 1144 if self.spec.loader is None:
1145 if self.spec.submodule_search_locations is None:
1146 raise ImportError('missing loader', name=self.spec.name)
1207 # namespace package 1147 # namespace package
1208 self.init_module_attrs(module) 1148 self.init_module_attrs(module, _override=True)
1209 return module 1149 return module
1210 if hasattr(self.spec.loader, 'supports_reload'): 1150 self.init_module_attrs(module, _override=True)
1211 if not self.spec.loader.supports_reload(name):
1212 raise ImportError('loader does not support reloading',
1213 name=name)
1214 if sys.modules.get(name) is not module:
1215 raise ImportError('module not in sys.modules')
1216 self.init_module_attrs(module)
1217 if not hasattr(self.spec.loader, 'exec_module'): 1151 if not hasattr(self.spec.loader, 'exec_module'):
1218 # XXX DeprecationWarning goes here... 1152 # XXX DeprecationWarning goes here...
1219 self.spec.loader.load_module(name) 1153 self.spec.loader.load_module(name)
1220 return sys.modules[name] 1154 else:
1221 module.__spec__ = self.spec # Must be set. 1155 self._exec(module)
1222 self._exec(module)
1223 return sys.modules[name] 1156 return sys.modules[name]
1224 1157
1225 def _load_backward_compatible(self): 1158 def _load_backward_compatible(self):
1226 # XXX DeprecationWarning goes here... 1159 # XXX DeprecationWarning goes here...
1227 spec = self.spec 1160 spec = self.spec
1228 # The module must be in sys.modules! 1161 # The module must be in sys.modules!
1229 spec.loader.load_module(spec.name) 1162 spec.loader.load_module(spec.name)
1230 module = sys.modules[spec.name] 1163 module = sys.modules[spec.name]
1231 if getattr(module, '__loader__', None) is None: 1164 if getattr(module, '__loader__', None) is None:
1232 try: 1165 try:
(...skipping 10 matching lines...) Expand all
1243 module.__package__ = spec.name.rpartition('.')[0] 1176 module.__package__ = spec.name.rpartition('.')[0]
1244 except AttributeError: 1177 except AttributeError:
1245 pass 1178 pass
1246 if getattr(module, '__spec__', None) is None: 1179 if getattr(module, '__spec__', None) is None:
1247 try: 1180 try:
1248 module.__spec__ = spec 1181 module.__spec__ = spec
1249 except AttributeError: 1182 except AttributeError:
1250 pass 1183 pass
1251 return module 1184 return module
1252 1185
1186 # XXX If we don't end up using this for pythonrun.c/runpy, we should
1187 # get rid of it.
1253 def _load_existing(self, module): 1188 def _load_existing(self, module):
1254 """Exec the spec'ed module into an existing module's namespace.""" 1189 """Exec the spec'ed module into an existing module's namespace."""
1255 # For use by runpy. 1190 # For use by runpy.
1256 with _installed_safely(module): 1191 with _installed_safely(module):
1257 loaded = self.exec(module) 1192 loaded = self.exec(module)
1258 return loaded 1193 return loaded
1259 1194
1260 def _load_unlocked(self): 1195 def _load_unlocked(self):
1261 # A helper for direct use by the import system. 1196 # A helper for direct use by the import system.
1262 if self.spec.loader is None: 1197 if self.spec.loader is not None:
1263 pass 1198 # not a namespace package
1264 elif not hasattr(self.spec.loader, 'exec_module'): 1199 if not hasattr(self.spec.loader, 'exec_module'):
1265 return self._load_backward_compatible() 1200 return self._load_backward_compatible()
1266 1201
1267 module = self.create() 1202 module = self.create()
1268 with _installed_safely(module): 1203 with _installed_safely(module):
1269 loaded = self._exec(module) 1204 if self.spec.loader is None:
1205 if self.spec.submodule_search_locations is None:
1206 raise ImportError('missing loader', name=self.spec.name)
1207 # A namespace package so do nothing.
1208 else:
1209 self._exec(module)
1270 1210
1271 # We don't ensure that the import-related module attributes get 1211 # We don't ensure that the import-related module attributes get
1272 # set in the sys.modules replacement case. Such modules are on 1212 # set in the sys.modules replacement case. Such modules are on
1273 # their own. 1213 # their own.
1274 return sys.modules[self.spec.name] 1214 return sys.modules[self.spec.name]
1275 1215
1216 # A method used during testing of _load_unlocked() and by
1217 # _load_module_shim().
1276 def load(self): 1218 def load(self):
1277 """Return a new module object, loaded by the spec's loader. 1219 """Return a new module object, loaded by the spec's loader.
1278 1220
1279 The module is not added to its parent. 1221 The module is not added to its parent.
1280 1222
1281 If a module is already in sys.modules, that existing module gets 1223 If a module is already in sys.modules, that existing module gets
1282 clobbered. 1224 clobbered.
1283 1225
1284 """ 1226 """
1285 # XXX Chance for deadlock with circular import? Reload only?
1286 # XXX Check to see if already in sys.modules?
1287 _imp.acquire_lock() 1227 _imp.acquire_lock()
1288 with _ModuleLockManager(self.spec.name): 1228 with _ModuleLockManager(self.spec.name):
1289 return self._load_unlocked() 1229 return self._load_unlocked()
1290 1230
1291 # def reload(self, module):
Jim.J.Jewett 2013/10/30 03:32:01 I assume this will be either uncommented or delete
eric.snow 2013/11/01 01:07:38 Yep. Probably deleted. I always sweep up any cod
1292 # """Reload the module, leaving it in sys.modules.
1293 #
1294 # This is a simple reload of the module. `importlib.reload()`
1295 # provides a richer reload experience.
1296 #
1297 # """
1298 # _imp.acquire_lock()
1299 # with _ModuleLockManager(spec.name):
1300 # cls.init_module_attrs(spec, module, _force_name=True)
1301 # if not hasattr(spec.loader, 'exec_module'):
1302 # # XXX DeprecationWarning goes here...
1303 # spec.loader.load_module(spec.name)
1304 # return sys.modules[spec.name]
1305 # cls.exec(spec, module)
1306 # return sys.modules[spec.name]
1307
1308 1231
1309 # Loaders ##################################################################### 1232 # Loaders #####################################################################
1310 1233
1311 class BuiltinImporter: 1234 class BuiltinImporter:
1312 1235
1313 """Meta path import for built-in modules. 1236 """Meta path import for built-in modules.
1314 1237
1315 All methods are either class or static methods to avoid the need to 1238 All methods are either class or static methods to avoid the need to
1316 instantiate the class. 1239 instantiate the class.
1317 1240
1318 """ 1241 """
1319 _ORIGIN = 'built-in' 1242
1320 1243 @staticmethod
1321 @classmethod 1244 def module_repr(module):
1322 def _get_spec(cls, fullname): 1245 # XXX deprecate
1323 return spec_from_loader(fullname, cls, origin=cls._ORIGIN)
1324
1325 # XXX BC issues with removing?
1326 @classmethod
1327 def module_repr(cls, module):
1328 return '<module {!r} (built-in)>'.format(module.__name__) 1246 return '<module {!r} (built-in)>'.format(module.__name__)
1329 1247
1330 # XXX Add shims for find_module and load_module. 1248 @classmethod
1331 1249 def find_spec(cls, fullname, path=None, target=None):
1332 # XXX Change to find_spec(). 1250 if path is not None:
1251 return None
1252 if _imp.is_builtin(fullname):
1253 return spec_from_loader(fullname, cls, origin='built-in')
1254 else:
1255 return None
1256
1333 @classmethod 1257 @classmethod
1334 def find_module(cls, fullname, path=None): 1258 def find_module(cls, fullname, path=None):
1335 """Find the built-in module. 1259 """Find the built-in module.
1336 1260
1337 If 'path' is ever specified then the search is considered a failure. 1261 If 'path' is ever specified then the search is considered a failure.
1338 1262
1339 """ 1263 """
1340 if path is not None: 1264 spec = cls.find_spec(fullname, path)
1341 return None 1265 return spec.loader if spec is not None else None
1342 return cls if _imp.is_builtin(fullname) else None 1266
1343 1267 @classmethod
1344 # XXX Change to exec_module().
1345 @classmethod
1346 @set_package
1347 @set_loader
1348 @_requires_builtin 1268 @_requires_builtin
1349 def load_module(cls, fullname): 1269 def load_module(cls, fullname):
1350 """Load a built-in module.""" 1270 """Load a built-in module."""
1351 with _ManageReload(fullname): 1271 with _ManageReload(fullname):
1352 return _call_with_frames_removed(_imp.init_builtin, fullname) 1272 module = _call_with_frames_removed(_imp.init_builtin, fullname)
1273 module.__loader__ = cls
1274 module.__package__ = ''
1275 return module
1353 1276
1354 @classmethod 1277 @classmethod
1355 @_requires_builtin 1278 @_requires_builtin
1356 def get_code(cls, fullname): 1279 def get_code(cls, fullname):
1357 """Return None as built-in modules do not have code objects.""" 1280 """Return None as built-in modules do not have code objects."""
1358 return None 1281 return None
1359 1282
1360 @classmethod 1283 @classmethod
1361 @_requires_builtin 1284 @_requires_builtin
1362 def get_source(cls, fullname): 1285 def get_source(cls, fullname):
1363 """Return None as built-in modules do not have source code.""" 1286 """Return None as built-in modules do not have source code."""
1364 return None 1287 return None
1365 1288
1366 @classmethod 1289 @classmethod
1367 @_requires_builtin 1290 @_requires_builtin
1368 def is_package(cls, fullname): 1291 def is_package(cls, fullname):
1369 """Return False as built-in modules are never packages.""" 1292 """Return False as built-in modules are never packages."""
1370 # XXX DeprecationWarning here... 1293 # XXX DeprecationWarning here...
1371 return False 1294 return False
1372 1295
1373 1296
1374 class FrozenImporter: 1297 class FrozenImporter:
1375 1298
1376 """Meta path import for frozen modules. 1299 """Meta path import for frozen modules.
1377 1300
1378 All methods are either class or static methods to avoid the need to 1301 All methods are either class or static methods to avoid the need to
1379 instantiate the class. 1302 instantiate the class.
1380 1303
1381 """ 1304 """
1382 _ORIGIN = 'frozen' 1305
1383 1306 @staticmethod
1384 # XXX BC issues with removing? 1307 def module_repr(m):
1385 @classmethod 1308 # XXX deprecate
1386 def module_repr(cls, m):
1387 return '<module {!r} (frozen)>'.format(m.__name__) 1309 return '<module {!r} (frozen)>'.format(m.__name__)
1388 1310
1389 # XXX Add shims for find_module and load_module. 1311 @classmethod
1390 1312 def find_spec(cls, fullname, path=None, target=None):
1391 # XXX Change to find_spec(). 1313 if _imp.is_frozen(fullname):
1314 return spec_from_loader(fullname, cls, origin='frozen')
1315 else:
1316 return None
1317
1392 @classmethod 1318 @classmethod
1393 def find_module(cls, fullname, path=None): 1319 def find_module(cls, fullname, path=None):
1394 """Find a frozen module.""" 1320 """Find a frozen module."""
1395 return cls if _imp.is_frozen(fullname) else None 1321 return cls if _imp.is_frozen(fullname) else None
1396 1322
1397 # XXX Change to exec_module(). 1323 @staticmethod
1398 @classmethod 1324 def exec_module(module):
1399 @set_package 1325 name = module.__spec__.name
1400 @set_loader 1326 if not _imp.is_frozen(name):
1401 @_requires_frozen 1327 raise ImportError('{!r} is not a frozen module'.format(name),
1328 name=name)
1329 code = _call_with_frames_removed(_imp.get_frozen_object, name)
1330 exec(code, module.__dict__)
1331
1332 @classmethod
1402 def load_module(cls, fullname): 1333 def load_module(cls, fullname):
1403 """Load a frozen module.""" 1334 """Load a frozen module."""
1404 with _ManageReload(fullname): 1335 return _load_module_shim(cls, fullname)
1405 m = _call_with_frames_removed(_imp.init_frozen, fullname)
1406 # Let our own module_repr() method produce a suitable repr.
1407 del m.__file__
1408 return m
1409 1336
1410 @classmethod 1337 @classmethod
1411 @_requires_frozen 1338 @_requires_frozen
1412 def get_code(cls, fullname): 1339 def get_code(cls, fullname):
1413 """Return the code object for the frozen module.""" 1340 """Return the code object for the frozen module."""
1414 return _imp.get_frozen_object(fullname) 1341 return _imp.get_frozen_object(fullname)
1415 1342
1416 @classmethod 1343 @classmethod
1417 @_requires_frozen 1344 @_requires_frozen
1418 def get_source(cls, fullname): 1345 def get_source(cls, fullname):
1419 """Return None as frozen modules do not have source code.""" 1346 """Return None as frozen modules do not have source code."""
1420 return None 1347 return None
1421 1348
1422 @classmethod 1349 @classmethod
1423 @_requires_frozen 1350 @_requires_frozen
1424 def is_package(cls, fullname): 1351 def is_package(cls, fullname):
1425 """Return True if the frozen module is a package.""" 1352 """Return True if the frozen module is a package."""
1426 return _imp.is_frozen_package(fullname) 1353 return _imp.is_frozen_package(fullname)
1427 1354
1428 1355
1429 class WindowsRegistryFinder: 1356 class WindowsRegistryFinder:
1430 1357
1431 """Meta path finder for modules declared in the Windows registry. 1358 """Meta path finder for modules declared in the Windows registry."""
1432 """
1433 1359
1434 REGISTRY_KEY = ( 1360 REGISTRY_KEY = (
1435 'Software\\Python\\PythonCore\\{sys_version}' 1361 'Software\\Python\\PythonCore\\{sys_version}'
1436 '\\Modules\\{fullname}') 1362 '\\Modules\\{fullname}')
1437 REGISTRY_KEY_DEBUG = ( 1363 REGISTRY_KEY_DEBUG = (
1438 'Software\\Python\\PythonCore\\{sys_version}' 1364 'Software\\Python\\PythonCore\\{sys_version}'
1439 '\\Modules\\{fullname}\\Debug') 1365 '\\Modules\\{fullname}\\Debug')
1440 DEBUG_BUILD = False # Changed in _setup() 1366 DEBUG_BUILD = False # Changed in _setup()
1441
1442 # XXX Add shim for find_module().
1443 1367
1444 @classmethod 1368 @classmethod
1445 def _open_registry(cls, key): 1369 def _open_registry(cls, key):
1446 try: 1370 try:
1447 return _winreg.OpenKey(_winreg.HKEY_CURRENT_USER, key) 1371 return _winreg.OpenKey(_winreg.HKEY_CURRENT_USER, key)
1448 except OSError: 1372 except OSError:
1449 return _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, key) 1373 return _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, key)
1450 1374
1451 @classmethod 1375 @classmethod
1452 def _search_registry(cls, fullname): 1376 def _search_registry(cls, fullname):
1453 if cls.DEBUG_BUILD: 1377 if cls.DEBUG_BUILD:
1454 registry_key = cls.REGISTRY_KEY_DEBUG 1378 registry_key = cls.REGISTRY_KEY_DEBUG
1455 else: 1379 else:
1456 registry_key = cls.REGISTRY_KEY 1380 registry_key = cls.REGISTRY_KEY
1457 key = registry_key.format(fullname=fullname, 1381 key = registry_key.format(fullname=fullname,
1458 sys_version=sys.version[:3]) 1382 sys_version=sys.version[:3])
1459 try: 1383 try:
1460 with cls._open_registry(key) as hkey: 1384 with cls._open_registry(key) as hkey:
1461 filepath = _winreg.QueryValue(hkey, '') 1385 filepath = _winreg.QueryValue(hkey, '')
1462 except OSError: 1386 except OSError:
1463 return None 1387 return None
1464 return filepath 1388 return filepath
1465 1389
1466 @classmethod 1390 @classmethod
1467 def find_module(cls, fullname, path=None): 1391 def find_spec(cls, fullname, path=None, target=None):
1468 """Find module named in the registry.""" 1392 # XXX untested! Need a Windows person to write tests (otherwise mock out appropriately)
1469 filepath = cls._search_registry(fullname) 1393 filepath = cls._search_registry(fullname)
1470 if filepath is None: 1394 if filepath is None:
1471 return None 1395 return None
1472 try: 1396 try:
1473 _os.stat(filepath) 1397 _path_stat(filepath)
1474 except OSError: 1398 except OSError:
1475 return None 1399 return None
1476 for loader, suffixes in _get_supported_file_loaders(): 1400 for loader, suffixes in _get_supported_file_loaders():
1477 if filepath.endswith(tuple(suffixes)): 1401 if filepath.endswith(tuple(suffixes)):
1478 return loader(fullname, filepath) 1402 spec = spec_from_loader(fullname, loader(fullname, filepath),
1403 origin=filepath)
1404 return spec
1405
1406 @classmethod
1407 def find_module(cls, fullname, path=None):
1408 """Find module named in the registry."""
1409 spec = self.find_spec(fullname, path)
1410 if spec is not None:
1411 return spec.loader
1412 else:
1413 return None
1479 1414
1480 1415
1481 class _LoaderBasics: 1416 class _LoaderBasics:
1482 1417
1483 """Base class of common code needed by both SourceLoader and 1418 """Base class of common code needed by both SourceLoader and
1484 SourcelessFileLoader.""" 1419 SourcelessFileLoader."""
1485
1486 # XXX Add shim for load_module().
1487 1420
1488 # XXX deprecate? 1421 # XXX deprecate?
1489 def is_package(self, fullname): 1422 def is_package(self, fullname):
1490 """Concrete implementation of InspectLoader.is_package by checking if 1423 """Concrete implementation of InspectLoader.is_package by checking if
1491 the path returned by get_filename has a filename of '__init__.py'.""" 1424 the path returned by get_filename has a filename of '__init__.py'."""
1492 filename = _path_split(self.get_filename(fullname))[1] 1425 filename = _path_split(self.get_filename(fullname))[1]
1493 filename_base = filename.rsplit('.', 1)[0] 1426 filename_base = filename.rsplit('.', 1)[0]
1494 tail_name = fullname.rpartition('.')[2] 1427 tail_name = fullname.rpartition('.')[2]
1495 return filename_base == '__init__' and tail_name != '__init__' 1428 return filename_base == '__init__' and tail_name != '__init__'
1496 1429
1497 # XXX Remove. 1430 def exec_module(self, module):
1498 def init_module_attrs(self, module): 1431 """Execute the module."""
1499 """Set various attributes on the module. 1432 code = self.get_code(module.__name__)
1500 1433 if code is None:
1501 ExecutionLoader.init_module_attrs() is used to set __loader__, 1434 raise ImportError('cannot load module {!r} when get_code() '
1502 __package__, __file__, and optionally __path__. The __cached__ attribute 1435 'returns None'.format(module.__name__))
1503 is set using imp.cache_from_source() and __file__. 1436 _call_with_frames_removed(exec, code, module.__dict__)
1504 """ 1437
1505 module.__loader__ = self # Loader 1438 load_module = _load_module_shim
1506 _init_package_attrs(self, module) # InspectLoader
1507 _init_file_attrs(self, module) # ExecutionLoader
1508 if hasattr(module, '__file__'): # SourceLoader
1509 try:
1510 module.__cached__ = cache_from_source(module.__file__)
1511 except NotImplementedError:
1512 pass
1513
1514 # XXX Change to exec_module().
1515 def load_module(self, fullname):
1516 """Load the specified module into sys.modules and return it."""
1517 with module_to_load(fullname) as module:
1518 self.init_module_attrs(module)
1519 code = self.get_code(fullname)
1520 if code is None:
1521 raise ImportError('cannot load module {!r} when get_code() '
1522 'returns None'.format(fullname))
1523 _call_with_frames_removed(exec, code, module.__dict__)
1524 return module
1525 1439
1526 1440
1527 class SourceLoader(_LoaderBasics): 1441 class SourceLoader(_LoaderBasics):
1528 1442
1529 def path_mtime(self, path): 1443 def path_mtime(self, path):
1530 """Optional method that returns the modification time (an int) for the 1444 """Optional method that returns the modification time (an int) for the
1531 specified path, where path is a str. 1445 specified path, where path is a str.
1532 1446
1533 Raises IOError when the path cannot be handled. 1447 Raises IOError when the path cannot be handled.
1534 """ 1448 """
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
1638 1552
1639 """Base file loader class which implements the loader protocol methods that 1553 """Base file loader class which implements the loader protocol methods that
1640 require file system usage.""" 1554 require file system usage."""
1641 1555
1642 def __init__(self, fullname, path): 1556 def __init__(self, fullname, path):
1643 """Cache the module name and the path to the file found by the 1557 """Cache the module name and the path to the file found by the
1644 finder.""" 1558 finder."""
1645 self.name = fullname 1559 self.name = fullname
1646 self.path = path 1560 self.path = path
1647 1561
1648 # XXX Change to exec_module().
1649 @_check_name 1562 @_check_name
1650 def load_module(self, fullname): 1563 def load_module(self, fullname):
1651 """Load a module from a file.""" 1564 """Load a module from a file."""
1652 # Issue #14857: Avoid the zero-argument form so the implementation 1565 # The only reason for this method is for the name check.
1566
1567 # Issue #14857: Avoid the zero-argument form of super so the implementat ion
1653 # of that form can be updated without breaking the frozen module 1568 # of that form can be updated without breaking the frozen module
1654 return super(FileLoader, self).load_module(fullname) 1569 return super(FileLoader, self).load_module(fullname)
1655 1570
1656 @_check_name 1571 @_check_name
1657 def get_filename(self, fullname): 1572 def get_filename(self, fullname):
1658 """Return the path to the source file as found by the finder.""" 1573 """Return the path to the source file as found by the finder."""
1659 return self.path 1574 return self.path
1660 1575
1661 def get_data(self, path): 1576 def get_data(self, path):
1662 """Return the data from path as raw bytes.""" 1577 """Return the data from path as raw bytes."""
1663 with _io.FileIO(path, 'r') as file: 1578 with _io.FileIO(path, 'r') as file:
1664 return file.read() 1579 return file.read()
1665 1580
1666 1581
1667 class SourceFileLoader(FileLoader, SourceLoader): 1582 class SourceFileLoader(FileLoader, SourceLoader):
1668 1583
1669 """Concrete implementation of SourceLoader using the file system.""" 1584 """Concrete implementation of SourceLoader using the file system."""
1670 1585
1671 def path_stats(self, path): 1586 def path_stats(self, path):
1672 """Return the metadata for the path.""" 1587 """Return the metadata for the path."""
1673 st = _os.stat(path) 1588 st = _path_stat(path)
1674 return {'mtime': st.st_mtime, 'size': st.st_size} 1589 return {'mtime': st.st_mtime, 'size': st.st_size}
1675 1590
1676 def _cache_bytecode(self, source_path, bytecode_path, data): 1591 def _cache_bytecode(self, source_path, bytecode_path, data):
1677 # Adapt between the two APIs 1592 # Adapt between the two APIs
1678 mode = _calc_mode(source_path) 1593 mode = _calc_mode(source_path)
1679 return self.set_data(bytecode_path, data, _mode=mode) 1594 return self.set_data(bytecode_path, data, _mode=mode)
1680 1595
1681 def set_data(self, path, data, *, _mode=0o666): 1596 def set_data(self, path, data, *, _mode=0o666):
1682 """Write bytes data to a file.""" 1597 """Write bytes data to a file."""
1683 parent, filename = _path_split(path) 1598 parent, filename = _path_split(path)
(...skipping 20 matching lines...) Expand all
1704 _verbose_message('created {!r}', path) 1619 _verbose_message('created {!r}', path)
1705 except OSError as exc: 1620 except OSError as exc:
1706 # Same as above: just don't write the bytecode. 1621 # Same as above: just don't write the bytecode.
1707 _verbose_message('could not create {!r}: {!r}', path, exc) 1622 _verbose_message('could not create {!r}: {!r}', path, exc)
1708 1623
1709 1624
1710 class SourcelessFileLoader(FileLoader, _LoaderBasics): 1625 class SourcelessFileLoader(FileLoader, _LoaderBasics):
1711 1626
1712 """Loader which handles sourceless file imports.""" 1627 """Loader which handles sourceless file imports."""
1713 1628
1714 # XXX Merge into finder.
1715 def init_module_attrs(self, module):
1716 super().init_module_attrs(module)
1717 module.__cached__ = module.__file__
1718
1719 def get_code(self, fullname): 1629 def get_code(self, fullname):
1720 path = self.get_filename(fullname) 1630 path = self.get_filename(fullname)
1721 data = self.get_data(path) 1631 data = self.get_data(path)
1722 bytes_data = _validate_bytecode_header(data, name=fullname, path=path) 1632 bytes_data = _validate_bytecode_header(data, name=fullname, path=path)
1723 return _compile_bytecode(bytes_data, name=fullname, bytecode_path=path) 1633 return _compile_bytecode(bytes_data, name=fullname, bytecode_path=path)
1724 1634
1725 def get_source(self, fullname): 1635 def get_source(self, fullname):
1726 """Return None as there is no source code.""" 1636 """Return None as there is no source code."""
1727 return None 1637 return None
1728 1638
1729 1639
1730 # Filled in by _setup(). 1640 # Filled in by _setup().
1731 EXTENSION_SUFFIXES = [] 1641 EXTENSION_SUFFIXES = []
1732 1642
1733 1643
1734 class ExtensionFileLoader: 1644 class ExtensionFileLoader:
1735 1645
1736 """Loader for extension modules. 1646 """Loader for extension modules.
1737 1647
1738 The constructor is designed to work with FileFinder. 1648 The constructor is designed to work with FileFinder.
1739 1649
1740 """ 1650 """
1741 1651
1742 def __init__(self, name, path): 1652 def __init__(self, name, path):
1743 self.name = name 1653 self.name = name
1744 self.path = path 1654 self.path = path
1745 1655
1746 # XXX Add shim for load_module().
1747
1748 # XXX Change to exec_module().
1749 @_check_name 1656 @_check_name
1750 @set_package
1751 @set_loader
1752 def load_module(self, fullname): 1657 def load_module(self, fullname):
1753 """Load an extension module.""" 1658 """Load an extension module."""
1754 with _ManageReload(fullname): 1659 with _ManageReload(fullname):
1755 module = _call_with_frames_removed(_imp.load_dynamic, 1660 module = _call_with_frames_removed(_imp.load_dynamic,
1756 fullname, self.path) 1661 fullname, self.path)
1757 _verbose_message('extension module loaded from {!r}', self.path) 1662 _verbose_message('extension module loaded from {!r}', self.path)
1758 if self.is_package(fullname) and not hasattr(module, '__path__'): 1663 is_package = self.is_package(fullname)
1759 module.__path__ = [_path_split(self.path)[0]] 1664 if is_package and not hasattr(module, '__path__'):
1760 return module 1665 module.__path__ = [_path_split(self.path)[0]]
1666 module.__loader__ = self
1667 module.__package__ = module.__name__
1668 if not is_package:
1669 module.__package__ = module.__package__.rpartition('.')[0]
1670 return module
1761 1671
1762 def is_package(self, fullname): 1672 def is_package(self, fullname):
1763 """Return True if the extension module is a package.""" 1673 """Return True if the extension module is a package."""
1764 file_name = _path_split(self.path)[1] 1674 file_name = _path_split(self.path)[1]
1765 return any(file_name == '__init__' + suffix 1675 return any(file_name == '__init__' + suffix
1766 for suffix in EXTENSION_SUFFIXES) 1676 for suffix in EXTENSION_SUFFIXES)
1767 1677
1768 def get_code(self, fullname): 1678 def get_code(self, fullname):
1769 """Return None as an extension module cannot create a code object.""" 1679 """Return None as an extension module cannot create a code object."""
1770 return None 1680 return None
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1803 return parent, '__path__' 1713 return parent, '__path__'
1804 1714
1805 def _get_parent_path(self): 1715 def _get_parent_path(self):
1806 parent_module_name, path_attr_name = self._find_parent_path_names() 1716 parent_module_name, path_attr_name = self._find_parent_path_names()
1807 return getattr(sys.modules[parent_module_name], path_attr_name) 1717 return getattr(sys.modules[parent_module_name], path_attr_name)
1808 1718
1809 def _recalculate(self): 1719 def _recalculate(self):
1810 # If the parent's path has changed, recalculate _path 1720 # If the parent's path has changed, recalculate _path
1811 parent_path = tuple(self._get_parent_path()) # Make a copy 1721 parent_path = tuple(self._get_parent_path()) # Make a copy
1812 if parent_path != self._last_parent_path: 1722 if parent_path != self._last_parent_path:
1813 loader, new_path = self._path_finder(self._name, parent_path) 1723 spec = self._path_finder(self._name, parent_path)
1814 # Note that no changes are made if a loader is returned, but we 1724 # Note that no changes are made if a loader is returned, but we
1815 # do remember the new parent path 1725 # do remember the new parent path
1816 if loader is None: 1726 if spec is not None and spec.loader is None:
1817 self._path = new_path 1727 if spec.submodule_search_locations:
1728 self._path = spec.submodule_search_locations
1818 self._last_parent_path = parent_path # Save the copy 1729 self._last_parent_path = parent_path # Save the copy
1819 return self._path 1730 return self._path
1820 1731
1821 def __iter__(self): 1732 def __iter__(self):
1822 return iter(self._recalculate()) 1733 return iter(self._recalculate())
1823 1734
1824 def __len__(self): 1735 def __len__(self):
1825 return len(self._recalculate()) 1736 return len(self._recalculate())
1826 1737
1827 def __repr__(self): 1738 def __repr__(self):
1828 return '_NamespacePath({!r})'.format(self._path) 1739 return '_NamespacePath({!r})'.format(self._path)
1829 1740
1830 def __contains__(self, item): 1741 def __contains__(self, item):
1831 return item in self._recalculate() 1742 return item in self._recalculate()
1832 1743
1833 def append(self, item): 1744 def append(self, item):
1834 self._path.append(item) 1745 self._path.append(item)
1835 1746
1836 1747
1837 # XXX Merge into ModuleSpec. 1748 # We use this exclusively in init_module_attrs() for backward-compatibility.
1838 class NamespaceLoader: 1749 class _NamespaceLoader:
1839
1840 def __init__(self, name, path, path_finder): 1750 def __init__(self, name, path, path_finder):
1841 self._path = _NamespacePath(name, path, path_finder) 1751 self._path = _NamespacePath(name, path, path_finder)
1842 1752
1843 # XXX Remove. 1753 # XXX Deprecate
1844 @classmethod 1754 @classmethod
1845 def module_repr(cls, module): 1755 def module_repr(cls, module):
1846 return '<module {!r} (namespace)>'.format(module.__name__) 1756 return '<module {!r} (namespace)>'.format(module.__name__)
1847 1757
1848 # XXX Add shim for load_module().
1849
1850 def is_package(self, fullname): 1758 def is_package(self, fullname):
1851 return True 1759 return True
1852 1760
1853 def get_source(self, fullname): 1761 def get_source(self, fullname):
1854 return '' 1762 return ''
1855 1763
1856 def get_code(self, fullname): 1764 def get_code(self, fullname):
1857 return compile('', '<string>', 'exec', dont_inherit=True) 1765 return compile('', '<string>', 'exec', dont_inherit=True)
1858 1766
1859 # XXX Remove. 1767 # XXX Deprecate
1860 def init_module_attrs(self, module):
1861 module.__loader__ = self
1862 module.__package__ = module.__name__
1863
1864 # XXX Change to exec_module().
1865 def load_module(self, fullname): 1768 def load_module(self, fullname):
1866 """Load a namespace module.""" 1769 """Load a namespace module."""
1867 _verbose_message('namespace module loaded with path {!r}', self._path) 1770 _verbose_message('namespace module loaded with path {!r}', self._path)
1868 with module_to_load(fullname) as module: 1771 return _load_module_shim(self, fullname)
1869 self.init_module_attrs(module)
1870 module.__path__ = self._path
1871 return module
1872 1772
1873 1773
1874 # Finders ##################################################################### 1774 # Finders #####################################################################
1875 1775
1876 class PathFinder: 1776 class PathFinder:
1877 1777
1878 """Meta path finder for sys.path and package __path__ attributes.""" 1778 """Meta path finder for sys.path and package __path__ attributes."""
1879
1880 # XXX Add shim for find_module().
1881 1779
1882 @classmethod 1780 @classmethod
1883 def invalidate_caches(cls): 1781 def invalidate_caches(cls):
1884 """Call the invalidate_caches() method on all path entry finders 1782 """Call the invalidate_caches() method on all path entry finders
1885 stored in sys.path_importer_caches (where implemented).""" 1783 stored in sys.path_importer_caches (where implemented)."""
1886 for finder in sys.path_importer_cache.values(): 1784 for finder in sys.path_importer_cache.values():
1887 if hasattr(finder, 'invalidate_caches'): 1785 if hasattr(finder, 'invalidate_caches'):
1888 finder.invalidate_caches() 1786 finder.invalidate_caches()
1889 1787
1890 @classmethod 1788 @classmethod
(...skipping 24 matching lines...) Expand all
1915 if path == '': 1813 if path == '':
1916 path = _os.getcwd() 1814 path = _os.getcwd()
1917 try: 1815 try:
1918 finder = sys.path_importer_cache[path] 1816 finder = sys.path_importer_cache[path]
1919 except KeyError: 1817 except KeyError:
1920 finder = cls._path_hooks(path) 1818 finder = cls._path_hooks(path)
1921 sys.path_importer_cache[path] = finder 1819 sys.path_importer_cache[path] = finder
1922 return finder 1820 return finder
1923 1821
1924 @classmethod 1822 @classmethod
1925 def _get_loader(cls, fullname, path): 1823 def _legacy_get_spec(cls, fullname, finder):
1824 if hasattr(finder, 'find_loader'):
1825 loader, portions = finder.find_loader(fullname)
1826 else:
1827 loader = finder.find_module(fullname)
1828 portions = None
1829 if loader is not None:
1830 return spec_from_loader(fullname, loader)
1831 spec = ModuleSpec(fullname, None)
1832 spec.submodule_search_locations = portions
1833 return spec
1834
1835 @classmethod
1836 def _get_spec(cls, fullname, path, target=None):
1926 """Find the loader or namespace_path for this module/package name.""" 1837 """Find the loader or namespace_path for this module/package name."""
1927 # If this ends up being a namespace package, namespace_path is 1838 # If this ends up being a namespace package, namespace_path is
1928 # the list of paths that will become its __path__ 1839 # the list of paths that will become its __path__
1929 namespace_path = [] 1840 namespace_path = []
1930 for entry in path: 1841 for entry in path:
1931 if not isinstance(entry, (str, bytes)): 1842 if not isinstance(entry, (str, bytes)):
1932 continue 1843 continue
1933 finder = cls._path_importer_cache(entry) 1844 finder = cls._path_importer_cache(entry)
1934 if finder is not None: 1845 if finder is not None:
1935 if hasattr(finder, 'find_loader'): 1846 if hasattr(finder, 'find_spec'):
1936 loader, portions = finder.find_loader(fullname) 1847 spec = finder.find_spec(fullname, target)
1937 else: 1848 else:
1938 loader = finder.find_module(fullname) 1849 spec = cls._legacy_get_spec(fullname, finder)
1939 portions = [] 1850 if spec is None:
1940 if loader is not None: 1851 continue
1941 # We found a loader: return it immediately. 1852 if spec.loader is not None:
1942 return loader, namespace_path 1853 return spec
1854 portions = spec.submodule_search_locations
1855 if portions is None:
1856 raise ImportError('spec missing loader')
1943 # This is possibly part of a namespace package. 1857 # This is possibly part of a namespace package.
1944 # Remember these path entries (if any) for when we 1858 # Remember these path entries (if any) for when we
1945 # create a namespace package, and continue iterating 1859 # create a namespace package, and continue iterating
1946 # on path. 1860 # on path.
1947 namespace_path.extend(portions) 1861 namespace_path.extend(portions)
1948 else: 1862 else:
1949 return None, namespace_path 1863 spec = ModuleSpec(fullname, None)
1950 1864 spec.submodule_search_locations = namespace_path
1951 @classmethod 1865 return spec
1952 def find_module(cls, fullname, path=None): 1866
1867 @classmethod
1868 def find_spec(cls, fullname, path=None, target=None):
1953 """find the module on sys.path or 'path' based on sys.path_hooks and 1869 """find the module on sys.path or 'path' based on sys.path_hooks and
1954 sys.path_importer_cache.""" 1870 sys.path_importer_cache."""
1955 if path is None: 1871 if path is None:
1956 path = sys.path 1872 path = sys.path
1957 loader, namespace_path = cls._get_loader(fullname, path) 1873 spec = cls._get_spec(fullname, path, target)
1958 if loader is None: 1874 if spec is None:
1875 return None
1876 elif spec.loader is None:
1877 namespace_path = spec.submodule_search_locations
1959 if namespace_path: 1878 if namespace_path:
1960 # We found at least one namespace path. Return a 1879 # We found at least one namespace path. Return a
1961 # loader which can create the namespace package. 1880 # spec which can create the namespace package.
1962 return NamespaceLoader(fullname, namespace_path, cls._get_loader ) 1881 spec.origin = 'namespace'
1882 spec.submodule_search_locations = _NamespacePath(fullname, names pace_path, cls._get_spec)
1883 return spec
1963 else: 1884 else:
1964 return None 1885 return None
1965 else: 1886 else:
1966 return loader 1887 return spec
1967 1888
1968 # @classmethod 1889 @classmethod
1969 # def find_spec(cls, fullname, path=None): 1890 def find_module(cls, fullname, path=None):
1970 # """find the module on sys.path or 'path' based on sys.path_hooks and 1891 """find the module on sys.path or 'path' based on sys.path_hooks and
1971 # sys.path_importer_cache.""" 1892 sys.path_importer_cache."""
1972 # if path is None: 1893 # XXX Deprecation warning here.
1973 # path = sys.path 1894 spec = cls.find_spec(fullname, path)
1974 # loader, namespace_path = cls._get_loader(fullname, path) 1895 if spec is None:
1975 # if loader is None: 1896 return None
1976 # if namespace_path: 1897 return spec.loader
1977 # # We found at least one namespace path. Return a
1978 # # loader which can create the namespace package.
1979 # loader = NamespaceLoader(fullname, namespace_path,
1980 # cls._get_loader)
1981 # return spec_from_loader(fullname, loader, origin='namespace',
1982 # is_package=True)
1983 # else:
1984 # return None
1985 # else:
1986 # # Defer to loader.get_filename() for the location.
1987 # return spec_from_file_location(fullname, loader=loader)
1988 #
1989 # # XXX Deprecate.
1990 # @classmethod
1991 # def find_module(cls, fullname, path=None):
1992 # """find the module on sys.path or 'path' based on sys.path_hooks and
Jim.J.Jewett 2013/10/30 03:32:01 Is this an already existing method despite the "ne
eric.snow 2013/11/01 01:07:38 This was the next step in the implementation that
1993 # sys.path_importer_cache."""
1994 # spec = cls.find_spec(fullname, path)
1995 # if spec is None:
1996 # return None
1997 # return spec.loader
1998 1898
1999 1899
2000 class FileFinder: 1900 class FileFinder:
2001 1901
2002 """File-based finder. 1902 """File-based finder.
2003 1903
2004 Interactions with the file system are cached for performance, being 1904 Interactions with the file system are cached for performance, being
2005 refreshed when the directory the finder is handling has been modified. 1905 refreshed when the directory the finder is handling has been modified.
2006 1906
2007 """ 1907 """
2008 1908
2009 def __init__(self, path, *loader_details): 1909 def __init__(self, path, *loader_details):
2010 """Initialize with the path to search on and a variable number of 1910 """Initialize with the path to search on and a variable number of
2011 2-tuples containing the loader and the file suffixes the loader 1911 2-tuples containing the loader and the file suffixes the loader
2012 recognizes.""" 1912 recognizes."""
2013 loaders = [] 1913 loaders = []
2014 for loader, suffixes in loader_details: 1914 for loader, suffixes in loader_details:
2015 loaders.extend((suffix, loader) for suffix in suffixes) 1915 loaders.extend((suffix, loader) for suffix in suffixes)
2016 self._loaders = loaders 1916 self._loaders = loaders
2017 # Base (directory) path 1917 # Base (directory) path
2018 self.path = path 1918 self.path = path or '.'
2019 self._path_mtime = -1 1919 self._path_mtime = -1
2020 self._path_cache = set() 1920 self._path_cache = set()
2021 self._relaxed_path_cache = set() 1921 self._relaxed_path_cache = set()
2022 1922
2023 def invalidate_caches(self): 1923 def invalidate_caches(self):
2024 """Invalidate the directory mtime.""" 1924 """Invalidate the directory mtime."""
2025 self._path_mtime = -1 1925 self._path_mtime = -1
2026 1926
2027 # XXX Use a different shim.
2028 find_module = _find_module_shim 1927 find_module = _find_module_shim
2029 1928
2030 # XXX Change to find_spec().
2031 def find_loader(self, fullname): 1929 def find_loader(self, fullname):
1930 """Try to find a loader for the specified module, or the namespace
1931 package portions. Returns (loader, list-of-portions)."""
1932 spec = self.find_spec(fullname)
1933 if spec is None:
1934 return None, []
1935 return spec.loader, spec.submodule_search_locations or []
1936
1937 def _get_spec(self, loader_class, fullname, path, submodule_search_locations , target):
1938 loader = loader_class(fullname, path)
1939 try:
1940 get_spec = loader._get_spec
1941 except AttributeError:
1942 return spec_from_file_location(fullname, path, loader=loader,
1943 submodule_search_locations=submodule_ search_locations)
1944 else:
1945 return get_spec(fullname, path, submodule_search_locations, target)
1946
1947 def find_spec(self, fullname, target=None):
2032 """Try to find a loader for the specified module, or the namespace 1948 """Try to find a loader for the specified module, or the namespace
2033 package portions. Returns (loader, list-of-portions).""" 1949 package portions. Returns (loader, list-of-portions)."""
2034 is_namespace = False 1950 is_namespace = False
2035 tail_module = fullname.rpartition('.')[2] 1951 tail_module = fullname.rpartition('.')[2]
2036 try: 1952 try:
2037 mtime = _os.stat(self.path or _os.getcwd()).st_mtime 1953 mtime = _path_stat(self.path or _os.getcwd()).st_mtime
2038 except OSError: 1954 except OSError:
2039 mtime = -1 1955 mtime = -1
2040 if mtime != self._path_mtime: 1956 if mtime != self._path_mtime:
2041 self._fill_cache() 1957 self._fill_cache()
2042 self._path_mtime = mtime 1958 self._path_mtime = mtime
2043 # tail_module keeps the original casing, for __file__ and friends 1959 # tail_module keeps the original casing, for __file__ and friends
2044 if _relax_case(): 1960 if _relax_case():
2045 cache = self._relaxed_path_cache 1961 cache = self._relaxed_path_cache
2046 cache_module = tail_module.lower() 1962 cache_module = tail_module.lower()
2047 else: 1963 else:
2048 cache = self._path_cache 1964 cache = self._path_cache
2049 cache_module = tail_module 1965 cache_module = tail_module
2050 # Check if the module is the name of a directory (and thus a package). 1966 # Check if the module is the name of a directory (and thus a package).
2051 if cache_module in cache: 1967 if cache_module in cache:
2052 base_path = _path_join(self.path, tail_module) 1968 base_path = _path_join(self.path, tail_module)
2053 for suffix, loader in self._loaders: 1969 for suffix, loader_class in self._loaders:
2054 init_filename = '__init__' + suffix 1970 init_filename = '__init__' + suffix
2055 full_path = _path_join(base_path, init_filename) 1971 full_path = _path_join(base_path, init_filename)
2056 if _path_isfile(full_path): 1972 if _path_isfile(full_path):
2057 return (loader(fullname, full_path), [base_path]) 1973 return self._get_spec(loader_class, fullname, full_path, [ba se_path], target)
2058 else: 1974 else:
2059 # If a namespace package, return the path if we don't 1975 # If a namespace package, return the path if we don't
2060 # find a module in the next section. 1976 # find a module in the next section.
2061 is_namespace = _path_isdir(base_path) 1977 is_namespace = _path_isdir(base_path)
2062 # Check for a file w/ a proper suffix exists. 1978 # Check for a file w/ a proper suffix exists.
2063 for suffix, loader in self._loaders: 1979 for suffix, loader_class in self._loaders:
2064 full_path = _path_join(self.path, tail_module + suffix) 1980 full_path = _path_join(self.path, tail_module + suffix)
2065 _verbose_message('trying {}'.format(full_path), verbosity=2) 1981 _verbose_message('trying {}'.format(full_path), verbosity=2)
2066 if cache_module + suffix in cache: 1982 if cache_module + suffix in cache:
2067 if _path_isfile(full_path): 1983 if _path_isfile(full_path):
2068 return (loader(fullname, full_path), []) 1984 return self._get_spec(loader_class, fullname, full_path, Non e, target)
2069 if is_namespace: 1985 if is_namespace:
2070 _verbose_message('possible namespace for {}'.format(base_path)) 1986 _verbose_message('possible namespace for {}'.format(base_path))
2071 return (None, [base_path]) 1987 spec = ModuleSpec(fullname, None)
2072 return (None, []) 1988 spec.submodule_search_locations = [base_path]
1989 return spec
1990 return None
2073 1991
2074 def _fill_cache(self): 1992 def _fill_cache(self):
2075 """Fill the cache of potential modules and packages for this directory." "" 1993 """Fill the cache of potential modules and packages for this directory." ""
2076 path = self.path 1994 path = self.path
2077 try: 1995 try:
2078 contents = _os.listdir(path or _os.getcwd()) 1996 contents = _os.listdir(path or _os.getcwd())
2079 except (FileNotFoundError, PermissionError, NotADirectoryError): 1997 except (FileNotFoundError, PermissionError, NotADirectoryError):
2080 # Directory has either been removed, turned into a file, or made 1998 # Directory has either been removed, turned into a file, or made
2081 # unreadable. 1999 # unreadable.
2082 contents = [] 2000 contents = []
(...skipping 12 matching lines...) Expand all
2095 name, dot, suffix = item.partition('.') 2013 name, dot, suffix = item.partition('.')
2096 if dot: 2014 if dot:
2097 new_name = '{}.{}'.format(name, suffix.lower()) 2015 new_name = '{}.{}'.format(name, suffix.lower())
2098 else: 2016 else:
2099 new_name = name 2017 new_name = name
2100 lower_suffix_contents.add(new_name) 2018 lower_suffix_contents.add(new_name)
2101 self._path_cache = lower_suffix_contents 2019 self._path_cache = lower_suffix_contents
2102 if sys.platform.startswith(_CASE_INSENSITIVE_PLATFORMS): 2020 if sys.platform.startswith(_CASE_INSENSITIVE_PLATFORMS):
2103 self._relaxed_path_cache = {fn.lower() for fn in contents} 2021 self._relaxed_path_cache = {fn.lower() for fn in contents}
2104 2022
2105 # XXX See _get_supported_file_loaders().
2106 @classmethod 2023 @classmethod
2107 def path_hook(cls, *loader_details): 2024 def path_hook(cls, *loader_details):
2108 """A class method which returns a closure to use on sys.path_hook 2025 """A class method which returns a closure to use on sys.path_hook
2109 which will return an instance using the specified loaders and the path 2026 which will return an instance using the specified loaders and the path
2110 called on the closure. 2027 called on the closure.
2111 2028
2112 If the path called on the closure is not a directory, ImportError is 2029 If the path called on the closure is not a directory, ImportError is
2113 raised. 2030 raised.
2114 2031
2115 """ 2032 """
(...skipping 26 matching lines...) Expand all
2142 2059
2143 def _resolve_name(name, package, level): 2060 def _resolve_name(name, package, level):
2144 """Resolve a relative module name to an absolute one.""" 2061 """Resolve a relative module name to an absolute one."""
2145 bits = package.rsplit('.', level - 1) 2062 bits = package.rsplit('.', level - 1)
2146 if len(bits) < level: 2063 if len(bits) < level:
2147 raise ValueError('attempted relative import beyond top-level package') 2064 raise ValueError('attempted relative import beyond top-level package')
2148 base = bits[0] 2065 base = bits[0]
2149 return '{}.{}'.format(base, name) if name else base 2066 return '{}.{}'.format(base, name) if name else base
2150 2067
2151 2068
2152 def _find_spec(name, path): 2069 def _find_spec(name, path, target=None):
2153 """Find a module's loader.""" 2070 """Find a module's loader."""
2154 if not sys.meta_path: 2071 if not sys.meta_path:
2155 _warnings.warn('sys.meta_path is empty', ImportWarning) 2072 _warnings.warn('sys.meta_path is empty', ImportWarning)
2073 # We check sys.modules here for the reload case. While a passed-in
2074 # target will usually indicate a reload there is no guarantee, whereas
2075 # sys.modules provides one.
2076 is_reload = name in sys.modules
2156 for finder in sys.meta_path: 2077 for finder in sys.meta_path:
2157 with _ImportLockContext(): 2078 with _ImportLockContext():
2158 try: 2079 try:
2159 find_spec = finder.find_spec 2080 find_spec = finder.find_spec
2160 except AttributeError: 2081 except AttributeError:
2161 loader = finder.find_module(name, path) 2082 loader = finder.find_module(name, path)
2162 if loader is None: 2083 if loader is None:
2163 continue 2084 continue
2164 spec = spec_from_loader(name, loader) 2085 spec = spec_from_loader(name, loader)
2165 else: 2086 else:
2166 spec = find_spec(name, path) 2087 spec = find_spec(name, path, target)
2167 if spec is not None: 2088 if spec is not None:
2168 # The parent import may have already imported this module. 2089 # The parent import may have already imported this module.
2169 if name in sys.modules: 2090 if not is_reload and name in sys.modules:
2170 module = sys.modules[name] 2091 module = sys.modules[name]
2171 try: 2092 try:
2172 return module.__spec__ 2093 __spec__ = module.__spec__
2173 except AttributeError: 2094 except AttributeError:
2174 # XXX Use _spec_from_module() here? 2095 # We use the found spec since that is the one that
2096 # we would have used if the parent module hadn't
2097 # beaten us to the punch.
2175 return spec 2098 return spec
2099 else:
2100 if __spec__ is None:
2101 return spec
2102 else:
2103 return __spec__
2176 else: 2104 else:
2177 return spec 2105 return spec
2178 else: 2106 else:
2179 return None 2107 return None
2180 2108
2181 2109
2182 def _sanity_check(name, package, level): 2110 def _sanity_check(name, package, level):
2183 """Verify arguments are "sane".""" 2111 """Verify arguments are "sane"."""
2184 if not isinstance(name, str): 2112 if not isinstance(name, str):
2185 raise TypeError('module name must be str, not {}'.format(type(name))) 2113 raise TypeError('module name must be str, not {}'.format(type(name)))
(...skipping 15 matching lines...) Expand all
2201 2129
2202 def _find_and_load_unlocked(name, import_): 2130 def _find_and_load_unlocked(name, import_):
2203 path = None 2131 path = None
2204 parent = name.rpartition('.')[0] 2132 parent = name.rpartition('.')[0]
2205 if parent: 2133 if parent:
2206 if parent not in sys.modules: 2134 if parent not in sys.modules:
2207 _call_with_frames_removed(import_, parent) 2135 _call_with_frames_removed(import_, parent)
2208 # Crazy side-effects! 2136 # Crazy side-effects!
2209 if name in sys.modules: 2137 if name in sys.modules:
2210 return sys.modules[name] 2138 return sys.modules[name]
2211 # Backwards-compatibility; be nicer to skip the dict lookup.
2212 parent_module = sys.modules[parent] 2139 parent_module = sys.modules[parent]
2213 try: 2140 try:
2214 path = parent_module.__path__ 2141 path = parent_module.__path__
2215 except AttributeError: 2142 except AttributeError:
2216 msg = (_ERR_MSG + '; {} is not a package').format(name, parent) 2143 msg = (_ERR_MSG + '; {!r} is not a package').format(name, parent)
2217 raise ImportError(msg, name=name) 2144 raise ImportError(msg, name=name)
2218 spec = _find_spec(name, path) 2145 spec = _find_spec(name, path)
2219 if spec is None: 2146 if spec is None:
2220 raise ImportError(_ERR_MSG.format(name), name=name) 2147 raise ImportError(_ERR_MSG.format(name), name=name)
2221 else: 2148 else:
2222 module = _SpecMethods(spec)._load_unlocked() 2149 module = _SpecMethods(spec)._load_unlocked()
2223 if parent: 2150 if parent:
2224 # Set the module as an attribute on its parent. 2151 # Set the module as an attribute on its parent.
2225 parent_module = sys.modules[parent] 2152 parent_module = sys.modules[parent]
2226 setattr(parent_module, name.rpartition('.')[2], module) 2153 setattr(parent_module, name.rpartition('.')[2], module)
2227 return module 2154 return module
2228 2155
2229 2156
2230 # XXX Eliminate?
2231 def _find_and_load(name, import_): 2157 def _find_and_load(name, import_):
2232 """Find and load the module, and release the import lock.""" 2158 """Find and load the module, and release the import lock."""
2233 with _ModuleLockManager(name): 2159 with _ModuleLockManager(name):
2234 return _find_and_load_unlocked(name, import_) 2160 return _find_and_load_unlocked(name, import_)
2235 2161
2236 2162
2237 def _gcd_import(name, package=None, level=0): 2163 def _gcd_import(name, package=None, level=0):
2238 """Import and return the module based on its name, the package the call is 2164 """Import and return the module based on its name, the package the call is
2239 being made from, and the level adjustment. 2165 being made from, and the level adjustment.
2240 2166
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
2345 # in 'name'. 2271 # in 'name'.
2346 cut_off = len(name) - len(name.partition('.')[0]) 2272 cut_off = len(name) - len(name.partition('.')[0])
2347 # Slice end needs to be positive to alleviate need to special-case 2273 # Slice end needs to be positive to alleviate need to special-case
2348 # when ``'.' not in name``. 2274 # when ``'.' not in name``.
2349 return sys.modules[module.__name__[:len(module.__name__)-cut_off]] 2275 return sys.modules[module.__name__[:len(module.__name__)-cut_off]]
2350 else: 2276 else:
2351 return _handle_fromlist(module, fromlist, _gcd_import) 2277 return _handle_fromlist(module, fromlist, _gcd_import)
2352 2278
2353 2279
2354 def _builtin_from_name(name): 2280 def _builtin_from_name(name):
2355 spec = BuiltinImporter._get_spec(name) 2281 spec = BuiltinImporter.find_spec(name)
2282 if spec is None:
2283 raise ImportError('no built-in module named ' + name)
2356 methods = _SpecMethods(spec) 2284 methods = _SpecMethods(spec)
2357 return methods._load_unlocked() 2285 return methods._load_unlocked()
2358 2286
2359 2287
2360 def _setup(sys_module, _imp_module): 2288 def _setup(sys_module, _imp_module):
2361 """Setup importlib by importing needed built-in modules and injecting them 2289 """Setup importlib by importing needed built-in modules and injecting them
2362 into the global namespace. 2290 into the global namespace.
2363 2291
2364 As sys is needed for sys.modules access and _imp is needed to load built-in 2292 As sys is needed for sys.modules access and _imp is needed to load built-in
2365 modules, those two modules must be explicitly passed in. 2293 modules, those two modules must be explicitly passed in.
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
2447 def _install(sys_module, _imp_module): 2375 def _install(sys_module, _imp_module):
2448 """Install importlib as the implementation of import.""" 2376 """Install importlib as the implementation of import."""
2449 _setup(sys_module, _imp_module) 2377 _setup(sys_module, _imp_module)
2450 supported_loaders = _get_supported_file_loaders() 2378 supported_loaders = _get_supported_file_loaders()
2451 sys.path_hooks.extend([FileFinder.path_hook(*supported_loaders)]) 2379 sys.path_hooks.extend([FileFinder.path_hook(*supported_loaders)])
2452 sys.meta_path.append(BuiltinImporter) 2380 sys.meta_path.append(BuiltinImporter)
2453 sys.meta_path.append(FrozenImporter) 2381 sys.meta_path.append(FrozenImporter)
2454 if _os.__name__ == 'nt': 2382 if _os.__name__ == 'nt':
2455 sys.meta_path.append(WindowsRegistryFinder) 2383 sys.meta_path.append(WindowsRegistryFinder)
2456 sys.meta_path.append(PathFinder) 2384 sys.meta_path.append(PathFinder)
LEFTRIGHT

RSS Feeds Recent Issues | This issue
This is Rietveld 894c83f36cb7+