2
\$\begingroup\$

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
200_success
145k22 gold badges190 silver badges478 bronze badges
asked Feb 15, 2012 at 18:53
\$\endgroup\$

1 Answer 1

3
\$\begingroup\$
#!/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)
answered Feb 15, 2012 at 19:38
\$\endgroup\$
4
  • \$\begingroup\$ I really like your new names, stuff like extract_dependencies and extract_dependencies. You also exposed me to the fact I didn't fully understand my code. Thanks also for writing a fully-working version of your own alternative, especially since I didn't quite get some of your suggestions. \$\endgroup\$ Commented Feb 15, 2012 at 20:34
  • 1
    \$\begingroup\$ "We usually create lists with [] not list()" but Alex Martelli does not like that (I cannot find the link though). \$\endgroup\$ Commented Feb 15, 2012 at 20:35
  • \$\begingroup\$ @Leonid stackoverflow.com/a/2745292 \$\endgroup\$ Commented Feb 15, 2012 at 20:47
  • \$\begingroup\$ @Tshepang, some exceptions exist, but [] is generally more common then list(). But its an issue of style, and you can go either way. \$\endgroup\$ Commented Feb 15, 2012 at 22:35

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.