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
1 Answer 1
#!/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)
-
\$\begingroup\$ I really like your new names, stuff like
extract_dependencies
andextract_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\$tshepang– tshepang2012年02月15日 20:34:06 +00:00Commented 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\$Leonid– Leonid2012年02月15日 20:35:51 +00:00Commented Feb 15, 2012 at 20:35
-
\$\begingroup\$ @Leonid stackoverflow.com/a/2745292 \$\endgroup\$tshepang– tshepang2012年02月15日 20:47:56 +00:00Commented Feb 15, 2012 at 20:47
-
\$\begingroup\$ @Tshepang, some exceptions exist, but
[]
is generally more common thenlist()
. But its an issue of style, and you can go either way. \$\endgroup\$Winston Ewert– Winston Ewert2012年02月15日 22:35:58 +00:00Commented Feb 15, 2012 at 22:35