mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 21:51:50 +00:00 
			
		
		
		
	Expose importlib.util.set___package__.
This commit is contained in:
		
							parent
							
								
									4d4975c0e4
								
							
						
					
					
						commit
						57b46f5b0e
					
				
					 4 changed files with 77 additions and 35 deletions
				
			
		|  | @ -167,20 +167,28 @@ an :term:`importer`. | ||||||
|     A :term:`decorator` for a :term:`loader` which handles selecting the proper |     A :term:`decorator` for a :term:`loader` which handles selecting the proper | ||||||
|     module object to load with. The decorated method is expected to have a call |     module object to load with. The decorated method is expected to have a call | ||||||
|     signature of ``method(self, module_object)`` for which the second argument |     signature of ``method(self, module_object)`` for which the second argument | ||||||
|     will be the module object to be used (note that the decorator will not work |     will be the module object to be used by the loader (note that the decorator | ||||||
|     on static methods because of the assumption of two arguments). |     will not work on static methods because of the assumption of two | ||||||
|  |     arguments). | ||||||
| 
 | 
 | ||||||
|     The decorated method will take in the name of the module to be loaded as |     The decorated method will take in the name of the module to be loaded as | ||||||
|     normal. If the module is not found in :data:`sys.modules` then a new one is |     expected for a :term:`loader`. If the module is not found in | ||||||
|     constructed with its :attr:`__name__` attribute set. Otherwise the module |     :data:`sys.modules` then a new one is constructed with its | ||||||
|     found in :data:`sys.modules` will be passed into the method. If an |     :attr:`__name__` attribute set. Otherwise the module found in | ||||||
|  |     :data:`sys.modules` will be passed into the method. If an | ||||||
|     exception is raised by the decorated method and a module was added to |     exception is raised by the decorated method and a module was added to | ||||||
|     :data:`sys.modules` it will be removed to prevent a partially initialized |     :data:`sys.modules` it will be removed to prevent a partially initialized | ||||||
|     module from being in left in :data:`sys.modules` If an exception is raised |     module from being in left in :data:`sys.modules`. If the module was already | ||||||
|     by the decorated method and a module was added to :data:`sys.modules` it |     in :data:`sys.modules` then it is left alone. | ||||||
|     will be removed to prevent a partially initialized module from being in |  | ||||||
|     left in :data:`sys.modules`. If the module was already in |  | ||||||
|     :data:`sys.modules` then it is left alone. |  | ||||||
| 
 | 
 | ||||||
|     Use of this decorator handles all the details of what module a loader |     Use of this decorator handles all the details of what module object a | ||||||
|     should use as specified by :pep:`302`. |     loader should initialize as specified by :pep:`302`. | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | .. function:: set___package__(method) | ||||||
|  | 
 | ||||||
|  |     A :term:`decorator` for a :term:`loader` to set the :attr:`__package__` | ||||||
|  |     attribute on the module returned by the loader. If :attr:`__package__` is | ||||||
|  |     set and has a value other than :keyword:`None` it will not be changed. | ||||||
|  |     Note that the module returned by the loader is what has the attribute | ||||||
|  |     set on and not the module found in :data:`sys.modules`. | ||||||
|  |  | ||||||
|  | @ -1,10 +1,6 @@ | ||||||
| to do | to do | ||||||
| ///// | ///// | ||||||
| 
 | 
 | ||||||
| * Implement PEP 302 protocol for loaders (should just be a matter of testing). |  | ||||||
| 
 |  | ||||||
|     + Source/bytecode. |  | ||||||
| 
 |  | ||||||
| * Public API left to expose (w/ docs!) | * Public API left to expose (w/ docs!) | ||||||
| 
 | 
 | ||||||
|     + abc |     + abc | ||||||
|  | @ -27,27 +23,15 @@ to do | ||||||
|             * get_code |             * get_code | ||||||
|             * get_source |             * get_source | ||||||
| 
 | 
 | ||||||
|         - (?) SourceLoader(ResourceLoader) |         - PyLoader(ResourceLoader) | ||||||
| 
 | 
 | ||||||
|             * source_path |             * source_path | ||||||
|  | 
 | ||||||
|  |         - PyPycLoader(PyLoader) | ||||||
|  | 
 | ||||||
|  |             * source_mtime | ||||||
|             * bytecode_path |             * bytecode_path | ||||||
|             * write_bytecode (not abstract) |             * write_bytecode | ||||||
| 
 |  | ||||||
|     + util |  | ||||||
| 
 |  | ||||||
|         - set___package__ decorator |  | ||||||
| 
 |  | ||||||
|     + machinery |  | ||||||
| 
 |  | ||||||
|         - Extensions importers |  | ||||||
| 
 |  | ||||||
|             * ExtensionFinder |  | ||||||
|             * (?) Loader |  | ||||||
| 
 |  | ||||||
|         - Source/bytecode importers |  | ||||||
| 
 |  | ||||||
|             * SourceFinder |  | ||||||
|             * (?) Loader |  | ||||||
| 
 | 
 | ||||||
|     + test (Really want to worry about compatibility with future versions?) |     + test (Really want to worry about compatibility with future versions?) | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -60,9 +60,58 @@ def test_reload_failure(self): | ||||||
|             self.assert_(sys.modules[name] is module) |             self.assert_(sys.modules[name] is module) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | class SetPackageTests(unittest.TestCase): | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     """Tests for importlib.util.set___package__.""" | ||||||
|  | 
 | ||||||
|  |     def verify(self, module, expect): | ||||||
|  |         """Verify the module has the expected value for __package__ after | ||||||
|  |         passing through set___package__.""" | ||||||
|  |         fxn = lambda: module | ||||||
|  |         wrapped = util.set___package__(fxn) | ||||||
|  |         wrapped() | ||||||
|  |         self.assert_(hasattr(module, '__package__')) | ||||||
|  |         self.assertEqual(expect, module.__package__) | ||||||
|  | 
 | ||||||
|  |     def test_top_level(self): | ||||||
|  |         # __package__ should be set to the empty string if a top-level module. | ||||||
|  |         # Implicitly tests when package is set to None. | ||||||
|  |         module = imp.new_module('module') | ||||||
|  |         module.__package__ = None | ||||||
|  |         self.verify(module, '') | ||||||
|  | 
 | ||||||
|  |     def test_package(self): | ||||||
|  |         # Test setting __package__ for a package. | ||||||
|  |         module = imp.new_module('pkg') | ||||||
|  |         module.__path__ = ['<path>'] | ||||||
|  |         module.__package__ = None | ||||||
|  |         self.verify(module, 'pkg') | ||||||
|  | 
 | ||||||
|  |     def test_submodule(self): | ||||||
|  |         # Test __package__ for a module in a package. | ||||||
|  |         module = imp.new_module('pkg.mod') | ||||||
|  |         module.__package__ = None | ||||||
|  |         self.verify(module, 'pkg') | ||||||
|  | 
 | ||||||
|  |     def test_setting_if_missing(self): | ||||||
|  |         # __package__ should be set if it is missing. | ||||||
|  |         module = imp.new_module('mod') | ||||||
|  |         if hasattr(module, '__package__'): | ||||||
|  |             delattr(module, '__package__') | ||||||
|  |         self.verify(module, '') | ||||||
|  | 
 | ||||||
|  |     def test_leaving_alone(self): | ||||||
|  |         # If __package__ is set and not None then leave it alone. | ||||||
|  |         for value in (True, False): | ||||||
|  |             module = imp.new_module('mod') | ||||||
|  |             module.__package__ = value | ||||||
|  |             self.verify(module, value) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| def test_main(): | def test_main(): | ||||||
|     from test import support |     from test import support | ||||||
|     support.run_unittest(ModuleForLoaderTests) |     support.run_unittest(ModuleForLoaderTests, SetPackageTests) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| if __name__ == '__main__': | if __name__ == '__main__': | ||||||
|  |  | ||||||
|  | @ -1,2 +1,3 @@ | ||||||
| """Utility code for constructing importers, etc.""" | """Utility code for constructing importers, etc.""" | ||||||
| from ._bootstrap import module_for_loader | from ._bootstrap import module_for_loader | ||||||
|  | from ._bootstrap import set___package__ | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Brett Cannon
						Brett Cannon