diff options
Diffstat (limited to 'apt')
| -rw-r--r-- | apt/cache.py | 19 | ||||
| -rw-r--r-- | apt/debfile.py | 39 | ||||
| -rw-r--r-- | apt/package.py | 19 | ||||
| -rw-r--r-- | apt/progress/base.py | 4 |
4 files changed, 60 insertions, 21 deletions
diff --git a/apt/cache.py b/apt/cache.py index be137b76..96b38a57 100644 --- a/apt/cache.py +++ b/apt/cache.py @@ -46,8 +46,13 @@ class LockFailedException(IOError): class Cache(object): """Dictionary-like package cache. - This class has all the packages that are available in it's - dictionary. + The APT cache file contains a hash table mapping names of binary + packages to their metadata. A Cache object is the in-core + representation of the same. It provides access to APTs idea of the + list of available packages. + + The cache can be used like a mapping from package names to Package + objects (although only getting items is supported). Keyword arguments: progress -- a OpProgress object @@ -84,6 +89,10 @@ class Cache(object): apt_pkg.config.set("Dir", rootdir) apt_pkg.config.set("Dir::State::status", rootdir + "/var/lib/dpkg/status") + # also set dpkg to the rootdir path so that its called for the + # --print-foreign-architectures call + apt_pkg.config.set("Dir::bin::dpkg", + os.path.join(rootdir, "usr", "bin", "dpkg")) # create required dirs/files when run with special rootdir # automatically self._check_and_create_required_dirs(rootdir) @@ -112,7 +121,7 @@ class Cache(object): ] for d in dirs: if not os.path.exists(rootdir + d): - print "creating: ", rootdir + d + #print "creating: ", rootdir + d os.makedirs(rootdir + d) for f in files: if not os.path.exists(rootdir + f): @@ -507,7 +516,7 @@ class Cache(object): self._callbacks[name].append(callback) def actiongroup(self): - """Return an ActionGroup() object for the current cache. + """Return an `ActionGroup` object for the current cache. Action groups can be used to speedup actions. The action group is active as soon as it is created, and disabled when the object is @@ -520,7 +529,7 @@ class Cache(object): for package in my_selected_packages: package.mark_install() - This way, the ActionGroup is automatically released as soon as the + This way, the action group is automatically released as soon as the with statement block is left. It also has the benefit of making it clear which parts of the code run with a action group and which don't. diff --git a/apt/debfile.py b/apt/debfile.py index d0f41def..17f1dbd9 100644 --- a/apt/debfile.py +++ b/apt/debfile.py @@ -53,6 +53,7 @@ class DebPackage(object): self.pkgname = "" self._sections = {} self._need_pkgs = [] + self._check_was_run = False self._failure_string = "" if filename: self.open(filename) @@ -68,7 +69,8 @@ class DebPackage(object): control = self._debfile.control.extractdata("control") self._sections = apt_pkg.TagSection(control) self.pkgname = self._sections["Package"] - + self._check_was_run = False + def __getitem__(self, key): return self._sections[key] @@ -308,6 +310,7 @@ class DebPackage(object): size = float(len(self._cache)) steps = max(int(size/50), 1) debver = self._sections["Version"] + debarch = self._sections["Architecture"] # 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): @@ -336,7 +339,7 @@ class DebPackage(object): 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 c_or.target_pkg.name == self.pkgname and c_or.target_pkg.architecture == debarch: 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 @@ -393,6 +396,8 @@ class DebPackage(object): """Check if the package is installable.""" self._dbg(3, "check") + self._check_was_run = True + # check arch if not "Architecture" in self._sections: self._dbg(1, "ERROR: no architecture field") @@ -472,8 +477,8 @@ class DebPackage(object): def missing_deps(self): """Return missing dependencies.""" self._dbg(1, "Installing: %s" % self._need_pkgs) - if self._need_pkgs is None: - self.check() + if not self._check_was_run: + raise AttributeError("property only available after check() was run") return self._need_pkgs @property @@ -485,6 +490,8 @@ class DebPackage(object): install = [] remove = [] unauthenticated = [] + if not self._check_was_run: + raise AttributeError("property only available after check() was run") for pkg in self._cache: if pkg.marked_install or pkg.marked_upgrade: install.append(pkg.name) @@ -524,11 +531,20 @@ class DebPackage(object): @staticmethod def to_strish(in_data): s = "" - for c in in_data: - if ord(c) < 10 or ord(c) > 127: - s += " " - else: - s += c + # py2 compat, in_data is type string + if type(in_data) == str: + for c in in_data: + if ord(c) < 10 or ord(c) > 127: + s += " " + else: + s += c + # py3 compat, in_data is type bytes + else: + for b in in_data: + if b < 10 or b > 127: + s += " " + else: + s += chr(b) return s def _get_content(self, part, name, auto_decompress=True, auto_hex=True): @@ -639,7 +655,8 @@ class DscSrcPackage(DebPackage): "source package '%s' that builds %s\n") % (self.pkgname, " ".join(self.binaries)) self._sections["Description"] = s - + self._check_was_run = False + def check(self): """Check if the package is installable..""" if not self.check_conflicts(): @@ -647,6 +664,8 @@ class DscSrcPackage(DebPackage): if self._cache[pkgname]._pkg.essential: raise Exception(_("An essential package would be removed")) self._cache[pkgname].mark_delete() + # properties are ok now + self._check_was_run = True # FIXME: a additional run of the check_conflicts() # after _satisfy_depends() should probably be done return self._satisfy_depends(self.depends) diff --git a/apt/package.py b/apt/package.py index 4104f93e..81f33a8b 100644 --- a/apt/package.py +++ b/apt/package.py @@ -94,7 +94,7 @@ class BaseDependency(object): preDepend = AttributeDeprecatedBy('pre_depend') -class Dependency(object): +class Dependency(list): """Represent an Or-group of dependencies. Attributes defined here: @@ -102,11 +102,12 @@ class Dependency(object): """ def __init__(self, alternatives): - self.or_dependencies = alternatives - - def __repr__(self): - return repr(self.or_dependencies) + super(Dependency, self).__init__() + self.extend(alternatives) + @property + def or_dependencies(self): + return self class DeprecatedProperty(property): """A property which gives DeprecationWarning on access. @@ -455,6 +456,11 @@ class Version(object): return self.get_dependencies("Recommends") @property + def suggests(self): + """Return the suggests of the package version.""" + return self.get_dependencies("Suggests") + + @property def origins(self): """Return a list of origins for the package version.""" origins = [] @@ -707,6 +713,9 @@ class Package(object): return '<Package: name:%r architecture=%r id:%r>' % (self._pkg.name, self._pkg.architecture, self._pkg.id) + def __lt__(self, other): + return self.name < other.name + def candidate(self): """Return the candidate version of the package. diff --git a/apt/progress/base.py b/apt/progress/base.py index 97375431..4943978c 100644 --- a/apt/progress/base.py +++ b/apt/progress/base.py @@ -27,6 +27,7 @@ import fcntl import os import re import select +import sys import apt_pkg @@ -196,7 +197,8 @@ class InstallProgress(object): os._exit(os.spawnlp(os.P_WAIT, "dpkg", "dpkg", "--status-fd", str(self.write_stream.fileno()), "-i", obj)) - except Exception: + except Exception as e: + sys.stderr.write("%s\n" % e) os._exit(apt_pkg.PackageManager.RESULT_FAILED) self.child_pid = pid |
