diff options
Diffstat (limited to 'Lib/importlib/util.py')
| -rw-r--r-- | Lib/importlib/util.py | 28 | 
1 files changed, 13 insertions, 15 deletions
| diff --git a/Lib/importlib/util.py b/Lib/importlib/util.py index e1fa07a664..6bdf0d445d 100644 --- a/Lib/importlib/util.py +++ b/Lib/importlib/util.py @@ -22,8 +22,8 @@ def resolve_name(name, package):      if not name.startswith('.'):          return name      elif not package: -        raise ValueError('{!r} is not a relative name ' -                         '(no leading dot)'.format(name)) +        raise ValueError(f'no package specified for {repr(name)} ' +                         '(required for relative module names)')      level = 0      for character in name:          if character != '.': @@ -204,11 +204,6 @@ def module_for_loader(fxn):      return module_for_loader_wrapper -class _Module(types.ModuleType): - -    """A subclass of the module type to allow __class__ manipulation.""" - -  class _LazyModule(types.ModuleType):      """A subclass of the module type which triggers loading upon attribute access.""" @@ -218,13 +213,14 @@ class _LazyModule(types.ModuleType):          # All module metadata must be garnered from __spec__ in order to avoid          # using mutated values.          # Stop triggering this method. -        self.__class__ = _Module +        self.__class__ = types.ModuleType          # Get the original name to make sure no object substitution occurred          # in sys.modules.          original_name = self.__spec__.name          # Figure out exactly what attributes were mutated between the creation          # of the module and now. -        attrs_then = self.__spec__.loader_state +        attrs_then = self.__spec__.loader_state['__dict__'] +        original_type = self.__spec__.loader_state['__class__']          attrs_now = self.__dict__          attrs_updated = {}          for key, value in attrs_now.items(): @@ -239,9 +235,9 @@ class _LazyModule(types.ModuleType):          # object was put into sys.modules.          if original_name in sys.modules:              if id(self) != id(sys.modules[original_name]): -                msg = ('module object for {!r} substituted in sys.modules ' -                       'during a lazy load') -                raise ValueError(msg.format(original_name)) +                raise ValueError(f"module object for {original_name!r} " +                                  "substituted in sys.modules during a lazy " +                                  "load")          # Update after loading since that's what would happen in an eager          # loading situation.          self.__dict__.update(attrs_updated) @@ -275,8 +271,7 @@ class LazyLoader(abc.Loader):          self.loader = loader      def create_module(self, spec): -        """Create a module which can have its __class__ manipulated.""" -        return _Module(spec.name) +        return self.loader.create_module(spec)      def exec_module(self, module):          """Make the module load lazily.""" @@ -286,5 +281,8 @@ class LazyLoader(abc.Loader):          # on an object would have triggered the load,          # e.g. ``module.__spec__.loader = None`` would trigger a load from          # trying to access module.__spec__. -        module.__spec__.loader_state = module.__dict__.copy() +        loader_state = {} +        loader_state['__dict__'] = module.__dict__.copy() +        loader_state['__class__'] = module.__class__ +        module.__spec__.loader_state = loader_state          module.__class__ = _LazyModule | 
