# Buggy code
def add_defaults_to_specs(r, linked, specs, update=False):
    # TODO: This should use the pinning mechanism. But don't change the API:
    # cas uses it.
    if r.explicit(specs):
        return
    log.debug("H0 specs=%r" % specs)
    names_linked = {install.name_dist(dist): dist for dist in linked}
    names_ms = {MatchSpec(s).name: MatchSpec(s) for s in specs}

    for name, def_ver in [
        ("python", default_python),
        # Default version required, but only used for Python
        ("lua", None),
    ]:
        ms = names_ms.get(name)
        if ms and not ms.is_simple():
            # if any of the specifications mention the Python/Numpy version,
            # we don't need to add the default spec
            log.debug("H1 %s" % name)
            continue

        any_depends_on = any(
            ms2.name == name
            for spec in specs
            for fn in r.find_matches(spec)
            for ms2 in r.ms_depends(fn)
        )
        log.debug("H2 %s %s" % (name, any_depends_on))

        if not any_depends_on and name not in names_ms:
            # if nothing depends on Python/Numpy AND the Python/Numpy is not
            # specified, we don't need to add the default spec
            log.debug("H2A %s" % name)
            continue

        if any_depends_on and len(specs) >= 1 and MatchSpec(specs[0]).is_exact():
            # if something depends on Python/Numpy, but the spec is very
            # explicit, we also don't need to add the default spec
            log.debug("H2B %s" % name)
            continue

        if name in names_linked:
            # if Python/Numpy is already linked, we add that instead of the
            # default
            log.debug("H3 %s" % name)
            fkey = names_linked[name] + ".tar.bz2"
            info = r.index[fkey]
            ver = ".".join(info["version"].split(".", 2)[:2])
            spec = "%s %s*" % (info["name"], ver)
            if update:
                spec += " (target=%s)" % fkey
            specs.append(spec)
            continue

        if (name, def_ver) in [("python", "3.3"), ("python", "3.4"), ("python", "3.5")]:
            # Don't include Python 3 in the specs if this is the Python 3
            # version of conda.
            continue

        specs.append("%s %s*" % (name, def_ver))
    log.debug("HF specs=%r" % specs)


# Traceback (TypeError)
Traceback (most recent call last):
File "/home/ilan/minonda/bin/conda", line 6, in <module>
sys.exit(main())
File "/home/ilan/conda/conda/cli/main.py", line 120, in main
args_func(args, p)
File "/home/ilan/conda/conda/cli/main.py", line 127, in args_func
args.func(args, p)
File "/home/ilan/conda/conda/cli/main_install.py", line 62, in execute
install.install(args, parser, 'install')
File "/home/ilan/conda/conda/cli/install.py", line 394, in install
plan.execute_actions(actions, index, verbose=not args.quiet)
File "/home/ilan/conda/conda/plan.py", line 555, in execute_actions
inst.execute_instructions(plan, index, verbose)
File "/home/ilan/conda/conda/instructions.py", line 133, in execute_instructions
cmd(state, arg)
File "/home/ilan/conda/conda/instructions.py", line 80, in UNLINK_CMD
install.unlink(state['prefix'], arg)
File "/home/ilan/conda/conda/install.py", line 1075, in unlink
mk_menus(prefix, meta['files'], remove=True)
TypeError: 'NoneType' object has no attribute '__getitem__'

# Fixed code
def add_defaults_to_specs(r, linked, specs, update=False):
    # TODO: This should use the pinning mechanism. But don't change the API:
    # cas uses it.
    if r.explicit(specs):
        return
    log.debug("H0 specs=%r" % specs)
    linked = [fn if fn.endswith(".tar.bz2") else fn + ".tar.bz2" for fn in linked]
    names_linked = {r.index[fn]["name"]: fn for fn in linked}
    names_ms = {MatchSpec(s).name: MatchSpec(s) for s in specs}

    for name, def_ver in [
        ("python", default_python),
        # Default version required, but only used for Python
        ("lua", None),
    ]:
        ms = names_ms.get(name)
        if ms and not ms.is_simple():
            # if any of the specifications mention the Python/Numpy version,
            # we don't need to add the default spec
            log.debug("H1 %s" % name)
            continue

        any_depends_on = any(
            ms2.name == name
            for spec in specs
            for fn in r.find_matches(spec)
            for ms2 in r.ms_depends(fn)
        )
        log.debug("H2 %s %s" % (name, any_depends_on))

        if not any_depends_on and name not in names_ms:
            # if nothing depends on Python/Numpy AND the Python/Numpy is not
            # specified, we don't need to add the default spec
            log.debug("H2A %s" % name)
            continue

        if any_depends_on and len(specs) >= 1 and MatchSpec(specs[0]).is_exact():
            # if something depends on Python/Numpy, but the spec is very
            # explicit, we also don't need to add the default spec
            log.debug("H2B %s" % name)
            continue

        if name in names_linked:
            # if Python/Numpy is already linked, we add that instead of the
            # default
            log.debug("H3 %s" % name)
            fkey = names_linked[name]
            info = r.index[fkey]
            ver = ".".join(info["version"].split(".", 2)[:2])
            spec = "%s %s*" % (info["name"], ver)
            if update:
                spec += " (target=%s)" % fkey
            specs.append(spec)
            continue

        if (name, def_ver) in [("python", "3.3"), ("python", "3.4"), ("python", "3.5")]:
            # Don't include Python 3 in the specs if this is the Python 3
            # version of conda.
            continue

        specs.append("%s %s*" % (name, def_ver))
    log.debug("HF specs=%r" % specs)