mirror of
https://github.com/python/cpython.git
synced 2025-10-17 04:08:28 +00:00
Issues #18088, 18089: Introduce
importlib.abc.Loader.init_module_attrs() and implement importlib.abc.InspectLoader.load_module(). The importlib.abc.Loader.init_module_attrs() method sets the various attributes on the module being loaded. It is done unconditionally to support reloading. Typically people used importlib.util.module_for_loader, but since that's a decorator there was no way to override it's actions, so init_module_attrs() came into existence to allow for overriding. This is also why module_for_loader is now pending deprecation (having its other use replaced by importlib.util.module_to_load). All of this allowed for importlib.abc.InspectLoader.load_module() to be implemented. At this point you can now implement a loader with nothing more than get_code() (which only requires get_source(); package support requires is_package()). Thanks to init_module_attrs() the implementation of load_module() is basically a context manager containing 2 methods calls, a call to exec(), and a return statement.
This commit is contained in:
parent
f1d7b11db9
commit
0dbb4c7f13
10 changed files with 3934 additions and 3637 deletions
|
@ -5,6 +5,7 @@ import sys
|
|||
from test import support
|
||||
import types
|
||||
import unittest
|
||||
import warnings
|
||||
|
||||
|
||||
class ModuleToLoadTests(unittest.TestCase):
|
||||
|
@ -72,14 +73,27 @@ class ModuleForLoaderTests(unittest.TestCase):
|
|||
|
||||
"""Tests for importlib.util.module_for_loader."""
|
||||
|
||||
@staticmethod
|
||||
def module_for_loader(func):
|
||||
with warnings.catch_warnings():
|
||||
warnings.simplefilter('ignore', PendingDeprecationWarning)
|
||||
return util.module_for_loader(func)
|
||||
|
||||
def test_warning(self):
|
||||
# Should raise a PendingDeprecationWarning when used.
|
||||
with warnings.catch_warnings():
|
||||
warnings.simplefilter('error', PendingDeprecationWarning)
|
||||
with self.assertRaises(PendingDeprecationWarning):
|
||||
func = util.module_for_loader(lambda x: x)
|
||||
|
||||
def return_module(self, name):
|
||||
fxn = util.module_for_loader(lambda self, module: module)
|
||||
fxn = self.module_for_loader(lambda self, module: module)
|
||||
return fxn(self, name)
|
||||
|
||||
def raise_exception(self, name):
|
||||
def to_wrap(self, module):
|
||||
raise ImportError
|
||||
fxn = util.module_for_loader(to_wrap)
|
||||
fxn = self.module_for_loader(to_wrap)
|
||||
try:
|
||||
fxn(self, name)
|
||||
except ImportError:
|
||||
|
@ -100,7 +114,7 @@ class ModuleForLoaderTests(unittest.TestCase):
|
|||
class FakeLoader:
|
||||
def is_package(self, name):
|
||||
return True
|
||||
@util.module_for_loader
|
||||
@self.module_for_loader
|
||||
def load_module(self, module):
|
||||
return module
|
||||
name = 'a.b.c'
|
||||
|
@ -134,7 +148,7 @@ class ModuleForLoaderTests(unittest.TestCase):
|
|||
|
||||
def test_decorator_attrs(self):
|
||||
def fxn(self, module): pass
|
||||
wrapped = util.module_for_loader(fxn)
|
||||
wrapped = self.module_for_loader(fxn)
|
||||
self.assertEqual(wrapped.__name__, fxn.__name__)
|
||||
self.assertEqual(wrapped.__qualname__, fxn.__qualname__)
|
||||
|
||||
|
@ -160,7 +174,7 @@ class ModuleForLoaderTests(unittest.TestCase):
|
|||
self._pkg = is_package
|
||||
def is_package(self, name):
|
||||
return self._pkg
|
||||
@util.module_for_loader
|
||||
@self.module_for_loader
|
||||
def load_module(self, module):
|
||||
return module
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue