Package: python-apt Version: 1.6.0~rc2 Severity: normal Dear Maintainer, I think I found a small bug in the Python apt package, but I admit that I am not 100% sure, so if the behavior described below is actually due to improper usage I apologize in advance.
(And sorry , this is going to be a bit verbose.) I wanted to write a function that would show me which packages will be changed when the user calls apt-get dist-upgrade. I first came up with the following simple solution: upgr_pkgs, new_pkgs, remv_pkgs, kept_pkgs, downgr_pkgs = [], [], [], [], [] cache = apt.Cache() cache.update() cache.open(None) cache.upgrade(dist_upgrade=True) for pkg in cache: if pkg.marked_install: new_pkgs.append(pkg.name) elif not pkg.is_installed: continue# faster than if p.is_installed: (...) else:(...) elif pkg.marked_upgrade: upgr_pkgs.append(pkg.name) elif pkg.is_upgradable and pkg.marked_keep: kept_pkgs.append(pkg.name) elif pkg.marked_delete: remv_pkgs.append(pkg.name) elif pkg.marked_downgrade: downgr_pkgs.append(pkg.name) cache.close() This worked fine on various systems where I tried it, but I noticed that on a machine runing siduction three packages were marked_install that apt-get dist-upgrade would not install. It showed that these were packages that would be installed if another package would be upgraded to a newer version, which however does not happen, apparently to some pinning mechanism used by siduction (this is here the audacious player, where siduction prefers an older version from deb-multimedia over the newer version from sid). Next thing I thought may code must be "too simple" and finally tried the more elaborate code from the depcache.py demo script. This however gave the same result. For testing I removed the here unneeded parts of depcache.py and slightly modified the final part, so it the result is easier to compare with what apt-get would actually do. My test version of depcache.py now looks like: ################################ #!/usr/bin/python # example how to deal with the depcache import apt_pkg # init apt_pkg.init() cache = apt_pkg.Cache() print "Available packages: %s " % cache.package_count depcache = apt_pkg.DepCache(cache) depcache.read_pinfile() # init is needed after the creation/pin file reading depcache.init() print "got a depcache: %s " % depcache print "Marked for install: %s " % depcache.inst_count print "\n Reinit" depcache.init() print "Broken count: %s" % depcache.broken_count print "fix_broken() " depcache.fix_broken() print "Broken count: %s" % depcache.broken_count print "\nPerforming DistUpgrade" depcache.upgrade(True) print "Keep: %s " % depcache.keep_count print "Install: %s " % depcache.inst_count print "Delete: %s " % depcache.del_count print "usr_size: %s " % apt_pkg.size_to_str(depcache.usr_size) print "deb_size: %s " % apt_pkg.size_to_str(depcache.deb_size) inst, remv, upgr, keep, downgr = [], [], [], [], [] # overview about what would happen for pkg in cache.packages: if depcache.marked_install(pkg): if pkg.current_ver is not None: upgr.append(pkg.name)#print "Marked upgrade: %s " % pkg.name else: inst.append(pkg.name)#print "Marked install: %s" % pkg.name elif depcache.marked_upgrade(pkg): upgr.append(pkg.name) elif depcache.marked_delete(pkg): remv.append(pkg.name)#print "Marked delete: %s" % pkg.name elif (pkg.current_ver is not None) and \ depcache.is_upgradable(pkg) and depcache.marked_keep(pkg): keep.append(pkg.name)#print "Marked keep: %s" % pkg.name elif depcache.marked_downgrade(pkg): downgr.append(pkg.name) for l in (inst, remv, upgr, keep, downgr): l.sort() print('\nWill be newly installed:') print(' ' + ' '.join(inst)) print('\nWill be kept:') print(' ' + ' '.join(keep)) print('\nOverall changes:') print(' Install: %d Remove: %d Upgrade: %d Keep: %d Downgrade: %d' %( len(inst), len(remv), len(upgr), len(keep), len(downgr))) ####################################### When I run this, I get the following output: # python depcache.py Reading package lists... Done Building dependency tree Reading state information... Done Available packages: 76519 got a depcache: <apt_pkg.DepCache object at 0x7fbb0dc48170> Marked for install: 0 Reinit Broken count: 0 fix_broken() Broken count: 0 Performing DistUpgrade Keep: 2 Install: 892 Delete: 4 usr_size: 82.7 M deb_size: 681 M Will be newly installed: fonts-hack gcc-8-base gnome-themes-extra gnome-themes-extra-data libaudcore5 libaudgui5 libaudtag3 libcom-err2 libdns-export1100 libdns1100 libext2fs2 libgdbm-compat4 libgdbm5 libgstreamer-gl1.0-0 libisc-export169 libisc169 libisl19 liblivemedia62 libmagickcore-6.q16-5 libmagickwand-6.q16-5 libminiupnpc16 libopenexr23 libplacebo4 libpoppler73 libproj13 libqpdf21 libqt5multimedia5 libre2-4 libruby2.5 libsrtp2-1 libunwind8 libvpx5 libwoff1 ruby2.5 yudit-common Will be kept: audacious audacious-plugins-data Overall changes: Install: 35 Remove: 4 Upgrade: 857 Keep: 2 Downgrade: 0 Compared to this the output of apt-get dist-upgrade, where the three libaud* packages are not going to be installed, obviously because they are merely dependencies for the newer version of audacious which will be kept back: # apt-get --assume-no --no-show-upgraded dist-upgrade Reading package lists... Done Building dependency tree Reading state information... Done Calculating upgrade... Done The following packages were automatically installed and are no longer required: (...) The following packages will be REMOVED: gnome-themes-standard-data libqt5xdg3 libqt5xdgiconloader3 screengrab The following NEW packages will be installed: fonts-hack gcc-8-base gnome-themes-extra gnome-themes-extra-data libcom-err2 libdns-export1100 libdns1100 libext2fs2 libgdbm-compat4 libgdbm5 libgstreamer-gl1.0-0 libisc-export169 libisc169 libisl19 liblivemedia62 libmagickcore-6.q16-5 libmagickwand-6.q16-5 libminiupnpc16 libopenexr23 libplacebo4 libpoppler73 libproj13 libqpdf21 libqt5multimedia5 libre2-4 libruby2.5 libsrtp2-1 libunwind8 libvpx5 libwoff1 ruby2.5 yudit-common The following packages have been kept back: audacious audacious-plugins-data 857 upgraded, 32 newly installed, 4 to remove and 2 not upgraded. Need to get 680 MB of archives. After this operation, 82.1 MB of additional disk space will be used. Do you want to continue? [Y/n] N Abort. This is at least unexpected after what I read in the python-apt documentation, so I figured after all it might be a bug (btw. the versions of apt and python- apt are the latest 1.6 versions from sid; the behavior with the previous 1.4 versions was the same). Best regards Michael -- System Information: Debian Release: buster/sid APT prefers unstable APT policy: (500, 'unstable') Architecture: amd64 (x86_64) Kernel: Linux 4.16.1-towo.1-siduction-amd64 (SMP w/2 CPU cores; PREEMPT) Locale: LANG=de_DE.UTF-8, LC_CTYPE=de_DE.UTF-8 (charmap=UTF-8), LANGUAGE=de_DE.UTF-8 (charmap=UTF-8) Shell: /bin/sh linked to /bin/dash Init: systemd (via /run/systemd/system) Versions of packages python-apt depends on: ii dirmngr 2.2.4-1 ii gnupg 2.2.4-1 ii libapt-inst2.0 1.6~alpha7 ii libapt-pkg5.0 1.6~beta1 ii libc6 2.26-5 ii libgcc1 1:7.3.0-1 ii libstdc++6 7.3.0-1 ii python 2.7.14-4 ii python-apt-common 1.6.0~rc2 Versions of packages python-apt recommends: ii iso-codes 3.77-1 ii lsb-release 9.20170808 ii xz-utils 5.2.2-1.3 Versions of packages python-apt suggests: ii apt 1.6~beta1 pn python-apt-dbg <none> ii python-apt-doc 1.6.0~rc2 -- no debconf information