Calculating reverse dependencies of a Debian package It works pretty well, but I suspect there's too many variables, and I wonder what else.

I'm using this library: Python APT.

#!/usr/bin/env python3

import argparse
import apt

def getdeps(deptype, pkg, otherpkg):
    deps = list()
    name = otherpkg.shortname
    otherpkg = otherpkg.candidate
    for deplist in otherpkg.get_dependencies(deptype):
        for dep in deplist.or_dependencies:
            if dep.name == pkg.shortname:
                deps.append(name)
    return deps


def reverse_dependencies(pkg):
    """Which packages have some kind of dependency on the given package"""

    cache = apt.cache.Cache()
    try:
        pkg = cache[pkg]
    except KeyError as e:
        print(str(e).strip('"'))
        return 1

    dependents = dict()
    recommends = list()
    suggests = list()
    replaces = list()
    enhances = list()
    depends = list()

    for key in cache.keys():
        otherpkg = cache[key]
        depends.append(getdeps("Depends", pkg, otherpkg))
        recommends.append(getdeps("Recommends", pkg, otherpkg))
        suggests.append(getdeps("Suggests", pkg, otherpkg))
        replaces.append(getdeps("Replaces", pkg, otherpkg))
        enhances.append(getdeps("Enhances", pkg, otherpkg))

    dependents["Depends"] = depends
    dependents["Recommends"] = recommends
    dependents["Suggests"] = suggests
    dependents["Replaces"] = replaces
    dependents["Enhances"] = enhances

    for deptype, deps in dependents.items():
        deps_output = list()
        for match in deps:
            if match:
                for item in match:
                    deps_output.append(item)
        if deps_output:
            print(deptype.upper(), end=": ")
            print(" ".join(deps_output))

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument("pkg", help="pkg to describe")
    args = parser.parse_args()
    reverse_dependencies(args.pkg)


Example terminal session:

$ ./rdeps.py python3-apt
DEPENDS: python3-apt-dbg wajig
ENHANCES: python-apt-common
#!/usr/bin/env python3

import argparse
import apt

def getdeps(deptype, pkg, otherpkg):


I recommend not using abbrivates like dep or pkg.

    deps = list()


We usually create lists with [] not list()

    name = otherpkg.shortname
    otherpkg = otherpkg.candidate


I wouldn't do this. You only use it once, so its actually best to just otherpkg.candidate.get_dependencies Generally, I recommend against replacing one variable with another because often it increases confusion.

    for deplist in otherpkg.get_dependencies(deptype):
        for dep in deplist.or_dependencies:
            if dep.name == pkg.shortname:
                deps.append(name)

    return deps


Why does this function return a list? It seems to me that you are checking whether otherpkg depends on pkg. If so, this function really ought to return True or False.

def reverse_dependencies(pkg):
    """Which packages have some kind of dependency on the given package"""

    cache = apt.cache.Cache()
    try:
        pkg = cache[pkg]
    except KeyError as e:
        print(str(e).strip('"'))
        return 1


You don't do anything with this return value. you should pass it to sys.exit()

    dependents = dict()


We usually create dicts with {}

    recommends = list()
    suggests = list()
    replaces = list()
    enhances = list()
    depends = list()


These are all basically the same thing which means they shouldn't be seperate variables. 

    for key in cache.keys():
        otherpkg = cache[key]
        depends.append(getdeps("Depends", pkg, otherpkg))
        recommends.append(getdeps("Recommends", pkg, otherpkg))
        suggests.append(getdeps("Suggests", pkg, otherpkg))
        replaces.append(getdeps("Replaces", pkg, otherpkg))
        enhances.append(getdeps("Enhances", pkg, otherpkg))


This would be better as iteration over a list of the dependency types. Also you are putting lists into lists. It'd be cleaner if you just had lists.

    dependents["Depends"] = depends
    dependents["Recommends"] = recommends
    dependents["Suggests"] = suggests
    dependents["Replaces"] = replaces
    dependents["Enhances"] = enhances

    for deptype, deps in dependents.items():
        deps_output = list()
        for match in deps:
            if match:


There's no point in doing this, because the loop will be executed 0 times if match is empty

                for item in match:
                    deps_output.append(item)


Use dep_output.extend(match) it has the same effect as this loop

        if deps_output:
            print(deptype.upper(), end=": ")
            print(" ".join(deps_output))

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument("pkg", help="pkg to describe")
    args = parser.parse_args()
    reverse_dependencies(args.pkg)


My reworking of your code:

#!/usr/bin/env python3

import argparse
import apt
import sys

DEPENDENCY_TYPES = [
    "Depends",
    "Recommends",
    "Suggests",
    "Replaces",
    "Enhances",
]

def extract_dependencies(package, dependency_type):
    """
    Generator that produce all the dependencies of a particular type
    """
    for dependency_list in package.candidate.get_dependencies(dependency_type):
        for dependency in dependency_list.or_dependencies:
            yield dependency.name

def reverse_dependencies(pkg):
    """Which packages have some kind of dependency on the given package"""

    cache = apt.cache.Cache()
    try:
        pkg = cache[pkg]
    except KeyError as error:
        print(error.args[0])
        sys.exit(1)

    dependents = { name : [] for name in DEPENDENCY_TYPES }

    for key in cache.keys():
        other_package = cache[key]
        for dependency_type, specific_dependents in dependents.items():
            if pkg.shortname in extract_dependencies(other_package, dependency_type):
                specific_dependents.append(other_package.shortname)

    for dependency_type, specific_dependents in dependents.items():
        if specific_dependents:
            print(dependency_type.upper(), ": ", " ".join(specific_dependents))

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument("pkg", help="pkg to describe")
    args = parser.parse_args()
    reverse_dependencies(args.pkg)