| 
									
										
										
										
											2013-04-09 16:59:39 -04:00
										 |  |  | import io | 
					
						
							|  |  |  | import marshal | 
					
						
							|  |  |  | import os | 
					
						
							|  |  |  | import sys | 
					
						
							| 
									
										
										
										
											2020-08-04 23:53:12 +08:00
										 |  |  | from test.support import import_helper | 
					
						
							| 
									
										
										
										
											2013-06-15 18:39:21 -04:00
										 |  |  | import types | 
					
						
							| 
									
										
										
										
											2009-03-09 03:35:50 +00:00
										 |  |  | import unittest | 
					
						
							| 
									
										
										
										
											2013-05-27 21:11:04 -04:00
										 |  |  | from unittest import mock | 
					
						
							| 
									
										
										
										
											2014-01-06 20:49:04 -07:00
										 |  |  | import warnings | 
					
						
							| 
									
										
										
										
											2009-03-09 03:35:50 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-22 19:05:05 +03:00
										 |  |  | from test.test_importlib import util as test_util | 
					
						
							| 
									
										
										
										
											2014-05-16 11:40:40 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  | init = test_util.import_importlib('importlib') | 
					
						
							|  |  |  | abc = test_util.import_importlib('importlib.abc') | 
					
						
							|  |  |  | machinery = test_util.import_importlib('importlib.machinery') | 
					
						
							|  |  |  | util = test_util.import_importlib('importlib.util') | 
					
						
							| 
									
										
										
										
											2009-03-09 03:35:50 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-04 14:47:14 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-26 16:45:10 -04:00
										 |  |  | ##### Inheritance ############################################################## | 
					
						
							| 
									
										
										
										
											2009-07-20 03:19:18 +00:00
										 |  |  | class InheritanceTests: | 
					
						
							| 
									
										
										
										
											2009-03-09 03:35:50 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-07-20 03:19:18 +00:00
										 |  |  |     """Test that the specified class is a subclass/superclass of the expected
 | 
					
						
							|  |  |  |     classes."""
 | 
					
						
							| 
									
										
										
										
											2009-03-09 03:35:50 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-07-20 03:19:18 +00:00
										 |  |  |     subclasses = [] | 
					
						
							|  |  |  |     superclasses = [] | 
					
						
							| 
									
										
										
										
											2009-03-09 03:35:50 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-16 11:40:40 -06:00
										 |  |  |     def setUp(self): | 
					
						
							| 
									
										
										
										
											2013-10-04 14:47:14 -04:00
										 |  |  |         self.superclasses = [getattr(self.abc, class_name) | 
					
						
							|  |  |  |                              for class_name in self.superclass_names] | 
					
						
							|  |  |  |         if hasattr(self, 'subclass_names'): | 
					
						
							|  |  |  |             # Because test.support.import_fresh_module() creates a new | 
					
						
							|  |  |  |             # importlib._bootstrap per module, inheritance checks fail when | 
					
						
							|  |  |  |             # checking across module boundaries (i.e. the _bootstrap in abc is | 
					
						
							|  |  |  |             # not the same as the one in machinery). That means stealing one of | 
					
						
							|  |  |  |             # the modules from the other to make sure the same instance is used. | 
					
						
							| 
									
										
										
										
											2014-05-16 11:40:40 -06:00
										 |  |  |             machinery = self.abc.machinery | 
					
						
							|  |  |  |             self.subclasses = [getattr(machinery, class_name) | 
					
						
							|  |  |  |                                for class_name in self.subclass_names] | 
					
						
							| 
									
										
										
										
											2009-07-20 03:19:18 +00:00
										 |  |  |         assert self.subclasses or self.superclasses, self.__class__ | 
					
						
							| 
									
										
										
										
											2014-05-16 11:40:40 -06:00
										 |  |  |         self.__test = getattr(self.abc, self._NAME) | 
					
						
							| 
									
										
										
										
											2009-03-09 03:35:50 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-07-20 03:19:18 +00:00
										 |  |  |     def test_subclasses(self): | 
					
						
							|  |  |  |         # Test that the expected subclasses inherit. | 
					
						
							|  |  |  |         for subclass in self.subclasses: | 
					
						
							|  |  |  |             self.assertTrue(issubclass(subclass, self.__test), | 
					
						
							|  |  |  |                 "{0} is not a subclass of {1}".format(subclass, self.__test)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_superclasses(self): | 
					
						
							|  |  |  |         # Test that the class inherits from the expected superclasses. | 
					
						
							|  |  |  |         for superclass in self.superclasses: | 
					
						
							|  |  |  |             self.assertTrue(issubclass(self.__test, superclass), | 
					
						
							|  |  |  |                "{0} is not a superclass of {1}".format(superclass, self.__test)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-04 14:47:14 -04:00
										 |  |  | class MetaPathFinder(InheritanceTests): | 
					
						
							| 
									
										
										
										
											2021-04-06 08:56:57 -07:00
										 |  |  |     superclass_names = [] | 
					
						
							| 
									
										
										
										
											2013-10-04 14:47:14 -04:00
										 |  |  |     subclass_names = ['BuiltinImporter', 'FrozenImporter', 'PathFinder', | 
					
						
							|  |  |  |                       'WindowsRegistryFinder'] | 
					
						
							| 
									
										
										
										
											2009-07-20 03:19:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-16 11:40:40 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  | (Frozen_MetaPathFinderInheritanceTests, | 
					
						
							|  |  |  |  Source_MetaPathFinderInheritanceTests | 
					
						
							|  |  |  |  ) = test_util.test_both(MetaPathFinder, abc=abc) | 
					
						
							| 
									
										
										
										
											2012-08-10 12:21:12 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-08-02 21:26:03 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-04 14:47:14 -04:00
										 |  |  | class PathEntryFinder(InheritanceTests): | 
					
						
							| 
									
										
										
										
											2021-04-06 08:56:57 -07:00
										 |  |  |     superclass_names = [] | 
					
						
							| 
									
										
										
										
											2013-10-04 14:47:14 -04:00
										 |  |  |     subclass_names = ['FileFinder'] | 
					
						
							| 
									
										
										
										
											2009-07-20 03:19:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-16 11:40:40 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  | (Frozen_PathEntryFinderInheritanceTests, | 
					
						
							|  |  |  |  Source_PathEntryFinderInheritanceTests | 
					
						
							|  |  |  |  ) = test_util.test_both(PathEntryFinder, abc=abc) | 
					
						
							| 
									
										
										
										
											2012-08-10 12:21:12 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-07-20 03:19:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-04 14:47:14 -04:00
										 |  |  | class ResourceLoader(InheritanceTests): | 
					
						
							|  |  |  |     superclass_names = ['Loader'] | 
					
						
							| 
									
										
										
										
											2009-07-20 03:19:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-16 11:40:40 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  | (Frozen_ResourceLoaderInheritanceTests, | 
					
						
							|  |  |  |  Source_ResourceLoaderInheritanceTests | 
					
						
							|  |  |  |  ) = test_util.test_both(ResourceLoader, abc=abc) | 
					
						
							| 
									
										
										
										
											2009-07-20 03:19:18 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-04 14:47:14 -04:00
										 |  |  | class InspectLoader(InheritanceTests): | 
					
						
							|  |  |  |     superclass_names = ['Loader'] | 
					
						
							|  |  |  |     subclass_names = ['BuiltinImporter', 'FrozenImporter', 'ExtensionFileLoader'] | 
					
						
							| 
									
										
										
										
											2009-07-20 03:19:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-16 11:40:40 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  | (Frozen_InspectLoaderInheritanceTests, | 
					
						
							|  |  |  |  Source_InspectLoaderInheritanceTests | 
					
						
							|  |  |  |  ) = test_util.test_both(InspectLoader, abc=abc) | 
					
						
							| 
									
										
										
										
											2009-07-20 03:19:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-07-20 04:23:48 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-04 14:47:14 -04:00
										 |  |  | class ExecutionLoader(InheritanceTests): | 
					
						
							|  |  |  |     superclass_names = ['InspectLoader'] | 
					
						
							| 
									
										
										
										
											2013-10-04 20:28:52 -06:00
										 |  |  |     subclass_names = ['ExtensionFileLoader'] | 
					
						
							| 
									
										
										
										
											2009-07-20 04:23:48 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-16 11:40:40 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  | (Frozen_ExecutionLoaderInheritanceTests, | 
					
						
							|  |  |  |  Source_ExecutionLoaderInheritanceTests | 
					
						
							|  |  |  |  ) = test_util.test_both(ExecutionLoader, abc=abc) | 
					
						
							| 
									
										
										
										
											2009-07-20 04:23:48 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-22 19:58:33 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-04 14:47:14 -04:00
										 |  |  | class FileLoader(InheritanceTests): | 
					
						
							|  |  |  |     superclass_names = ['ResourceLoader', 'ExecutionLoader'] | 
					
						
							|  |  |  |     subclass_names = ['SourceFileLoader', 'SourcelessFileLoader'] | 
					
						
							| 
									
										
										
										
											2012-04-22 19:58:33 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-16 11:40:40 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  | (Frozen_FileLoaderInheritanceTests, | 
					
						
							|  |  |  |  Source_FileLoaderInheritanceTests | 
					
						
							|  |  |  |  ) = test_util.test_both(FileLoader, abc=abc) | 
					
						
							| 
									
										
										
										
											2012-04-22 19:58:33 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-28 05:46:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-04 14:47:14 -04:00
										 |  |  | class SourceLoader(InheritanceTests): | 
					
						
							|  |  |  |     superclass_names = ['ResourceLoader', 'ExecutionLoader'] | 
					
						
							|  |  |  |     subclass_names = ['SourceFileLoader'] | 
					
						
							| 
									
										
										
										
											2010-06-28 05:46:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-16 11:40:40 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  | (Frozen_SourceLoaderInheritanceTests, | 
					
						
							|  |  |  |  Source_SourceLoaderInheritanceTests | 
					
						
							|  |  |  |  ) = test_util.test_both(SourceLoader, abc=abc) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-28 05:46:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-26 16:45:10 -04:00
										 |  |  | ##### Default return values #################################################### | 
					
						
							| 
									
										
										
										
											2014-05-16 11:40:40 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  | def make_abc_subclasses(base_class, name=None, inst=False, **kwargs): | 
					
						
							|  |  |  |     if name is None: | 
					
						
							|  |  |  |         name = base_class.__name__ | 
					
						
							|  |  |  |     base = {kind: getattr(splitabc, name) | 
					
						
							|  |  |  |             for kind, splitabc in abc.items()} | 
					
						
							|  |  |  |     return {cls._KIND: cls() if inst else cls | 
					
						
							|  |  |  |             for cls in test_util.split_frozen(base_class, base, **kwargs)} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class ABCTestHarness: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @property | 
					
						
							|  |  |  |     def ins(self): | 
					
						
							|  |  |  |         # Lazily set ins on the class. | 
					
						
							|  |  |  |         cls = self.SPLIT[self._KIND] | 
					
						
							|  |  |  |         ins = cls() | 
					
						
							|  |  |  |         self.__class__.ins = ins | 
					
						
							|  |  |  |         return ins | 
					
						
							| 
									
										
										
										
											2013-10-04 14:47:14 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class MetaPathFinder: | 
					
						
							| 
									
										
										
										
											2013-04-09 16:59:39 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-03 04:55:22 -07:00
										 |  |  |     pass | 
					
						
							| 
									
										
										
										
											2013-04-09 16:59:39 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-16 11:40:40 -06:00
										 |  |  | class MetaPathFinderDefaultsTests(ABCTestHarness): | 
					
						
							| 
									
										
										
										
											2013-04-09 16:59:39 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-16 11:40:40 -06:00
										 |  |  |     SPLIT = make_abc_subclasses(MetaPathFinder) | 
					
						
							| 
									
										
										
										
											2013-04-09 16:59:39 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_invalidate_caches(self): | 
					
						
							|  |  |  |         # Calling the method is a no-op. | 
					
						
							|  |  |  |         self.ins.invalidate_caches() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-16 11:40:40 -06:00
										 |  |  | (Frozen_MPFDefaultTests, | 
					
						
							|  |  |  |  Source_MPFDefaultTests | 
					
						
							|  |  |  |  ) = test_util.test_both(MetaPathFinderDefaultsTests) | 
					
						
							| 
									
										
										
										
											2013-10-04 14:47:14 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class PathEntryFinder: | 
					
						
							| 
									
										
										
										
											2013-04-09 16:59:39 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-03 04:55:22 -07:00
										 |  |  |     pass | 
					
						
							| 
									
										
										
										
											2013-04-09 16:59:39 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-16 11:40:40 -06:00
										 |  |  | class PathEntryFinderDefaultsTests(ABCTestHarness): | 
					
						
							| 
									
										
										
										
											2013-04-09 16:59:39 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-16 11:40:40 -06:00
										 |  |  |     SPLIT = make_abc_subclasses(PathEntryFinder) | 
					
						
							| 
									
										
										
										
											2013-04-09 16:59:39 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_invalidate_caches(self): | 
					
						
							|  |  |  |         # Should be a no-op. | 
					
						
							|  |  |  |         self.ins.invalidate_caches() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-16 11:40:40 -06:00
										 |  |  | (Frozen_PEFDefaultTests, | 
					
						
							|  |  |  |  Source_PEFDefaultTests | 
					
						
							|  |  |  |  ) = test_util.test_both(PathEntryFinderDefaultsTests) | 
					
						
							| 
									
										
										
										
											2013-10-04 14:47:14 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class Loader: | 
					
						
							| 
									
										
										
										
											2013-04-09 16:59:39 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-03 04:55:22 -07:00
										 |  |  |     pass | 
					
						
							| 
									
										
										
										
											2013-04-09 16:59:39 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-16 11:40:40 -06:00
										 |  |  | class LoaderDefaultsTests(ABCTestHarness): | 
					
						
							| 
									
										
										
										
											2013-10-04 14:47:14 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-16 11:40:40 -06:00
										 |  |  |     SPLIT = make_abc_subclasses(Loader) | 
					
						
							| 
									
										
										
										
											2013-04-09 16:59:39 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-10 16:21:03 -06:00
										 |  |  |     def test_create_module(self): | 
					
						
							|  |  |  |         spec = 'a spec' | 
					
						
							|  |  |  |         self.assertIsNone(self.ins.create_module(spec)) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-09 16:59:39 -04:00
										 |  |  |     def test_load_module(self): | 
					
						
							|  |  |  |         with self.assertRaises(ImportError): | 
					
						
							|  |  |  |             self.ins.load_module('something') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_module_repr(self): | 
					
						
							| 
									
										
										
										
											2013-06-15 18:39:21 -04:00
										 |  |  |         mod = types.ModuleType('blah') | 
					
						
							| 
									
										
										
										
											2021-03-26 11:55:07 -07:00
										 |  |  |         with warnings.catch_warnings(): | 
					
						
							| 
									
										
										
										
											2021-04-02 12:35:32 -07:00
										 |  |  |             warnings.simplefilter("ignore", DeprecationWarning) | 
					
						
							|  |  |  |             original_repr = repr(mod) | 
					
						
							|  |  |  |             mod.__loader__ = self.ins | 
					
						
							|  |  |  |             # Should still return a proper repr. | 
					
						
							|  |  |  |             self.assertTrue(repr(mod)) | 
					
						
							| 
									
										
										
										
											2013-04-09 16:59:39 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-16 11:40:40 -06:00
										 |  |  | (Frozen_LDefaultTests, | 
					
						
							|  |  |  |  SourceLDefaultTests | 
					
						
							|  |  |  |  ) = test_util.test_both(LoaderDefaultsTests) | 
					
						
							| 
									
										
										
										
											2013-10-04 14:47:14 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class ResourceLoader(Loader): | 
					
						
							| 
									
										
										
										
											2013-04-09 16:59:39 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def get_data(self, path): | 
					
						
							|  |  |  |         return super().get_data(path) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-16 11:40:40 -06:00
										 |  |  | class ResourceLoaderDefaultsTests(ABCTestHarness): | 
					
						
							| 
									
										
										
										
											2013-10-04 14:47:14 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-16 11:40:40 -06:00
										 |  |  |     SPLIT = make_abc_subclasses(ResourceLoader) | 
					
						
							| 
									
										
										
										
											2013-04-09 16:59:39 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_get_data(self): | 
					
						
							| 
									
										
										
										
											2025-01-16 21:29:16 +00:00
										 |  |  |         with ( | 
					
						
							|  |  |  |             self.assertRaises(IOError), | 
					
						
							|  |  |  |             self.assertWarnsRegex( | 
					
						
							|  |  |  |                 DeprecationWarning, | 
					
						
							|  |  |  |                 r"importlib\.abc\.ResourceLoader is deprecated in favour of " | 
					
						
							|  |  |  |                 r"supporting resource loading through importlib\.resources" | 
					
						
							|  |  |  |                 r"\.abc\.TraversableResources.", | 
					
						
							|  |  |  |             ), | 
					
						
							|  |  |  |         ): | 
					
						
							| 
									
										
										
										
											2013-04-09 16:59:39 -04:00
										 |  |  |             self.ins.get_data('/some/path') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-16 11:40:40 -06:00
										 |  |  | (Frozen_RLDefaultTests, | 
					
						
							|  |  |  |  Source_RLDefaultTests | 
					
						
							|  |  |  |  ) = test_util.test_both(ResourceLoaderDefaultsTests) | 
					
						
							| 
									
										
										
										
											2013-10-04 14:47:14 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class InspectLoader(Loader): | 
					
						
							| 
									
										
										
										
											2013-04-09 16:59:39 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def is_package(self, fullname): | 
					
						
							|  |  |  |         return super().is_package(fullname) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def get_source(self, fullname): | 
					
						
							|  |  |  |         return super().get_source(fullname) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-16 11:40:40 -06:00
										 |  |  | SPLIT_IL = make_abc_subclasses(InspectLoader) | 
					
						
							| 
									
										
										
										
											2013-04-09 16:59:39 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-04 14:47:14 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-16 11:40:40 -06:00
										 |  |  | class InspectLoaderDefaultsTests(ABCTestHarness): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     SPLIT = SPLIT_IL | 
					
						
							| 
									
										
										
										
											2013-04-09 16:59:39 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_is_package(self): | 
					
						
							|  |  |  |         with self.assertRaises(ImportError): | 
					
						
							|  |  |  |             self.ins.is_package('blah') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_get_source(self): | 
					
						
							|  |  |  |         with self.assertRaises(ImportError): | 
					
						
							|  |  |  |             self.ins.get_source('blah') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-16 11:40:40 -06:00
										 |  |  | (Frozen_ILDefaultTests, | 
					
						
							|  |  |  |  Source_ILDefaultTests | 
					
						
							|  |  |  |  ) = test_util.test_both(InspectLoaderDefaultsTests) | 
					
						
							| 
									
										
										
										
											2013-10-04 14:47:14 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class ExecutionLoader(InspectLoader): | 
					
						
							| 
									
										
										
										
											2013-04-09 16:59:39 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def get_filename(self, fullname): | 
					
						
							|  |  |  |         return super().get_filename(fullname) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-16 11:40:40 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  | SPLIT_EL = make_abc_subclasses(ExecutionLoader) | 
					
						
							| 
									
										
										
										
											2013-04-09 16:59:39 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-16 11:40:40 -06:00
										 |  |  | class ExecutionLoaderDefaultsTests(ABCTestHarness): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     SPLIT = SPLIT_EL | 
					
						
							| 
									
										
										
										
											2013-04-09 16:59:39 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_get_filename(self): | 
					
						
							|  |  |  |         with self.assertRaises(ImportError): | 
					
						
							|  |  |  |             self.ins.get_filename('blah') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-04 14:47:14 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-16 11:40:40 -06:00
										 |  |  | (Frozen_ELDefaultTests, | 
					
						
							|  |  |  |  Source_ELDefaultsTests | 
					
						
							|  |  |  |  ) = test_util.test_both(InspectLoaderDefaultsTests) | 
					
						
							| 
									
										
										
										
											2013-10-04 14:47:14 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-07 15:52:42 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-15 16:29:35 -08:00
										 |  |  | class ResourceReader: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def open_resource(self, *args, **kwargs): | 
					
						
							|  |  |  |         return super().open_resource(*args, **kwargs) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def resource_path(self, *args, **kwargs): | 
					
						
							|  |  |  |         return super().resource_path(*args, **kwargs) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def is_resource(self, *args, **kwargs): | 
					
						
							|  |  |  |         return super().is_resource(*args, **kwargs) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def contents(self, *args, **kwargs): | 
					
						
							|  |  |  |         return super().contents(*args, **kwargs) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-16 11:40:40 -06:00
										 |  |  | ##### MetaPathFinder concrete methods ########################################## | 
					
						
							| 
									
										
										
										
											2014-01-07 15:52:42 -05:00
										 |  |  | class MetaPathFinderFindModuleTests: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @classmethod | 
					
						
							|  |  |  |     def finder(cls, spec): | 
					
						
							|  |  |  |         class MetaPathSpecFinder(cls.abc.MetaPathFinder): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             def find_spec(self, fullname, path, target=None): | 
					
						
							|  |  |  |                 self.called_for = fullname, path | 
					
						
							|  |  |  |                 return spec | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return MetaPathSpecFinder() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 15:17:00 -03:00
										 |  |  |     def test_find_spec_with_explicit_target(self): | 
					
						
							|  |  |  |         loader = object() | 
					
						
							|  |  |  |         spec = self.util.spec_from_loader('blah', loader) | 
					
						
							|  |  |  |         finder = self.finder(spec) | 
					
						
							|  |  |  |         found = finder.find_spec('blah', 'blah', None) | 
					
						
							|  |  |  |         self.assertEqual(found, spec) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_no_spec(self): | 
					
						
							|  |  |  |         finder = self.finder(None) | 
					
						
							|  |  |  |         path = ['a', 'b', 'c'] | 
					
						
							|  |  |  |         name = 'blah' | 
					
						
							|  |  |  |         found = finder.find_spec(name, path, None) | 
					
						
							|  |  |  |         self.assertIsNone(found) | 
					
						
							| 
									
										
										
										
											2014-01-07 15:52:42 -05:00
										 |  |  |         self.assertEqual(name, finder.called_for[0]) | 
					
						
							|  |  |  |         self.assertEqual(path, finder.called_for[1]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_spec(self): | 
					
						
							|  |  |  |         loader = object() | 
					
						
							|  |  |  |         spec = self.util.spec_from_loader('blah', loader) | 
					
						
							|  |  |  |         finder = self.finder(spec) | 
					
						
							| 
									
										
										
										
											2019-06-21 15:17:00 -03:00
										 |  |  |         found = finder.find_spec('blah', None) | 
					
						
							|  |  |  |         self.assertIs(found, spec) | 
					
						
							| 
									
										
										
										
											2014-01-07 15:52:42 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-16 11:40:40 -06:00
										 |  |  | (Frozen_MPFFindModuleTests, | 
					
						
							|  |  |  |  Source_MPFFindModuleTests | 
					
						
							|  |  |  |  ) = test_util.test_both(MetaPathFinderFindModuleTests, abc=abc, util=util) | 
					
						
							| 
									
										
										
										
											2014-01-07 15:52:42 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ##### Loader concrete methods ################################################## | 
					
						
							|  |  |  | class LoaderLoadModuleTests: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def loader(self): | 
					
						
							|  |  |  |         class SpecLoader(self.abc.Loader): | 
					
						
							|  |  |  |             found = None | 
					
						
							|  |  |  |             def exec_module(self, module): | 
					
						
							|  |  |  |                 self.found = module | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             def is_package(self, fullname): | 
					
						
							|  |  |  |                 """Force some non-default module state to be set.""" | 
					
						
							|  |  |  |                 return True | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return SpecLoader() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_fresh(self): | 
					
						
							| 
									
										
										
										
											2020-12-04 15:39:21 -08:00
										 |  |  |         with warnings.catch_warnings(): | 
					
						
							|  |  |  |             warnings.simplefilter("ignore", DeprecationWarning) | 
					
						
							|  |  |  |             loader = self.loader() | 
					
						
							|  |  |  |             name = 'blah' | 
					
						
							|  |  |  |             with test_util.uncache(name): | 
					
						
							|  |  |  |                 loader.load_module(name) | 
					
						
							|  |  |  |                 module = loader.found | 
					
						
							|  |  |  |                 self.assertIs(sys.modules[name], module) | 
					
						
							|  |  |  |             self.assertEqual(loader, module.__loader__) | 
					
						
							|  |  |  |             self.assertEqual(loader, module.__spec__.loader) | 
					
						
							|  |  |  |             self.assertEqual(name, module.__name__) | 
					
						
							|  |  |  |             self.assertEqual(name, module.__spec__.name) | 
					
						
							|  |  |  |             self.assertIsNotNone(module.__path__) | 
					
						
							|  |  |  |             self.assertIsNotNone(module.__path__, | 
					
						
							|  |  |  |                                 module.__spec__.submodule_search_locations) | 
					
						
							| 
									
										
										
										
											2014-01-07 15:52:42 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_reload(self): | 
					
						
							| 
									
										
										
										
											2020-12-04 15:39:21 -08:00
										 |  |  |         with warnings.catch_warnings(): | 
					
						
							|  |  |  |             warnings.simplefilter("ignore", DeprecationWarning) | 
					
						
							|  |  |  |             name = 'blah' | 
					
						
							|  |  |  |             loader = self.loader() | 
					
						
							|  |  |  |             module = types.ModuleType(name) | 
					
						
							|  |  |  |             module.__spec__ = self.util.spec_from_loader(name, loader) | 
					
						
							|  |  |  |             module.__loader__ = loader | 
					
						
							|  |  |  |             with test_util.uncache(name): | 
					
						
							|  |  |  |                 sys.modules[name] = module | 
					
						
							|  |  |  |                 loader.load_module(name) | 
					
						
							|  |  |  |                 found = loader.found | 
					
						
							|  |  |  |                 self.assertIs(found, sys.modules[name]) | 
					
						
							|  |  |  |                 self.assertIs(module, sys.modules[name]) | 
					
						
							| 
									
										
										
										
											2014-01-07 15:52:42 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-16 11:40:40 -06:00
										 |  |  | (Frozen_LoaderLoadModuleTests, | 
					
						
							|  |  |  |  Source_LoaderLoadModuleTests | 
					
						
							|  |  |  |  ) = test_util.test_both(LoaderLoadModuleTests, abc=abc, util=util) | 
					
						
							| 
									
										
										
										
											2014-01-07 15:52:42 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-04 14:47:14 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-26 16:45:10 -04:00
										 |  |  | ##### InspectLoader concrete methods ########################################### | 
					
						
							| 
									
										
										
										
											2013-10-04 14:47:14 -04:00
										 |  |  | class InspectLoaderSourceToCodeTests: | 
					
						
							| 
									
										
										
										
											2013-05-26 16:45:10 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def source_to_module(self, data, path=None): | 
					
						
							|  |  |  |         """Help with source_to_code() tests.""" | 
					
						
							| 
									
										
										
										
											2013-06-15 18:39:21 -04:00
										 |  |  |         module = types.ModuleType('blah') | 
					
						
							| 
									
										
										
										
											2013-10-04 14:47:14 -04:00
										 |  |  |         loader = self.InspectLoaderSubclass() | 
					
						
							| 
									
										
										
										
											2013-05-26 16:45:10 -04:00
										 |  |  |         if path is None: | 
					
						
							|  |  |  |             code = loader.source_to_code(data) | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             code = loader.source_to_code(data, path) | 
					
						
							|  |  |  |         exec(code, module.__dict__) | 
					
						
							|  |  |  |         return module | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_source_to_code_source(self): | 
					
						
							|  |  |  |         # Since compile() can handle strings, so should source_to_code(). | 
					
						
							|  |  |  |         source = 'attr = 42' | 
					
						
							|  |  |  |         module = self.source_to_module(source) | 
					
						
							|  |  |  |         self.assertTrue(hasattr(module, 'attr')) | 
					
						
							|  |  |  |         self.assertEqual(module.attr, 42) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_source_to_code_bytes(self): | 
					
						
							|  |  |  |         # Since compile() can handle bytes, so should source_to_code(). | 
					
						
							|  |  |  |         source = b'attr = 42' | 
					
						
							|  |  |  |         module = self.source_to_module(source) | 
					
						
							|  |  |  |         self.assertTrue(hasattr(module, 'attr')) | 
					
						
							|  |  |  |         self.assertEqual(module.attr, 42) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_source_to_code_path(self): | 
					
						
							|  |  |  |         # Specifying a path should set it for the code object. | 
					
						
							|  |  |  |         path = 'path/to/somewhere' | 
					
						
							| 
									
										
										
										
											2013-10-04 14:47:14 -04:00
										 |  |  |         loader = self.InspectLoaderSubclass() | 
					
						
							| 
									
										
										
										
											2013-05-26 16:45:10 -04:00
										 |  |  |         code = loader.source_to_code('', path) | 
					
						
							|  |  |  |         self.assertEqual(code.co_filename, path) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_source_to_code_no_path(self): | 
					
						
							|  |  |  |         # Not setting a path should still work and be set to <string> since that | 
					
						
							|  |  |  |         # is a pre-existing practice as a default to compile(). | 
					
						
							| 
									
										
										
										
											2013-10-04 14:47:14 -04:00
										 |  |  |         loader = self.InspectLoaderSubclass() | 
					
						
							| 
									
										
										
										
											2013-05-26 16:45:10 -04:00
										 |  |  |         code = loader.source_to_code('') | 
					
						
							|  |  |  |         self.assertEqual(code.co_filename, '<string>') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-16 11:40:40 -06:00
										 |  |  | (Frozen_ILSourceToCodeTests, | 
					
						
							|  |  |  |  Source_ILSourceToCodeTests | 
					
						
							|  |  |  |  ) = test_util.test_both(InspectLoaderSourceToCodeTests, | 
					
						
							|  |  |  |                          InspectLoaderSubclass=SPLIT_IL) | 
					
						
							| 
									
										
										
										
											2013-10-04 14:47:14 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class InspectLoaderGetCodeTests: | 
					
						
							| 
									
										
										
										
											2013-05-27 21:11:04 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_get_code(self): | 
					
						
							|  |  |  |         # Test success. | 
					
						
							| 
									
										
										
										
											2013-06-15 18:39:21 -04:00
										 |  |  |         module = types.ModuleType('blah') | 
					
						
							| 
									
										
										
										
											2013-10-04 14:47:14 -04:00
										 |  |  |         with mock.patch.object(self.InspectLoaderSubclass, 'get_source') as mocked: | 
					
						
							| 
									
										
										
										
											2013-05-27 21:11:04 -04:00
										 |  |  |             mocked.return_value = 'attr = 42' | 
					
						
							| 
									
										
										
										
											2013-10-04 14:47:14 -04:00
										 |  |  |             loader = self.InspectLoaderSubclass() | 
					
						
							| 
									
										
										
										
											2013-05-27 21:11:04 -04:00
										 |  |  |             code = loader.get_code('blah') | 
					
						
							|  |  |  |         exec(code, module.__dict__) | 
					
						
							|  |  |  |         self.assertEqual(module.attr, 42) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_get_code_source_is_None(self): | 
					
						
							|  |  |  |         # If get_source() is None then this should be None. | 
					
						
							| 
									
										
										
										
											2013-10-04 14:47:14 -04:00
										 |  |  |         with mock.patch.object(self.InspectLoaderSubclass, 'get_source') as mocked: | 
					
						
							| 
									
										
										
										
											2013-05-27 21:11:04 -04:00
										 |  |  |             mocked.return_value = None | 
					
						
							| 
									
										
										
										
											2013-10-04 14:47:14 -04:00
										 |  |  |             loader = self.InspectLoaderSubclass() | 
					
						
							| 
									
										
										
										
											2013-05-27 21:11:04 -04:00
										 |  |  |             code = loader.get_code('blah') | 
					
						
							|  |  |  |         self.assertIsNone(code) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_get_code_source_not_found(self): | 
					
						
							|  |  |  |         # If there is no source then there is no code object. | 
					
						
							| 
									
										
										
										
											2013-10-04 14:47:14 -04:00
										 |  |  |         loader = self.InspectLoaderSubclass() | 
					
						
							| 
									
										
										
										
											2013-05-27 21:11:04 -04:00
										 |  |  |         with self.assertRaises(ImportError): | 
					
						
							|  |  |  |             loader.get_code('blah') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-16 11:40:40 -06:00
										 |  |  | (Frozen_ILGetCodeTests, | 
					
						
							|  |  |  |  Source_ILGetCodeTests | 
					
						
							|  |  |  |  ) = test_util.test_both(InspectLoaderGetCodeTests, | 
					
						
							|  |  |  |                          InspectLoaderSubclass=SPLIT_IL) | 
					
						
							| 
									
										
										
										
											2013-10-04 14:47:14 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class InspectLoaderLoadModuleTests: | 
					
						
							| 
									
										
										
										
											2013-05-31 18:56:47 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     """Test InspectLoader.load_module().""" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     module_name = 'blah' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def setUp(self): | 
					
						
							| 
									
										
										
										
											2020-08-04 23:53:12 +08:00
										 |  |  |         import_helper.unload(self.module_name) | 
					
						
							|  |  |  |         self.addCleanup(import_helper.unload, self.module_name) | 
					
						
							| 
									
										
										
										
											2013-05-31 18:56:47 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-10 16:21:03 -06:00
										 |  |  |     def load(self, loader): | 
					
						
							|  |  |  |         spec = self.util.spec_from_loader(self.module_name, loader) | 
					
						
							|  |  |  |         with warnings.catch_warnings(): | 
					
						
							|  |  |  |             warnings.simplefilter('ignore', DeprecationWarning) | 
					
						
							|  |  |  |             return self.init._bootstrap._load_unlocked(spec) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-31 18:56:47 -04:00
										 |  |  |     def mock_get_code(self): | 
					
						
							| 
									
										
										
										
											2013-10-04 14:47:14 -04:00
										 |  |  |         return mock.patch.object(self.InspectLoaderSubclass, 'get_code') | 
					
						
							| 
									
										
										
										
											2013-05-31 18:56:47 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_get_code_ImportError(self): | 
					
						
							|  |  |  |         # If get_code() raises ImportError, it should propagate. | 
					
						
							|  |  |  |         with self.mock_get_code() as mocked_get_code: | 
					
						
							|  |  |  |             mocked_get_code.side_effect = ImportError | 
					
						
							|  |  |  |             with self.assertRaises(ImportError): | 
					
						
							| 
									
										
										
										
											2013-10-04 14:47:14 -04:00
										 |  |  |                 loader = self.InspectLoaderSubclass() | 
					
						
							| 
									
										
										
										
											2016-05-10 16:21:03 -06:00
										 |  |  |                 self.load(loader) | 
					
						
							| 
									
										
										
										
											2013-05-31 18:56:47 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_get_code_None(self): | 
					
						
							|  |  |  |         # If get_code() returns None, raise ImportError. | 
					
						
							|  |  |  |         with self.mock_get_code() as mocked_get_code: | 
					
						
							|  |  |  |             mocked_get_code.return_value = None | 
					
						
							|  |  |  |             with self.assertRaises(ImportError): | 
					
						
							| 
									
										
										
										
											2013-10-04 14:47:14 -04:00
										 |  |  |                 loader = self.InspectLoaderSubclass() | 
					
						
							| 
									
										
										
										
											2016-05-10 16:21:03 -06:00
										 |  |  |                 self.load(loader) | 
					
						
							| 
									
										
										
										
											2013-05-31 18:56:47 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_module_returned(self): | 
					
						
							|  |  |  |         # The loaded module should be returned. | 
					
						
							|  |  |  |         code = compile('attr = 42', '<string>', 'exec') | 
					
						
							|  |  |  |         with self.mock_get_code() as mocked_get_code: | 
					
						
							|  |  |  |             mocked_get_code.return_value = code | 
					
						
							| 
									
										
										
										
											2013-10-04 14:47:14 -04:00
										 |  |  |             loader = self.InspectLoaderSubclass() | 
					
						
							| 
									
										
										
										
											2016-05-10 16:21:03 -06:00
										 |  |  |             module = self.load(loader) | 
					
						
							| 
									
										
										
										
											2013-05-31 18:56:47 -04:00
										 |  |  |             self.assertEqual(module, sys.modules[self.module_name]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-16 11:40:40 -06:00
										 |  |  | (Frozen_ILLoadModuleTests, | 
					
						
							|  |  |  |  Source_ILLoadModuleTests | 
					
						
							|  |  |  |  ) = test_util.test_both(InspectLoaderLoadModuleTests, | 
					
						
							| 
									
										
										
										
											2016-05-10 16:21:03 -06:00
										 |  |  |                          InspectLoaderSubclass=SPLIT_IL, | 
					
						
							|  |  |  |                          init=init, | 
					
						
							|  |  |  |                          util=util) | 
					
						
							| 
									
										
										
										
											2013-10-04 14:47:14 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-27 21:11:04 -04:00
										 |  |  | ##### ExecutionLoader concrete methods ######################################### | 
					
						
							| 
									
										
										
										
											2013-10-04 14:47:14 -04:00
										 |  |  | class ExecutionLoaderGetCodeTests: | 
					
						
							| 
									
										
										
										
											2013-05-27 21:11:04 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def mock_methods(self, *, get_source=False, get_filename=False): | 
					
						
							|  |  |  |         source_mock_context, filename_mock_context = None, None | 
					
						
							|  |  |  |         if get_source: | 
					
						
							| 
									
										
										
										
											2013-10-04 14:47:14 -04:00
										 |  |  |             source_mock_context = mock.patch.object(self.ExecutionLoaderSubclass, | 
					
						
							| 
									
										
										
										
											2013-05-27 21:11:04 -04:00
										 |  |  |                                                     'get_source') | 
					
						
							|  |  |  |         if get_filename: | 
					
						
							| 
									
										
										
										
											2013-10-04 14:47:14 -04:00
										 |  |  |             filename_mock_context = mock.patch.object(self.ExecutionLoaderSubclass, | 
					
						
							| 
									
										
										
										
											2013-05-27 21:11:04 -04:00
										 |  |  |                                                       'get_filename') | 
					
						
							|  |  |  |         return source_mock_context, filename_mock_context | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_get_code(self): | 
					
						
							|  |  |  |         path = 'blah.py' | 
					
						
							|  |  |  |         source_mock_context, filename_mock_context = self.mock_methods( | 
					
						
							|  |  |  |                 get_source=True, get_filename=True) | 
					
						
							|  |  |  |         with source_mock_context as source_mock, filename_mock_context as name_mock: | 
					
						
							|  |  |  |             source_mock.return_value = 'attr = 42' | 
					
						
							|  |  |  |             name_mock.return_value = path | 
					
						
							| 
									
										
										
										
											2013-10-04 14:47:14 -04:00
										 |  |  |             loader = self.ExecutionLoaderSubclass() | 
					
						
							| 
									
										
										
										
											2013-05-27 21:11:04 -04:00
										 |  |  |             code = loader.get_code('blah') | 
					
						
							|  |  |  |         self.assertEqual(code.co_filename, path) | 
					
						
							| 
									
										
										
										
											2013-06-15 18:39:21 -04:00
										 |  |  |         module = types.ModuleType('blah') | 
					
						
							| 
									
										
										
										
											2013-05-27 21:11:04 -04:00
										 |  |  |         exec(code, module.__dict__) | 
					
						
							|  |  |  |         self.assertEqual(module.attr, 42) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_get_code_source_is_None(self): | 
					
						
							|  |  |  |         # If get_source() is None then this should be None. | 
					
						
							|  |  |  |         source_mock_context, _ = self.mock_methods(get_source=True) | 
					
						
							|  |  |  |         with source_mock_context as mocked: | 
					
						
							|  |  |  |             mocked.return_value = None | 
					
						
							| 
									
										
										
										
											2013-10-04 14:47:14 -04:00
										 |  |  |             loader = self.ExecutionLoaderSubclass() | 
					
						
							| 
									
										
										
										
											2013-05-27 21:11:04 -04:00
										 |  |  |             code = loader.get_code('blah') | 
					
						
							|  |  |  |         self.assertIsNone(code) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_get_code_source_not_found(self): | 
					
						
							|  |  |  |         # If there is no source then there is no code object. | 
					
						
							| 
									
										
										
										
											2013-10-04 14:47:14 -04:00
										 |  |  |         loader = self.ExecutionLoaderSubclass() | 
					
						
							| 
									
										
										
										
											2013-05-27 21:11:04 -04:00
										 |  |  |         with self.assertRaises(ImportError): | 
					
						
							|  |  |  |             loader.get_code('blah') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_get_code_no_path(self): | 
					
						
							|  |  |  |         # If get_filename() raises ImportError then simply skip setting the path | 
					
						
							|  |  |  |         # on the code object. | 
					
						
							|  |  |  |         source_mock_context, filename_mock_context = self.mock_methods( | 
					
						
							|  |  |  |                 get_source=True, get_filename=True) | 
					
						
							|  |  |  |         with source_mock_context as source_mock, filename_mock_context as name_mock: | 
					
						
							|  |  |  |             source_mock.return_value = 'attr = 42' | 
					
						
							|  |  |  |             name_mock.side_effect = ImportError | 
					
						
							| 
									
										
										
										
											2013-10-04 14:47:14 -04:00
										 |  |  |             loader = self.ExecutionLoaderSubclass() | 
					
						
							| 
									
										
										
										
											2013-05-27 21:11:04 -04:00
										 |  |  |             code = loader.get_code('blah') | 
					
						
							|  |  |  |         self.assertEqual(code.co_filename, '<string>') | 
					
						
							| 
									
										
										
										
											2013-06-15 18:39:21 -04:00
										 |  |  |         module = types.ModuleType('blah') | 
					
						
							| 
									
										
										
										
											2013-05-27 21:11:04 -04:00
										 |  |  |         exec(code, module.__dict__) | 
					
						
							|  |  |  |         self.assertEqual(module.attr, 42) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-16 11:40:40 -06:00
										 |  |  | (Frozen_ELGetCodeTests, | 
					
						
							|  |  |  |  Source_ELGetCodeTests | 
					
						
							|  |  |  |  ) = test_util.test_both(ExecutionLoaderGetCodeTests, | 
					
						
							|  |  |  |                          ExecutionLoaderSubclass=SPLIT_EL) | 
					
						
							| 
									
										
										
										
											2013-10-04 14:47:14 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-26 16:45:10 -04:00
										 |  |  | ##### SourceLoader concrete methods ############################################ | 
					
						
							| 
									
										
										
										
											2014-05-16 11:40:40 -06:00
										 |  |  | class SourceOnlyLoader: | 
					
						
							| 
									
										
										
										
											2013-04-09 16:59:39 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # Globals that should be defined for all modules. | 
					
						
							|  |  |  |     source = (b"_ = '::'.join([__name__, __file__, __cached__, __package__, " | 
					
						
							|  |  |  |               b"repr(__loader__)])") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def __init__(self, path): | 
					
						
							|  |  |  |         self.path = path | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def get_data(self, path): | 
					
						
							|  |  |  |         if path != self.path: | 
					
						
							|  |  |  |             raise IOError | 
					
						
							|  |  |  |         return self.source | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def get_filename(self, fullname): | 
					
						
							|  |  |  |         return self.path | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-16 11:40:40 -06:00
										 |  |  | SPLIT_SOL = make_abc_subclasses(SourceOnlyLoader, 'SourceLoader') | 
					
						
							| 
									
										
										
										
											2013-10-04 14:47:14 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-16 11:40:40 -06:00
										 |  |  | class SourceLoader(SourceOnlyLoader): | 
					
						
							| 
									
										
										
										
											2013-04-09 16:59:39 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     source_mtime = 1 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-04 14:47:14 -04:00
										 |  |  |     def __init__(self, path, magic=None): | 
					
						
							| 
									
										
										
										
											2013-04-09 16:59:39 -04:00
										 |  |  |         super().__init__(path) | 
					
						
							| 
									
										
										
										
											2013-10-04 14:47:14 -04:00
										 |  |  |         self.bytecode_path = self.util.cache_from_source(self.path) | 
					
						
							| 
									
										
										
										
											2013-04-09 16:59:39 -04:00
										 |  |  |         self.source_size = len(self.source) | 
					
						
							| 
									
										
										
										
											2013-10-04 14:47:14 -04:00
										 |  |  |         if magic is None: | 
					
						
							|  |  |  |             magic = self.util.MAGIC_NUMBER | 
					
						
							| 
									
										
										
										
											2013-04-09 16:59:39 -04:00
										 |  |  |         data = bytearray(magic) | 
					
						
							| 
									
										
										
										
											2018-09-18 22:22:29 +03:00
										 |  |  |         data.extend(self.init._pack_uint32(0)) | 
					
						
							|  |  |  |         data.extend(self.init._pack_uint32(self.source_mtime)) | 
					
						
							|  |  |  |         data.extend(self.init._pack_uint32(self.source_size)) | 
					
						
							| 
									
										
										
										
											2013-04-09 16:59:39 -04:00
										 |  |  |         code_object = compile(self.source, self.path, 'exec', | 
					
						
							|  |  |  |                                 dont_inherit=True) | 
					
						
							|  |  |  |         data.extend(marshal.dumps(code_object)) | 
					
						
							|  |  |  |         self.bytecode = bytes(data) | 
					
						
							|  |  |  |         self.written = {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def get_data(self, path): | 
					
						
							|  |  |  |         if path == self.path: | 
					
						
							|  |  |  |             return super().get_data(path) | 
					
						
							|  |  |  |         elif path == self.bytecode_path: | 
					
						
							|  |  |  |             return self.bytecode | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             raise OSError | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def path_stats(self, path): | 
					
						
							|  |  |  |         if path != self.path: | 
					
						
							|  |  |  |             raise IOError | 
					
						
							|  |  |  |         return {'mtime': self.source_mtime, 'size': self.source_size} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def set_data(self, path, data): | 
					
						
							|  |  |  |         self.written[path] = bytes(data) | 
					
						
							|  |  |  |         return path == self.bytecode_path | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-16 11:40:40 -06:00
										 |  |  | SPLIT_SL = make_abc_subclasses(SourceLoader, util=util, init=init) | 
					
						
							| 
									
										
										
										
											2013-10-04 14:47:14 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class SourceLoaderTestHarness: | 
					
						
							| 
									
										
										
										
											2013-04-09 16:59:39 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def setUp(self, *, is_package=True, **kwargs): | 
					
						
							|  |  |  |         self.package = 'pkg' | 
					
						
							|  |  |  |         if is_package: | 
					
						
							|  |  |  |             self.path = os.path.join(self.package, '__init__.py') | 
					
						
							|  |  |  |             self.name = self.package | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             module_name = 'mod' | 
					
						
							|  |  |  |             self.path = os.path.join(self.package, '.'.join(['mod', 'py'])) | 
					
						
							|  |  |  |             self.name = '.'.join([self.package, module_name]) | 
					
						
							| 
									
										
										
										
											2013-10-04 14:47:14 -04:00
										 |  |  |         self.cached = self.util.cache_from_source(self.path) | 
					
						
							| 
									
										
										
										
											2013-04-09 16:59:39 -04:00
										 |  |  |         self.loader = self.loader_mock(self.path, **kwargs) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def verify_module(self, module): | 
					
						
							|  |  |  |         self.assertEqual(module.__name__, self.name) | 
					
						
							|  |  |  |         self.assertEqual(module.__file__, self.path) | 
					
						
							|  |  |  |         self.assertEqual(module.__cached__, self.cached) | 
					
						
							|  |  |  |         self.assertEqual(module.__package__, self.package) | 
					
						
							|  |  |  |         self.assertEqual(module.__loader__, self.loader) | 
					
						
							|  |  |  |         values = module._.split('::') | 
					
						
							|  |  |  |         self.assertEqual(values[0], self.name) | 
					
						
							|  |  |  |         self.assertEqual(values[1], self.path) | 
					
						
							|  |  |  |         self.assertEqual(values[2], self.cached) | 
					
						
							|  |  |  |         self.assertEqual(values[3], self.package) | 
					
						
							|  |  |  |         self.assertEqual(values[4], repr(self.loader)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def verify_code(self, code_object): | 
					
						
							| 
									
										
										
										
											2013-06-15 18:39:21 -04:00
										 |  |  |         module = types.ModuleType(self.name) | 
					
						
							| 
									
										
										
										
											2013-04-09 16:59:39 -04:00
										 |  |  |         module.__file__ = self.path | 
					
						
							|  |  |  |         module.__cached__ = self.cached | 
					
						
							|  |  |  |         module.__package__ = self.package | 
					
						
							|  |  |  |         module.__loader__ = self.loader | 
					
						
							|  |  |  |         module.__path__ = [] | 
					
						
							|  |  |  |         exec(code_object, module.__dict__) | 
					
						
							|  |  |  |         self.verify_module(module) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class SourceOnlyLoaderTests(SourceLoaderTestHarness): | 
					
						
							| 
									
										
										
										
											2022-10-07 03:57:10 +03:00
										 |  |  |     """Test importlib.abc.SourceLoader for source-only loading.""" | 
					
						
							| 
									
										
										
										
											2013-04-09 16:59:39 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_get_source(self): | 
					
						
							|  |  |  |         # Verify the source code is returned as a string. | 
					
						
							|  |  |  |         # If an OSError is raised by get_data then raise ImportError. | 
					
						
							|  |  |  |         expected_source = self.loader.source.decode('utf-8') | 
					
						
							|  |  |  |         self.assertEqual(self.loader.get_source(self.name), expected_source) | 
					
						
							|  |  |  |         def raise_OSError(path): | 
					
						
							|  |  |  |             raise OSError | 
					
						
							|  |  |  |         self.loader.get_data = raise_OSError | 
					
						
							|  |  |  |         with self.assertRaises(ImportError) as cm: | 
					
						
							|  |  |  |             self.loader.get_source(self.name) | 
					
						
							|  |  |  |         self.assertEqual(cm.exception.name, self.name) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_is_package(self): | 
					
						
							|  |  |  |         # Properly detect when loading a package. | 
					
						
							|  |  |  |         self.setUp(is_package=False) | 
					
						
							|  |  |  |         self.assertFalse(self.loader.is_package(self.name)) | 
					
						
							|  |  |  |         self.setUp(is_package=True) | 
					
						
							|  |  |  |         self.assertTrue(self.loader.is_package(self.name)) | 
					
						
							|  |  |  |         self.assertFalse(self.loader.is_package(self.name + '.__init__')) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_get_code(self): | 
					
						
							|  |  |  |         # Verify the code object is created. | 
					
						
							|  |  |  |         code_object = self.loader.get_code(self.name) | 
					
						
							|  |  |  |         self.verify_code(code_object) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_source_to_code(self): | 
					
						
							|  |  |  |         # Verify the compiled code object. | 
					
						
							|  |  |  |         code = self.loader.source_to_code(self.loader.source, self.path) | 
					
						
							|  |  |  |         self.verify_code(code) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_load_module(self): | 
					
						
							|  |  |  |         # Loading a module should set __name__, __loader__, __package__, | 
					
						
							|  |  |  |         # __path__ (for packages), __file__, and __cached__. | 
					
						
							|  |  |  |         # The module should also be put into sys.modules. | 
					
						
							| 
									
										
										
										
											2020-12-04 15:39:21 -08:00
										 |  |  |         with warnings.catch_warnings(): | 
					
						
							|  |  |  |             warnings.simplefilter("ignore", ImportWarning) | 
					
						
							|  |  |  |             with test_util.uncache(self.name): | 
					
						
							|  |  |  |                 with warnings.catch_warnings(): | 
					
						
							|  |  |  |                     warnings.simplefilter('ignore', DeprecationWarning) | 
					
						
							|  |  |  |                     module = self.loader.load_module(self.name) | 
					
						
							|  |  |  |                 self.verify_module(module) | 
					
						
							|  |  |  |                 self.assertEqual(module.__path__, [os.path.dirname(self.path)]) | 
					
						
							|  |  |  |                 self.assertIn(self.name, sys.modules) | 
					
						
							| 
									
										
										
										
											2013-04-09 16:59:39 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_package_settings(self): | 
					
						
							|  |  |  |         # __package__ needs to be set, while __path__ is set on if the module | 
					
						
							|  |  |  |         # is a package. | 
					
						
							|  |  |  |         # Testing the values for a package are covered by test_load_module. | 
					
						
							| 
									
										
										
										
											2020-12-04 15:39:21 -08:00
										 |  |  |         with warnings.catch_warnings(): | 
					
						
							|  |  |  |             warnings.simplefilter("ignore", ImportWarning) | 
					
						
							|  |  |  |             self.setUp(is_package=False) | 
					
						
							|  |  |  |             with test_util.uncache(self.name): | 
					
						
							|  |  |  |                 with warnings.catch_warnings(): | 
					
						
							|  |  |  |                     warnings.simplefilter('ignore', DeprecationWarning) | 
					
						
							|  |  |  |                     module = self.loader.load_module(self.name) | 
					
						
							|  |  |  |                 self.verify_module(module) | 
					
						
							|  |  |  |                 self.assertFalse(hasattr(module, '__path__')) | 
					
						
							| 
									
										
										
										
											2013-04-09 16:59:39 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_get_source_encoding(self): | 
					
						
							|  |  |  |         # Source is considered encoded in UTF-8 by default unless otherwise | 
					
						
							|  |  |  |         # specified by an encoding line. | 
					
						
							|  |  |  |         source = "_ = 'ü'" | 
					
						
							|  |  |  |         self.loader.source = source.encode('utf-8') | 
					
						
							|  |  |  |         returned_source = self.loader.get_source(self.name) | 
					
						
							|  |  |  |         self.assertEqual(returned_source, source) | 
					
						
							|  |  |  |         source = "# coding: latin-1\n_ = ü" | 
					
						
							|  |  |  |         self.loader.source = source.encode('latin-1') | 
					
						
							|  |  |  |         returned_source = self.loader.get_source(self.name) | 
					
						
							|  |  |  |         self.assertEqual(returned_source, source) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-16 11:40:40 -06:00
										 |  |  | (Frozen_SourceOnlyLoaderTests, | 
					
						
							|  |  |  |  Source_SourceOnlyLoaderTests | 
					
						
							|  |  |  |  ) = test_util.test_both(SourceOnlyLoaderTests, util=util, | 
					
						
							|  |  |  |                          loader_mock=SPLIT_SOL) | 
					
						
							| 
									
										
										
										
											2013-10-04 14:47:14 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-09 16:59:39 -04:00
										 |  |  | @unittest.skipIf(sys.dont_write_bytecode, "sys.dont_write_bytecode is true") | 
					
						
							|  |  |  | class SourceLoaderBytecodeTests(SourceLoaderTestHarness): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     """Test importlib.abc.SourceLoader's use of bytecode.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Source-only testing handled by SourceOnlyLoaderTests. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def verify_code(self, code_object, *, bytecode_written=False): | 
					
						
							|  |  |  |         super().verify_code(code_object) | 
					
						
							|  |  |  |         if bytecode_written: | 
					
						
							|  |  |  |             self.assertIn(self.cached, self.loader.written) | 
					
						
							| 
									
										
										
										
											2013-10-04 14:47:14 -04:00
										 |  |  |             data = bytearray(self.util.MAGIC_NUMBER) | 
					
						
							| 
									
										
										
										
											2018-09-18 22:22:29 +03:00
										 |  |  |             data.extend(self.init._pack_uint32(0)) | 
					
						
							|  |  |  |             data.extend(self.init._pack_uint32(self.loader.source_mtime)) | 
					
						
							|  |  |  |             data.extend(self.init._pack_uint32(self.loader.source_size)) | 
					
						
							| 
									
										
										
										
											2013-04-09 16:59:39 -04:00
										 |  |  |             data.extend(marshal.dumps(code_object)) | 
					
						
							|  |  |  |             self.assertEqual(self.loader.written[self.cached], bytes(data)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_code_with_everything(self): | 
					
						
							|  |  |  |         # When everything should work. | 
					
						
							|  |  |  |         code_object = self.loader.get_code(self.name) | 
					
						
							|  |  |  |         self.verify_code(code_object) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_no_bytecode(self): | 
					
						
							|  |  |  |         # If no bytecode exists then move on to the source. | 
					
						
							|  |  |  |         self.loader.bytecode_path = "<does not exist>" | 
					
						
							|  |  |  |         # Sanity check | 
					
						
							|  |  |  |         with self.assertRaises(OSError): | 
					
						
							| 
									
										
										
										
											2013-10-04 14:47:14 -04:00
										 |  |  |             bytecode_path = self.util.cache_from_source(self.path) | 
					
						
							| 
									
										
										
										
											2013-04-09 16:59:39 -04:00
										 |  |  |             self.loader.get_data(bytecode_path) | 
					
						
							|  |  |  |         code_object = self.loader.get_code(self.name) | 
					
						
							|  |  |  |         self.verify_code(code_object, bytecode_written=True) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_code_bad_timestamp(self): | 
					
						
							|  |  |  |         # Bytecode is only used when the timestamp matches the source EXACTLY. | 
					
						
							|  |  |  |         for source_mtime in (0, 2): | 
					
						
							|  |  |  |             assert source_mtime != self.loader.source_mtime | 
					
						
							|  |  |  |             original = self.loader.source_mtime | 
					
						
							|  |  |  |             self.loader.source_mtime = source_mtime | 
					
						
							|  |  |  |             # If bytecode is used then EOFError would be raised by marshal. | 
					
						
							|  |  |  |             self.loader.bytecode = self.loader.bytecode[8:] | 
					
						
							|  |  |  |             code_object = self.loader.get_code(self.name) | 
					
						
							|  |  |  |             self.verify_code(code_object, bytecode_written=True) | 
					
						
							|  |  |  |             self.loader.source_mtime = original | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_code_bad_magic(self): | 
					
						
							|  |  |  |         # Skip over bytecode with a bad magic number. | 
					
						
							|  |  |  |         self.setUp(magic=b'0000') | 
					
						
							|  |  |  |         # If bytecode is used then EOFError would be raised by marshal. | 
					
						
							|  |  |  |         self.loader.bytecode = self.loader.bytecode[8:] | 
					
						
							|  |  |  |         code_object = self.loader.get_code(self.name) | 
					
						
							|  |  |  |         self.verify_code(code_object, bytecode_written=True) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_dont_write_bytecode(self): | 
					
						
							|  |  |  |         # Bytecode is not written if sys.dont_write_bytecode is true. | 
					
						
							|  |  |  |         # Can assume it is false already thanks to the skipIf class decorator. | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             sys.dont_write_bytecode = True | 
					
						
							|  |  |  |             self.loader.bytecode_path = "<does not exist>" | 
					
						
							|  |  |  |             code_object = self.loader.get_code(self.name) | 
					
						
							|  |  |  |             self.assertNotIn(self.cached, self.loader.written) | 
					
						
							|  |  |  |         finally: | 
					
						
							|  |  |  |             sys.dont_write_bytecode = False | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_no_set_data(self): | 
					
						
							|  |  |  |         # If set_data is not defined, one can still read bytecode. | 
					
						
							|  |  |  |         self.setUp(magic=b'0000') | 
					
						
							| 
									
										
										
										
											2013-10-04 14:47:14 -04:00
										 |  |  |         original_set_data = self.loader.__class__.mro()[1].set_data | 
					
						
							| 
									
										
										
										
											2013-04-09 16:59:39 -04:00
										 |  |  |         try: | 
					
						
							| 
									
										
										
										
											2013-10-04 14:47:14 -04:00
										 |  |  |             del self.loader.__class__.mro()[1].set_data | 
					
						
							| 
									
										
										
										
											2013-04-09 16:59:39 -04:00
										 |  |  |             code_object = self.loader.get_code(self.name) | 
					
						
							|  |  |  |             self.verify_code(code_object) | 
					
						
							|  |  |  |         finally: | 
					
						
							| 
									
										
										
										
											2013-10-04 14:47:14 -04:00
										 |  |  |             self.loader.__class__.mro()[1].set_data = original_set_data | 
					
						
							| 
									
										
										
										
											2013-04-09 16:59:39 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_set_data_raises_exceptions(self): | 
					
						
							|  |  |  |         # Raising NotImplementedError or OSError is okay for set_data. | 
					
						
							|  |  |  |         def raise_exception(exc): | 
					
						
							|  |  |  |             def closure(*args, **kwargs): | 
					
						
							|  |  |  |                 raise exc | 
					
						
							|  |  |  |             return closure | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.setUp(magic=b'0000') | 
					
						
							|  |  |  |         self.loader.set_data = raise_exception(NotImplementedError) | 
					
						
							|  |  |  |         code_object = self.loader.get_code(self.name) | 
					
						
							|  |  |  |         self.verify_code(code_object) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-16 11:40:40 -06:00
										 |  |  | (Frozen_SLBytecodeTests, | 
					
						
							|  |  |  |  SourceSLBytecodeTests | 
					
						
							|  |  |  |  ) = test_util.test_both(SourceLoaderBytecodeTests, init=init, util=util, | 
					
						
							|  |  |  |                          loader_mock=SPLIT_SL) | 
					
						
							| 
									
										
										
										
											2013-10-04 14:47:14 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class SourceLoaderGetSourceTests: | 
					
						
							| 
									
										
										
										
											2013-04-09 16:59:39 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     """Tests for importlib.abc.SourceLoader.get_source().""" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_default_encoding(self): | 
					
						
							|  |  |  |         # Should have no problems with UTF-8 text. | 
					
						
							|  |  |  |         name = 'mod' | 
					
						
							| 
									
										
										
										
											2013-10-04 14:47:14 -04:00
										 |  |  |         mock = self.SourceOnlyLoaderMock('mod.file') | 
					
						
							| 
									
										
										
										
											2013-04-09 16:59:39 -04:00
										 |  |  |         source = 'x = "ü"' | 
					
						
							|  |  |  |         mock.source = source.encode('utf-8') | 
					
						
							|  |  |  |         returned_source = mock.get_source(name) | 
					
						
							|  |  |  |         self.assertEqual(returned_source, source) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_decoded_source(self): | 
					
						
							|  |  |  |         # Decoding should work. | 
					
						
							|  |  |  |         name = 'mod' | 
					
						
							| 
									
										
										
										
											2013-10-04 14:47:14 -04:00
										 |  |  |         mock = self.SourceOnlyLoaderMock("mod.file") | 
					
						
							| 
									
										
										
										
											2013-04-09 16:59:39 -04:00
										 |  |  |         source = "# coding: Latin-1\nx='ü'" | 
					
						
							|  |  |  |         assert source.encode('latin-1') != source.encode('utf-8') | 
					
						
							|  |  |  |         mock.source = source.encode('latin-1') | 
					
						
							|  |  |  |         returned_source = mock.get_source(name) | 
					
						
							|  |  |  |         self.assertEqual(returned_source, source) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_universal_newlines(self): | 
					
						
							|  |  |  |         # PEP 302 says universal newlines should be used. | 
					
						
							|  |  |  |         name = 'mod' | 
					
						
							| 
									
										
										
										
											2013-10-04 14:47:14 -04:00
										 |  |  |         mock = self.SourceOnlyLoaderMock('mod.file') | 
					
						
							| 
									
										
										
										
											2013-04-09 16:59:39 -04:00
										 |  |  |         source = "x = 42\r\ny = -13\r\n" | 
					
						
							|  |  |  |         mock.source = source.encode('utf-8') | 
					
						
							|  |  |  |         expect = io.IncrementalNewlineDecoder(None, True).decode(source) | 
					
						
							|  |  |  |         self.assertEqual(mock.get_source(name), expect) | 
					
						
							| 
									
										
										
										
											2009-03-09 03:35:50 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-16 11:40:40 -06:00
										 |  |  | (Frozen_SourceOnlyLoaderGetSourceTests, | 
					
						
							|  |  |  |  Source_SourceOnlyLoaderGetSourceTests | 
					
						
							|  |  |  |  ) = test_util.test_both(SourceLoaderGetSourceTests, | 
					
						
							|  |  |  |                          SourceOnlyLoaderMock=SPLIT_SOL) | 
					
						
							| 
									
										
										
										
											2013-10-04 14:47:14 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-15 01:48:46 +01:00
										 |  |  | class SourceLoaderDeprecationWarningsTests(unittest.TestCase): | 
					
						
							|  |  |  |     """Tests SourceLoader deprecation warnings.""" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_deprecated_path_mtime(self): | 
					
						
							|  |  |  |         from importlib.abc import SourceLoader | 
					
						
							|  |  |  |         class DummySourceLoader(SourceLoader): | 
					
						
							|  |  |  |             def get_data(self, path): | 
					
						
							|  |  |  |                 return b'' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             def get_filename(self, fullname): | 
					
						
							|  |  |  |                 return 'foo.py' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             def path_stats(self, path): | 
					
						
							|  |  |  |                 return {'mtime': 1} | 
					
						
							| 
									
										
										
										
											2025-01-16 21:29:16 +00:00
										 |  |  |         with self.assertWarnsRegex( | 
					
						
							|  |  |  |             DeprecationWarning, | 
					
						
							|  |  |  |             r"importlib\.abc\.ResourceLoader is deprecated in favour of " | 
					
						
							|  |  |  |             r"supporting resource loading through importlib\.resources" | 
					
						
							|  |  |  |             r"\.abc\.TraversableResources.", | 
					
						
							|  |  |  |         ): | 
					
						
							|  |  |  |             loader = DummySourceLoader() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         with self.assertWarnsRegex( | 
					
						
							|  |  |  |             DeprecationWarning, | 
					
						
							|  |  |  |             r"SourceLoader\.path_mtime is deprecated in favour of " | 
					
						
							|  |  |  |             r"SourceLoader\.path_stats\(\)\." | 
					
						
							|  |  |  |         ): | 
					
						
							| 
									
										
										
										
											2025-01-15 01:48:46 +01:00
										 |  |  |             loader.path_mtime('foo.py') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class ResourceLoaderDeprecationWarningsTests(unittest.TestCase): | 
					
						
							|  |  |  |     """Tests ResourceLoader deprecation warnings.""" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_deprecated_resource_loader(self): | 
					
						
							|  |  |  |         from importlib.abc import ResourceLoader | 
					
						
							|  |  |  |         class DummyLoader(ResourceLoader): | 
					
						
							|  |  |  |             def get_data(self, path): | 
					
						
							|  |  |  |                 return b'' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         with self.assertWarns(DeprecationWarning): | 
					
						
							|  |  |  |             DummyLoader() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-09 03:35:50 +00:00
										 |  |  | if __name__ == '__main__': | 
					
						
							| 
									
										
										
										
											2013-04-09 16:59:39 -04:00
										 |  |  |     unittest.main() |