From 2c39f0847c8f32b93cac8d450d30b657548bafd4 Mon Sep 17 00:00:00 2001 From: Martin Pitt Date: Fri, 25 Jun 2010 15:24:27 +0200 Subject: tests/test_apt_cache.py: Test accessing the record of all packages during iteration. This both ensures that it's well-formatted and structured, and also that accessing it does not take an inordinate amount of time. This exposes a severe performance problem when using gzip compressed package indexes. --- debian/changelog | 7 +++++++ tests/test_apt_cache.py | 9 +++++++++ 2 files changed, 16 insertions(+) diff --git a/debian/changelog b/debian/changelog index 8f76bb3e..ae9f5689 100644 --- a/debian/changelog +++ b/debian/changelog @@ -12,6 +12,13 @@ python-apt (0.7.96) UNRELEASED; urgency=low * utils/get_debian_mirrors.py: - ignore mirrors without a county + [ Martin Pitt ] + * tests/test_apt_cache.py: Test accessing the record of all packages during + iteration. This both ensures that it's well-formatted and structured, and + also that accessing it does not take an inordinate amount of time. This + exposes a severe performance problem when using gzip compressed package + indexes. + -- Michael Vogt Tue, 01 Jun 2010 16:20:00 +0200 python-apt (0.7.95) unstable; urgency=low diff --git a/tests/test_apt_cache.py b/tests/test_apt_cache.py index fdcf482d..a00fa08b 100644 --- a/tests/test_apt_cache.py +++ b/tests/test_apt_cache.py @@ -30,5 +30,14 @@ class TestAptCache(unittest.TestCase): self.assertTrue(isinstance(dep.relation, str)) self.assertTrue(dep.pre_depend in (True, False)) + # accessing record should take a reasonable time; in + # particular, when using compressed indexes, it should not use + # tons of seek operations + r = pkg.candidate.record + self.assertEqual(r['Package'], pkg.name) + self.assert_('Version' in r) + self.assert_(len(r['Description']) > 0) + self.assert_(str(r).startswith('Package: %s\n' % pkg.name)) + if __name__ == "__main__": unittest.main() -- cgit v1.2.3 From 337fec14957b98c01bc61a5b516bcf8cd98ccb82 Mon Sep 17 00:00:00 2001 From: Martin Pitt Date: Fri, 25 Jun 2010 16:10:13 +0200 Subject: apt/cache.py: When iterating over the cache, do so sorted by package name. With this we read the the package lists linearly if we need to access the package records, instead of having to do thousands of random seeks; the latter is disastrous if we use compressed package indexes, and slower than necessary for uncompressed indexes. --- apt/cache.py | 12 +++++++++++- debian/changelog | 5 +++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/apt/cache.py b/apt/cache.py index 8e07e4d0..3679e4ba 100644 --- a/apt/cache.py +++ b/apt/cache.py @@ -64,6 +64,7 @@ class Cache(object): self._callbacks = {} self._weakref = weakref.WeakValueDictionary() self._set = set() + self._sorted_set = None if memonly: # force apt to build its caches in memory apt_pkg.config.set("Dir::Cache::pkgcache", "") @@ -126,6 +127,7 @@ class Cache(object): self._list = apt_pkg.SourceList() self._list.read_main_list() self._set.clear() + self._sorted_set = None self._weakref.clear() progress.op = _("Building data structures") @@ -157,7 +159,15 @@ class Cache(object): raise KeyError('The cache has no package named %r' % key) def __iter__(self): - for pkgname in self._set: + # We iterate sorted over package names here. With this we read the + # package lists linearly if we need to access the package records, + # instead of having to do thousands of random seeks; the latter + # is disastrous if we use compressed package indexes, and slower than + # necessary for uncompressed indexes. + if self._sorted_set is None: + self._sorted_set = sorted(self._set) + + for pkgname in self._sorted_set: yield self[pkgname] raise StopIteration diff --git a/debian/changelog b/debian/changelog index ae9f5689..b7bb3ad0 100644 --- a/debian/changelog +++ b/debian/changelog @@ -18,6 +18,11 @@ python-apt (0.7.96) UNRELEASED; urgency=low also that accessing it does not take an inordinate amount of time. This exposes a severe performance problem when using gzip compressed package indexes. + * apt/cache.py: When iterating over the cache, do so sorted by package name. + With this we read the the package lists linearly if we need to access the + package records, instead of having to do thousands of random seeks; the + latter is disastrous if we use compressed package indexes, and slower than + necessary for uncompressed indexes. -- Michael Vogt Tue, 01 Jun 2010 16:20:00 +0200 -- cgit v1.2.3 From 0be0102d652ff86a2066088535bfe58cf2d713a4 Mon Sep 17 00:00:00 2001 From: Kiwinote Date: Fri, 25 Jun 2010 17:46:47 +0100 Subject: Merge gdebi changes --- apt/cache.py | 68 ++++++++--- apt/debfile.py | 351 +++++++++++++++++++++++++++++++++++++++++---------------- 2 files changed, 310 insertions(+), 109 deletions(-) diff --git a/apt/cache.py b/apt/cache.py index 8e07e4d0..f7a8bbaa 100644 --- a/apt/cache.py +++ b/apt/cache.py @@ -1,23 +1,23 @@ # cache.py - apt cache abstraction # -# Copyright (c) 2005-2009 Canonical +# Copyright (c) 2005-2010 Canonical, Ltd. # -# Author: Michael Vogt +# Author: Michael Vogt # -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of the -# License, or (at your option) any later version. +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. # -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. # -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 -# USA +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +# USA import os import weakref @@ -84,6 +84,11 @@ class Cache(object): # recognized (LP: #320665) apt_pkg.init_system() self.open(progress) + if progress: + self.op_progress = progress + else: + self.op_progress = apt.progress.base.OpProgress() + def _check_and_create_required_dirs(self, rootdir): """ @@ -198,6 +203,16 @@ class Cache(object): self._depcache.upgrade(dist_upgrade) self.cache_post_change() + def downloadable(self, pkg, use_candidate=True): + """Check if the given package can be downloaded.""" + if use_candidate: + ver = self._depcache.get_candidate_ver(pkg._pkg) + else: + ver = pkg._pkg.current_ver + if ver == None: + return False + return ver.downloadable + @property def required_download(self): """Get the size of the packages that are required to download.""" @@ -306,6 +321,30 @@ class Cache(object): providers.add(package) return list(providers) + def get_providers_for(self, pkgname): + """Return a list of all packages providing a non-virtual package.""" + providers = [] + for pkg in self: + v = self._depcache.get_candidate_ver(pkg._pkg) + if v == None: + continue + for p in v.provides_list: + #print virtual_pkg + #print p[0] + if pkgname == p[0]: + # we found a pkg that provides this virtual + # pkg, check if the proivdes is any good + providers.append(pkg) + #cand = self._cache[pkg.name] + #candver = self._cache._depcache.GetCandidateVer(cand._pkg) + #instver = cand._pkg.CurrentVer + #res = apt_pkg.CheckDep(candver.VerStr,oper,ver) + #if res == True: + # self._dbg(1,"we can use %s" % pkg.name) + # or_found = True + # break + return providers + @deprecated_args def update(self, fetch_progress=None, pulse_interval=0, raise_on_error=True): @@ -474,6 +513,7 @@ class Cache(object): _fetchArchives = function_deprecated_by(_fetch_archives) isVirtualPackage = function_deprecated_by(is_virtual_package) getProvidingPackages = function_deprecated_by(get_providing_packages) + getProvidersFor = function_deprecated_by(get_providers_for) installArchives = function_deprecated_by(install_archives) cachePostChange = function_deprecated_by(cache_post_change) cachePreChange = function_deprecated_by(cache_pre_change) diff --git a/apt/debfile.py b/apt/debfile.py index ccaa25e4..494dd14e 100644 --- a/apt/debfile.py +++ b/apt/debfile.py @@ -1,79 +1,65 @@ -# Copyright (c) 2005-2009 Canonical +# Copyright (c) 2005-2010 Canonical, Ltd. # -# Author: Michael Vogt +# Author: Michael Vogt # -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of the -# License, or (at your option) any later version. +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. # -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. # -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 -# USA +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +# USA """Classes for working with locally available Debian packages.""" +import apt_inst +import apt_pkg +import gzip import os import sys -import apt_inst -import apt_pkg from apt_pkg import gettext as _ - - -# Constants for comparing the local package file with the version in the cache -(VERSION_NONE, VERSION_OUTDATED, VERSION_SAME, VERSION_NEWER) = range(4) - +from debian.debfile import DebFile +from StringIO import StringIO class NoDebArchiveException(IOError): """Exception which is raised if a file is no Debian archive.""" - class DebPackage(object): """A Debian Package (.deb file).""" + # Constants for comparing the local package file with the version in the cache + (VERSION_NONE, VERSION_OUTDATED, VERSION_SAME, VERSION_NEWER) = range(4) + _supported_data_members = ("data.tar.gz", "data.tar.bz2", "data.tar.lzma") debug = 0 def __init__(self, filename=None, cache=None): + if cache: + cache.clear() self._cache = cache + self.file = filename self._need_pkgs = [] + self._sections = {} self._debfile = None self.pkgname = "" - self.filename = filename - self._sections = {} self._installed_conflicts = set() self._failure_string = "" - if filename: - self.open(filename) + if self.file: + self.open(self.file) - def open(self, filename): + def open(self, file): " open given debfile " - self.filename = filename - self._debfile = apt_inst.DebFile(self.filename) - control = self._debfile.control.extractdata("control") + control = apt_inst.debExtractControl(open(file)) self._sections = apt_pkg.TagSection(control) self.pkgname = self._sections["Package"] - def __getitem__(self, key): - return self._sections[key] - - @property - def filelist(self): - """return the list of files in the deb.""" - files = [] - try: - self._debfile.data.go(lambda item, data: files.append(item.name)) - except SystemError: - return [_("List of files for '%s' could not be read" % - self.filename)] - return files - def _is_or_group_satisfied(self, or_group): """Return True if at least one dependency of the or-group is satisfied. @@ -90,20 +76,34 @@ class DebPackage(object): # check for virtual pkgs if not depname in self._cache: if self._cache.is_virtual_package(depname): - self._dbg(3, "_isOrGroupSatisfied(): %s is virtual dep" % - depname) + self._dbg(3, "_is_or_group_satisfied(): %s is virtual dep" % depname) for pkg in self._cache.get_providing_packages(depname): if pkg.is_installed: return True continue - + # check real dependency inst = self._cache[depname].installed if inst is not None and apt_pkg.check_dep(inst.version, oper, ver): return True + + # if no real dependency is installed, check if there is + # a package installed that provides this dependency + # (e.g. scrollkeeper dependecies are provided by rarian-compat) + # but only do that if there is no version required in the + # dependency (we do not supprot versionized dependencies) + if not oper: + for ppkg in self._cache.get_providers_for(depname): + if ppkg.is_installed: + self._dbg(3, "found installed '%s' that provides '%s'" % (ppkg.name, depname)) + return True return False def _satisfy_or_group(self, or_group): """Try to satisfy the or_group.""" + + or_found = False + virtual_pkg = None + for dep in or_group: depname, ver, oper = dep @@ -136,19 +136,18 @@ class DebPackage(object): or_str = "" for dep in or_group: or_str += dep[0] - if dep != or_group[-1]: + if ver and oper: + or_str += " (%s %s)" % (dep[2], dep[1]) + if dep != or_group[len(or_group)-1]: or_str += "|" - self._failure_string += _("Dependency is not satisfiable: %s\n" % - or_str) + self._failure_string += _("Dependency is not satisfiable: %s\n") % or_str return False def _check_single_pkg_conflict(self, pkgname, ver, oper): """Return True if a pkg conflicts with a real installed/marked pkg.""" # FIXME: deal with conflicts against its own provides # (e.g. Provides: ftp-server, Conflicts: ftp-server) - self._dbg(3, "_checkSinglePkgConflict() pkg='%s' ver='%s' oper='%s'" % - (pkgname, ver, oper)) - + self._dbg(3, "_check_single_pkg_conflict() pkg='%s' ver='%s' oper='%s'" % (pkgname, ver, oper)) pkg = self._cache[pkgname] if pkg.is_installed: pkgver = pkg.installed.version @@ -162,8 +161,7 @@ class DebPackage(object): #print "oper: %s " % oper if (apt_pkg.check_dep(pkgver, oper, ver) and not self.replaces_real_pkg(pkgname, oper, ver)): - self._failure_string += _("Conflicts with the installed package " - "'%s'" % pkg.name) + self._failure_string += _("Conflicts with the installed package '%s'") % pkg.name return True return False @@ -171,6 +169,9 @@ class DebPackage(object): """Check the or-group for conflicts with installed pkgs.""" self._dbg(2, "_check_conflicts_or_group(): %s " % (or_group)) + or_found = False + virtual_pkg = None + for dep in or_group: depname = dep[0] ver = dep[1] @@ -187,8 +188,7 @@ class DebPackage(object): if self.pkgname == pkg.name: self._dbg(3, "conflict on self, ignoring") continue - if self._check_single_pkg_conflict(pkg.name, ver, - oper): + if self._check_single_pkg_conflict(pkg.name, ver, oper): self._installed_conflicts.add(pkg.name) continue if self._check_single_pkg_conflict(depname, ver, oper): @@ -209,7 +209,7 @@ class DebPackage(object): """List of package names on which this package depends on.""" depends = [] # find depends - for key in "Depends", "PreDepends": + for key in "Depends", "Pre-Depends": try: depends.extend(apt_pkg.parse_depends(self._sections[key])) except KeyError: @@ -240,7 +240,7 @@ class DebPackage(object): Return True if the deb packages replaces a real (not virtual) packages named (pkgname, oper, ver). """ - self._dbg(3, "replacesPkg() %s %s %s" % (pkgname, oper, ver)) + self._dbg(3, "replaces_real_pkg() %s %s %s" % (pkgname, oper, ver)) pkg = self._cache[pkgname] if pkg.is_installed: pkgver = pkg.installed.version @@ -262,6 +262,19 @@ class DebPackage(object): Check if the package conflicts with a existing or to be installed package. Return True if the pkg is OK. """ + for con in self.conflicts: + for pro in self.provides: + if con[0][0] == pro[0][0]: + if con[0][2]: + pro_ver = self._sections["Version"] + if apt_pkg.check_dep(pro_ver, con[0][1], con[0][2]): + #print "Conflicts with provided pkg!" + self._failure_string = "Conflicts with a provided package" + return False + else: + #print "Conflicts with provided pkg!" + self._failure_string = "Conflicts with a provided package" + return False res = True for or_group in self.conflicts: if self._check_conflicts_or_group(or_group): @@ -270,6 +283,57 @@ class DebPackage(object): res = False return res + def check_breaks_existing_packages(self): + """ + check if installing the package would break exsisting + package on the system, e.g. system has: + smc depends on smc-data (= 1.4) + and user tries to installs smc-data 1.6 + """ + # show progress information as this step may take some time + size = float(len(self._cache)) + steps = int(size/50) + debver = self._sections["Version"] + for (i, pkg) in enumerate(self._cache): + if i%steps == 0: + self._cache.op_progress.update(float(i)/size*100.0) + if not pkg.is_installed: + continue + # check if the exising dependencies are still satisfied + # with the package + ver = pkg._pkg.current_ver + for dep_or in pkg.installed.dependencies: + for dep in dep_or.or_dependencies: + if dep.name == self.pkgname: + if not apt_pkg.check_dep(debver, dep.relation, dep.version): + self._dbg(2, "would break (depends) %s" % pkg.name) + # TRANSLATORS: the first '%s' is the package that breaks, the second the dependency that makes it break, the third the relation (e.g. >=) and the latest the version for the releation + self._failure_string += _("Breaks existing package '%(pkgname)s' dependency %(depname)s (%(deprelation)s %(depversion)s)") % { + 'pkgname' : pkg.name, + 'depname' : dep.name, + 'deprelation' : dep.relation, + 'depversion' : dep.version} + self._cache.op_progress.done() + return False + # now check if there are conflicts against this package on + # the existing system + if "Conflicts" in ver.depends_list: + for conflicts_ver_list in ver.depends_list["Conflicts"]: + for c_or in conflicts_ver_list: + if c_or.target_pkg.name == self.pkgname: + if apt_pkg.check_dep(debver, c_or.comp_type, c_or.target_ver): + self._dbg(2, "would break (conflicts) %s" % pkg.name) + # TRANSLATORS: the first '%s' is the package that conflicts, the second the packagename that it conflicts with (so the name of the deb the user tries to install), the third is the relation (e.g. >=) and the last is the version for the relation + self._failureString += _("Breaks existing package '%(pkgname)s' conflict: %(targetpkg)s (%(comptype)s %(targetver)s)") % { + 'pkgname' : pkg.name, + 'targetpkg' : c_or.target_pkg.name, + 'comptype' : c_or.comp_type, + 'targetver' : c_or.target_ver } + self._cache.op_progress.done() + return False + self._cache.op_progress.done() + return True + def compare_to_version_in_cache(self, use_installed=True): """Compare the package to the version available in the cache. @@ -277,7 +341,7 @@ class DebPackage(object): and if so in what version, returns one of (VERSION_NONE, VERSION_OUTDATED, VERSION_SAME, VERSION_NEWER). """ - self._dbg(3, "compareToVersionInCache") + self._dbg(3, "compare_to_version_in_cache") pkgname = self._sections["Package"] debver = self._sections["Version"] self._dbg(1, "debver: %s" % debver) @@ -287,32 +351,37 @@ class DebPackage(object): else: cachever = self._cache[pkgname].candidate.version if cachever is not None: - cmpres = apt_pkg.version_compare(cachever, debver) - self._dbg(1, "CompareVersion(debver,instver): %s" % cmpres) - if cmpres == 0: - return VERSION_SAME - elif cmpres < 0: - return VERSION_NEWER - elif cmpres > 0: - return VERSION_OUTDATED - return VERSION_NONE + cmp = apt_pkg.version_compare(cachever, debver) + self._dbg(1, "CompareVersion(debver,instver): %s" % cmp) + if cmp == 0: + return self.VERSION_SAME + elif cmp < 0: + return self.VERSION_NEWER + elif cmp > 0: + return self.VERSION_OUTDATED + return self.VERSION_NONE def check(self): """Check if the package is installable.""" self._dbg(3, "check_depends") # check arch + if not "Architecture" in self._sections: + self._dbg(1, "ERROR: no architecture field") + self._failure_string = _("No Architecture field in the package") + return False arch = self._sections["Architecture"] if arch != "all" and arch != apt_pkg.config.find("APT::Architecture"): self._dbg(1, "ERROR: Wrong architecture dude!") - self._failure_string = _("Wrong architecture '%s'" % arch) + self._failure_string = _("Wrong architecture '%s'") % arch return False # check version - if self.compare_to_version_in_cache() == VERSION_OUTDATED: - # the deb is older than the installed - self._failure_string = _("A later version is already installed") - return False + if self.compare_to_version_in_cache() == self.VERSION_OUTDATED: + if self._cache[self.pkgname].installed: + # the deb is older than the installed + self._failure_string = _("A later version is already installed") + return False # FIXME: this sort of error handling sux self._failure_string = "" @@ -321,6 +390,11 @@ class DebPackage(object): if not self.check_conflicts(): return False + # check if installing it would break anything on the + # current system + if not self.check_breaks_existing_packages(): + return False + # try to satisfy the dependencies if not self._satisfy_depends(self.depends): return False @@ -331,8 +405,7 @@ class DebPackage(object): return False if self._cache._depcache.broken_count > 0: - self._failure_string = _("Failed to satisfy all dependencies " - "(broken cache)") + self._failure_string = _("Failed to satisfy all dependencies (broken cache)") # clean the cache again self._cache.clear() return False @@ -352,19 +425,18 @@ class DebPackage(object): # check depends for or_group in depends: #print "or_group: %s" % or_group - #print "or_group satified: %s" % self._is_or_group_satisfied( - # or_group) + #print "or_group satified: %s" % self._is_or_group_satisfied(or_group) if not self._is_or_group_satisfied(or_group): if not self._satisfy_or_group(or_group): return False # now try it out in the cache - for pkg in self._need_pkgs: - try: - self._cache[pkg].mark_install(fromUser=False) - except SystemError: - self._failure_string = _("Cannot install '%s'" % pkg) - self._cache.clear() - return False + for pkg in self._need_pkgs: + try: + self._cache[pkg].mark_install(from_user=False) + except SystemError, e: + self._failure_string = _("Cannot install '%s'") % pkg + self._cache.clear() + return False return True @property @@ -398,6 +470,95 @@ class DebPackage(object): remove.append(pkg.name) return (install, remove, unauthenticated) + def control_filelist(self): + """ return the list of files in control.tar.gt """ + content = [] + for name in DebFile(self.file).control: + if name and name != ".": + content.append(name) + return sorted(content) + control_filelist = property(control_filelist) + + def to_hex(self, in_data): + hex = "" + for (i, c) in enumerate(in_data): + if i%80 == 0: + hex += "\n" + hex += "%2.2x " % ord(c) + return hex + + def to_strish(self, in_data): + s = "" + for c in in_data: + if ord(c) < 10 or ord(c) > 127: + s += " " + else: + s += c + return s + + def _get_content(self, part, name, auto_decompress=True, auto_hex=True): + data = part.get_content(name) + # check for zip content + if name.endswith(".gz") and auto_decompress: + io = StringIO(data) + gz = gzip.GzipFile(fileobj=io) + data = _("Automatically decompressed:\n\n") + data += gz.read() + # auto-convert to hex + try: + data = unicode(data, "utf-8") + except Exception, e: + new_data = _("Automatically converted to printable ascii:\n") + new_data += self.to_strish(data) + return new_data + return data + + def control_content(self, name): + """ return the content of a specific control.tar.gz file """ + control = DebFile(self.file).control + if name in control: + return self._get_content(control, name) + return "" + + def data_content(self, name): + """ return the content of a specific control.tar.gz file """ + data = DebFile(self.file).data + if name in data: + return self._get_content(data, name) + return "" + + @property + def filelist(self): + """ return the list of files in the deb. """ + files = [] + def extract_cb(What,Name,Link,Mode,UID,GID,Size,MTime,Major,Minor): + #print "%s '%s','%s',%u,%u,%u,%u,%u,%u,%u"\ + # % (What,Name,Link,Mode,UID,GID,Size, MTime, Major, Minor) + if Name != "./": + files.append(Name) + try: + try: + apt_inst.debExtract(open(self.file), extract_cb, "data.tar.gz") + except SystemError, e: + try: + apt_inst.debExtract(open(self.file), extract_cb, "data.tar.bz2") + except SystemError, e: + try: + apt_inst.debExtract(open(self.file), extract_cb, "data.tar.lzma") + except SystemError, e: + return [_("List of files could not be read, please report this as a bug")] + # IOError may happen because of gvfs madness (LP: #211822) + except IOError, e: + return [_("IOError during filelist read: %s") % e] + return files + + def __getitem__(self,item): + if not item in self._sections: + # Translators: it's for missing entries in the deb package, + # e.g. a missing "Maintainer" field + return _("%s is not available") % item + return self._sections[item] + def _dbg(self, level, msg): """Write debugging output to sys.stderr.""" if level <= self.debug: @@ -406,31 +567,31 @@ class DebPackage(object): def install(self, install_progress=None): """Install the package.""" if install_progress is None: - return os.spawnlp(os.P_WAIT, "dpkg", "dpkg", "-i", self.filename) + return os.spawnlp(os.P_WAIT, "dpkg", "dpkg", "-i", self.file) else: try: install_progress.start_update() except AttributeError: install_progress.startUpdate() - res = install_progress.run(self.filename) + res = install_progress.run(self.file) try: install_progress.finish_update() except AttributeError: install_progress.finishUpdate() return res - class DscSrcPackage(DebPackage): """A locally available source package.""" def __init__(self, filename=None, cache=None): DebPackage.__init__(self, None, cache) + self.file = filename self._depends = [] self._conflicts = [] self.pkgname = "" self.binaries = [] - if filename is not None: - self.open(filename) + if self.file is not None: + self.open(self.file) @property def depends(self): @@ -446,7 +607,6 @@ class DscSrcPackage(DebPackage): """Open the package.""" depends_tags = ["Build-Depends", "Build-Depends-Indep"] conflicts_tags = ["Build-Conflicts", "Build-Conflicts-Indep"] - fobj = open(file) tagfile = apt_pkg.TagFile(fobj) try: @@ -481,11 +641,10 @@ class DscSrcPackage(DebPackage): if self._cache[pkgname]._pkg.essential: raise Exception(_("An essential package would be removed")) self._cache[pkgname].mark_delete() - # FIXME: a additional run of the checkConflicts() - # after _satisfyDepends() should probably be done + # FIXME: a additional run of the check_conflicts() + # after _satisfy_depends() should probably be done return self._satisfy_depends(self.depends) - def _test(): """Test function""" from apt.cache import Cache @@ -494,7 +653,7 @@ def _test(): cache = Cache() vp = "www-browser" - #print "%s virtual: %s" % (vp, cache.isVirtualPackage(vp)) + print "%s virtual: %s" % (vp, cache.is_virtual_pkg(vp)) providers = cache.get_providing_packages(vp) print "Providers for %s :" % vp for pkg in providers: @@ -508,6 +667,8 @@ def _test(): print "missing deps: %s" % d.missing_deps print d.required_changes + print d.filelist + print "Installing ..." ret = d.install(DpkgInstallProgress()) print ret -- cgit v1.2.3 From 45a7ba935c89034c0ccc0c9ccc4f801a3d465bcf Mon Sep 17 00:00:00 2001 From: Kiwinote Date: Fri, 25 Jun 2010 19:07:16 +0100 Subject: Remove unneeded cache.downloadable() --- apt/cache.py | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/apt/cache.py b/apt/cache.py index f7a8bbaa..e50940ce 100644 --- a/apt/cache.py +++ b/apt/cache.py @@ -203,16 +203,6 @@ class Cache(object): self._depcache.upgrade(dist_upgrade) self.cache_post_change() - def downloadable(self, pkg, use_candidate=True): - """Check if the given package can be downloaded.""" - if use_candidate: - ver = self._depcache.get_candidate_ver(pkg._pkg) - else: - ver = pkg._pkg.current_ver - if ver == None: - return False - return ver.downloadable - @property def required_download(self): """Get the size of the packages that are required to download.""" -- cgit v1.2.3 From ae363bccb5b52ffc7a17e3f6b3d7b1cff5f65a98 Mon Sep 17 00:00:00 2001 From: Kiwinote Date: Fri, 25 Jun 2010 21:11:57 +0100 Subject: Merge cache.get_providers_for() into cache.get_providing_packages() and update debfile.py to use this --- apt/cache.py | 90 ++++++++++++++++++++++++++++------------------------------ apt/debfile.py | 4 +-- 2 files changed, 46 insertions(+), 48 deletions(-) diff --git a/apt/cache.py b/apt/cache.py index e50940ce..98241379 100644 --- a/apt/cache.py +++ b/apt/cache.py @@ -282,59 +282,57 @@ class Cache(object): else: return bool(pkg.has_provides and not pkg.has_versions) - def get_providing_packages(self, virtual, candidate_only=True): - """Return a list of all packages providing a virtual package. + def get_providing_packages(self, pkgname, candidate_only=True): + """Return a list of all packages providing a package. - Return a list of packages which provide the virtual package of the - specified name. If 'candidate_only' is False, return all packages - with at least one version providing the virtual package. Otherwise, - return only those packages where the candidate version provides - the virtual package. + Return a list of packages which provide the package of the specified + name. For virtual packages, if 'candidate_only' is False, return all + packages with at least one version providing the package. Otherwise, + return only those packages where the candidate version provides the + package. """ providers = set() - get_candidate_ver = self._depcache.get_candidate_ver - try: - vp = self._cache[virtual] - if vp.has_versions: + virtual = self.is_virtual_package(pkgname) + if not virtual: + for pkg in self: + v = self._depcache.get_candidate_ver(pkg._pkg) + if v == None: + continue + for p in v.provides_list: + #print virtual_pkg + #print p[0] + if pkgname == p[0]: + # we found a pkg that provides this virtual + # pkg, check if the proivdes is any good + providers.add(pkg) + #cand = self._cache[pkg.name] + #candver = self._cache._depcache.GetCandidateVer(cand._pkg) + #instver = cand._pkg.CurrentVer + #res = apt_pkg.CheckDep(candver.VerStr,oper,ver) + #if res == True: + # self._dbg(1,"we can use %s" % pkg.name) + # or_found = True + # break + else: + get_candidate_ver = self._depcache.get_candidate_ver + try: + vp = self._cache[pkgname] + if vp.has_versions: + return list(providers) + except KeyError: return list(providers) - except KeyError: - return list(providers) - for provides, providesver, version in vp.provides_list: - pkg = version.parent_pkg - if not candidate_only or (version == get_candidate_ver(pkg)): - try: - providers.add(self._weakref[pkg.name]) - except KeyError: - package = self._weakref[pkg.name] = Package(self, pkg) - providers.add(package) + for provides, providesver, version in vp.provides_list: + pkg = version.parent_pkg + if not candidate_only or (version == get_candidate_ver(pkg)): + try: + providers.add(self._weakref[pkg.name]) + except KeyError: + package = self._weakref[pkg.name] = Package(self, pkg) + providers.add(package) return list(providers) - def get_providers_for(self, pkgname): - """Return a list of all packages providing a non-virtual package.""" - providers = [] - for pkg in self: - v = self._depcache.get_candidate_ver(pkg._pkg) - if v == None: - continue - for p in v.provides_list: - #print virtual_pkg - #print p[0] - if pkgname == p[0]: - # we found a pkg that provides this virtual - # pkg, check if the proivdes is any good - providers.append(pkg) - #cand = self._cache[pkg.name] - #candver = self._cache._depcache.GetCandidateVer(cand._pkg) - #instver = cand._pkg.CurrentVer - #res = apt_pkg.CheckDep(candver.VerStr,oper,ver) - #if res == True: - # self._dbg(1,"we can use %s" % pkg.name) - # or_found = True - # break - return providers - @deprecated_args def update(self, fetch_progress=None, pulse_interval=0, raise_on_error=True): @@ -503,7 +501,7 @@ class Cache(object): _fetchArchives = function_deprecated_by(_fetch_archives) isVirtualPackage = function_deprecated_by(is_virtual_package) getProvidingPackages = function_deprecated_by(get_providing_packages) - getProvidersFor = function_deprecated_by(get_providers_for) + getProvidersFor = function_deprecated_by(get_providing_packages) installArchives = function_deprecated_by(install_archives) cachePostChange = function_deprecated_by(cache_post_change) cachePreChange = function_deprecated_by(cache_pre_change) diff --git a/apt/debfile.py b/apt/debfile.py index 494dd14e..90d58449 100644 --- a/apt/debfile.py +++ b/apt/debfile.py @@ -92,7 +92,7 @@ class DebPackage(object): # but only do that if there is no version required in the # dependency (we do not supprot versionized dependencies) if not oper: - for ppkg in self._cache.get_providers_for(depname): + for ppkg in self._cache.get_providing_packages(depname): if ppkg.is_installed: self._dbg(3, "found installed '%s' that provides '%s'" % (ppkg.name, depname)) return True @@ -653,7 +653,7 @@ def _test(): cache = Cache() vp = "www-browser" - print "%s virtual: %s" % (vp, cache.is_virtual_pkg(vp)) + print "%s virtual: %s" % (vp, cache.is_virtual_package(vp)) providers = cache.get_providing_packages(vp) print "Providers for %s :" % vp for pkg in providers: -- cgit v1.2.3 From 5ced3fd6f12111305f43f8cdc9b04a5b3bc2be7e Mon Sep 17 00:00:00 2001 From: Kiwinote Date: Fri, 25 Jun 2010 21:45:19 +0100 Subject: Don't depend on python-debian --- apt/debfile.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/apt/debfile.py b/apt/debfile.py index 90d58449..469cbb36 100644 --- a/apt/debfile.py +++ b/apt/debfile.py @@ -24,7 +24,6 @@ import os import sys from apt_pkg import gettext as _ -from debian.debfile import DebFile from StringIO import StringIO class NoDebArchiveException(IOError): @@ -470,14 +469,18 @@ class DebPackage(object): remove.append(pkg.name) return (install, remove, unauthenticated) + @property def control_filelist(self): """ return the list of files in control.tar.gt """ + try: + from debian.debfile import DebFile + except: + raise Exception(_("Python-debian module not available")) content = [] for name in DebFile(self.file).control: if name and name != ".": content.append(name) return sorted(content) - control_filelist = property(control_filelist) def to_hex(self, in_data): hex = "" @@ -515,6 +518,10 @@ class DebPackage(object): def control_content(self, name): """ return the content of a specific control.tar.gz file """ + try: + from debian.debfile import DebFile + except: + raise Exception(_("Python-debian module not available")) control = DebFile(self.file).control if name in control: return self._get_content(control, name) @@ -522,6 +529,10 @@ class DebPackage(object): def data_content(self, name): """ return the content of a specific control.tar.gz file """ + try: + from debian.debfile import DebFile + except: + raise Exception(_("Python-debian module not available")) data = DebFile(self.file).data if name in data: return self._get_content(data, name) -- cgit v1.2.3 From 70da3b041dcb31e783c381d002fdee8bba9ec292 Mon Sep 17 00:00:00 2001 From: Kiwinote Date: Mon, 28 Jun 2010 09:22:23 +0100 Subject: Don't query cache[].candidate.version when no cache[].candidate is available --- apt/debfile.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/apt/debfile.py b/apt/debfile.py index 469cbb36..f74b6981 100644 --- a/apt/debfile.py +++ b/apt/debfile.py @@ -347,8 +347,10 @@ class DebPackage(object): if pkgname in self._cache: if use_installed and self._cache[pkgname].installed: cachever = self._cache[pkgname].installed.version - else: + elif self._cache[pkgname].candidate: cachever = self._cache[pkgname].candidate.version + else: + return self.VERSION_NONE if cachever is not None: cmp = apt_pkg.version_compare(cachever, debver) self._dbg(1, "CompareVersion(debver,instver): %s" % cmp) -- cgit v1.2.3 From dc53e59cb9718fd5751066539fed46d7cdf01268 Mon Sep 17 00:00:00 2001 From: Kiwinote Date: Mon, 28 Jun 2010 09:54:06 +0100 Subject: December is month 12, not month 0 --- apt/utils.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/apt/utils.py b/apt/utils.py index 80ba6d65..f4d34261 100644 --- a/apt/utils.py +++ b/apt/utils.py @@ -33,6 +33,8 @@ def get_maintenance_end_date(release_date, m_months): support_end_year = (release_date.year + years + (release_date.month + months)/12) support_end_month = (release_date.month + months) % 12 + if support_end_month == 0: + support_end_month = 12 return (support_end_year, support_end_month) -- cgit v1.2.3 From 944626c874a7b42043d279d918c92c407627a314 Mon Sep 17 00:00:00 2001 From: Kiwinote Date: Mon, 28 Jun 2010 10:02:06 +0100 Subject: And subtract a year --- apt/utils.py | 1 + 1 file changed, 1 insertion(+) diff --git a/apt/utils.py b/apt/utils.py index f4d34261..4b3da39f 100644 --- a/apt/utils.py +++ b/apt/utils.py @@ -35,6 +35,7 @@ def get_maintenance_end_date(release_date, m_months): support_end_month = (release_date.month + months) % 12 if support_end_month == 0: support_end_month = 12 + support_end_year -= 1 return (support_end_year, support_end_month) -- cgit v1.2.3 From 1c66ccad17b32488aaac0a78016f5378a789bfb1 Mon Sep 17 00:00:00 2001 From: Kiwinote Date: Mon, 28 Jun 2010 11:14:20 +0100 Subject: self.conflicts returns name, ver, oper, rather than name, oper, ver --- apt/debfile.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/apt/debfile.py b/apt/debfile.py index f74b6981..1c33d25f 100644 --- a/apt/debfile.py +++ b/apt/debfile.py @@ -261,12 +261,12 @@ class DebPackage(object): Check if the package conflicts with a existing or to be installed package. Return True if the pkg is OK. """ - for con in self.conflicts: + for [(con_name, con_ver, con_oper)] in self.conflicts: for pro in self.provides: - if con[0][0] == pro[0][0]: - if con[0][2]: + if con_name == pro[0][0]: + if con_ver: pro_ver = self._sections["Version"] - if apt_pkg.check_dep(pro_ver, con[0][1], con[0][2]): + if apt_pkg.check_dep(pro_ver, con_oper, con_ver): #print "Conflicts with provided pkg!" self._failure_string = "Conflicts with a provided package" return False -- cgit v1.2.3 From 0c4bbfa36f36d42cc3d700e58d531e05ba898e0e Mon Sep 17 00:00:00 2001 From: Kiwinote Date: Mon, 28 Jun 2010 12:54:51 +0100 Subject: Revert own change, as we can conflict/provide the same package --- apt/debfile.py | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/apt/debfile.py b/apt/debfile.py index 1c33d25f..c0ae4e28 100644 --- a/apt/debfile.py +++ b/apt/debfile.py @@ -261,19 +261,6 @@ class DebPackage(object): Check if the package conflicts with a existing or to be installed package. Return True if the pkg is OK. """ - for [(con_name, con_ver, con_oper)] in self.conflicts: - for pro in self.provides: - if con_name == pro[0][0]: - if con_ver: - pro_ver = self._sections["Version"] - if apt_pkg.check_dep(pro_ver, con_oper, con_ver): - #print "Conflicts with provided pkg!" - self._failure_string = "Conflicts with a provided package" - return False - else: - #print "Conflicts with provided pkg!" - self._failure_string = "Conflicts with a provided package" - return False res = True for or_group in self.conflicts: if self._check_conflicts_or_group(or_group): -- cgit v1.2.3 From 508f1ddb5b6a0cc69655e39dbd59fe3466173a84 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Tue, 29 Jun 2010 11:23:31 +0200 Subject: * apt/cache.py: - add new "dpkg_journal_dirty" property that can be used to detect a interrupted dpkg (the famous "E: dpkg was interrupted, you must manually run 'dpkg --configure -a'") --- apt/cache.py | 15 +++++++++++++++ debian/changelog | 4 ++++ tests/test_apt_cache.py | 26 ++++++++++++++++++++++++++ 3 files changed, 45 insertions(+) diff --git a/apt/cache.py b/apt/cache.py index 3679e4ba..3962bb4f 100644 --- a/apt/cache.py +++ b/apt/cache.py @@ -19,6 +19,7 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 # USA +import fnmatch import os import weakref @@ -454,6 +455,20 @@ class Cache(object): """ return apt_pkg.ActionGroup(self._depcache) + @property + def dpkg_journal_dirty(self): + """Return True if the dpkg was interrupted + + All dpkg operations will fail until this is fixed, the action to + fix the system if dpkg got interrupted is to run + 'dpkg --configure -a' as root. + """ + dpkg_status_dir = os.path.dirname(apt_pkg.Config.find_file("Dir::State::status")) + for f in os.listdir(os.path.join(dpkg_status_dir, "updates")): + if fnmatch.fnmatch(f, "[0-9]*"): + return True + return False + @property def broken_count(self): """Return the number of packages with broken dependencies.""" diff --git a/debian/changelog b/debian/changelog index b7bb3ad0..b1c7c1b5 100644 --- a/debian/changelog +++ b/debian/changelog @@ -11,6 +11,10 @@ python-apt (0.7.96) UNRELEASED; urgency=low - do not fail on non-digits in the version number * utils/get_debian_mirrors.py: - ignore mirrors without a county + * apt/cache.py: + - add new "dpkg_journal_dirty" property that can be used to + detect a interrupted dpkg (the famous + "E: dpkg was interrupted, you must manually run 'dpkg --configure -a'") [ Martin Pitt ] * tests/test_apt_cache.py: Test accessing the record of all packages during diff --git a/tests/test_apt_cache.py b/tests/test_apt_cache.py index a00fa08b..b27ed778 100644 --- a/tests/test_apt_cache.py +++ b/tests/test_apt_cache.py @@ -9,6 +9,9 @@ import unittest import apt +import apt_pkg +import os +import tempfile class TestAptCache(unittest.TestCase): @@ -39,5 +42,28 @@ class TestAptCache(unittest.TestCase): self.assert_(len(r['Description']) > 0) self.assert_(str(r).startswith('Package: %s\n' % pkg.name)) + def test_dpkg_journal_dirty(self): + # backup old value + old_status = apt_pkg.Config.find_file("Dir::State::status") + # create tmp env + tmpdir = tempfile.mkdtemp() + dpkg_dir = os.path.join(tmpdir,"var","lib","dpkg") + os.makedirs(os.path.join(dpkg_dir,"updates")) + open(os.path.join(dpkg_dir,"status"), "w") + apt_pkg.Config.set("Dir::State::status", + os.path.join(dpkg_dir,"status")) + cache = apt.Cache() + # test empty + self.assertFalse(cache.dpkg_journal_dirty) + # that is ok, only [0-9] are dpkg jounral entries + open(os.path.join(dpkg_dir,"updates","xxx"), "w") + self.assertFalse(cache.dpkg_journal_dirty) + # that is a dirty journal + open(os.path.join(dpkg_dir,"updates","000"), "w") + self.assertTrue(cache.dpkg_journal_dirty) + # reset config value + apt_pkg.Config.set("Dir::State::status", old_status) + + if __name__ == "__main__": unittest.main() -- cgit v1.2.3 From a90b26aad2824d4bd224586cdf14c0ad21059ac3 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Fri, 2 Jul 2010 10:59:08 +0200 Subject: add test_progress.py test --- tests/data/fake-packages/Packages | 21 +++++++++++++++++ tests/data/fake-packages/Packages.gz | Bin 0 -> 555 bytes tests/test_progress.py | 44 +++++++++++++++++++++++++++++++++++ 3 files changed, 65 insertions(+) create mode 100644 tests/data/fake-packages/Packages create mode 100644 tests/data/fake-packages/Packages.gz create mode 100644 tests/test_progress.py diff --git a/tests/data/fake-packages/Packages b/tests/data/fake-packages/Packages new file mode 100644 index 00000000..9fbab957 --- /dev/null +++ b/tests/data/fake-packages/Packages @@ -0,0 +1,21 @@ +Package: 2vcard +Priority: optional +Section: universe/utils +Installed-Size: 108 +Maintainer: Arvind Autar +Architecture: amd64 +Version: 0.5-1ubuntu1 +Filename: pool/universe/2/2vcard/2vcard_0.5-1ubuntu1_amd64.deb +Size: 14164 +MD5sum: 105ea91f0a75417d0f9e8e9624513b2a +SHA1: d55beee01c08efc33cd131e106330dca72ee14be +SHA256: 4a72edaf87cdb826e5508b85311fcf0bec9b7e019a55740ded7feb1b9e197f11 +Description: A little perl script to convert an adressbook to VCARD file format + 2vcard is a little perl script that you can use to convert the popular vcard + file format. Currently 2vcard can only convert adressbooks and alias files from + the following formats: abook,eudora,juno,ldif,mutt,mh and pine. + . + The VCARD format is used by gnomecard, for example, which is turn is used by + the balsa email client. +Bugs: mailto:ubuntu-users@lists.ubuntu.com +Origin: Ubuntu diff --git a/tests/data/fake-packages/Packages.gz b/tests/data/fake-packages/Packages.gz new file mode 100644 index 00000000..506bc8d4 Binary files /dev/null and b/tests/data/fake-packages/Packages.gz differ diff --git a/tests/test_progress.py b/tests/test_progress.py new file mode 100644 index 00000000..2ab8ce5e --- /dev/null +++ b/tests/test_progress.py @@ -0,0 +1,44 @@ +#!/usr/bin/python +# +# Copyright (C) 2010 Michael Vogt +# +# Copying and distribution of this file, with or without modification, +# are permitted in any medium without royalty provided the copyright +# notice and this notice are preserved. +"""Unit tests for verifying the correctness of apt.progress""" +import unittest + +import apt +import apt_pkg +import os + +class TestAcquireProgress(apt.progress.base.AcquireProgress): + def pulse(self, owner): + self.pulsed = True + +class TestProgress(unittest.TestCase): + + def setUp(self): + basedir = os.path.abspath(os.path.dirname(__file__)) + # setup apt_pkg config + apt_pkg.init() + apt_pkg.config.set("APT::Architecture", "amd64") + apt_pkg.config.set("Dir::Etc", basedir) + apt_pkg.config.set("Dir::Etc::sourceparts", "/xxx") + # setup lists dir + if not os.path.exists("./tmp/partial"): + os.makedirs("./tmp/partial") + apt_pkg.config.set("Dir::state::lists", "./tmp") + # create artifical line + deb_line = "deb file:%s/data/fake-packages/ /\n" % basedir + open("fetch_sources.list","w").write(deb_line) + apt_pkg.config.set("Dir::Etc::sourcelist", "fetch_sources.list") + + def test_acquire_progress(self): + progress = TestAcquireProgress() + cache = apt.Cache() + res = cache.update(progress) + self.assertTrue(progress.pulsed) + +if __name__ == "__main__": + unittest.main() -- cgit v1.2.3 From 7dd530ec0cfd871d4b2b21c88f17aebca29b3dcd Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Fri, 2 Jul 2010 15:25:05 +0200 Subject: apt/debfile.py: DebFile needs a open file --- apt/debfile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apt/debfile.py b/apt/debfile.py index 83a5d68c..528cd311 100644 --- a/apt/debfile.py +++ b/apt/debfile.py @@ -58,7 +58,7 @@ class DebPackage(object): def open(self, filename): """ open given debfile """ self.filename = filename - self._debfile = apt_inst.DebFile(self.filename) + self._debfile = apt_inst.DebFile(open(self.filename)) control = self._debfile.control.extractdata("control") self._sections = apt_pkg.TagSection(control) self.pkgname = self._sections["Package"] -- cgit v1.2.3 From 850c486cc0c96f2a36a2b405354163fe41d356e7 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Fri, 2 Jul 2010 15:34:30 +0200 Subject: apt/debfile.py: fix bug in compare_to_version_in_cache with use_installed=True --- apt/debfile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apt/debfile.py b/apt/debfile.py index 528cd311..3b3a8d97 100644 --- a/apt/debfile.py +++ b/apt/debfile.py @@ -355,7 +355,7 @@ class DebPackage(object): if pkgname in self._cache: if use_installed and self._cache[pkgname].installed: cachever = self._cache[pkgname].installed.version - elif self._cache[pkgname].candidate: + elif not use_installed and self._cache[pkgname].candidate: cachever = self._cache[pkgname].candidate.version else: return self.VERSION_NONE -- cgit v1.2.3 From 945084be45a95fe532a6669e2c85a0ba363ecfd9 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Fri, 2 Jul 2010 16:12:13 +0200 Subject: * apt/debfile.py: - check if the debfiles provides are in conflict with the systems packages --- apt/debfile.py | 13 ++++++++++++- debian/changelog | 3 +++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/apt/debfile.py b/apt/debfile.py index 3b3a8d97..173521b1 100644 --- a/apt/debfile.py +++ b/apt/debfile.py @@ -301,6 +301,8 @@ class DebPackage(object): size = float(len(self._cache)) steps = int(size/50) debver = self._sections["Version"] + # store what we provide so that we can later check against that + provides = [ x[0][0] for x in self.provides] for (i, pkg) in enumerate(self._cache): if i%steps == 0: self._cache.op_progress.update(float(i)/size*100.0) @@ -331,13 +333,22 @@ class DebPackage(object): if apt_pkg.check_dep(debver, c_or.comp_type, c_or.target_ver): self._dbg(2, "would break (conflicts) %s" % pkg.name) # TRANSLATORS: the first '%s' is the package that conflicts, the second the packagename that it conflicts with (so the name of the deb the user tries to install), the third is the relation (e.g. >=) and the last is the version for the relation - self._failureString += _("Breaks existing package '%(pkgname)s' conflict: %(targetpkg)s (%(comptype)s %(targetver)s)") % { + self._failure_string += _("Breaks existing package '%(pkgname)s' conflict: %(targetpkg)s (%(comptype)s %(targetver)s)") % { 'pkgname' : pkg.name, 'targetpkg' : c_or.target_pkg.name, 'comptype' : c_or.comp_type, 'targetver' : c_or.target_ver } self._cache.op_progress.done() return False + if c_or.target_pkg.name in provides: + self._dbg(2, "would break (conflicts) %s" % provides) + self._failure_string += _("Breaks existing package '%(pkgname)s' that conflict: '%(targetpkg)s'. But the '%(debfile)s' provides it via: '%(provides)s'") % { + 'provides' : ",".join(provides), + 'debfile' : self.filename, + 'targetpkg' : c_or.target_pkg.name, + 'pkgname' : pkg.name } + self._cache.op_progress.done() + return False self._cache.op_progress.done() return True diff --git a/debian/changelog b/debian/changelog index 69db957f..29f37932 100644 --- a/debian/changelog +++ b/debian/changelog @@ -18,6 +18,9 @@ python-apt (0.7.96) UNRELEASED; urgency=low * merged lp:~kiwinote/python-apt/merge-gdebi-changes, this port the DebPackage class fixes from gdebi into python-apt so that gdebi can use the class from python-apt directly + * apt/debfile.py: + - check if the debfiles provides are in conflict with the systems + packages [ Martin Pitt ] * tests/test_apt_cache.py: Test accessing the record of all packages during -- cgit v1.2.3 From dd86db9ddb22b43867b5b4dc211f4440dec7aa6a Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Fri, 2 Jul 2010 16:37:45 +0200 Subject: * tests/test_debs/*.deb, tests/test_debfile.py: - add automatic test based on the test debs from gdebi --- apt/debfile.py | 10 ++++--- debian/changelog | 2 ++ tests/test_debfile.py | 56 +++++++++++++++++++++++++++++++++++++++ tests/test_debs/gdebi-test1.deb | Bin 0 -> 934 bytes tests/test_debs/gdebi-test10.deb | Bin 0 -> 614 bytes tests/test_debs/gdebi-test2.deb | Bin 0 -> 554 bytes tests/test_debs/gdebi-test3.deb | Bin 0 -> 570 bytes tests/test_debs/gdebi-test4.deb | Bin 0 -> 2306 bytes tests/test_debs/gdebi-test5.deb | Bin 0 -> 2306 bytes tests/test_debs/gdebi-test6.deb | Bin 0 -> 4312 bytes tests/test_debs/gdebi-test7.deb | Bin 0 -> 578 bytes tests/test_debs/gdebi-test8.deb | Bin 0 -> 598 bytes tests/test_debs/gdebi-test9.deb | Bin 0 -> 586 bytes 13 files changed, 64 insertions(+), 4 deletions(-) create mode 100644 tests/test_debfile.py create mode 100644 tests/test_debs/gdebi-test1.deb create mode 100644 tests/test_debs/gdebi-test10.deb create mode 100644 tests/test_debs/gdebi-test2.deb create mode 100644 tests/test_debs/gdebi-test3.deb create mode 100644 tests/test_debs/gdebi-test4.deb create mode 100644 tests/test_debs/gdebi-test5.deb create mode 100644 tests/test_debs/gdebi-test6.deb create mode 100644 tests/test_debs/gdebi-test7.deb create mode 100644 tests/test_debs/gdebi-test8.deb create mode 100644 tests/test_debs/gdebi-test9.deb diff --git a/apt/debfile.py b/apt/debfile.py index 173521b1..81cd1dd2 100644 --- a/apt/debfile.py +++ b/apt/debfile.py @@ -17,6 +17,7 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 # USA """Classes for working with locally available Debian packages.""" +import apt import apt_inst import apt_pkg import gzip @@ -44,19 +45,20 @@ class DebPackage(object): debug = 0 def __init__(self, filename=None, cache=None): + if cache is None: + cache = apt.Cache() self._cache = cache - self._need_pkgs = [] self._debfile = None self.pkgname = "" - self.filename = filename self._sections = {} - self._installed_conflicts = set() - self._failure_string = "" if filename: self.open(filename) def open(self, filename): """ open given debfile """ + self._need_pkgs = [] + self._installed_conflicts = set() + self._failure_string = "" self.filename = filename self._debfile = apt_inst.DebFile(open(self.filename)) control = self._debfile.control.extractdata("control") diff --git a/debian/changelog b/debian/changelog index 29f37932..b8ae49c1 100644 --- a/debian/changelog +++ b/debian/changelog @@ -21,6 +21,8 @@ python-apt (0.7.96) UNRELEASED; urgency=low * apt/debfile.py: - check if the debfiles provides are in conflict with the systems packages + * tests/test_debs/*.deb, tests/test_debfile.py: + - add automatic test based on the test debs from gdebi [ Martin Pitt ] * tests/test_apt_cache.py: Test accessing the record of all packages during diff --git a/tests/test_debfile.py b/tests/test_debfile.py new file mode 100644 index 00000000..02e25117 --- /dev/null +++ b/tests/test_debfile.py @@ -0,0 +1,56 @@ +#!/usr/bin/python +# +# Copyright (C) 2010 Michael Vogt +# +# Copying and distribution of this file, with or without modification, +# are permitted in any medium without royalty provided the copyright +# notice and this notice are preserved. +"""Unit tests for verifying the correctness of DebPackage in apt.debfile.""" +import os +import logging +import unittest + +import sys +sys.path.insert(0, "..") + +import apt.debfile + + +class TestDebfilee(unittest.TestCase): + """ test the apt cache """ + + TEST_DEBS = [ + # conflicts with apt + ('gdebi-test1.deb', False), + # impossible dependency + ('gdebi-test2.deb', False), + # or-group (impossible-dependency|apt) + ('gdebi-test3.deb', True), + # Conflicts: apt (<= 0.1) + ('gdebi-test4.deb', True), + # Conflicts: apt (>= 0.1) + ('gdebi-test5.deb', False), + # invalid unicode in descr + ('gdebi-test6.deb', True), + # provides/conflicts against "foobarbaz" + ('gdebi-test7.deb', True), + # provides/conflicts/replaces against "mail-transport-agent" + # (should fails if mail-transport-agent is installed) + ('gdebi-test8.deb', False), + # provides/conflicts against real pkg + ('gdebi-test9.deb', True), + # provides debconf-tiny and the real debconf conflicts with + ('gdebi-test10.deb', False), + ] + + def testDebFile(self): + deb = apt.debfile.DebPackage() + for (filename, expected_res) in self.TEST_DEBS: + logging.debug("testing %s, expecting %s" % (filename, expected_res)) + deb.open(os.path.join("test_debs", filename)) + res = deb.check() + self.assertEqual(res, expected_res) + +if __name__ == "__main__": + #logging.basicConfig(level=logging.DEBUG) + unittest.main() diff --git a/tests/test_debs/gdebi-test1.deb b/tests/test_debs/gdebi-test1.deb new file mode 100644 index 00000000..ea9991ac Binary files /dev/null and b/tests/test_debs/gdebi-test1.deb differ diff --git a/tests/test_debs/gdebi-test10.deb b/tests/test_debs/gdebi-test10.deb new file mode 100644 index 00000000..ca43ace6 Binary files /dev/null and b/tests/test_debs/gdebi-test10.deb differ diff --git a/tests/test_debs/gdebi-test2.deb b/tests/test_debs/gdebi-test2.deb new file mode 100644 index 00000000..307ac689 Binary files /dev/null and b/tests/test_debs/gdebi-test2.deb differ diff --git a/tests/test_debs/gdebi-test3.deb b/tests/test_debs/gdebi-test3.deb new file mode 100644 index 00000000..436b9258 Binary files /dev/null and b/tests/test_debs/gdebi-test3.deb differ diff --git a/tests/test_debs/gdebi-test4.deb b/tests/test_debs/gdebi-test4.deb new file mode 100644 index 00000000..9eb92d1b Binary files /dev/null and b/tests/test_debs/gdebi-test4.deb differ diff --git a/tests/test_debs/gdebi-test5.deb b/tests/test_debs/gdebi-test5.deb new file mode 100644 index 00000000..0c98c03f Binary files /dev/null and b/tests/test_debs/gdebi-test5.deb differ diff --git a/tests/test_debs/gdebi-test6.deb b/tests/test_debs/gdebi-test6.deb new file mode 100644 index 00000000..32fd1800 Binary files /dev/null and b/tests/test_debs/gdebi-test6.deb differ diff --git a/tests/test_debs/gdebi-test7.deb b/tests/test_debs/gdebi-test7.deb new file mode 100644 index 00000000..c0414990 Binary files /dev/null and b/tests/test_debs/gdebi-test7.deb differ diff --git a/tests/test_debs/gdebi-test8.deb b/tests/test_debs/gdebi-test8.deb new file mode 100644 index 00000000..439f8ca7 Binary files /dev/null and b/tests/test_debs/gdebi-test8.deb differ diff --git a/tests/test_debs/gdebi-test9.deb b/tests/test_debs/gdebi-test9.deb new file mode 100644 index 00000000..9901d906 Binary files /dev/null and b/tests/test_debs/gdebi-test9.deb differ -- cgit v1.2.3 From 9cfc2cd1213ab98d744b42bbfe3a4f8ca5e870ea Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Mon, 5 Jul 2010 18:22:37 +0200 Subject: Re-enable Python 3 support for latest python-default changes (hack). --- debian/changelog | 3 +++ debian/rules | 2 ++ utils/pyversions | 2 ++ 3 files changed, 7 insertions(+) create mode 100755 utils/pyversions diff --git a/debian/changelog b/debian/changelog index b8ae49c1..e82c0487 100644 --- a/debian/changelog +++ b/debian/changelog @@ -36,6 +36,9 @@ python-apt (0.7.96) UNRELEASED; urgency=low latter is disastrous if we use compressed package indexes, and slower than necessary for uncompressed indexes. + [ Julian Andres Klode ] + * Re-enable Python 3 support for latest python-default changes (hack). + -- Michael Vogt Tue, 01 Jun 2010 16:20:00 +0200 python-apt (0.7.95) unstable; urgency=low diff --git a/debian/rules b/debian/rules index a65c5cfd..e93d682f 100755 --- a/debian/rules +++ b/debian/rules @@ -3,6 +3,8 @@ export DH_PYCENTRAL=nomove export DEBVER=$(shell dpkg-parsechangelog | sed -n -e 's/^Version: //p') export CFLAGS=-Wno-write-strings -DCOMPAT_0_7 +export PATH :=$(CURDIR)/utils:$(PATH) +export SHELL=PATH=$(PATH) sh %: dh --with python-central $@ diff --git a/utils/pyversions b/utils/pyversions new file mode 100755 index 00000000..3accad3f --- /dev/null +++ b/utils/pyversions @@ -0,0 +1,2 @@ +#!/bin/sh +(/usr/bin/pyversions "$@"; /usr/bin/py3versions "$@"; ) | tr '\n' ' ' -- cgit v1.2.3 From dc7c1b076167d70b5c2f5c99c67160a0730814d5 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Mon, 5 Jul 2010 18:25:58 +0200 Subject: rules: Fix SHELL override. --- debian/rules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/rules b/debian/rules index e93d682f..f7cca130 100755 --- a/debian/rules +++ b/debian/rules @@ -4,7 +4,7 @@ export DH_PYCENTRAL=nomove export DEBVER=$(shell dpkg-parsechangelog | sed -n -e 's/^Version: //p') export CFLAGS=-Wno-write-strings -DCOMPAT_0_7 export PATH :=$(CURDIR)/utils:$(PATH) -export SHELL=PATH=$(PATH) sh +export SHELL = env PATH=$(PATH) sh %: dh --with python-central $@ -- cgit v1.2.3 From 750c50bd08d909b5802f892c88441000609183c0 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Mon, 5 Jul 2010 18:28:48 +0200 Subject: apt/debfile.py: make to_{hex,strish} staticmethods --- apt/debfile.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/apt/debfile.py b/apt/debfile.py index 81cd1dd2..06854cf2 100644 --- a/apt/debfile.py +++ b/apt/debfile.py @@ -506,6 +506,7 @@ class DebPackage(object): content.append(name) return sorted(content) + @staticmethod def to_hex(self, in_data): hex = "" for (i, c) in enumerate(in_data): @@ -514,6 +515,7 @@ class DebPackage(object): hex += "%2.2x " % ord(c) return hex + @staticmethod def to_strish(self, in_data): s = "" for c in in_data: -- cgit v1.2.3 From 9da50582230f21c9267a25eb92dbf3c080dfcafc Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Mon, 5 Jul 2010 18:35:07 +0200 Subject: test_debfile: Do not insert path (breaks py3k, use test_all for testing). --- tests/test_debfile.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/test_debfile.py b/tests/test_debfile.py index 02e25117..b9ed89c3 100644 --- a/tests/test_debfile.py +++ b/tests/test_debfile.py @@ -10,9 +10,6 @@ import os import logging import unittest -import sys -sys.path.insert(0, "..") - import apt.debfile -- cgit v1.2.3 From b94455e7afd0e08ce1a8aab890dbee0d42566d7b Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Tue, 6 Jul 2010 09:45:16 +0200 Subject: fix debfile to work with py3, update tests --- apt/debfile.py | 3 ++- tests/test_all.py | 32 ++++++++++++++++++++------------ tests/test_debfile.py | 3 ++- tests/test_debs/gdebi-test6.deb | Bin 4312 -> 600 bytes 4 files changed, 24 insertions(+), 14 deletions(-) diff --git a/apt/debfile.py b/apt/debfile.py index 81cd1dd2..16d1b15e 100644 --- a/apt/debfile.py +++ b/apt/debfile.py @@ -62,7 +62,8 @@ class DebPackage(object): self.filename = filename self._debfile = apt_inst.DebFile(open(self.filename)) control = self._debfile.control.extractdata("control") - self._sections = apt_pkg.TagSection(control) + # hm, 'replace' is probably better but python2.6 test fail with that + self._sections = apt_pkg.TagSection(control.decode("UTF-8", 'ignore')) self.pkgname = self._sections["Package"] def __getitem__(self, key): diff --git a/tests/test_all.py b/tests/test_all.py index d561a9ae..d6370747 100644 --- a/tests/test_all.py +++ b/tests/test_all.py @@ -9,21 +9,29 @@ import os import unittest import sys -if __name__ == '__main__': - sys.stderr.write("[tests] Running on %s\n" % sys.version.replace("\n", "")) - os.chdir(os.path.dirname(__file__)) +def get_library_dir(): # Find the path to the built apt_pkg and apt_inst extensions - if os.path.exists("../build"): - from distutils.util import get_platform - from distutils.sysconfig import get_python_version - # Set the path to the build directory. - plat_specifier = ".%s-%s" % (get_platform(), get_python_version()) - if sys.version_info[0] >= 3 or sys.version_info[1] >= 6: - library_dir = "../build/lib%s%s" % (plat_specifier, + if not os.path.exists("../build"): + return None + from distutils.util import get_platform + from distutils.sysconfig import get_python_version + # Set the path to the build directory. + plat_specifier = ".%s-%s" % (get_platform(), get_python_version()) + if sys.version_info[0] >= 3 or sys.version_info[1] >= 6: + library_dir = "../build/lib%s%s" % (plat_specifier, (sys.pydebug and "-pydebug" or "")) - else: - library_dir = "../build/lib%s%s" % ((sys.pydebug and "_d" or ""), + else: + library_dir = "../build/lib%s%s" % ((sys.pydebug and "_d" or ""), plat_specifier) + return os.path.abspath(library_dir) + +if __name__ == '__main__': + sys.stderr.write("[tests] Running on %s\n" % sys.version.replace("\n", "")) + dirname = os.path.dirname(__file__) + if dirname: + os.chdir(dirname) + library_dir = get_library_dir() + if library_dir: sys.path.insert(0, os.path.abspath(library_dir)) for path in os.listdir('.'): diff --git a/tests/test_debfile.py b/tests/test_debfile.py index 02e25117..56bbba9f 100644 --- a/tests/test_debfile.py +++ b/tests/test_debfile.py @@ -10,8 +10,9 @@ import os import logging import unittest +from test_all import get_library_dir import sys -sys.path.insert(0, "..") +sys.path.insert(0, get_library_dir()) import apt.debfile diff --git a/tests/test_debs/gdebi-test6.deb b/tests/test_debs/gdebi-test6.deb index 32fd1800..8ceacadc 100644 Binary files a/tests/test_debs/gdebi-test6.deb and b/tests/test_debs/gdebi-test6.deb differ -- cgit v1.2.3 From e94861e437dc544da9bf4a0161a25dedafd93f34 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Tue, 6 Jul 2010 10:35:57 +0200 Subject: * python/progress.cc: - deal with missing return value from the acquire progress in pulse() --- debian/changelog | 2 ++ python/progress.cc | 5 ++++- tests/test_progress.py | 3 +++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/debian/changelog b/debian/changelog index 98be965a..b592eb84 100644 --- a/debian/changelog +++ b/debian/changelog @@ -24,6 +24,8 @@ python-apt (0.7.96) UNRELEASED; urgency=low - fix py3 compatibility * tests/test_debs/*.deb, tests/test_debfile.py: - add automatic test based on the test debs from gdebi + * python/progress.cc: + - deal with missing return value from the acquire progress in pulse() [ Martin Pitt ] * tests/test_apt_cache.py: Test accessing the record of all packages during diff --git a/python/progress.cc b/python/progress.cc index 9002b3eb..437309cf 100644 --- a/python/progress.cc +++ b/python/progress.cc @@ -300,7 +300,10 @@ bool PyFetchProgress::Pulse(pkgAcquire * Owner) Py_INCREF(pyAcquire); if (RunSimpleCallback("pulse", TUPLEIZE(pyAcquire) , &result1)) { - if (result1 != NULL && PyArg_Parse(result1, "b", &res1) && res1 == false) { + if (result1 != NULL && + result1 != Py_None && + PyArg_Parse(result1, "b", &res1) && + res1 == false) { // the user returned a explicit false here, stop PyCbObj_BEGIN_ALLOW_THREADS return false; diff --git a/tests/test_progress.py b/tests/test_progress.py index 2ab8ce5e..ffab5bc0 100644 --- a/tests/test_progress.py +++ b/tests/test_progress.py @@ -15,6 +15,9 @@ import os class TestAcquireProgress(apt.progress.base.AcquireProgress): def pulse(self, owner): self.pulsed = True + # there should be a return value here, either (True,False) + # but often this is forgoten (and causes odd error messages) + # so the lib supports it. we test the lack of support value here class TestProgress(unittest.TestCase): -- cgit v1.2.3 From 443fb34e5fa04392c82c0cf56d3ea3e086c704f8 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Tue, 6 Jul 2010 10:42:26 +0200 Subject: tests/test_apt_cache.py: fixes for 0.8 compatibility --- tests/test_apt_cache.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/test_apt_cache.py b/tests/test_apt_cache.py index 653a0f48..a43e92d2 100644 --- a/tests/test_apt_cache.py +++ b/tests/test_apt_cache.py @@ -62,13 +62,13 @@ class TestAptCache(unittest.TestCase): def test_dpkg_journal_dirty(self): # backup old value - old_status = apt_pkg.Config.find_file("Dir::State::status") + old_status = apt_pkg.config.find_file("Dir::State::status") # create tmp env tmpdir = tempfile.mkdtemp() dpkg_dir = os.path.join(tmpdir,"var","lib","dpkg") os.makedirs(os.path.join(dpkg_dir,"updates")) open(os.path.join(dpkg_dir,"status"), "w") - apt_pkg.Config.set("Dir::State::status", + apt_pkg.config.set("Dir::State::status", os.path.join(dpkg_dir,"status")) cache = apt.Cache() # test empty @@ -80,7 +80,7 @@ class TestAptCache(unittest.TestCase): open(os.path.join(dpkg_dir,"updates","000"), "w") self.assertTrue(cache.dpkg_journal_dirty) # reset config value - apt_pkg.Config.set("Dir::State::status", old_status) + apt_pkg.config.set("Dir::State::status", old_status) if __name__ == "__main__": -- cgit v1.2.3 From dd58eafe47bb69797966f70f1181e4046856cfe4 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Tue, 6 Jul 2010 10:47:00 +0200 Subject: apt/cache.py: use apt_pkg.config instead of apt_pkg.Config --- apt/cache.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apt/cache.py b/apt/cache.py index 26532c76..f64b489a 100644 --- a/apt/cache.py +++ b/apt/cache.py @@ -471,7 +471,8 @@ class Cache(object): fix the system if dpkg got interrupted is to run 'dpkg --configure -a' as root. """ - dpkg_status_dir = os.path.dirname(apt_pkg.Config.find_file("Dir::State::status")) + dpkg_status_dir = os.path.dirname( + apt_pkg.config.find_file("Dir::State::status")) for f in os.listdir(os.path.join(dpkg_status_dir, "updates")): if fnmatch.fnmatch(f, "[0-9]*"): return True -- cgit v1.2.3 From e965c1321637d50986c243468d8095077f3e80ca Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Fri, 9 Jul 2010 22:51:51 +0200 Subject: tests/test_aptsources.py: fix test by forcing id=Ubuntu --- tests/test_aptsources.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_aptsources.py b/tests/test_aptsources.py index 767f5244..3ef20f64 100644 --- a/tests/test_aptsources.py +++ b/tests/test_aptsources.py @@ -98,7 +98,7 @@ class TestAptSources(unittest.TestCase): apt_pkg.config.set("Dir::Etc::sourcelist", "data/aptsources/" "sources.list.testDistribution") sources = aptsources.sourceslist.SourcesList(True, self.templates) - distro = aptsources.distro.get_distro() + distro = aptsources.distro.get_distro(id="Ubuntu") distro.get_sources(sources) # test if all suits of the current distro were detected correctly dist_templates = set() @@ -111,7 +111,7 @@ class TestAptSources(unittest.TestCase): apt_pkg.config.set("Dir::Etc::sourcelist", "data/aptsources/" "sources.list.testDistribution") sources = aptsources.sourceslist.SourcesList(True, self.templates) - distro = aptsources.distro.get_distro() + distro = aptsources.distro.get_distro(id="Ubuntu") distro.get_sources(sources) # test if all suits of the current distro were detected correctly dist_templates = set() -- cgit v1.2.3 From 51668ea3a95413a06684433a09f2097edc8e62b2 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Mon, 12 Jul 2010 09:51:42 +0200 Subject: po/*: refreshed po --- po/python-apt.pot | 67 ++++++++++++++++++++++++++----------------------------- 1 file changed, 32 insertions(+), 35 deletions(-) diff --git a/po/python-apt.pot b/po/python-apt.pot index 9c10c43f..0d683700 100644 --- a/po/python-apt.pot +++ b/po/python-apt.pot @@ -8,10 +8,11 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2010-07-02 14:12+0200\n" +"POT-Creation-Date: 2010-07-12 09:45+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" +"Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" @@ -413,91 +414,87 @@ msgid "" "Please check your Internet connection." msgstr "" -#: ../apt/debfile.py:142 +#: ../apt/debfile.py:79 +#, python-format +msgid "List of files for '%s' could not be read" +msgstr "" + +#: ../apt/debfile.py:164 #, python-format msgid "Dependency is not satisfiable: %s\n" msgstr "" -#: ../apt/debfile.py:163 +#: ../apt/debfile.py:185 #, python-format msgid "Conflicts with the installed package '%s'" msgstr "" #. TRANSLATORS: the first '%s' is the package that breaks, the second the dependency that makes it break, the third the relation (e.g. >=) and the latest the version for the releation -#: ../apt/debfile.py:297 +#: ../apt/debfile.py:323 #, python-format msgid "" -"Breaks existing package '%(pkgname)s' dependency %(depname)s (%(deprelation)" -"s %(depversion)s)" +"Breaks existing package '%(pkgname)s' dependency %(depname)s " +"(%(deprelation)s %(depversion)s)" msgstr "" #. TRANSLATORS: the first '%s' is the package that conflicts, the second the packagename that it conflicts with (so the name of the deb the user tries to install), the third is the relation (e.g. >=) and the last is the version for the relation -#: ../apt/debfile.py:313 +#: ../apt/debfile.py:339 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' conflict: %(targetpkg)s (%(comptype)s " +"%(targetver)s)" +msgstr "" + +#: ../apt/debfile.py:348 #, python-format msgid "" -"Breaks existing package '%(pkgname)s' conflict: %(targetpkg)s (%(comptype)s %" -"(targetver)s)" +"Breaks existing package '%(pkgname)s' that conflict: '%(targetpkg)s'. But " +"the '%(debfile)s' provides it via: '%(provides)s'" msgstr "" -#: ../apt/debfile.py:359 +#: ../apt/debfile.py:394 msgid "No Architecture field in the package" msgstr "" -#: ../apt/debfile.py:364 +#: ../apt/debfile.py:399 #, python-format msgid "Wrong architecture '%s'" msgstr "" #. the deb is older than the installed -#: ../apt/debfile.py:371 +#: ../apt/debfile.py:406 msgid "A later version is already installed" msgstr "" -#: ../apt/debfile.py:396 +#: ../apt/debfile.py:431 msgid "Failed to satisfy all dependencies (broken cache)" msgstr "" -#: ../apt/debfile.py:425 +#: ../apt/debfile.py:461 #, python-format msgid "Cannot install '%s'" msgstr "" -#: ../apt/debfile.py:467 ../apt/debfile.py:513 ../apt/debfile.py:524 +#: ../apt/debfile.py:503 ../apt/debfile.py:551 ../apt/debfile.py:562 msgid "Python-debian module not available" msgstr "" -#: ../apt/debfile.py:497 +#: ../apt/debfile.py:535 msgid "" "Automatically decompressed:\n" "\n" msgstr "" -#: ../apt/debfile.py:503 +#: ../apt/debfile.py:541 msgid "Automatically converted to printable ascii:\n" msgstr "" -#: ../apt/debfile.py:549 -msgid "List of files could not be read, please report this as a bug" -msgstr "" - -#: ../apt/debfile.py:552 -#, python-format -msgid "IOError during filelist read: %s" -msgstr "" - -#. Translators: it's for missing entries in the deb package, -#. e.g. a missing "Maintainer" field -#: ../apt/debfile.py:559 -#, python-format -msgid "%s is not available" -msgstr "" - -#: ../apt/debfile.py:632 +#: ../apt/debfile.py:638 #, python-format msgid "Install Build-Dependencies for source package '%s' that builds %s\n" msgstr "" -#: ../apt/debfile.py:642 +#: ../apt/debfile.py:648 msgid "An essential package would be removed" msgstr "" -- cgit v1.2.3 From f6b65060dac5f655b6273a227f81e9b947694596 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Mon, 12 Jul 2010 09:52:05 +0200 Subject: releasing version 0.7.96 --- debian/changelog | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/debian/changelog b/debian/changelog index b592eb84..b44031b9 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,4 +1,4 @@ -python-apt (0.7.96) UNRELEASED; urgency=low +python-apt (0.7.96) unstable; urgency=low [ Michael Vogt ] * data/templates/gNewSense.info.in, @@ -42,7 +42,7 @@ python-apt (0.7.96) UNRELEASED; urgency=low [ Julian Andres Klode ] * Re-enable Python 3 support for latest python-default changes (hack). - -- Michael Vogt Tue, 01 Jun 2010 16:20:00 +0200 + -- Michael Vogt Mon, 12 Jul 2010 08:58:42 +0200 python-apt (0.7.95) unstable; urgency=low -- cgit v1.2.3 From f75c59b6b250d14b1e52e1eebebfb5b11482d2ef Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Mon, 12 Jul 2010 14:10:40 +0200 Subject: tests/test_debfile.py: add fixture dpkg-status file to make tests work --- apt/debfile.py | 2 +- po/python-apt.pot | 58 ++++++++++++++++++++++++--------------------------- tests/test_debfile.py | 15 +++++++++---- 3 files changed, 39 insertions(+), 36 deletions(-) diff --git a/apt/debfile.py b/apt/debfile.py index 16d1b15e..7a1fa82d 100644 --- a/apt/debfile.py +++ b/apt/debfile.py @@ -302,7 +302,7 @@ class DebPackage(object): """ # show progress information as this step may take some time size = float(len(self._cache)) - steps = int(size/50) + steps = max(int(size/50), 1) debver = self._sections["Version"] # store what we provide so that we can later check against that provides = [ x[0][0] for x in self.provides] diff --git a/po/python-apt.pot b/po/python-apt.pot index 9c10c43f..036495e2 100644 --- a/po/python-apt.pot +++ b/po/python-apt.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2010-07-02 14:12+0200\n" +"POT-Creation-Date: 2010-07-12 14:07+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -413,18 +413,23 @@ msgid "" "Please check your Internet connection." msgstr "" -#: ../apt/debfile.py:142 +#: ../apt/debfile.py:79 +#, python-format +msgid "List of files for '%s' could not be read" +msgstr "" + +#: ../apt/debfile.py:164 #, python-format msgid "Dependency is not satisfiable: %s\n" msgstr "" -#: ../apt/debfile.py:163 +#: ../apt/debfile.py:185 #, python-format msgid "Conflicts with the installed package '%s'" msgstr "" #. TRANSLATORS: the first '%s' is the package that breaks, the second the dependency that makes it break, the third the relation (e.g. >=) and the latest the version for the releation -#: ../apt/debfile.py:297 +#: ../apt/debfile.py:323 #, python-format msgid "" "Breaks existing package '%(pkgname)s' dependency %(depname)s (%(deprelation)" @@ -432,72 +437,63 @@ msgid "" msgstr "" #. TRANSLATORS: the first '%s' is the package that conflicts, the second the packagename that it conflicts with (so the name of the deb the user tries to install), the third is the relation (e.g. >=) and the last is the version for the relation -#: ../apt/debfile.py:313 +#: ../apt/debfile.py:339 #, python-format msgid "" "Breaks existing package '%(pkgname)s' conflict: %(targetpkg)s (%(comptype)s %" "(targetver)s)" msgstr "" -#: ../apt/debfile.py:359 +#: ../apt/debfile.py:348 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' that conflict: '%(targetpkg)s'. But " +"the '%(debfile)s' provides it via: '%(provides)s'" +msgstr "" + +#: ../apt/debfile.py:394 msgid "No Architecture field in the package" msgstr "" -#: ../apt/debfile.py:364 +#: ../apt/debfile.py:399 #, python-format msgid "Wrong architecture '%s'" msgstr "" #. the deb is older than the installed -#: ../apt/debfile.py:371 +#: ../apt/debfile.py:406 msgid "A later version is already installed" msgstr "" -#: ../apt/debfile.py:396 +#: ../apt/debfile.py:431 msgid "Failed to satisfy all dependencies (broken cache)" msgstr "" -#: ../apt/debfile.py:425 +#: ../apt/debfile.py:461 #, python-format msgid "Cannot install '%s'" msgstr "" -#: ../apt/debfile.py:467 ../apt/debfile.py:513 ../apt/debfile.py:524 +#: ../apt/debfile.py:503 ../apt/debfile.py:549 ../apt/debfile.py:560 msgid "Python-debian module not available" msgstr "" -#: ../apt/debfile.py:497 +#: ../apt/debfile.py:533 msgid "" "Automatically decompressed:\n" "\n" msgstr "" -#: ../apt/debfile.py:503 +#: ../apt/debfile.py:539 msgid "Automatically converted to printable ascii:\n" msgstr "" -#: ../apt/debfile.py:549 -msgid "List of files could not be read, please report this as a bug" -msgstr "" - -#: ../apt/debfile.py:552 -#, python-format -msgid "IOError during filelist read: %s" -msgstr "" - -#. Translators: it's for missing entries in the deb package, -#. e.g. a missing "Maintainer" field -#: ../apt/debfile.py:559 -#, python-format -msgid "%s is not available" -msgstr "" - -#: ../apt/debfile.py:632 +#: ../apt/debfile.py:636 #, python-format msgid "Install Build-Dependencies for source package '%s' that builds %s\n" msgstr "" -#: ../apt/debfile.py:642 +#: ../apt/debfile.py:646 msgid "An essential package would be removed" msgstr "" diff --git a/tests/test_debfile.py b/tests/test_debfile.py index 56bbba9f..6af0cf1c 100644 --- a/tests/test_debfile.py +++ b/tests/test_debfile.py @@ -13,10 +13,9 @@ import unittest from test_all import get_library_dir import sys sys.path.insert(0, get_library_dir()) - +import apt_pkg import apt.debfile - class TestDebfilee(unittest.TestCase): """ test the apt cache """ @@ -44,13 +43,21 @@ class TestDebfilee(unittest.TestCase): ('gdebi-test10.deb', False), ] + def setUp(self): + apt_pkg.config.set("APT::Architecture","i386") + apt_pkg.config.set("Dir::State::status", + "./test_debs/var/lib/dpkg/status") + self.cache = apt.Cache() + def testDebFile(self): - deb = apt.debfile.DebPackage() + deb = apt.debfile.DebPackage(cache=self.cache) for (filename, expected_res) in self.TEST_DEBS: logging.debug("testing %s, expecting %s" % (filename, expected_res)) deb.open(os.path.join("test_debs", filename)) res = deb.check() - self.assertEqual(res, expected_res) + self.assertEqual(res, expected_res, + "Unexpected result for package '%s' (got %s wanted %s)" % ( + filename, res, expected_res)) if __name__ == "__main__": #logging.basicConfig(level=logging.DEBUG) -- cgit v1.2.3 From 4325749c7bfe5f1e83983415e13eafd84bb62907 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Mon, 12 Jul 2010 14:37:58 +0200 Subject: tests/test_debs/var/lib/dpkg/status: adding fake status file --- tests/test_debs/var/lib/dpkg/status | 77 +++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 tests/test_debs/var/lib/dpkg/status diff --git a/tests/test_debs/var/lib/dpkg/status b/tests/test_debs/var/lib/dpkg/status new file mode 100644 index 00000000..443262e1 --- /dev/null +++ b/tests/test_debs/var/lib/dpkg/status @@ -0,0 +1,77 @@ +Package: apt +Status: hold ok installed +Priority: important +Section: admin +Installed-Size: 5456 +Maintainer: APT Development Team +Architecture: i386 +Version: 0.7.25.3 +Replaces: libapt-pkg-dev (<< 0.3.7), libapt-pkg-doc (<< 0.3.7) +Provides: libapt-pkg-libc6.10-6-4.8 +Suggests: aptitude | synaptic | wajig, dpkg-dev, apt-doc, bzip2, lzma, python-apt +Conffiles: + /etc/cron.daily/apt 3528ddf873535d4c268d83e73e85dc79 + /etc/apt/apt.conf.d/01autoremove 6154750d39a78704b5bbf6fafd65ada7 + /etc/logrotate.d/apt 179f2ed4f85cbaca12fa3d69c2a4a1c3 + /etc/apt/apt.conf.d/01ubuntu 078b96538a377743bee0f554eb5b2fc6 obsolete +Description: Advanced front-end for dpkg + This is Debian's next generation front-end for the dpkg package manager. + It provides the apt-get utility and APT dselect method that provides a + simpler, safer way to install and upgrade packages. + . + APT features complete installation ordering, multiple source capability + and several other unique features, see the Users Guide in apt-doc. + +Package: postfix +Status: install ok installed +Priority: extra +Section: mail +Installed-Size: 3488 +Maintainer: LaMont Jones +Architecture: i386 +Version: 2.7.0-1 +Replaces: mail-transport-agent, postfix-tls +Provides: default-mta, mail-transport-agent, postfix-tls +Recommends: python +Suggests: procmail, postfix-mysql, postfix-pgsql, postfix-ldap, postfix-pcre, sasl2-bin, libsasl2-modules, resolvconf, postfix-cdb, mail-reader, ufw +Conflicts: libnss-db (<< 2.2-3), mail-transport-agent, postfix-tls, smail +Conffiles: + /etc/init.d/postfix e47d7ef0cbd2e212324812d74c409d77 + /etc/ppp/ip-up.d/postfix fccc53fc4eeeab46941ebcc95a71e766 + /etc/ppp/ip-down.d/postfix 52275dc23864f3bfca412c7558e28fe6 + /etc/network/if-up.d/postfix fccc53fc4eeeab46941ebcc95a71e766 + /etc/network/if-down.d/postfix 52275dc23864f3bfca412c7558e28fe6 + /etc/postfix/postfix-script 0d01860b2f0778cf41951c801f538b30 + /etc/postfix/post-install d53706c232f6497539fa0c99df674b33 + /etc/postfix/postfix-files 47e63262ab84069c840556b469b0fb2f + /etc/rsyslog.d/postfix.conf d8a09827fff2a22311e4dd4a83e95c83 + /etc/ufw/applications.d/postfix 6716a7729145a40bf7cb721c8dc6c3b0 + /etc/resolvconf/update-libc.d/postfix 6c80adbe120bc46cbf42658a7364e17f +Description: High-performance mail transport agent + Postfix is Wietse Venema's mail transport agent that started life as an + alternative to the widely-used Sendmail program. Postfix attempts to + be fast, easy to administer, and secure, while at the same time being + sendmail compatible enough to not upset existing users. Thus, the outside + has a sendmail-ish flavor, but the inside is completely different. + +Package: debconf +Status: install ok installed +Priority: important +Section: admin +Installed-Size: 924 +Maintainer: Debconf Developers +Architecture: all +Version: 1.5.28 +Replaces: debconf-tiny +Provides: debconf-2.0 +Recommends: apt-utils (>= 0.5.1) +Suggests: debconf-doc, debconf-utils, whiptail | dialog | gnome-utils, libterm-readline-gnu-perl, libgnome2-perl, libnet-ldap-perl, perl +Conflicts: apt (<< 0.3.12.1), cdebconf (<< 0.96), debconf-tiny, debconf-utils (<< 1.3.22), dialog (<< 0.9b-20020814-1), menu (<= 2.1.3-1), whiptail (<< 0.51.4-11), whiptail-utf8 (<= 0.50.17-13) +Conffiles: + /etc/apt/apt.conf.d/70debconf 7e9d09d5801a42b4926b736b8eeabb73 + /etc/bash_completion.d/debconf 8fa1862734fbe54d7178aaaa419f5a11 + /etc/debconf.conf 8c0619be413824f1fc7698cee0f23811 +Description: Debian configuration management system + Debconf is a configuration management system for debian packages. Packages + use Debconf to ask questions when they are installed. +Python-Version: 2.6, 3.1 -- cgit v1.2.3 From 3b155e595fed78f8eac22de78106cd3dcad9793c Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Mon, 12 Jul 2010 14:42:39 +0200 Subject: tests/test_debfile.py: move test_debs into tests/data --- tests/data/test_debs/gdebi-test1.deb | Bin 0 -> 934 bytes tests/data/test_debs/gdebi-test10.deb | Bin 0 -> 614 bytes tests/data/test_debs/gdebi-test2.deb | Bin 0 -> 554 bytes tests/data/test_debs/gdebi-test3.deb | Bin 0 -> 570 bytes tests/data/test_debs/gdebi-test4.deb | Bin 0 -> 2306 bytes tests/data/test_debs/gdebi-test5.deb | Bin 0 -> 2306 bytes tests/data/test_debs/gdebi-test6.deb | Bin 0 -> 600 bytes tests/data/test_debs/gdebi-test7.deb | Bin 0 -> 578 bytes tests/data/test_debs/gdebi-test8.deb | Bin 0 -> 598 bytes tests/data/test_debs/gdebi-test9.deb | Bin 0 -> 586 bytes tests/data/test_debs/var/lib/dpkg/status | 77 +++++++++++++++++++++++++++++++ tests/test_debfile.py | 4 +- tests/test_debs/gdebi-test1.deb | Bin 934 -> 0 bytes tests/test_debs/gdebi-test10.deb | Bin 614 -> 0 bytes tests/test_debs/gdebi-test2.deb | Bin 554 -> 0 bytes tests/test_debs/gdebi-test3.deb | Bin 570 -> 0 bytes tests/test_debs/gdebi-test4.deb | Bin 2306 -> 0 bytes tests/test_debs/gdebi-test5.deb | Bin 2306 -> 0 bytes tests/test_debs/gdebi-test6.deb | Bin 600 -> 0 bytes tests/test_debs/gdebi-test7.deb | Bin 578 -> 0 bytes tests/test_debs/gdebi-test8.deb | Bin 598 -> 0 bytes tests/test_debs/gdebi-test9.deb | Bin 586 -> 0 bytes tests/test_debs/var/lib/dpkg/status | 77 ------------------------------- 23 files changed, 79 insertions(+), 79 deletions(-) create mode 100644 tests/data/test_debs/gdebi-test1.deb create mode 100644 tests/data/test_debs/gdebi-test10.deb create mode 100644 tests/data/test_debs/gdebi-test2.deb create mode 100644 tests/data/test_debs/gdebi-test3.deb create mode 100644 tests/data/test_debs/gdebi-test4.deb create mode 100644 tests/data/test_debs/gdebi-test5.deb create mode 100644 tests/data/test_debs/gdebi-test6.deb create mode 100644 tests/data/test_debs/gdebi-test7.deb create mode 100644 tests/data/test_debs/gdebi-test8.deb create mode 100644 tests/data/test_debs/gdebi-test9.deb create mode 100644 tests/data/test_debs/var/lib/dpkg/status delete mode 100644 tests/test_debs/gdebi-test1.deb delete mode 100644 tests/test_debs/gdebi-test10.deb delete mode 100644 tests/test_debs/gdebi-test2.deb delete mode 100644 tests/test_debs/gdebi-test3.deb delete mode 100644 tests/test_debs/gdebi-test4.deb delete mode 100644 tests/test_debs/gdebi-test5.deb delete mode 100644 tests/test_debs/gdebi-test6.deb delete mode 100644 tests/test_debs/gdebi-test7.deb delete mode 100644 tests/test_debs/gdebi-test8.deb delete mode 100644 tests/test_debs/gdebi-test9.deb delete mode 100644 tests/test_debs/var/lib/dpkg/status diff --git a/tests/data/test_debs/gdebi-test1.deb b/tests/data/test_debs/gdebi-test1.deb new file mode 100644 index 00000000..ea9991ac Binary files /dev/null and b/tests/data/test_debs/gdebi-test1.deb differ diff --git a/tests/data/test_debs/gdebi-test10.deb b/tests/data/test_debs/gdebi-test10.deb new file mode 100644 index 00000000..ca43ace6 Binary files /dev/null and b/tests/data/test_debs/gdebi-test10.deb differ diff --git a/tests/data/test_debs/gdebi-test2.deb b/tests/data/test_debs/gdebi-test2.deb new file mode 100644 index 00000000..307ac689 Binary files /dev/null and b/tests/data/test_debs/gdebi-test2.deb differ diff --git a/tests/data/test_debs/gdebi-test3.deb b/tests/data/test_debs/gdebi-test3.deb new file mode 100644 index 00000000..436b9258 Binary files /dev/null and b/tests/data/test_debs/gdebi-test3.deb differ diff --git a/tests/data/test_debs/gdebi-test4.deb b/tests/data/test_debs/gdebi-test4.deb new file mode 100644 index 00000000..9eb92d1b Binary files /dev/null and b/tests/data/test_debs/gdebi-test4.deb differ diff --git a/tests/data/test_debs/gdebi-test5.deb b/tests/data/test_debs/gdebi-test5.deb new file mode 100644 index 00000000..0c98c03f Binary files /dev/null and b/tests/data/test_debs/gdebi-test5.deb differ diff --git a/tests/data/test_debs/gdebi-test6.deb b/tests/data/test_debs/gdebi-test6.deb new file mode 100644 index 00000000..8ceacadc Binary files /dev/null and b/tests/data/test_debs/gdebi-test6.deb differ diff --git a/tests/data/test_debs/gdebi-test7.deb b/tests/data/test_debs/gdebi-test7.deb new file mode 100644 index 00000000..c0414990 Binary files /dev/null and b/tests/data/test_debs/gdebi-test7.deb differ diff --git a/tests/data/test_debs/gdebi-test8.deb b/tests/data/test_debs/gdebi-test8.deb new file mode 100644 index 00000000..439f8ca7 Binary files /dev/null and b/tests/data/test_debs/gdebi-test8.deb differ diff --git a/tests/data/test_debs/gdebi-test9.deb b/tests/data/test_debs/gdebi-test9.deb new file mode 100644 index 00000000..9901d906 Binary files /dev/null and b/tests/data/test_debs/gdebi-test9.deb differ diff --git a/tests/data/test_debs/var/lib/dpkg/status b/tests/data/test_debs/var/lib/dpkg/status new file mode 100644 index 00000000..443262e1 --- /dev/null +++ b/tests/data/test_debs/var/lib/dpkg/status @@ -0,0 +1,77 @@ +Package: apt +Status: hold ok installed +Priority: important +Section: admin +Installed-Size: 5456 +Maintainer: APT Development Team +Architecture: i386 +Version: 0.7.25.3 +Replaces: libapt-pkg-dev (<< 0.3.7), libapt-pkg-doc (<< 0.3.7) +Provides: libapt-pkg-libc6.10-6-4.8 +Suggests: aptitude | synaptic | wajig, dpkg-dev, apt-doc, bzip2, lzma, python-apt +Conffiles: + /etc/cron.daily/apt 3528ddf873535d4c268d83e73e85dc79 + /etc/apt/apt.conf.d/01autoremove 6154750d39a78704b5bbf6fafd65ada7 + /etc/logrotate.d/apt 179f2ed4f85cbaca12fa3d69c2a4a1c3 + /etc/apt/apt.conf.d/01ubuntu 078b96538a377743bee0f554eb5b2fc6 obsolete +Description: Advanced front-end for dpkg + This is Debian's next generation front-end for the dpkg package manager. + It provides the apt-get utility and APT dselect method that provides a + simpler, safer way to install and upgrade packages. + . + APT features complete installation ordering, multiple source capability + and several other unique features, see the Users Guide in apt-doc. + +Package: postfix +Status: install ok installed +Priority: extra +Section: mail +Installed-Size: 3488 +Maintainer: LaMont Jones +Architecture: i386 +Version: 2.7.0-1 +Replaces: mail-transport-agent, postfix-tls +Provides: default-mta, mail-transport-agent, postfix-tls +Recommends: python +Suggests: procmail, postfix-mysql, postfix-pgsql, postfix-ldap, postfix-pcre, sasl2-bin, libsasl2-modules, resolvconf, postfix-cdb, mail-reader, ufw +Conflicts: libnss-db (<< 2.2-3), mail-transport-agent, postfix-tls, smail +Conffiles: + /etc/init.d/postfix e47d7ef0cbd2e212324812d74c409d77 + /etc/ppp/ip-up.d/postfix fccc53fc4eeeab46941ebcc95a71e766 + /etc/ppp/ip-down.d/postfix 52275dc23864f3bfca412c7558e28fe6 + /etc/network/if-up.d/postfix fccc53fc4eeeab46941ebcc95a71e766 + /etc/network/if-down.d/postfix 52275dc23864f3bfca412c7558e28fe6 + /etc/postfix/postfix-script 0d01860b2f0778cf41951c801f538b30 + /etc/postfix/post-install d53706c232f6497539fa0c99df674b33 + /etc/postfix/postfix-files 47e63262ab84069c840556b469b0fb2f + /etc/rsyslog.d/postfix.conf d8a09827fff2a22311e4dd4a83e95c83 + /etc/ufw/applications.d/postfix 6716a7729145a40bf7cb721c8dc6c3b0 + /etc/resolvconf/update-libc.d/postfix 6c80adbe120bc46cbf42658a7364e17f +Description: High-performance mail transport agent + Postfix is Wietse Venema's mail transport agent that started life as an + alternative to the widely-used Sendmail program. Postfix attempts to + be fast, easy to administer, and secure, while at the same time being + sendmail compatible enough to not upset existing users. Thus, the outside + has a sendmail-ish flavor, but the inside is completely different. + +Package: debconf +Status: install ok installed +Priority: important +Section: admin +Installed-Size: 924 +Maintainer: Debconf Developers +Architecture: all +Version: 1.5.28 +Replaces: debconf-tiny +Provides: debconf-2.0 +Recommends: apt-utils (>= 0.5.1) +Suggests: debconf-doc, debconf-utils, whiptail | dialog | gnome-utils, libterm-readline-gnu-perl, libgnome2-perl, libnet-ldap-perl, perl +Conflicts: apt (<< 0.3.12.1), cdebconf (<< 0.96), debconf-tiny, debconf-utils (<< 1.3.22), dialog (<< 0.9b-20020814-1), menu (<= 2.1.3-1), whiptail (<< 0.51.4-11), whiptail-utf8 (<= 0.50.17-13) +Conffiles: + /etc/apt/apt.conf.d/70debconf 7e9d09d5801a42b4926b736b8eeabb73 + /etc/bash_completion.d/debconf 8fa1862734fbe54d7178aaaa419f5a11 + /etc/debconf.conf 8c0619be413824f1fc7698cee0f23811 +Description: Debian configuration management system + Debconf is a configuration management system for debian packages. Packages + use Debconf to ask questions when they are installed. +Python-Version: 2.6, 3.1 diff --git a/tests/test_debfile.py b/tests/test_debfile.py index 6af0cf1c..c71c34a3 100644 --- a/tests/test_debfile.py +++ b/tests/test_debfile.py @@ -46,14 +46,14 @@ class TestDebfilee(unittest.TestCase): def setUp(self): apt_pkg.config.set("APT::Architecture","i386") apt_pkg.config.set("Dir::State::status", - "./test_debs/var/lib/dpkg/status") + "./data/test_debs/var/lib/dpkg/status") self.cache = apt.Cache() def testDebFile(self): deb = apt.debfile.DebPackage(cache=self.cache) for (filename, expected_res) in self.TEST_DEBS: logging.debug("testing %s, expecting %s" % (filename, expected_res)) - deb.open(os.path.join("test_debs", filename)) + deb.open(os.path.join("data", "test_debs", filename)) res = deb.check() self.assertEqual(res, expected_res, "Unexpected result for package '%s' (got %s wanted %s)" % ( diff --git a/tests/test_debs/gdebi-test1.deb b/tests/test_debs/gdebi-test1.deb deleted file mode 100644 index ea9991ac..00000000 Binary files a/tests/test_debs/gdebi-test1.deb and /dev/null differ diff --git a/tests/test_debs/gdebi-test10.deb b/tests/test_debs/gdebi-test10.deb deleted file mode 100644 index ca43ace6..00000000 Binary files a/tests/test_debs/gdebi-test10.deb and /dev/null differ diff --git a/tests/test_debs/gdebi-test2.deb b/tests/test_debs/gdebi-test2.deb deleted file mode 100644 index 307ac689..00000000 Binary files a/tests/test_debs/gdebi-test2.deb and /dev/null differ diff --git a/tests/test_debs/gdebi-test3.deb b/tests/test_debs/gdebi-test3.deb deleted file mode 100644 index 436b9258..00000000 Binary files a/tests/test_debs/gdebi-test3.deb and /dev/null differ diff --git a/tests/test_debs/gdebi-test4.deb b/tests/test_debs/gdebi-test4.deb deleted file mode 100644 index 9eb92d1b..00000000 Binary files a/tests/test_debs/gdebi-test4.deb and /dev/null differ diff --git a/tests/test_debs/gdebi-test5.deb b/tests/test_debs/gdebi-test5.deb deleted file mode 100644 index 0c98c03f..00000000 Binary files a/tests/test_debs/gdebi-test5.deb and /dev/null differ diff --git a/tests/test_debs/gdebi-test6.deb b/tests/test_debs/gdebi-test6.deb deleted file mode 100644 index 8ceacadc..00000000 Binary files a/tests/test_debs/gdebi-test6.deb and /dev/null differ diff --git a/tests/test_debs/gdebi-test7.deb b/tests/test_debs/gdebi-test7.deb deleted file mode 100644 index c0414990..00000000 Binary files a/tests/test_debs/gdebi-test7.deb and /dev/null differ diff --git a/tests/test_debs/gdebi-test8.deb b/tests/test_debs/gdebi-test8.deb deleted file mode 100644 index 439f8ca7..00000000 Binary files a/tests/test_debs/gdebi-test8.deb and /dev/null differ diff --git a/tests/test_debs/gdebi-test9.deb b/tests/test_debs/gdebi-test9.deb deleted file mode 100644 index 9901d906..00000000 Binary files a/tests/test_debs/gdebi-test9.deb and /dev/null differ diff --git a/tests/test_debs/var/lib/dpkg/status b/tests/test_debs/var/lib/dpkg/status deleted file mode 100644 index 443262e1..00000000 --- a/tests/test_debs/var/lib/dpkg/status +++ /dev/null @@ -1,77 +0,0 @@ -Package: apt -Status: hold ok installed -Priority: important -Section: admin -Installed-Size: 5456 -Maintainer: APT Development Team -Architecture: i386 -Version: 0.7.25.3 -Replaces: libapt-pkg-dev (<< 0.3.7), libapt-pkg-doc (<< 0.3.7) -Provides: libapt-pkg-libc6.10-6-4.8 -Suggests: aptitude | synaptic | wajig, dpkg-dev, apt-doc, bzip2, lzma, python-apt -Conffiles: - /etc/cron.daily/apt 3528ddf873535d4c268d83e73e85dc79 - /etc/apt/apt.conf.d/01autoremove 6154750d39a78704b5bbf6fafd65ada7 - /etc/logrotate.d/apt 179f2ed4f85cbaca12fa3d69c2a4a1c3 - /etc/apt/apt.conf.d/01ubuntu 078b96538a377743bee0f554eb5b2fc6 obsolete -Description: Advanced front-end for dpkg - This is Debian's next generation front-end for the dpkg package manager. - It provides the apt-get utility and APT dselect method that provides a - simpler, safer way to install and upgrade packages. - . - APT features complete installation ordering, multiple source capability - and several other unique features, see the Users Guide in apt-doc. - -Package: postfix -Status: install ok installed -Priority: extra -Section: mail -Installed-Size: 3488 -Maintainer: LaMont Jones -Architecture: i386 -Version: 2.7.0-1 -Replaces: mail-transport-agent, postfix-tls -Provides: default-mta, mail-transport-agent, postfix-tls -Recommends: python -Suggests: procmail, postfix-mysql, postfix-pgsql, postfix-ldap, postfix-pcre, sasl2-bin, libsasl2-modules, resolvconf, postfix-cdb, mail-reader, ufw -Conflicts: libnss-db (<< 2.2-3), mail-transport-agent, postfix-tls, smail -Conffiles: - /etc/init.d/postfix e47d7ef0cbd2e212324812d74c409d77 - /etc/ppp/ip-up.d/postfix fccc53fc4eeeab46941ebcc95a71e766 - /etc/ppp/ip-down.d/postfix 52275dc23864f3bfca412c7558e28fe6 - /etc/network/if-up.d/postfix fccc53fc4eeeab46941ebcc95a71e766 - /etc/network/if-down.d/postfix 52275dc23864f3bfca412c7558e28fe6 - /etc/postfix/postfix-script 0d01860b2f0778cf41951c801f538b30 - /etc/postfix/post-install d53706c232f6497539fa0c99df674b33 - /etc/postfix/postfix-files 47e63262ab84069c840556b469b0fb2f - /etc/rsyslog.d/postfix.conf d8a09827fff2a22311e4dd4a83e95c83 - /etc/ufw/applications.d/postfix 6716a7729145a40bf7cb721c8dc6c3b0 - /etc/resolvconf/update-libc.d/postfix 6c80adbe120bc46cbf42658a7364e17f -Description: High-performance mail transport agent - Postfix is Wietse Venema's mail transport agent that started life as an - alternative to the widely-used Sendmail program. Postfix attempts to - be fast, easy to administer, and secure, while at the same time being - sendmail compatible enough to not upset existing users. Thus, the outside - has a sendmail-ish flavor, but the inside is completely different. - -Package: debconf -Status: install ok installed -Priority: important -Section: admin -Installed-Size: 924 -Maintainer: Debconf Developers -Architecture: all -Version: 1.5.28 -Replaces: debconf-tiny -Provides: debconf-2.0 -Recommends: apt-utils (>= 0.5.1) -Suggests: debconf-doc, debconf-utils, whiptail | dialog | gnome-utils, libterm-readline-gnu-perl, libgnome2-perl, libnet-ldap-perl, perl -Conflicts: apt (<< 0.3.12.1), cdebconf (<< 0.96), debconf-tiny, debconf-utils (<< 1.3.22), dialog (<< 0.9b-20020814-1), menu (<= 2.1.3-1), whiptail (<< 0.51.4-11), whiptail-utf8 (<= 0.50.17-13) -Conffiles: - /etc/apt/apt.conf.d/70debconf 7e9d09d5801a42b4926b736b8eeabb73 - /etc/bash_completion.d/debconf 8fa1862734fbe54d7178aaaa419f5a11 - /etc/debconf.conf 8c0619be413824f1fc7698cee0f23811 -Description: Debian configuration management system - Debconf is a configuration management system for debian packages. Packages - use Debconf to ask questions when they are installed. -Python-Version: 2.6, 3.1 -- cgit v1.2.3 From 07e4a58a369de9ce7855db79d51490296d5cf6e5 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Mon, 12 Jul 2010 15:16:45 +0200 Subject: apply fix from juliank for the tests (many thanks!) --- tests/test_debfile.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/test_debfile.py b/tests/test_debfile.py index e4755b5b..bb9fd62c 100644 --- a/tests/test_debfile.py +++ b/tests/test_debfile.py @@ -44,9 +44,11 @@ class TestDebfilee(unittest.TestCase): ] def setUp(self): + apt_pkg.init_config() apt_pkg.config.set("APT::Architecture","i386") apt_pkg.config.set("Dir::State::status", "./data/test_debs/var/lib/dpkg/status") + apt_pkg.init_system() self.cache = apt.Cache() def testDebFile(self): -- cgit v1.2.3 From f85293fe8cdd2233ba7ce365711b6c0e275be19d Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Mon, 12 Jul 2010 15:45:26 +0200 Subject: releasing version 0.7.96.1 --- debian/changelog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/changelog b/debian/changelog index 466913a5..b08a117c 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,4 +1,4 @@ -python-apt (0.7.96.1) UNRELEASED; urgency=low +python-apt (0.7.96.1) unstable; urgency=low * tests/test_debfile.py: - properly setup fixture data to make debfile test pass -- cgit v1.2.3 From 7219ee607e72438bbbb755caebdc7f617ee440f4 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Fri, 23 Jul 2010 16:16:24 +0200 Subject: * python/tag.cc: - Support gzip compression for control files (Closes: #383617), requires APT (>> 0.7.26~exp10) to work. --- debian/changelog | 8 ++++++++ python/tag.cc | 5 +++++ 2 files changed, 13 insertions(+) diff --git a/debian/changelog b/debian/changelog index b08a117c..cb2bcebb 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,11 @@ +python-apt (0.7.97) UNRELEASED; urgency=low + + * python/tag.cc: + - Support gzip compression for control files (Closes: #383617), + requires APT (>> 0.7.26~exp10) to work. + + -- Julian Andres Klode Fri, 23 Jul 2010 16:14:39 +0200 + python-apt (0.7.96.1) unstable; urgency=low * tests/test_debfile.py: diff --git a/python/tag.cc b/python/tag.cc index 9fe12a1a..97039bc4 100644 --- a/python/tag.cc +++ b/python/tag.cc @@ -393,7 +393,12 @@ static PyObject *TagFileNew(PyTypeObject *type,PyObject *Args,PyObject *kwds) return 0; TagFileData *New = (TagFileData*)type->tp_alloc(type, 0); +#ifdef APT_HAS_GZIP + new (&New->Fd) FileFd(); + New->Fd.OpenDescriptor(fileno, FileFd::ReadOnlyGzip, false); +#else new (&New->Fd) FileFd(fileno,false); +#endif New->Owner = File; Py_INCREF(New->Owner); new (&New->Object) pkgTagFile(&New->Fd); -- cgit v1.2.3 From d4982e0e6d4b4fefb55043bb999784f5cfb2b686 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Fri, 23 Jul 2010 16:32:54 +0200 Subject: * doc/conf.py: - Correctly handle non-digit characters in version (ignore everything after them). --- debian/changelog | 3 +++ doc/source/conf.py | 9 +++++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/debian/changelog b/debian/changelog index cb2bcebb..c76efa37 100644 --- a/debian/changelog +++ b/debian/changelog @@ -3,6 +3,9 @@ python-apt (0.7.97) UNRELEASED; urgency=low * python/tag.cc: - Support gzip compression for control files (Closes: #383617), requires APT (>> 0.7.26~exp10) to work. + * doc/conf.py: + - Correctly handle non-digit characters in version (ignore everything + after them). -- Julian Andres Klode Fri, 23 Jul 2010 16:14:39 +0200 diff --git a/doc/source/conf.py b/doc/source/conf.py index 05490da7..18c8642e 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -78,8 +78,13 @@ except KeyError: release = p2.communicate()[0] # Handle the alpha release scheme -release_raw = release.split("~")[0].split(".")[2] -if release_raw.isdigit() and int(release_raw) >= 90: +release_raw = "0" +for c in release.split("~")[0].split(".")[2]: + if not c.isdigit(): + break + release_raw += c + +if int(release_raw) >= 90: version_s = release.split("~")[0].split(".")[:3] # Set the version to 0.X.100 if the release is 0.X.9Y (0.7.90 => 0.7.100) # Use -- cgit v1.2.3 From d642c9ea22f5705acfcba79493f48293626771c3 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Fri, 23 Jul 2010 16:37:13 +0200 Subject: * python/apt_pkgmodule.cc: - Bind pkgAcquire::Item::StatTransientNetworkError (Closes: #589010) --- debian/changelog | 2 ++ doc/source/library/apt_pkg.rst | 4 ++++ python/apt_pkgmodule.cc | 2 ++ 3 files changed, 8 insertions(+) diff --git a/debian/changelog b/debian/changelog index c76efa37..cb747f14 100644 --- a/debian/changelog +++ b/debian/changelog @@ -6,6 +6,8 @@ python-apt (0.7.97) UNRELEASED; urgency=low * doc/conf.py: - Correctly handle non-digit characters in version (ignore everything after them). + * python/apt_pkgmodule.cc: + - Bind pkgAcquire::Item::StatTransientNetworkError (Closes: #589010) -- Julian Andres Klode Fri, 23 Jul 2010 16:14:39 +0200 diff --git a/doc/source/library/apt_pkg.rst b/doc/source/library/apt_pkg.rst index dd958959..b91790db 100644 --- a/doc/source/library/apt_pkg.rst +++ b/doc/source/library/apt_pkg.rst @@ -1381,6 +1381,10 @@ installation. The item is yet to be fetched. + .. attribute:: STAT_TRANSIENT_NETWORK_ERROR + + There was a network error. + .. class:: AcquireFile(owner, uri[, md5, size, descr, short_descr, destdir, destfile]) diff --git a/python/apt_pkgmodule.cc b/python/apt_pkgmodule.cc index a1e9ada0..cacbf77a 100644 --- a/python/apt_pkgmodule.cc +++ b/python/apt_pkgmodule.cc @@ -905,6 +905,8 @@ extern "C" void initapt_pkg() Py_BuildValue("i", pkgAcquire::Item::StatFetching)); PyDict_SetItemString(PyAcquireItem_Type.tp_dict, "STAT_DONE", Py_BuildValue("i", pkgAcquire::Item::StatDone)); + PyDict_SetItemString(PyAcquireItem_Type.tp_dict, "STAT_TRANSIENT_NETWORK_ERROR", + Py_BuildValue("i", pkgAcquire::Item::StatTransientNetworkError)); PyDict_SetItemString(PyAcquireItem_Type.tp_dict, "STAT_ERROR", Py_BuildValue("i", pkgAcquire::Item::StatError)); PyDict_SetItemString(PyAcquireItem_Type.tp_dict, "STAT_AUTH_ERROR", -- cgit v1.2.3