code: def exec_module(self, module):
      try:
          # Perform all actions of the original loader
          self._orig_loader.exec_module(module)
      except BaseException:
          raise  # We re-raise it always; the `finally` clause will still restore things
      else:
          # It loaded, we move and rename appropriately
          module.__spec__.name = self._fullname
          module.__orig_name__ = module.__name__
          module.__name__ = self._fullname
          module.__package__ = (
              module.__spec__.parent
          )  # assumption since 3.6
          sys.modules[self._fullname] = module
          del sys.modules[self._orig_name]
  
      finally:
          # At this point, the original module is loaded with the original name. We
          # want to replace it with previously_loaded_module if it exists. We
          # also replace the parent properly
          if self._previously_loaded_module:
              sys.modules[
                  self._orig_name
              ] = self._previously_loaded_module
          if self._previously_loaded_parent_module:
              sys.modules[
                  ".".join(self._orig_name.split(".")[:-1])
              ] = self._previously_loaded_parent_module
  
imports: from __future__ import print_function
  import importlib
  import json
  import os
  import re
  import sys
  import types
  from collections import defaultdict, namedtuple
  from importlib.abc import MetaPathFinder, Loader
  from itertools import chain
label_desc: Use image node_id 3 for calling the _OrigLoader obj's underlying member method code with example usage: obj.exec_module(module) without return types