# Buggy code
def _load_module(self, name):
    mod = None
    fpath, suffix = self.file_mapping[name]
    self.loaded_files.add(name)
    try:
        sys.path.append(os.path.dirname(fpath))
        if suffix == ".pyx":
            mod = pyximport.load_module(name, fpath, tempfile.gettempdir())
        elif suffix == ".o":
            top_mod = __import__(fpath, globals(), locals(), [])
            comps = fpath.split(".")
            if len(comps) < 2:
                mod = top_mod
            else:
                mod = top_mod
                for subname in comps[1:]:
                    mod = getattr(mod, subname)
        elif suffix == ".zip":
            mod = zipimporter(fpath).load_module(name)
        else:
            desc = self.suffix_map[suffix]
            # if it is a directory, we dont open a file
            if suffix == "":
                mod = imp.load_module(
                    "{0}.{1}.{2}.{3}".format(
                        self.loaded_base_name,
                        self.mod_type_check(fpath),
                        self.tag,
                        name,
                    ),
                    None,
                    fpath,
                    desc,
                )
                # reload all submodules if necessary
                if not self.initial_load:
                    self._reload_submodules(mod)
            else:
                with salt.utils.fopen(fpath, desc[1]) as fn_:
                    mod = imp.load_module(
                        "{0}.{1}.{2}.{3}".format(
                            self.loaded_base_name,
                            self.mod_type_check(fpath),
                            self.tag,
                            name,
                        ),
                        fn_,
                        fpath,
                        desc,
                    )

    except IOError:
        raise
    except ImportError:
        log.debug("Failed to import {0} {1}:\n".format(self.tag, name), exc_info=True)
        return False
    except Exception as error:
        log.error(
            "Failed to import {0} {1}, this is due most likely to a "
            "syntax error:\n".format(self.tag, name),
            exc_info=True,
        )
        return False
    except SystemExit:
        log.error(
            "Failed to import {0} {1} as the module called exit()\n".format(
                self.tag, name
            ),
            exc_info=True,
        )
        return False
    finally:
        sys.path.pop()

    if hasattr(mod, "__opts__"):
        mod.__opts__.update(self.opts)
    else:
        mod.__opts__ = self.opts

    mod.__grains__ = self._grains
    mod.__pillar__ = self._pillar

    # pack whatever other globals we were asked to
    for p_name, p_value in six.iteritems(self.pack):
        setattr(mod, p_name, p_value)

    module_name = mod.__name__.rsplit(".", 1)[-1]

    # Call a module's initialization method if it exists
    module_init = getattr(mod, "__init__", None)
    if inspect.isfunction(module_init):
        try:
            module_init(self.opts)
        except TypeError as e:
            log.error(e)
        except Exception:
            err_string = "__init__ failed"
            log.debug(
                "Error loading {0}.{1}: {2}".format(self.tag, module_name, err_string),
                exc_info=True,
            )
            self.missing_modules[module_name] = err_string
            self.missing_modules[name] = err_string
            return False

    # if virtual modules are enabled, we need to look for the
    # __virtual__() function inside that module and run it.
    if self.virtual_enable:
        (virtual_ret, module_name, virtual_err) = self.process_virtual(
            mod,
            module_name,
        )
        if virtual_err is not None:
            log.debug(
                "Error loading {0}.{1}: {2}".format(
                    self.tag,
                    module_name,
                    virtual_err,
                )
            )

        # if process_virtual returned a non-True value then we are
        # supposed to not process this module
        if virtual_ret is not True:
            # If a module has information about why it could not be loaded, record it
            self.missing_modules[module_name] = virtual_err
            self.missing_modules[name] = virtual_err
            return False

    # If this is a proxy minion then MOST modules cannot work. Therefore, require that
    # any module that does work with salt-proxy-minion define __proxyenabled__ as a list
    # containing the names of the proxy types that the module supports.
    #
    # Render modules and state modules are OK though
    if "proxymodule" in self.opts:
        if self.tag not in ["render", "states", "utils"]:
            if not hasattr(mod, "__proxyenabled__") or (
                self.opts["proxymodule"].loaded_base_name not in mod.__proxyenabled__
                and "*" not in mod.__proxyenabled__
            ):
                err_string = "not a proxy_minion enabled module"
                self.missing_modules[module_name] = err_string
                self.missing_modules[name] = err_string
                return False

    if getattr(mod, "__load__", False) is not False:
        log.info(
            "The functions from module '{0}' are being loaded from the "
            "provided __load__ attribute".format(module_name)
        )
    mod_dict = self.mod_dict_class()
    for attr in getattr(mod, "__load__", dir(mod)):
        if attr.startswith("_"):
            # private functions are skipped
            continue
        func = getattr(mod, attr)
        if not inspect.isfunction(func):
            # Not a function!? Skip it!!!
            continue
        # Let's get the function name.
        # If the module has the __func_alias__ attribute, it must be a
        # dictionary mapping in the form of(key -> value):
        #   <real-func-name> -> <desired-func-name>
        #
        # It default's of course to the found callable attribute name
        # if no alias is defined.
        funcname = getattr(mod, "__func_alias__", {}).get(attr, attr)
        # Save many references for lookups
        self._dict["{0}.{1}".format(module_name, funcname)] = func
        setattr(mod_dict, funcname, func)
        mod_dict[funcname] = func
        self._apply_outputter(func, mod)

    # enforce depends
    try:
        Depends.enforce_dependencies(self._dict, self.tag)
    except RuntimeError as exc:
        log.info("Depends.enforce_dependencies() failed for reasons: {0}".format(exc))

    self.loaded_modules[module_name] = mod_dict
    return True


# Traceback (RuntimeError)
2015-05-05 15:52:48,917 [salt.loader                                ][ERROR   ][25815] Failed to read the virtual function for states: xmpp
Traceback (most recent call last):
File "/usr/lib/python2.6/site-packages/salt/loader.py", line 1098, in process_virtual
virtual = mod.__virtual__()
File "/usr/lib/python2.6/site-packages/salt/states/xmpp.py", line 25, in __virtual__
return 'xmpp' if 'xmpp.send_msg' in __salt__ else False
File "/usr/lib64/python2.6/_abcoll.py", line 342, in __contains__
self[key]
File "/usr/lib/python2.6/site-packages/salt/utils/lazy.py", line 85, in __getitem__
if self._load(key):
File "/usr/lib/python2.6/site-packages/salt/loader.py", line 1024, in _load
ret = _inner_load(mod_name)
File "/usr/lib/python2.6/site-packages/salt/loader.py", line 1013, in _inner_load
if self._load_module(name) and key in self._dict:
File "/usr/lib/python2.6/site-packages/salt/loader.py", line 990, in _load_module
Depends.enforce_dependencies(self._dict, self.tag)
File "/usr/lib/python2.6/site-packages/salt/utils/decorators/__init__.py", line 81, in enforce_dependencies
for module, func, fallback_function in dependent_set:
RuntimeError: Set changed size during iteration

# Fixed code
def _load_module(self, name):
    mod = None
    fpath, suffix = self.file_mapping[name]
    self.loaded_files.add(name)
    try:
        sys.path.append(os.path.dirname(fpath))
        if suffix == ".pyx":
            mod = pyximport.load_module(name, fpath, tempfile.gettempdir())
        elif suffix == ".o":
            top_mod = __import__(fpath, globals(), locals(), [])
            comps = fpath.split(".")
            if len(comps) < 2:
                mod = top_mod
            else:
                mod = top_mod
                for subname in comps[1:]:
                    mod = getattr(mod, subname)
        elif suffix == ".zip":
            mod = zipimporter(fpath).load_module(name)
        else:
            desc = self.suffix_map[suffix]
            # if it is a directory, we dont open a file
            if suffix == "":
                mod = imp.load_module(
                    "{0}.{1}.{2}.{3}".format(
                        self.loaded_base_name,
                        self.mod_type_check(fpath),
                        self.tag,
                        name,
                    ),
                    None,
                    fpath,
                    desc,
                )
                # reload all submodules if necessary
                if not self.initial_load:
                    self._reload_submodules(mod)
            else:
                with salt.utils.fopen(fpath, desc[1]) as fn_:
                    mod = imp.load_module(
                        "{0}.{1}.{2}.{3}".format(
                            self.loaded_base_name,
                            self.mod_type_check(fpath),
                            self.tag,
                            name,
                        ),
                        fn_,
                        fpath,
                        desc,
                    )

    except IOError:
        raise
    except ImportError:
        log.debug("Failed to import {0} {1}:\n".format(self.tag, name), exc_info=True)
        return False
    except Exception as error:
        log.error(
            "Failed to import {0} {1}, this is due most likely to a "
            "syntax error:\n".format(self.tag, name),
            exc_info=True,
        )
        return False
    except SystemExit:
        log.error(
            "Failed to import {0} {1} as the module called exit()\n".format(
                self.tag, name
            ),
            exc_info=True,
        )
        return False
    finally:
        sys.path.pop()

    if hasattr(mod, "__opts__"):
        mod.__opts__.update(self.opts)
    else:
        mod.__opts__ = self.opts

    # pack whatever other globals we were asked to
    for p_name, p_value in six.iteritems(self.pack):
        setattr(mod, p_name, p_value)

    module_name = mod.__name__.rsplit(".", 1)[-1]

    # Call a module's initialization method if it exists
    module_init = getattr(mod, "__init__", None)
    if inspect.isfunction(module_init):
        try:
            module_init(self.opts)
        except TypeError as e:
            log.error(e)
        except Exception:
            err_string = "__init__ failed"
            log.debug(
                "Error loading {0}.{1}: {2}".format(self.tag, module_name, err_string),
                exc_info=True,
            )
            self.missing_modules[module_name] = err_string
            self.missing_modules[name] = err_string
            return False

    # if virtual modules are enabled, we need to look for the
    # __virtual__() function inside that module and run it.
    if self.virtual_enable:
        (virtual_ret, module_name, virtual_err) = self.process_virtual(
            mod,
            module_name,
        )
        if virtual_err is not None:
            log.debug(
                "Error loading {0}.{1}: {2}".format(
                    self.tag,
                    module_name,
                    virtual_err,
                )
            )

        # if process_virtual returned a non-True value then we are
        # supposed to not process this module
        if virtual_ret is not True:
            # If a module has information about why it could not be loaded, record it
            self.missing_modules[module_name] = virtual_err
            self.missing_modules[name] = virtual_err
            return False

    # If this is a proxy minion then MOST modules cannot work. Therefore, require that
    # any module that does work with salt-proxy-minion define __proxyenabled__ as a list
    # containing the names of the proxy types that the module supports.
    #
    # Render modules and state modules are OK though
    if "proxymodule" in self.opts:
        if self.tag not in ["render", "states", "utils"]:
            if not hasattr(mod, "__proxyenabled__") or (
                self.opts["proxymodule"].loaded_base_name not in mod.__proxyenabled__
                and "*" not in mod.__proxyenabled__
            ):
                err_string = "not a proxy_minion enabled module"
                self.missing_modules[module_name] = err_string
                self.missing_modules[name] = err_string
                return False

    if getattr(mod, "__load__", False) is not False:
        log.info(
            "The functions from module '{0}' are being loaded from the "
            "provided __load__ attribute".format(module_name)
        )
    mod_dict = self.mod_dict_class()
    for attr in getattr(mod, "__load__", dir(mod)):
        if attr.startswith("_"):
            # private functions are skipped
            continue
        func = getattr(mod, attr)
        if not inspect.isfunction(func):
            # Not a function!? Skip it!!!
            continue
        # Let's get the function name.
        # If the module has the __func_alias__ attribute, it must be a
        # dictionary mapping in the form of(key -> value):
        #   <real-func-name> -> <desired-func-name>
        #
        # It default's of course to the found callable attribute name
        # if no alias is defined.
        funcname = getattr(mod, "__func_alias__", {}).get(attr, attr)
        # Save many references for lookups
        self._dict["{0}.{1}".format(module_name, funcname)] = func
        setattr(mod_dict, funcname, func)
        mod_dict[funcname] = func
        self._apply_outputter(func, mod)

    # enforce depends
    try:
        Depends.enforce_dependencies(self._dict, self.tag)
    except RuntimeError as exc:
        log.info("Depends.enforce_dependencies() failed for reasons: {0}".format(exc))

    self.loaded_modules[module_name] = mod_dict
    return True