Sunday, March 13, 2022

[SOLVED] Python-apt: install package with specific version

Issue

I'm using python-apt to install a debian package. I need to be able to install it with a specific version, but can not figure out how. According to the documentation for href="http://apt.alioth.debian.org/python-apt-doc/library/apt.package.html#apt.package.Package.candidate" rel="nofollow">candidate:

Just assign a Version() object, and it will be set as the candidate version.

Currently I'm installing the package the following way:

import apt
cache = apt.cache.Cache()
pkg = cache['byobu']  # Or any random package for testing
pkg.mark_install()
cache.commit()

The only way I've found so far to set the Version have been through apt.apt_pkg like this, but I do not know how to progress from here:

pkg_name = 'byobu'
cache = apt.cache.Cache()
pkg = cache[pkg_name]
version = apt.apt_pkg.Cache()[pkg_name].version_list[1]  # 5.77-0ubuntu1
new_version = apt.package.Version(pkg, version)  # 5.77-0ubuntu1
new_version.package.candidate  # 5.77-0ubuntu1.2 <---
new_version.package.mark_install()
cache.commit()  # Returns True

The version in the end is the installed one and cache.commit() just returns True without doing anything (probably because the candidate version is the installed one). What am I doing wrong?


Solution

And after writing this down in a structured way I finally understood that pgk.candidate is overwritable by my new_version. I've tried previously but not with the mix of apt.package.Version, apt.cache.Cache and apt.apt_pkg.Cache.

I'm leaving this here for someone else to use in the future. Final sample code:

pkg_name = 'byobu'
cache = apt.cache.Cache()
package = cache[pkg_name]
version = apt.apt_pkg.Cache()[pkg_name].version_list[1]
candidate = apt.package.Version(package, version)
package.candidate = candidate
package.mark_install()
cache.commit()

Edit:

Feeling stupid, realised that I don't have to build the version but can just use it from the version list... Remember kids, don't code while drunk.

Even better final code:

cache = apt.cache.Cache()
package = cache[package_name]
candidate = package.versions.get(version)
package.candidate = candidate
package.mark_install()
cache.commit()


Answered By - olofom
Answer Checked By - Dawn Plyler (WPSolving Volunteer)