# Buggy code
def install(
    name=None,
    refresh=False,
    fromrepo=None,
    skip_verify=False,
    debconf=None,
    pkgs=None,
    sources=None,
    **kwargs,
):
    """
    Install the passed package, add refresh=True to update the dpkg database.

    name
        The name of the package to be installed. Note that this parameter is
        ignored if either "pkgs" or "sources" is passed. Additionally, please
        note that this option can only be used to install packages from a
        software repository. To install a package file manually, use the
        "sources" option.

        32-bit packages can be installed on 64-bit systems by appending the
        architecture designation (``:i386``, etc.) to the end of the package
        name.

        CLI Example:

        .. code-block:: bash

            salt '*' pkg.install <package name>

    refresh
        Whether or not to refresh the package database before installing.

    fromrepo
        Specify a package repository to install from
        (e.g., ``apt-get -t unstable install somepackage``)

    skip_verify
        Skip the GPG verification check (e.g., ``--allow-unauthenticated``, or
        ``--force-bad-verify`` for install from package file).

    debconf
        Provide the path to a debconf answers file, processed before
        installation.

    version
        Install a specific version of the package, e.g. 1.2.3~0ubuntu0. Ignored
        if "pkgs" or "sources" is passed.


    Multiple Package Installation Options:

    pkgs
        A list of packages to install from a software repository. Must be
        passed as a python list.

        CLI Example:

        .. code-block:: bash

            salt '*' pkg.install pkgs='["foo", "bar"]'
            salt '*' pkg.install pkgs='["foo", {"bar": "1.2.3-0ubuntu0"}]'

    sources
        A list of DEB packages to install. Must be passed as a list of dicts,
        with the keys being package names, and the values being the source URI
        or local path to the package.

        32-bit packages can be installed on 64-bit systems by appending the
        architecture designation (``:i386``, etc.) to the end of the package
        name.

        CLI Example:

        .. code-block:: bash

            salt '*' pkg.install sources='[{"foo": "salt://foo.deb"},{"bar": "salt://bar.deb"}]'


    Returns a dict containing the new package names and versions::

        {'<package>': {'old': '<old-version>',
                       'new': '<new-version>'}}
    """
    if salt.utils.is_true(refresh):
        refresh_db()

    if debconf:
        __salt__["debconf.set_file"](debconf)

    pkg_params, pkg_type = __salt__["pkg_resource.parse_targets"](
        name, pkgs, sources, **kwargs
    )

    # Support old "repo" argument
    repo = kwargs.get("repo", "")
    if not fromrepo and repo:
        fromrepo = repo

    if kwargs.get("env"):
        try:
            os.environ.update(kwargs.get("env"))
        except Exception as e:
            log.exception(e)

    old = list_pkgs()

    downgrade = False
    if pkg_params is None or len(pkg_params) == 0:
        return {}
    elif pkg_type == "file":
        cmd = "dpkg -i {confold} {verify} {pkg}".format(
            confold="--force-confold",
            verify="--force-bad-verify" if skip_verify else "",
            pkg=" ".join(pkg_params),
        )
    elif pkg_type == "repository":
        if pkgs is None and kwargs.get("version") and len(pkg_params) == 1:
            # Only use the 'version' param if 'name' was not specified as a
            # comma-separated list
            pkg_params = {name: kwargs.get("version")}
        targets = []
        for param, version_num in pkg_params.iteritems():
            if version_num is None:
                targets.append(param)
            else:
                cver = old.get(param)
                if cver is not None and __salt__["pkg.compare"](
                    pkg1=version_num, oper="<", pkg2=cver
                ):
                    downgrade = True
                targets.append('"{0}={1}"'.format(param, version_num))
        if fromrepo:
            log.info('Targeting repo "{0}"'.format(fromrepo))
        cmd = (
            "apt-get -q -y {force_yes} {confold} {confdef} {verify} "
            "{target} install {pkg}".format(
                force_yes="--force-yes" if downgrade else "",
                confold="-o DPkg::Options::=--force-confold",
                confdef="-o DPkg::Options::=--force-confdef",
                verify="--allow-unauthenticated" if skip_verify else "",
                target="-t {0}".format(fromrepo) if fromrepo else "",
                pkg=" ".join(targets),
            )
        )

    __salt__["cmd.run_all"](cmd)
    __context__.pop("pkg.list_pkgs", None)
    new = list_pkgs()
    return __salt__["pkg_resource.find_changes"](old, new)


# Traceback (AttributeError)
[ERROR   ] Error in function _master_opts:
Traceback (most recent call last):
File "/usr/lib/pymodules/python2.7/salt/master.py", line 1444, in run_func
ret = getattr(self, func)(load)
File "/usr/lib/pymodules/python2.7/salt/master.py", line 891, in _master_opts
envs = self._file_envs()
File "/usr/lib/pymodules/python2.7/salt/fileserver/__init__.py", line 153, in envs
ret.update(self.servers[fstr]())
File "/usr/lib/pymodules/python2.7/salt/fileserver/hgfs.py", line 176, in envs
tags = repo.get_tags()
AttributeError: 'hgclient' object has no attribute 'get_tags'

# Fixed code
def install(
    name=None,
    refresh=False,
    fromrepo=None,
    skip_verify=False,
    debconf=None,
    pkgs=None,
    sources=None,
    **kwargs,
):
    """
    Install the passed package, add refresh=True to update the dpkg database.

    name
        The name of the package to be installed. Note that this parameter is
        ignored if either "pkgs" or "sources" is passed. Additionally, please
        note that this option can only be used to install packages from a
        software repository. To install a package file manually, use the
        "sources" option.

        32-bit packages can be installed on 64-bit systems by appending the
        architecture designation (``:i386``, etc.) to the end of the package
        name.

        CLI Example:

        .. code-block:: bash

            salt '*' pkg.install <package name>

    refresh
        Whether or not to refresh the package database before installing.

    fromrepo
        Specify a package repository to install from
        (e.g., ``apt-get -t unstable install somepackage``)

    skip_verify
        Skip the GPG verification check (e.g., ``--allow-unauthenticated``, or
        ``--force-bad-verify`` for install from package file).

    debconf
        Provide the path to a debconf answers file, processed before
        installation.

    version
        Install a specific version of the package, e.g. 1.2.3~0ubuntu0. Ignored
        if "pkgs" or "sources" is passed.


    Multiple Package Installation Options:

    pkgs
        A list of packages to install from a software repository. Must be
        passed as a python list.

        CLI Example:

        .. code-block:: bash

            salt '*' pkg.install pkgs='["foo", "bar"]'
            salt '*' pkg.install pkgs='["foo", {"bar": "1.2.3-0ubuntu0"}]'

    sources
        A list of DEB packages to install. Must be passed as a list of dicts,
        with the keys being package names, and the values being the source URI
        or local path to the package.

        32-bit packages can be installed on 64-bit systems by appending the
        architecture designation (``:i386``, etc.) to the end of the package
        name.

        CLI Example:

        .. code-block:: bash

            salt '*' pkg.install sources='[{"foo": "salt://foo.deb"},{"bar": "salt://bar.deb"}]'


    Returns a dict containing the new package names and versions::

        {'<package>': {'old': '<old-version>',
                       'new': '<new-version>'}}
    """
    if salt.utils.is_true(refresh):
        refresh_db()

    if debconf:
        __salt__["debconf.set_file"](debconf)

    pkg_params, pkg_type = __salt__["pkg_resource.parse_targets"](
        name, pkgs, sources, **kwargs
    )

    # Support old "repo" argument
    repo = kwargs.get("repo", "")
    if not fromrepo and repo:
        fromrepo = repo

    if kwargs.get("env"):
        try:
            os.environ.update(kwargs.get("env"))
        except Exception as e:
            log.exception(e)

    old = list_pkgs()

    downgrade = False
    if pkg_params is None or len(pkg_params) == 0:
        return {}
    elif pkg_type == "file":
        cmd = "dpkg -i {confold} {verify} {pkg}".format(
            confold="--force-confold",
            verify="--force-bad-verify" if skip_verify else "",
            pkg=" ".join(pkg_params),
        )
    elif pkg_type == "repository":
        if pkgs is None and kwargs.get("version") and len(pkg_params) == 1:
            # Only use the 'version' param if 'name' was not specified as a
            # comma-separated list
            pkg_params = {name: kwargs.get("version")}
        targets = []
        for param, version_num in pkg_params.iteritems():
            if version_num is None:
                targets.append(param)
            else:
                cver = old.get(param)
                if cver is not None and salt.utils.compare_versions(
                    ver1=version_num, oper="<", ver2=cver, cmp_func=version_cmp
                ):
                    downgrade = True
                targets.append('"{0}={1}"'.format(param, version_num))
        if fromrepo:
            log.info('Targeting repo "{0}"'.format(fromrepo))
        cmd = (
            "apt-get -q -y {force_yes} {confold} {confdef} {verify} "
            "{target} install {pkg}".format(
                force_yes="--force-yes" if downgrade else "",
                confold="-o DPkg::Options::=--force-confold",
                confdef="-o DPkg::Options::=--force-confdef",
                verify="--allow-unauthenticated" if skip_verify else "",
                target="-t {0}".format(fromrepo) if fromrepo else "",
                pkg=" ".join(targets),
            )
        )

    __salt__["cmd.run_all"](cmd)
    __context__.pop("pkg.list_pkgs", None)
    new = list_pkgs()
    return __salt__["pkg_resource.find_changes"](old, new)