summaryrefslogtreecommitdiffstats
path: root/doc
diff options
context:
space:
mode:
Diffstat (limited to 'doc')
-rw-r--r--doc/Makefile79
-rw-r--r--doc/client-example.cc68
-rw-r--r--doc/examples/acquire.py80
-rw-r--r--doc/examples/action.py116
-rw-r--r--doc/examples/all_deps.py37
-rw-r--r--doc/examples/architecture.py12
-rwxr-xr-xdoc/examples/build-deps-old.py74
-rwxr-xr-xdoc/examples/build-deps.py58
-rw-r--r--doc/examples/cdrom.py24
-rwxr-xr-xdoc/examples/checkstate.py37
-rwxr-xr-xdoc/examples/config.py60
-rwxr-xr-xdoc/examples/configisc.py49
-rwxr-xr-xdoc/examples/deb_inspect.py61
-rw-r--r--doc/examples/depcache.py109
-rwxr-xr-xdoc/examples/dependant-pkgs.py38
-rw-r--r--doc/examples/desc.py25
-rw-r--r--doc/examples/indexfile.py22
-rw-r--r--doc/examples/inst.py47
-rw-r--r--doc/examples/metaindex.py16
-rwxr-xr-xdoc/examples/print_uris.py10
-rw-r--r--doc/examples/progress.py118
-rwxr-xr-xdoc/examples/recommends.py37
-rwxr-xr-xdoc/examples/records.py16
-rw-r--r--doc/examples/sources.py21
-rwxr-xr-xdoc/examples/tagfile.py8
-rwxr-xr-xdoc/examples/update.py14
-rwxr-xr-xdoc/examples/versiontest.py54
-rw-r--r--doc/source/c++/api.rst858
-rw-r--r--doc/source/c++/embedding.rst34
-rw-r--r--doc/source/c++/index.rst8
-rw-r--r--doc/source/conf.py245
-rw-r--r--doc/source/contents.rst19
-rw-r--r--doc/source/examples/apt-cdrom.py79
-rwxr-xr-xdoc/source/examples/cache-packages.py23
-rwxr-xr-xdoc/source/examples/cache-pkgfile.py30
-rwxr-xr-xdoc/source/examples/dpkg-contents.py68
-rwxr-xr-xdoc/source/examples/dpkg-extract.py27
-rwxr-xr-xdoc/source/examples/dpkg-info.py22
-rwxr-xr-xdoc/source/examples/missing-deps.py59
-rwxr-xr-xdoc/source/examples/update-print-uris.py24
-rw-r--r--doc/source/library/apt.cache.rst83
-rw-r--r--doc/source/library/apt.cdrom.rst7
-rw-r--r--doc/source/library/apt.debfile.rst39
-rw-r--r--doc/source/library/apt.package.rst122
-rw-r--r--doc/source/library/apt.progress.base.rst335
-rw-r--r--doc/source/library/apt.progress.text.rst21
-rw-r--r--doc/source/library/apt_inst.rst323
-rw-r--r--doc/source/library/apt_pkg.rst2904
-rw-r--r--doc/source/library/aptsources.distinfo.rst11
-rw-r--r--doc/source/library/aptsources.distro.rst11
-rw-r--r--doc/source/library/aptsources.sourceslist.rst11
-rw-r--r--doc/source/library/index.rst35
-rw-r--r--doc/source/templates/indexcontent.html50
-rw-r--r--doc/source/templates/layout.html4
-rw-r--r--doc/source/tutorials/apt-cdrom.rst156
-rw-r--r--doc/source/tutorials/apt-get.rst46
-rw-r--r--doc/source/tutorials/contributing.rst315
-rw-r--r--doc/source/tutorials/index.rst8
-rw-r--r--doc/source/whatsnew/0.7.100.rst211
-rw-r--r--doc/source/whatsnew/0.8.0.rst38
-rw-r--r--doc/source/whatsnew/0.9.4.rst17
-rw-r--r--doc/source/whatsnew/1.0.rst75
-rw-r--r--doc/source/whatsnew/1.1.rst28
-rw-r--r--doc/source/whatsnew/1.4.rst16
-rw-r--r--doc/source/whatsnew/1.6.rst26
-rw-r--r--doc/source/whatsnew/1.7.rst42
-rw-r--r--doc/source/whatsnew/1.8.rst8
-rw-r--r--doc/source/whatsnew/2.0.rst37
-rw-r--r--doc/source/whatsnew/2.1.rst7
-rw-r--r--doc/source/whatsnew/index.rst9
70 files changed, 7781 insertions, 0 deletions
diff --git a/doc/Makefile b/doc/Makefile
new file mode 100644
index 0000000..327bba9
--- /dev/null
+++ b/doc/Makefile
@@ -0,0 +1,79 @@
+# Makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line.
+SPHINXOPTS =
+SPHINXBUILD = sphinx-build
+PAPER =
+
+# Internal variables.
+PAPEROPT_a4 = -D latex_paper_size=a4
+PAPEROPT_letter = -D latex_paper_size=letter
+ALLSPHINXOPTS = -d build/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
+
+.PHONY: help clean html web pickle htmlhelp latex changes linkcheck
+
+help:
+ @echo "Please use \`make <target>' where <target> is one of"
+ @echo " html to make standalone HTML files"
+ @echo " pickle to make pickle files"
+ @echo " json to make JSON files"
+ @echo " htmlhelp to make HTML files and a HTML help project"
+ @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
+ @echo " changes to make an overview over all changed/added/deprecated items"
+ @echo " linkcheck to check all external links for integrity"
+
+clean:
+ -rm -rf build/*
+
+text:
+ mkdir -p build/text build/doctrees
+ $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) build/text
+
+html:
+ mkdir -p build/html build/doctrees
+ $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) build/html
+ @echo
+ @echo "Build finished. The HTML pages are in build/html."
+
+pickle:
+ mkdir -p build/pickle build/doctrees
+ $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) build/pickle
+ @echo
+ @echo "Build finished; now you can process the pickle files."
+
+web: pickle
+
+json:
+ mkdir -p build/json build/doctrees
+ $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) build/json
+ @echo
+ @echo "Build finished; now you can process the JSON files."
+
+htmlhelp:
+ mkdir -p build/htmlhelp build/doctrees
+ $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) build/htmlhelp
+ @echo
+ @echo "Build finished; now you can run HTML Help Workshop with the" \
+ ".hhp project file in build/htmlhelp."
+
+latex:
+ mkdir -p build/latex build/doctrees
+ $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) build/latex
+ @echo
+ @echo "Build finished; the LaTeX files are in build/latex."
+ @echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \
+ "run these through (pdf)latex."
+
+changes:
+ mkdir -p build/changes build/doctrees
+ $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) build/changes
+ @echo
+ @echo "The overview file is in build/changes."
+
+linkcheck:
+ mkdir -p build/linkcheck build/doctrees
+ $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) build/linkcheck
+ @echo
+ @echo "Link check complete; look for any errors in the above output " \
+ "or in build/linkcheck/output.txt."
diff --git a/doc/client-example.cc b/doc/client-example.cc
new file mode 100644
index 0000000..73fa3ee
--- /dev/null
+++ b/doc/client-example.cc
@@ -0,0 +1,68 @@
+/*
+ * client-example.cc - A simple example for using the python-apt C++ API.
+ *
+ * Copyright 2009 Julian Andres Klode <jak@debian.org>
+ *
+ * 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.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include <python-apt/python-apt.h>
+#include <apt-pkg/hashes.h>
+
+// The module initialization.
+extern "C" void initclient() {
+ if (import_apt_pkg() < 0)
+ return;
+ // Initialize a module.
+ PyObject *Module = Py_InitModule("client", NULL);
+
+ // Create a HashString, which will be added to the module.
+ HashString *hash = new HashString("0966a120bb936bdc6fdeac445707aa6b");
+ // Create a Python object for the hashstring and add it to the module
+ PyModule_AddObject(Module, "hash", PyHashString_FromCpp(hash, false, NULL));
+
+ // Another example: Add the HashString type to the module.
+ Py_INCREF(&PyHashString_Type);
+ PyModule_AddObject(Module, "HashString", (PyObject*)(&PyHashString_Type));
+}
+
+int main(int argc, char *argv[]) {
+ // Return value.
+ int ret = 0;
+ // Initialize python
+ Py_Initialize();
+ // Make the client module importable
+ PyImport_AppendInittab("client", &initclient);
+ // Set the commandline arguments.
+ PySys_SetArgv(argc, argv);
+
+ // Import the module, so the user does not have to import it.
+ if (PyRun_SimpleString("import client\n") < 0) {
+ // Failure (should never be reached)
+ ret = 1;
+ goto end;
+ }
+
+ // Run IPython if available, otherwise a normal interpreter.
+ if (PyRun_SimpleString("from IPython.Shell import start\n") == 0)
+ PyRun_SimpleString("start(user_ns=dict(client=client)).mainloop()\n");
+ else
+ Py_Main(argc, argv);
+
+end:
+ Py_Finalize();
+ return ret;
+}
diff --git a/doc/examples/acquire.py b/doc/examples/acquire.py
new file mode 100644
index 0000000..3d1e31b
--- /dev/null
+++ b/doc/examples/acquire.py
@@ -0,0 +1,80 @@
+#!/usr/bin/python3
+import os
+
+import apt_pkg
+
+import apt
+import apt.progress.text
+
+
+def get_file(fetcher, uri, destfile):
+ # get the file
+ af = apt_pkg.AcquireFile(fetcher, uri=uri, descr="sample descr", destfile=destfile)
+ print(f"desc_uri: {af.desc_uri} -> {af.destfile}")
+ res = fetcher.run()
+ if res != fetcher.RESULT_CONTINUE:
+ return False
+ return True
+
+
+apt_pkg.init()
+
+# apt_pkg.config.set("Debug::pkgDPkgPM","1");
+# apt_pkg.config.set("Debug::pkgPackageManager","1");
+# apt_pkg.config.set("Debug::pkgDPkgProgressReporting","1");
+
+cache = apt_pkg.Cache()
+depcache = apt_pkg.DepCache(cache)
+
+recs = apt_pkg.PackageRecords(cache)
+list = apt_pkg.SourceList()
+list.read_main_list()
+
+# show the amount fetch needed for a dist-upgrade
+depcache.upgrade(True)
+progress = apt.progress.text.AcquireProgress()
+fetcher = apt_pkg.Acquire(progress)
+pm = apt_pkg.PackageManager(depcache)
+pm.get_archives(fetcher, list, recs)
+print(f"{apt_pkg.size_to_str(fetcher.fetch_needed)} ({fetcher.fetch_needed})")
+actiongroup = apt_pkg.ActionGroup(depcache)
+for pkg in cache.packages:
+ depcache.mark_keep(pkg)
+
+try:
+ os.mkdir("/tmp/pyapt-test")
+ os.mkdir("/tmp/pyapt-test/partial")
+except OSError:
+ pass
+apt_pkg.config.set("Dir::Cache::archives", "/tmp/pyapt-test")
+
+pkg = cache["2vcard"]
+depcache.mark_install(pkg)
+
+progress = apt.progress.text.AcquireProgress()
+fetcher = apt_pkg.Acquire(progress)
+# fetcher = apt_pkg.Acquire()
+pm = apt_pkg.PackageManager(depcache)
+
+print(pm)
+print(fetcher)
+
+get_file(fetcher, "ftp://ftp.debian.org/debian/dists/README", "/tmp/lala")
+
+pm.get_archives(fetcher, list, recs)
+
+for item in fetcher.items:
+ print(item)
+ if item.status == item.STAT_ERROR:
+ print("Some error ocured: '%s'" % item.error_text)
+ if not item.complete:
+ print("No error, still nothing downloaded (%s)" % item.error_text)
+ print()
+
+
+res = fetcher.run()
+print("fetcher.Run() returned: %s" % res)
+
+print("now runing pm.DoInstall()")
+res = pm.do_install(1)
+print("pm.DoInstall() returned: %s" % res)
diff --git a/doc/examples/action.py b/doc/examples/action.py
new file mode 100644
index 0000000..59e050b
--- /dev/null
+++ b/doc/examples/action.py
@@ -0,0 +1,116 @@
+#!/usr/bin/python3
+#
+# LOW LEVEL example how to deal with the depcache
+#
+# you probably do not want to use this low level code and use
+# the high level "apt" interface instead that can do all this
+# but with a nicer API
+
+import apt_pkg
+from progress import TextFetchProgress
+
+from apt.progress.text import OpProgress
+
+# init
+apt_pkg.init()
+
+progress = OpProgress()
+cache = apt_pkg.Cache(progress)
+print("Available packages: %s " % cache.package_count)
+
+print("Fetching")
+progress = TextFetchProgress()
+source = apt_pkg.SourceList()
+cache.update(progress, source)
+
+iter = cache["base-config"]
+print("example package iter: %s" % iter)
+
+# get depcache
+print("\n\n depcache")
+depcache = apt_pkg.DepCache(cache)
+depcache.read_pinfile()
+print("got a depcache: %s " % depcache)
+print("Marked for install: %s " % depcache.inst_count)
+
+print("\n\n Reinit")
+depcache.init(progress)
+
+# sys.exit()
+
+# get a canidate version
+ver = depcache.get_candidate_ver(iter)
+print("Candidate version: %s " % ver)
+
+print("\n\nQuerry interface")
+print(f"{iter.name}.is_upgradable(): {depcache.is_upgradable(iter)}")
+
+print("\nMarking interface")
+print("Marking '%s' for install" % iter.name)
+depcache.mark_install(iter)
+print("Install count: %s " % depcache.inst_count)
+print(f"{iter.name}.marked_install(): {depcache.marked_install(iter)}")
+print(f"{iter.name}.marked_upgrade(): {depcache.marked_upgrade(iter)}")
+print(f"{iter.name}.marked_delete(): {depcache.marked_delete(iter)}")
+
+print("Marking %s for delete" % iter.name)
+depcache.mark_delete(iter)
+print("del_count: %s " % depcache.del_count)
+print(f"{iter.name}.marked_delete(): {depcache.marked_delete(iter)}")
+
+iter = cache["apt"]
+print("\nMarking '%s' for install" % iter.name)
+depcache.mark_install(iter)
+print("Install count: %s " % depcache.inst_count)
+print(f"{iter.name}.marked_install(): {depcache.marked_install(iter)}")
+print(f"{iter.name}.marked_upgrade(): {depcache.marked_upgrade(iter)}")
+print(f"{iter.name}.marked_delete(): {depcache.marked_delete(iter)}")
+
+print("Marking %s for keep" % iter.name)
+depcache.mark_keep(iter)
+print("Install: %s " % depcache.inst_count)
+
+iter = cache["python-apt"]
+print("\nMarking '%s' for install" % iter.name)
+depcache.mark_install(iter)
+print("Install: %s " % depcache.inst_count)
+print("Broken count: %s" % depcache.broken_count)
+print("fix_broken() ")
+depcache.fix_broken()
+print("Broken count: %s" % depcache.broken_count)
+
+print("\nPerforming upgrade")
+depcache.upgrade()
+print("Keep: %s " % depcache.keep_count)
+print("Install: %s " % depcache.inst_count)
+print("Delete: %s " % depcache.del_count)
+print("usr_size: %s " % apt_pkg.size_to_str(depcache.usr_size))
+print("deb_size: %s " % apt_pkg.size_to_str(depcache.deb_size))
+
+for pkg in cache.packages:
+ if (
+ pkg.current_ver is not None
+ and not depcache.marked_install(pkg)
+ and depcache.is_upgradable(pkg)
+ ):
+ print("upgrade didn't upgrade (kept): %s" % pkg.name)
+
+print("\nPerforming Distupgrade")
+depcache.upgrade(True)
+print("Keep: %s " % depcache.keep_count)
+print("Install: %s " % depcache.inst_count)
+print("Delete: %s " % depcache.del_count)
+print("usr_size: %s " % apt_pkg.size_to_str(depcache.usr_size))
+print("deb_size: %s " % apt_pkg.size_to_str(depcache.deb_size))
+
+# overview about what would happen
+for pkg in cache.packages:
+ if depcache.marked_install(pkg):
+ if pkg.current_ver is not None:
+ print("Marked upgrade: %s " % pkg.name)
+ else:
+ print("Marked install: %s" % pkg.name)
+ elif depcache.marked_delete(pkg):
+ print("Marked delete: %s" % pkg.name)
+ elif depcache.marked_keep(pkg):
+ print("Marked keep: %s" % pkg.name)
diff --git a/doc/examples/all_deps.py b/doc/examples/all_deps.py
new file mode 100644
index 0000000..df8610a
--- /dev/null
+++ b/doc/examples/all_deps.py
@@ -0,0 +1,37 @@
+#!/usr/bin/python3
+import sys
+
+import apt
+
+
+def dependencies(cache, pkg, deps, key="Depends"):
+ # print "pkg: %s (%s)" % (pkg.name, deps)
+ candver = cache._depcache.get_candidate_ver(pkg._pkg)
+ if candver is None:
+ return deps
+ dependslist = candver.depends_list
+ if key in dependslist:
+ for depVerList in dependslist[key]:
+ for dep in depVerList:
+ if dep.target_pkg.name in cache:
+ if (
+ pkg.name != dep.target_pkg.name
+ and dep.target_pkg.name not in deps
+ ):
+ deps.add(dep.target_pkg.name)
+ dependencies(cache, cache[dep.target_pkg.name], deps, key)
+ return deps
+
+
+pkgname = sys.argv[1]
+c = apt.Cache()
+pkg = c[pkgname]
+
+deps = set()
+
+deps = dependencies(c, pkg, deps, "Depends")
+print(" ".join(deps))
+
+preDeps = set()
+preDeps = dependencies(c, pkg, preDeps, "PreDepends")
+print(" ".join(preDeps))
diff --git a/doc/examples/architecture.py b/doc/examples/architecture.py
new file mode 100644
index 0000000..3972234
--- /dev/null
+++ b/doc/examples/architecture.py
@@ -0,0 +1,12 @@
+import apt_pkg
+
+
+def main():
+ apt_pkg.init_config()
+
+ print("Native architecture:", apt_pkg.config["APT::Architecture"])
+ print("All architectures:", apt_pkg.config.value_list("APT::Architectures"))
+
+
+if __name__ == "__main__":
+ main()
diff --git a/doc/examples/build-deps-old.py b/doc/examples/build-deps-old.py
new file mode 100755
index 0000000..71a081e
--- /dev/null
+++ b/doc/examples/build-deps-old.py
@@ -0,0 +1,74 @@
+#!/usr/bin/python3
+# this is a example how to access the build dependencies of a package
+
+import sys
+
+import apt_pkg
+
+
+def get_source_pkg(pkg, records, depcache):
+ """get the source package name of a given package"""
+ version = depcache.get_candidate_ver(pkg)
+ if not version:
+ return None
+ file, index = version.file_list.pop(0)
+ records.lookup((file, index))
+ if records.source_pkg != "":
+ srcpkg = records.source_pkg
+ else:
+ srcpkg = pkg.name
+ return srcpkg
+
+
+# main
+apt_pkg.init()
+cache = apt_pkg.Cache()
+depcache = apt_pkg.DepCache(cache)
+depcache.init()
+records = apt_pkg.PackageRecords(cache)
+srcrecords = apt_pkg.SourceRecords()
+
+# base package that we use for build-depends calculation
+if len(sys.argv) < 2:
+ print("need a package name as argument")
+ sys.exit(1)
+try:
+ pkg = base = cache[sys.argv[1]]
+except KeyError:
+ print("No package %s found" % sys.argv[1])
+ sys.exit(1)
+all_build_depends = set()
+
+# get the build depdends for the package itself
+srcpkg_name = get_source_pkg(base, records, depcache)
+print("srcpkg_name: %s " % srcpkg_name)
+if not srcpkg_name:
+ print("Can't find source package for '%s'" % pkg.mame)
+srcrec = srcrecords.lookup(srcpkg_name)
+if srcrec:
+ print("Files:")
+ print(srcrecords.files)
+ bd = srcrecords.build_depends
+ print("build-depends of the package: %s " % bd)
+ for b in bd:
+ all_build_depends.add(b[0])
+
+# calculate the build depends for all dependencies
+depends = depcache.get_candidate_ver(base).depends_list
+for dep in depends["Depends"]: # FIXME: do we need to consider PreDepends?
+ pkg = dep[0].target_pkg
+ srcpkg_name = get_source_pkg(pkg, records, depcache)
+ if not srcpkg_name:
+ print("Can't find source package for '%s'" % pkg.name)
+ continue
+ srcrec = srcrecords.lookup(srcpkg_name)
+ if srcrec:
+ # print srcrecords.package
+ # print srcrecords.binaries
+ bd = srcrecords.build_depends
+ # print "%s: %s " % (srcpkg_name, bd)
+ for b in bd:
+ all_build_depends.add(b[0])
+
+
+print("\n".join(all_build_depends))
diff --git a/doc/examples/build-deps.py b/doc/examples/build-deps.py
new file mode 100755
index 0000000..714d1c4
--- /dev/null
+++ b/doc/examples/build-deps.py
@@ -0,0 +1,58 @@
+#!/usr/bin/python3
+# this is a example how to access the build dependencies of a package
+
+import sys
+
+import apt_pkg
+
+import apt
+
+# main
+cache = apt.Cache()
+srcrecords = apt_pkg.SourceRecords()
+
+# base package that we use for build-depends calculation
+if len(sys.argv) < 2:
+ print("need a package name as argument")
+ sys.exit(1)
+try:
+ pkg = base = cache[sys.argv[1]]
+except KeyError:
+ print("No package %s found" % sys.argv[1])
+ sys.exit(1)
+all_build_depends = set()
+
+# get the build depdends for the package itself
+srcpkg_name = base.candidate.source_name
+print("srcpkg_name: %s " % srcpkg_name)
+if not srcpkg_name:
+ print("Can't find source package for '%s'" % pkg.name)
+srcrec = srcrecords.lookup(srcpkg_name)
+if srcrec:
+ print("Files:")
+ print(srcrecords.files)
+ bd = srcrecords.build_depends
+ print("build-depends of the package: %s " % bd)
+ for b in bd:
+ all_build_depends.add(b[0])
+
+# calculate the build depends for all dependencies
+depends = base.candidate.dependencies
+for or_dep in depends:
+ for dep in or_dep.or_dependencies:
+ pkg = cache[dep.name]
+ srcpkg_name = pkg.candidate.source_name
+ if not srcpkg_name:
+ print("Can't find source package for '%s'" % pkg.name)
+ continue
+ srcrec = srcrecords.lookup(srcpkg_name)
+ if srcrec:
+ # print srcrecords.package
+ # print srcrecords.binaries
+ bd = srcrecords.build_depends
+ # print "%s: %s " % (srcpkg_name, bd)
+ for b in bd:
+ all_build_depends.add(b[0])
+
+
+print("\n".join(all_build_depends))
diff --git a/doc/examples/cdrom.py b/doc/examples/cdrom.py
new file mode 100644
index 0000000..ad4d2ba
--- /dev/null
+++ b/doc/examples/cdrom.py
@@ -0,0 +1,24 @@
+#!/usr/bin/python3
+# example how to deal with the depcache
+
+import sys
+
+import apt_pkg
+from progress import TextCdromProgress
+
+# init
+apt_pkg.init()
+
+cdrom = apt_pkg.Cdrom()
+print(cdrom)
+
+progress = TextCdromProgress()
+
+(res, ident) = cdrom.ident(progress)
+print(f"ident result is: {res} ({ident}) ")
+
+apt_pkg.config["APT::CDROM::Rename"] = "True"
+cdrom.add(progress)
+
+print("Exiting")
+sys.exit(0)
diff --git a/doc/examples/checkstate.py b/doc/examples/checkstate.py
new file mode 100755
index 0000000..d4276e8
--- /dev/null
+++ b/doc/examples/checkstate.py
@@ -0,0 +1,37 @@
+#!/usr/bin/python3
+#
+#
+# this example is not usefull to find out about updated, upgradable packages
+# use the depcache.py example for it (because a pkgPolicy is not used here)
+#
+
+import apt_pkg
+
+apt_pkg.init()
+
+cache = apt_pkg.Cache()
+packages = cache.packages
+
+uninstalled, updated, upgradable = {}, {}, {}
+
+for package in packages:
+ versions = package.version_list
+ if not versions:
+ continue
+ version = versions[0]
+ for other_version in versions:
+ if apt_pkg.version_compare(version.ver_str, other_version.ver_str) < 0:
+ version = other_version
+ if package.current_ver:
+ current = package.current_ver
+ if apt_pkg.version_compare(current.ver_str, version.ver_str) < 0:
+ upgradable[package.name] = version
+ break
+ else:
+ updated[package.name] = current
+ else:
+ uninstalled[package.name] = version
+
+
+for line in (uninstalled, updated, upgradable):
+ print(list(line.items())[0])
diff --git a/doc/examples/config.py b/doc/examples/config.py
new file mode 100755
index 0000000..fb687e3
--- /dev/null
+++ b/doc/examples/config.py
@@ -0,0 +1,60 @@
+#!/usr/bin/python3
+# Example demonstrating how to use the configuration/commandline system
+# for configuration.
+# Some valid command lines..
+# config.py -h --help ; Turn on help
+# config.py -no-h --no-help --help=no ; Turn off help
+# config.py -qqq -q=3 ; verbosity to 3
+# config.py -c /etc/apt/apt.conf ; include that config file]
+# config.py -o help=true ; Turn on help by giving a
+# ; config file string
+# config.py -no-h -- -help ; Turn off help, specify the file '-help'
+# -c and -o are standard APT-program options.
+
+import posixpath
+import sys
+
+# This shows how to use the system for configuration and option control.
+# The other varient is for ISC object config files. See configisc.py.
+import apt_pkg
+
+# Create a new empty Configuration object - there is also the system global
+# configuration object apt_pkg.config which is used interally by apt-pkg
+# routines to control unusual situations. I recommend using the sytem global
+# whenever possible..
+Cnf = apt_pkg.Configuration()
+
+print("Command line is", sys.argv)
+
+# Load the default configuration file, init_config() does this better..
+Cnf.set("config-file", "/etc/apt/apt.conf") # or Cnf["config-file"] = ".."
+if posixpath.exists(Cnf.find_file("config-file")):
+ apt_pkg.read_config_file(Cnf, "/etc/apt/apt.conf")
+
+# Merge the command line arguments into the configuration space
+Arguments = [
+ ("h", "help", "help"),
+ ("v", "version", "version"),
+ ("q", "quiet", "quiet", "IntLevel"),
+ ("c", "config-file", "", "ConfigFile"),
+ ("o", "option", "", "ArbItem"),
+]
+print("FileNames", apt_pkg.parse_commandline(Cnf, Arguments, sys.argv))
+
+print("Quiet level selected is", Cnf.find_i("quiet", 0))
+
+# Do some stuff with it
+if Cnf.find_b("version", 0) == 1:
+ print("Version selected - 1.1")
+
+if Cnf.find_b("help", 0) == 1:
+ print("python-apt", apt_pkg.VERSION, "compiled on", apt_pkg.DATE, apt_pkg.TIME)
+ print("Hi, I am the help text for this program")
+ sys.exit(0)
+
+print("No help for you, try -h")
+
+# Print the configuration space
+print("The Configuration space looks like:")
+for item in list(Cnf.keys()):
+ print(f'{item} "{Cnf[item]}";')
diff --git a/doc/examples/configisc.py b/doc/examples/configisc.py
new file mode 100755
index 0000000..10700dc
--- /dev/null
+++ b/doc/examples/configisc.py
@@ -0,0 +1,49 @@
+#!/usr/bin/python3
+# Example demonstrating how to use the configuration/commandline system
+# for object setup.
+
+# This parses the given config file in 'ISC' style where the sections
+# represent object instances and shows how to iterate over the sections.
+# Pass it the sample apt-ftparchive configuration,
+# doc/examples/ftp-archive.conf
+# or a bind8 config file..
+
+import sys
+
+import apt_pkg
+
+ConfigFile = apt_pkg.parse_commandline(apt_pkg.config, [], sys.argv)
+
+if len(ConfigFile) != 1:
+ print("Must have exactly 1 file name")
+ sys.exit(0)
+
+Cnf = apt_pkg.Configuration()
+apt_pkg.read_config_file_isc(Cnf, ConfigFile[0])
+
+# Print the configuration space
+# print "The Configuration space looks like:"
+# for item in Cnf.keys():
+# print "%s \"%s\";" % (item, Cnf[item])
+
+# bind8 config file..
+if "Zone" in Cnf:
+ print("Zones: ", Cnf.sub_tree("zone").list())
+ for item in Cnf.list("zone"):
+ SubCnf = Cnf.sub_tree(item)
+ if SubCnf.find("type") == "slave":
+ print(
+ "Masters for {}: {}".format(
+ SubCnf.my_tag(), SubCnf.value_list("masters")
+ )
+ )
+else:
+ print("Tree definitions:")
+ for item in Cnf.list("tree"):
+ SubCnf = Cnf.sub_tree(item)
+ # This could use Find which would eliminate the possibility of
+ # exceptions.
+ print(
+ "Subtree %s with sections '%s' and architectures '%s'"
+ % (SubCnf.my_tag(), SubCnf["Sections"], SubCnf["Architectures"])
+ )
diff --git a/doc/examples/deb_inspect.py b/doc/examples/deb_inspect.py
new file mode 100755
index 0000000..72050e3
--- /dev/null
+++ b/doc/examples/deb_inspect.py
@@ -0,0 +1,61 @@
+#!/usr/bin/python3
+# some example for apt_inst
+
+import os.path
+import sys
+
+import apt_inst
+import apt_pkg
+
+
+def Callback(member, data):
+ """callback for debExtract"""
+ print(
+ "'%s','%s',%u,%u,%u,%u,%u,%u,%u"
+ % (
+ member.name,
+ member.linkname,
+ member.mode,
+ member.uid,
+ member.gid,
+ member.size,
+ member.mtime,
+ member.major,
+ member.minor,
+ )
+ )
+
+
+if __name__ == "__main__":
+ if len(sys.argv) < 2:
+ print("need filename argumnet")
+ sys.exit(1)
+ file = sys.argv[1]
+
+ print("Working on: %s" % file)
+ print("Displaying data.tar.gz:")
+ apt_inst.DebFile(open(file)).data.go(Callback)
+
+ print("Now extracting the control file:")
+ control = apt_inst.DebFile(open(file)).control.extractdata("control")
+ sections = apt_pkg.TagSection(control)
+
+ print("Maintainer is: ")
+ print(sections["Maintainer"])
+
+ print()
+ print("DependsOn: ")
+ depends = sections["Depends"]
+ print(apt_pkg.parse_depends(depends))
+
+ print("extracting archive")
+ dir = "/tmp/deb"
+ os.mkdir(dir)
+ apt_inst.DebFile(open(file)).data.extractall(dir)
+
+ def visit(arg, dirname, names):
+ print("%s/" % dirname)
+ for file in names:
+ print("\t%s" % file)
+
+ os.path.walk(dir, visit, None)
diff --git a/doc/examples/depcache.py b/doc/examples/depcache.py
new file mode 100644
index 0000000..f6dff52
--- /dev/null
+++ b/doc/examples/depcache.py
@@ -0,0 +1,109 @@
+#!/usr/bin/python3
+# example how to deal with the depcache
+
+import apt_pkg
+from progress import TextProgress
+
+# init
+apt_pkg.init()
+
+progress = TextProgress()
+cache = apt_pkg.Cache(progress)
+print("Available packages: %s " % cache.package_count)
+
+iter = cache["base-config"]
+print("example package iter: %s" % iter)
+
+# get depcache
+print("\n\n depcache")
+depcache = apt_pkg.DepCache(cache)
+depcache.read_pinfile()
+# init is needed after the creation/pin file reading
+depcache.init(progress)
+print("got a depcache: %s " % depcache)
+print("Marked for install: %s " % depcache.inst_count)
+
+print("\n\n Reinit")
+depcache.init(progress)
+
+# sys.exit()
+
+
+# get a canidate version
+ver = depcache.get_candidate_ver(iter)
+print("Candidate version: %s " % ver)
+
+print("\n\nQuerry interface")
+print(f"{iter.name}.is_upgradable(): {depcache.is_upgradable(iter)}")
+
+print("\nMarking interface")
+print("Marking '%s' for install" % iter.name)
+depcache.mark_install(iter)
+print("Install count: %s " % depcache.inst_count)
+print(f"{iter.name}.marked_install(): {depcache.marked_install(iter)}")
+print(f"{iter.name}.marked_upgrade(): {depcache.marked_upgrade(iter)}")
+print(f"{iter.name}.marked_delete(): {depcache.marked_delete(iter)}")
+
+print("Marking %s for delete" % iter.name)
+depcache.mark_delete(iter)
+print("del_count: %s " % depcache.del_count)
+print(f"{iter.name}.marked_delete(): {depcache.marked_delete(iter)}")
+
+
+iter = cache["3dchess"]
+print("\nMarking '%s' for install" % iter.name)
+depcache.mark_install(iter)
+print("Install count: %s " % depcache.inst_count)
+print(f"{iter.name}.marked_install(): {depcache.marked_install(iter)}")
+print(f"{iter.name}.marked_upgrade(): {depcache.marked_upgrade(iter)}")
+print(f"{iter.name}.marked_delete(): {depcache.marked_delete(iter)}")
+
+print("Marking %s for keep" % iter.name)
+depcache.mark_keep(iter)
+print("Install: %s " % depcache.inst_count)
+
+iter = cache["synaptic"]
+print("\nMarking '%s' for install" % iter.name)
+depcache.mark_install(iter)
+print("Install: %s " % depcache.inst_count)
+print("Broken count: %s" % depcache.broken_count)
+print("fix_broken() ")
+depcache.fix_broken()
+print("Broken count: %s" % depcache.broken_count)
+
+print("\nPerforming upgrade")
+depcache.upgrade()
+print("Keep: %s " % depcache.keep_count)
+print("Install: %s " % depcache.inst_count)
+print("Delete: %s " % depcache.del_count)
+print("usr_size: %s " % apt_pkg.size_to_str(depcache.usr_size))
+print("deb_size: %s " % apt_pkg.size_to_str(depcache.deb_size))
+
+for pkg in cache.packages:
+ if (
+ pkg.current_ver is not None
+ and not depcache.marked_install(pkg)
+ and depcache.is_upgradable(pkg)
+ ):
+ print("upgrade didn't upgrade (kept): %s" % pkg.name)
+
+
+print("\nPerforming DistUpgrade")
+depcache.upgrade(True)
+print("Keep: %s " % depcache.keep_count)
+print("Install: %s " % depcache.inst_count)
+print("Delete: %s " % depcache.del_count)
+print("usr_size: %s " % apt_pkg.size_to_str(depcache.usr_size))
+print("deb_size: %s " % apt_pkg.size_to_str(depcache.deb_size))
+
+# overview about what would happen
+for pkg in cache.packages:
+ if depcache.marked_install(pkg):
+ if pkg.current_ver is not None:
+ print("Marked upgrade: %s " % pkg.name)
+ else:
+ print("Marked install: %s" % pkg.name)
+ elif depcache.marked_delete(pkg):
+ print("Marked delete: %s" % pkg.name)
+ elif depcache.marked_keep(pkg):
+ print("Marked keep: %s" % pkg.name)
diff --git a/doc/examples/dependant-pkgs.py b/doc/examples/dependant-pkgs.py
new file mode 100755
index 0000000..e5985b8
--- /dev/null
+++ b/doc/examples/dependant-pkgs.py
@@ -0,0 +1,38 @@
+#!/usr/bin/python3
+
+import sys
+
+import apt
+
+pkgs = set()
+cache = apt.Cache()
+for pkg in cache:
+ candver = cache._depcache.get_candidate_ver(pkg._pkg)
+ if candver is None:
+ continue
+ dependslist = candver.depends_list
+ for dep in list(dependslist.keys()):
+ # get the list of each dependency object
+ for depVerList in dependslist[dep]:
+ for z in depVerList:
+ # get all TargetVersions of
+ # the dependency object
+ for tpkg in z.all_targets():
+ if sys.argv[1] == tpkg.parent_pkg.name:
+ pkgs.add(pkg.name)
+
+main = set()
+universe = set()
+for pkg in pkgs:
+ cand = cache[pkg].candidate
+ if "universe" in cand.section:
+ universe.add(cand.source_name)
+ else:
+ main.add(cand.source_name)
+
+print("main:")
+print("\n".join(sorted(main)))
+print()
+
+print("universe:")
+print("\n".join(sorted(universe)))
diff --git a/doc/examples/desc.py b/doc/examples/desc.py
new file mode 100644
index 0000000..7e8e3e8
--- /dev/null
+++ b/doc/examples/desc.py
@@ -0,0 +1,25 @@
+#!/usr/bin/python3
+
+import apt_pkg
+
+apt_pkg.init()
+
+apt_pkg.config.set("APT::Acquire::Translation", "de")
+
+cache = apt_pkg.Cache()
+depcache = apt_pkg.DepCache(cache)
+
+pkg = cache["gcc"]
+cand = depcache.get_candidate_ver(pkg)
+print(cand)
+
+desc = cand.TranslatedDescription
+print(desc)
+print(desc.file_list)
+(f, index) = desc.file_list.pop(0)
+
+records = apt_pkg.PackageRecords(cache)
+records.lookup((f, index))
+desc = records.long_desc
+print(len(desc))
+print(desc)
diff --git a/doc/examples/indexfile.py b/doc/examples/indexfile.py
new file mode 100644
index 0000000..34ea94e
--- /dev/null
+++ b/doc/examples/indexfile.py
@@ -0,0 +1,22 @@
+#!/usr/bin/python3
+
+import apt_pkg
+
+apt_pkg.init()
+
+sources = apt_pkg.SourceList()
+sources.read_main_list()
+
+cache = apt_pkg.Cache()
+depcache = apt_pkg.DepCache(cache)
+pkg = cache["libimlib2"]
+cand = depcache.get_candidate_ver(pkg)
+for f, i in cand.file_list:
+ index = sources.find_index(f)
+ print(index)
+ if index:
+ print(index.size)
+ print(index.is_trusted)
+ print(index.exists)
+ print(index.has_packages)
+ print(index.archive_uri("some/path"))
diff --git a/doc/examples/inst.py b/doc/examples/inst.py
new file mode 100644
index 0000000..892b43b
--- /dev/null
+++ b/doc/examples/inst.py
@@ -0,0 +1,47 @@
+#!/usr/bin/python3
+# example how to deal with the depcache
+
+import sys
+
+import apt
+from apt.progress import InstallProgress
+
+
+class TextInstallProgress(InstallProgress):
+ def __init__(self):
+ apt.progress.InstallProgress.__init__(self)
+ self.last = 0.0
+
+ def updateInterface(self):
+ InstallProgress.updateInterface(self)
+ if self.last >= self.percent:
+ return
+ sys.stdout.write(f"\r[{self.percent}] {self.status}\n")
+ sys.stdout.flush()
+ self.last = self.percent
+
+ def conffile(self, current, new):
+ print(f"conffile prompt: {current} {new}")
+
+ def error(self, errorstr):
+ print("got dpkg error: '%s'" % errorstr)
+
+
+cache = apt.Cache(apt.progress.OpTextProgress())
+
+fprogress = apt.progress.TextFetchProgress()
+iprogress = TextInstallProgress()
+
+pkg = cache["3dchess"]
+
+# install or remove, the importend thing is to keep us busy :)
+if pkg.is_installed:
+ print("Going to delete %s" % pkg.name)
+ pkg.mark_delete()
+else:
+ print("Going to install %s" % pkg.name)
+ pkg.mark_install()
+res = cache.commit(fprogress, iprogress)
+print(res)
+
+sys.exit(0)
diff --git a/doc/examples/metaindex.py b/doc/examples/metaindex.py
new file mode 100644
index 0000000..2497e65
--- /dev/null
+++ b/doc/examples/metaindex.py
@@ -0,0 +1,16 @@
+#!/usr/bin/python3
+
+import apt_pkg
+
+apt_pkg.init()
+
+sources = apt_pkg.SourceList()
+sources.read_main_list()
+
+
+for metaindex in sources.list:
+ print(metaindex)
+ print("uri: ", metaindex.uri)
+ print("dist: ", metaindex.dist)
+ print("index_files: ", "\n".join([str(i) for i in metaindex.index_files]))
+ print()
diff --git a/doc/examples/print_uris.py b/doc/examples/print_uris.py
new file mode 100755
index 0000000..1b59e00
--- /dev/null
+++ b/doc/examples/print_uris.py
@@ -0,0 +1,10 @@
+#!/usr/bin/python3
+#
+# a example that prints the URIs of all upgradable packages
+#
+
+import apt
+
+for pkg in apt.Cache():
+ if pkg.is_upgradable:
+ print(pkg.candidate.uri)
diff --git a/doc/examples/progress.py b/doc/examples/progress.py
new file mode 100644
index 0000000..680a64d
--- /dev/null
+++ b/doc/examples/progress.py
@@ -0,0 +1,118 @@
+#!/usr/bin/python3
+
+import sys
+import time
+
+import apt_pkg
+
+import apt
+import apt.progress.base
+
+
+class TextProgress(apt.progress.base.OpProgress):
+ def __init__(self):
+ self.last = 0.0
+
+ def update(self, percent):
+ if (self.last + 1.0) <= percent:
+ sys.stdout.write("\rProgress: %i.2 " % (percent))
+ self.last = percent
+ if percent >= 100:
+ self.last = 0.0
+
+ def done(self):
+ self.last = 0.0
+ print("\rDone ")
+
+
+class TextFetchProgress(apt.progress.base.AcquireProgress):
+ def __init__(self):
+ pass
+
+ def start(self):
+ pass
+
+ def stop(self):
+ pass
+
+ def fail(self, item):
+ print("fail", item)
+
+ def fetch(self, item):
+ print("fetch", item)
+
+ def ims_hit(self, item):
+ print("ims_hit", item)
+
+ def pulse(self, owner):
+ print(
+ "pulse: CPS: %s/s; Bytes: %s/%s; Item: %s/%s"
+ % (
+ apt_pkg.size_to_str(self.current_cps),
+ apt_pkg.size_to_str(self.current_bytes),
+ apt_pkg.size_to_str(self.total_bytes),
+ self.current_items,
+ self.total_items,
+ )
+ )
+ return True
+
+ def media_change(self, medium, drive):
+ print(f"Please insert medium {medium} in drive {drive}")
+ sys.stdin.readline()
+ # return False
+
+
+class TextInstallProgress(apt.progress.base.InstallProgress):
+ def __init__(self):
+ apt.progress.base.InstallProgress.__init__(self)
+
+ def start_update(self):
+ print("start_update")
+
+ def finish_update(self):
+ print("finish_update")
+
+ def status_change(self, pkg, percent, status):
+ print(f"[{percent}] {pkg}: {status}")
+
+ def update_interface(self):
+ apt.progress.base.InstallProgress.update_interface(self)
+ # usefull to e.g. redraw a GUI
+ time.sleep(0.1)
+
+
+class TextCdromProgress(apt.progress.base.CdromProgress):
+ def __init__(self):
+ pass
+
+ # update is called regularly so that the gui can be redrawn
+
+ def update(self, text, step):
+ # check if we actually have some text to display
+ if text != "":
+ print(f"Update: {text.strip()} {step}")
+
+ def ask_cdrom_name(self):
+ sys.stdout.write("Please enter cd-name: ")
+ cd_name = sys.stdin.readline()
+ return (True, cd_name.strip())
+
+ def change_cdrom(self):
+ print("Please insert cdrom and press <ENTER>")
+ answer = sys.stdin.readline()
+ print(answer)
+ return True
+
+
+if __name__ == "__main__":
+ c = apt.Cache()
+ pkg = c["3dchess"]
+ if pkg.is_installed:
+ pkg.mark_delete()
+ else:
+ pkg.mark_install()
+
+ res = c.commit(TextFetchProgress(), TextInstallProgress())
+
+ print(res)
diff --git a/doc/examples/recommends.py b/doc/examples/recommends.py
new file mode 100755
index 0000000..8539cd5
--- /dev/null
+++ b/doc/examples/recommends.py
@@ -0,0 +1,37 @@
+#!/usr/bin/python3
+
+import apt_pkg
+
+apt_pkg.init()
+
+cache = apt_pkg.Cache()
+
+
+class Wanted:
+ def __init__(self, name):
+ self.name = name
+ self.recommended = []
+ self.suggested = []
+
+
+wanted = {}
+
+for package in cache.packages:
+ current = package.current_ver
+ if not current:
+ continue
+ depends = current.depends_list
+ for key, attr in (("Suggests", "suggested"), ("Recommends", "recommended")):
+ list = depends.get(key, [])
+ for dependency in list:
+ name = dependency[0].target_pkg.name
+ dep = cache[name]
+ if dep.current_ver:
+ continue
+ getattr(wanted.setdefault(name, Wanted(name)), attr).append(package.name)
+
+ks = list(wanted.keys())
+ks.sort()
+
+for want in ks:
+ print(want, wanted[want].recommended, wanted[want].suggested)
diff --git a/doc/examples/records.py b/doc/examples/records.py
new file mode 100755
index 0000000..b88ed75
--- /dev/null
+++ b/doc/examples/records.py
@@ -0,0 +1,16 @@
+#!/usr/bin/python3
+
+import apt
+
+cache = apt.Cache()
+
+for pkg in cache:
+ if not pkg.candidate.record:
+ continue
+ if "Task" in pkg.candidate.record:
+ print(
+ "Pkg {} is part of '{}'".format(
+ pkg.name, pkg.candidate.record["Task"].split()
+ )
+ )
+ # print pkg.candidateRecord
diff --git a/doc/examples/sources.py b/doc/examples/sources.py
new file mode 100644
index 0000000..b467b7d
--- /dev/null
+++ b/doc/examples/sources.py
@@ -0,0 +1,21 @@
+#!/usr/bin/python3
+
+import apt_pkg
+
+apt_pkg.init()
+
+# cache = apt_pkg.Cache()
+# sources = apt_pkg.SourceRecords(cache)
+
+sources = apt_pkg.SourceRecords()
+sources.restart()
+while sources.lookup("hello"):
+ print(
+ sources.package,
+ sources.version,
+ sources.maintainer,
+ sources.section,
+ repr(sources.binaries),
+ )
+ print(sources.files)
+ print(sources.index.archive_uri(sources.files[0][2]))
diff --git a/doc/examples/tagfile.py b/doc/examples/tagfile.py
new file mode 100755
index 0000000..beb749b
--- /dev/null
+++ b/doc/examples/tagfile.py
@@ -0,0 +1,8 @@
+#!/usr/bin/python3
+import apt_pkg
+
+Parse = apt_pkg.TagFile(open("/var/lib/dpkg/status"))
+
+while Parse.step() == 1:
+ print(Parse.section.get("Package"))
+ print(apt_pkg.parse_depends(Parse.section.get("Depends", "")))
diff --git a/doc/examples/update.py b/doc/examples/update.py
new file mode 100755
index 0000000..a8d46b6
--- /dev/null
+++ b/doc/examples/update.py
@@ -0,0 +1,14 @@
+#!/usr/bin/python3
+import os.path
+
+import apt_pkg
+
+import apt
+
+if __name__ == "__main__":
+ apt_pkg.config.set("APT::Update::Pre-Invoke::", "touch /tmp/update-about-to-run")
+ apt_pkg.config.set("APT::Update::Post-Invoke::", "touch /tmp/update-was-run")
+ c = apt.Cache()
+ res = c.update(apt.progress.TextFetchProgress())
+ print("res: ", res)
+ assert os.path.exists("/tmp/update-about-to-run")
diff --git a/doc/examples/versiontest.py b/doc/examples/versiontest.py
new file mode 100755
index 0000000..fcc4c25
--- /dev/null
+++ b/doc/examples/versiontest.py
@@ -0,0 +1,54 @@
+#!/usr/bin/python3
+
+# This is a simple clone of tests/versiontest.cc
+import re
+import sys
+
+import apt_pkg
+
+apt_pkg.init_config()
+apt_pkg.init_system()
+
+TestFile = apt_pkg.parse_commandline(apt_pkg.config, [], sys.argv)
+if len(TestFile) != 1:
+ print("Must have exactly 1 file name")
+ sys.exit(0)
+
+# Go over the file..
+list = open(TestFile[0])
+CurLine = 0
+while True:
+ Line = list.readline()
+ CurLine = CurLine + 1
+ if Line == "":
+ break
+ Line = Line.strip()
+ if len(Line) == 0 or Line[0] == "#":
+ continue
+
+ Split = re.split("[ \n]", Line)
+
+ # Check forward
+ if apt_pkg.version_compare(Split[0], Split[1]) != int(Split[2]):
+ print(
+ "Comparision failed on line %u. '%s' ? '%s' %i != %i"
+ % (
+ CurLine,
+ Split[0],
+ Split[1],
+ apt_pkg.version_compare(Split[0], Split[1]),
+ int(Split[2]),
+ )
+ )
+ # Check reverse
+ if apt_pkg.version_compare(Split[1], Split[0]) != -1 * int(Split[2]):
+ print(
+ "Comparision failed on line %u. '%s' ? '%s' %i != %i"
+ % (
+ CurLine,
+ Split[1],
+ Split[0],
+ apt_pkg.version_compare(Split[1], Split[0]),
+ -1 * int(Split[2]),
+ )
+ )
diff --git a/doc/source/c++/api.rst b/doc/source/c++/api.rst
new file mode 100644
index 0000000..c8e52ab
--- /dev/null
+++ b/doc/source/c++/api.rst
@@ -0,0 +1,858 @@
+Python APT C++ API
+==================
+The C++ API provides functions to create Python objects from C++ objects and
+to retrieve the C++ object stored in the Python object. An object may have
+another Python object as its owner and keeps its owner alive for its
+lifetime. Some objects require an owner of a specific type, while others
+require none. Refer to the sections below for details.
+
+The C++ API names use the name of the class in apt_pkg and are prefixed with
+Py. For each supported class, there is a _Type object, a _Check() function,
+a _CheckExact() function, a _FromCpp() and a _ToCpp() function.
+
+.. versionadded:: 0.7.100
+
+Acquire (pkgAcquire)
+--------------------
+.. cpp:var:: PyTypeObject PyAcquire_Type
+
+ The type object for :class:`apt_pkg.Acquire` objects.
+
+.. cpp:function:: int PyAcquire_Check(PyObject *object)
+
+ Check that the object *object* is an :class:`apt_pkg.Acquire` object, or
+ a subclass thereof.
+
+.. cpp:function:: int PyAcquire_CheckExact(PyObject *object)
+
+ Check that the object *object* is an :class:`apt_pkg.Acquire` object and no
+ subclass thereof.
+
+.. cpp:function:: PyObject* PyAcquire_FromCpp(pkgAcquire *acquire, bool delete, PyObject *owner)
+
+ Create a new :class:`apt_pkg.Acquire` object from the :cpp:type:`pkgAcquire`
+ pointer given by the parameter *acquire*. If the parameter *delete* is
+ true, the object pointed to by *acquire* will be deleted when the refcount
+ of the return value reaches 0.
+
+.. cpp:function:: pkgAcquire* PyAcquire_ToCpp(PyObject *acquire)
+
+ Return the :cpp:type:`pkgAcquire` pointer contained in the Python object
+ *acquire*.
+
+
+AcquireFile (pkgAcqFile)
+------------------------
+.. cpp:var:: PyTypeObject PyAcquireFile_Type
+
+ The type object for :class:`apt_pkg.AcquireFile` objects.
+
+.. cpp:function:: int PyAcquireFile_Check(PyObject *object)
+
+ Check that the object *object* is an :class:`apt_pkg.AcquireFile` object, or
+ a subclass thereof.
+
+.. cpp:function:: int PyAcquireFile_CheckExact(PyObject *object)
+
+ Check that the object *object* is an :class:`apt_pkg.AcquireFile` object
+ and no subclass thereof.
+
+.. cpp:function:: PyObject* PyAcquireFile_FromCpp(pkgAcqFile *file, bool delete, PyObject *owner)
+
+ Create a new :class:`apt_pkg.AcquireFile` object from the :cpp:type:`pkgAcqFile`
+ pointer given by the parameter *file*. If the parameter *delete* is
+ true, the object pointed to by *file* will be deleted when the reference
+ count of the returned object reaches 0. The parameter *owner* should point
+ to a :class:`apt_pkg.Acquire` object.
+
+.. cpp:function:: pkgAcqFile* PyAcquireFile_ToCpp(PyObject *acquire)
+
+ Return the :cpp:type:`pkgAcqFile` pointer contained in the Python object
+ *acquire*.
+
+AcquireItem (pkgAcquire::Item)
+------------------------------
+.. cpp:var:: PyTypeObject PyAcquireItem_Type
+
+ The type object for :class:`apt_pkg.AcquireItem` objects.
+
+.. cpp:function:: int PyAcquireItem_Check(PyObject *object)
+
+ Check that the object *object* is an :class:`apt_pkg.AcquireItem` object, or
+ a subclass thereof.
+
+.. cpp:function:: int PyAcquireItem_CheckExact(PyObject *object)
+
+ Check that the object *object* is an :class:`apt_pkg.AcquireItem` object
+ and no subclass thereof.
+
+.. cpp:function:: PyObject* PyAcquireItem_FromCpp(pkgAcquire::Item *item, bool delete, PyObject *owner)
+
+ Create a new :class:`apt_pkg.AcquireItem` object from the :cpp:type:`pkgAcquire::Item`
+ pointer given by the parameter *item*. If the parameter *delete* is
+ true, the object pointed to by *item* will be deleted when the reference
+ count of the returned object reaches 0. The parameter *owner* should point
+ to a :class:`apt_pkg.Acquire` object.
+
+.. cpp:function:: pkgAcquire::Item* PyAcquireItem_ToCpp(PyObject *object)
+
+ Return the :cpp:type:`pkgAcquire::Item` pointer contained in the Python object
+ *object*.
+
+AcquireItemDesc (pkgAcquire::ItemDesc)
+--------------------------------------
+.. cpp:var:: PyTypeObject PyAcquireItemDesc_Type
+
+ The type object for :class:`apt_pkg.AcquireItemDesc` objects.
+
+.. cpp:function:: int PyAcquireItemDesc_Check(PyObject *object)
+
+ Check that the object *object* is an :class:`apt_pkg.AcquireItemDesc` object, or
+ a subclass thereof.
+
+.. cpp:function:: int PyAcquireItemDesc_CheckExact(PyObject *object)
+
+ Check that the object *object* is an :class:`apt_pkg.AcquireItemDesc` object
+ and no subclass thereof.
+
+.. cpp:function:: PyObject* PyAcquireItemDesc_FromCpp(pkgAcquire::ItemDesc *desc, bool delete, PyObject *owner)
+
+ Create a new :class:`apt_pkg.AcquireItemDesc` object from the :cpp:type:`pkgAcquire::ItemDesc`
+ pointer given by the parameter *desc*. If the parameter *delete* is
+ true, the object pointed to by *desc* will be deleted when the reference
+ count of the returned object reaches 0. The parameter *owner* should point
+ to a :class:`apt_pkg.AcquireItem` object.
+
+.. cpp:function:: pkgAcquire::ItemDesc* PyAcquireItemDesc_ToCpp(PyObject *object)
+
+ Return the :cpp:type:`pkgAcquire::ItemDesc` pointer contained in the Python object
+ *object*.
+
+AcquireWorker (pkgAcquire::Worker)
+----------------------------------
+.. cpp:var:: PyTypeObject PyAcquireWorker_Type
+
+ The type object for :class:`apt_pkg.AcquireWorker` objects.
+
+.. cpp:function:: int PyAcquireWorker_Check(PyObject *object)
+
+ Check that the object *object* is an :class:`apt_pkg.AcquireWorker` object, or
+ a subclass thereof.
+
+.. cpp:function:: int PyAcquireWorker_CheckExact(PyObject *object)
+
+ Check that the object *object* is an :class:`apt_pkg.AcquireWorker` object
+ and no subclass thereof.
+
+.. cpp:function:: PyObject* PyAcquireWorker_FromCpp(pkgAcquire::Worker *worker, bool delete, PyObject *owner)
+
+ Create a new :class:`apt_pkg.AcquireWorker` object from the :cpp:type:`pkgAcquire::Worker`
+ pointer given by the parameter *worker*. If the parameter *delete* is
+ true, the object pointed to by *worker* will be deleted when the reference
+ count of the returned object reaches 0. The parameter *owner* should point
+ to a :class:`apt_pkg.Acquire` object.
+
+.. cpp:function:: pkgAcquire::Worker* PyAcquireWorker_ToCpp(PyObject *object)
+
+ Return the :cpp:type:`pkgAcquire::Worker` pointer contained in the Python object
+ *object*.
+
+ActionGroup (pkgDepCache::ActionGroup)
+--------------------------------------
+.. cpp:var:: PyTypeObject PyActionGroup_Type
+
+ The type object for :class:`apt_pkg.ActionGroup` objects.
+
+.. cpp:function:: int PyActionGroup_Check(PyObject *object)
+
+ Check that the object *object* is an :class:`apt_pkg.ActionGroup` object, or
+ a subclass thereof.
+
+.. cpp:function:: int PyActionGroup_CheckExact(PyObject *object)
+
+ Check that the object *object* is an :class:`apt_pkg.ActionGroup` object
+ and no subclass thereof.
+
+.. cpp:function:: PyObject* PyActionGroup_FromCpp(pkgDepCache::ActionGroup *agroup, bool delete, PyObject *owner)
+
+ Create a new :class:`apt_pkg.ActionGroup` object from the :cpp:type:`pkgDepCache::ActionGroup`
+ pointer given by the parameter *agroup*. If the parameter *delete* is
+ true, the object pointed to by *agroup* will be deleted when the reference
+ count of the returned object reaches 0. The parameter *owner* should point
+ to a :class:`apt_pkg.DepCache` object.
+
+.. cpp:function:: pkgDepCache::ActionGroup* PyActionGroup_ToCpp(PyObject *object)
+
+ Return the :cpp:type:`pkgDepCache::ActionGroup` pointer contained in the
+ Python object *object*.
+
+Cache (pkgCache)
+------------------------
+.. cpp:var:: PyTypeObject PyCache_Type
+
+ The type object for :class:`apt_pkg.Cache` objects.
+
+.. cpp:function:: int PyCache_Check(PyObject *object)
+
+ Check that the object *object* is an :class:`apt_pkg.Cache` object, or
+ a subclass thereof.
+
+.. cpp:function:: int PyCache_CheckExact(PyObject *object)
+
+ Check that the object *object* is an :class:`apt_pkg.Cache` object
+ and no subclass thereof.
+
+.. cpp:function:: PyObject* PyCache_FromCpp(pkgCache *cache, bool delete, PyObject *owner)
+
+ Create a new :class:`apt_pkg.Cache` object from the :cpp:type:`pkgCache`
+ pointer given by the parameter *cache*. If the parameter *delete* is
+ true, the object pointed to by *cache* will be deleted when the reference
+ count of the returned object reaches 0. The parameter *owner* shall point
+ to a object of the type :cpp:var:`PyCacheFile_Type`.
+
+.. cpp:function:: pkgCache* PyCache_ToCpp(PyObject *object)
+
+ Return the :cpp:type:`pkgCache` pointer contained in the Python object
+ *object*.
+
+
+CacheFile (pkgCacheFile)
+------------------------
+.. cpp:var:: PyTypeObject PyCacheFile_Type
+
+ The type object for CacheFile. This type is internal and not exported to
+ Python anywhere.
+
+.. cpp:function:: int PyCacheFile_Check(PyObject *object)
+
+ Check that the object *object* is of the type :cpp:var:`PyCacheFile_Type` or
+ a subclass thereof.
+
+.. cpp:function:: int PyCacheFile_CheckExact(PyObject *object)
+
+ Check that the object *object* is of the type :cpp:var:`PyCacheFile_Type` and
+ no subclass thereof.
+
+.. cpp:function:: PyObject* PyCacheFile_FromCpp(pkgCacheFile *file, bool delete, PyObject *owner)
+
+ Create a new :class:`apt_pkg.CacheFile` object from the :cpp:type:`pkgCacheFile`
+ pointer given by the parameter *file* If the parameter *delete* is
+ true, the object pointed to by *file* will be deleted when the reference
+ count of the returned object reaches 0.
+
+.. cpp:function:: pkgCacheFile* PyCacheFile_ToCpp(PyObject *object)
+
+ Return the :cpp:type:`pkgCacheFile` pointer contained in the Python object
+ *object*.
+
+Cdrom (pkgCdrom)
+------------------------
+.. cpp:var:: PyTypeObject PyCdrom_Type
+
+ The type object for :class:`apt_pkg.Cdrom` objects.
+
+.. cpp:function:: int PyCdrom_Check(PyObject *object)
+
+ Check that the object *object* is an :class:`apt_pkg.Cdrom` object, or
+ a subclass thereof.
+
+.. cpp:function:: int PyCdrom_CheckExact(PyObject *object)
+
+ Check that the object *object* is an :class:`apt_pkg.Cdrom` object
+ and no subclass thereof.
+
+.. cpp:function:: PyObject* PyCdrom_FromCpp(pkgCdrom &cdrom, bool delete, PyObject *owner)
+
+ Create a new :class:`apt_pkg.Cdrom` object from the :cpp:type:`pkgCdrom`
+ reference given by the parameter *cdrom*. If the parameter *delete* is
+ true, *cdrom* will be deleted when the reference count of the returned
+ object reaches 0.
+
+.. cpp:function:: pkgCdrom& PyCdrom_ToCpp(PyObject *object)
+
+ Return the :cpp:type:`pkgCdrom` reference contained in the Python object
+ *object*.
+
+Configuration (Configuration)
+-------------------------------
+.. cpp:var:: PyTypeObject PyConfiguration_Type
+
+ The type object for :class:`apt_pkg.Configuration` objects.
+
+.. cpp:function:: int PyConfiguration_Check(PyObject *object)
+
+ Check that the object *object* is an :class:`apt_pkg.Configuration` object, or
+ a subclass thereof.
+
+.. cpp:function:: int PyConfiguration_CheckExact(PyObject *object)
+
+ Check that the object *object* is an :class:`apt_pkg.Configuration` object
+ and no subclass thereof.
+
+.. cpp:function:: PyObject* PyConfiguration_FromCpp(Configuration *cpp, bool delete, PyObject *owner)
+
+ Create a new :class:`apt_pkg.Configuration` object from the :cpp:type:`Configuration`
+ pointer given by the parameter *cpp*. If the parameter *delete* is
+ true, the object pointed to by *cpp* will be deleted when the reference
+ count of the returned object reaches 0. The parameter *owner* may refer to
+ a parent object (e.g. when exposing a sub tree of a configuration object).
+
+.. cpp:function:: Configuration* PyConfiguration_ToCpp(PyObject *object)
+
+ Return the :cpp:type:`Configuration` pointer contained in the Python object
+ *object*.
+
+DepCache (pkgDepCache)
+------------------------
+.. cpp:var:: PyTypeObject PyDepCache_Type
+
+ The type object for :class:`apt_pkg.DepCache` objects.
+
+.. cpp:function:: int PyDepCache_Check(PyObject *object)
+
+ Check that the object *object* is an :class:`apt_pkg.DepCache` object, or
+ a subclass thereof.
+
+.. cpp:function:: int PyDepCache_CheckExact(PyObject *object)
+
+ Check that the object *object* is an :class:`apt_pkg.DepCache` object
+ and no subclass thereof.
+
+.. cpp:function:: PyObject* PyDepCache_FromCpp(pkgDepCache *cpp, bool delete, PyObject *owner)
+
+ Create a new :class:`apt_pkg.DepCache` object from the :cpp:type:`pkgDepCache`
+ pointer given by the parameter *cpp*. If the parameter *delete* is
+ true, the object pointed to by *cpp* will be deleted when the reference
+ count of the returned object reaches 0. The parameter *owner* must be
+ a PyObject of the type :cpp:var:`PyCache_Type`.
+
+.. cpp:function:: pkgDepCache* PyDepCache_ToCpp(PyObject *object)
+
+ Return the :cpp:type:`pkgDepCache` pointer contained in the Python object
+ *object*.
+
+Dependency (pkgCache::DepIterator)
+----------------------------------
+.. cpp:var:: PyTypeObject PyDependency_Type
+
+ The type object for :class:`apt_pkg.Dependency` objects.
+
+.. cpp:function:: int PyDependency_Check(PyObject *object)
+
+ Check that the object *object* is an :class:`apt_pkg.Dependency` object, or
+ a subclass thereof.
+
+.. cpp:function:: int PyDependency_CheckExact(PyObject *object)
+
+ Check that the object *object* is an :class:`apt_pkg.Dependency` object
+ and no subclass thereof.
+
+.. cpp:function:: PyObject* PyDependency_FromCpp(pkgCache::DepIterator &cpp, bool delete, PyObject *owner)
+
+ Create a new :class:`apt_pkg.Dependency` object from the :cpp:type:`pkgCache::DepIterator`
+ reference given by the parameter *cpp*. If the parameter *delete* is
+ true, *cpp* will be deleted when the reference
+ count of the returned object reaches 0. The parameter *owner* must be
+ a PyObject of the type :cpp:var:`PyPackage_Type`.
+
+.. cpp:function:: pkgCache::DepIterator& PyDependency_ToCpp(PyObject *object)
+
+ Return the :cpp:type:`pkgCache::DepIterator` reference contained in the
+ Python object *object*.
+
+Description (pkgCache::DescIterator)
+------------------------------------
+.. cpp:var:: PyTypeObject PyDescription_Type
+
+ The type object for :class:`apt_pkg.Description` objects.
+
+.. cpp:function:: int PyDescription_Check(PyObject *object)
+
+ Check that the object *object* is an :class:`apt_pkg.Description` object, or
+ a subclass thereof.
+
+.. cpp:function:: int PyDescription_CheckExact(PyObject *object)
+
+ Check that the object *object* is an :class:`apt_pkg.Description` object
+ and no subclass thereof.
+
+.. cpp:function:: PyObject* PyDescription_FromCpp(pkgCache::DescIterator &cpp, bool delete, PyObject *owner)
+
+ Create a new :class:`apt_pkg.Description` object from the :cpp:type:`pkgCache::DescIterator`
+ reference given by the parameter *cpp*. If the parameter *delete* is
+ true, *cpp* will be deleted when the reference
+ count of the returned object reaches 0. The parameter *owner* must be
+ a PyObject of the type :cpp:var:`PyPackage_Type`.
+
+.. cpp:function:: pkgCache::DescIterator& PyDescription_ToCpp(PyObject *object)
+
+ Return the :cpp:type:`pkgCache::DescIterator` reference contained in the
+ Python object *object*.
+
+
+Group (pkgCache::GrpIterator)
+----------------------------------
+.. versionadded:: 0.8.0
+
+.. cpp:var:: PyTypeObject PyGroup_Type
+
+ The type object for :class:`apt_pkg.Group` objects.
+
+.. cpp:function:: int PyGroup_Check(PyObject *object)
+
+ Check that the object *object* is an :class:`apt_pkg.Group` object, or
+ a subclass thereof.
+
+.. cpp:function:: int PyGroup_CheckExact(PyObject *object)
+
+ Check that the object *object* is an :class:`apt_pkg.Group` object
+ and no subclass thereof.
+
+.. cpp:function:: PyObject* PyGroup_FromCpp(pkgCache::GrpIterator &cpp, bool delete, PyObject *owner)
+
+ Create a new :class:`apt_pkg.Group` object from the :cpp:type:`pkgCache::GrpIterator`
+ reference given by the parameter *cpp*. If the parameter *delete* is
+ true, *cpp* will be deleted when the reference
+ count of the returned object reaches 0. The parameter *owner* should be
+ a PyObject of the type :cpp:var:`PyCache_Type`.
+
+.. cpp:function:: pkgCache::GrpIterator& PyGroup_ToCpp(PyObject *object)
+
+ Return the :cpp:type:`pkgCache::GrpIterator` reference contained in the
+ Python object *object*.
+
+Hashes (Hashes)
+----------------------------------
+.. cpp:var:: PyTypeObject PyHashes_Type
+
+ The type object for :class:`apt_pkg.Hashes` objects.
+
+.. cpp:function:: int PyHashes_Check(PyObject *object)
+
+ Check that the object *object* is an :class:`apt_pkg.Hashes` object, or
+ a subclass thereof.
+
+.. cpp:function:: int PyHashes_CheckExact(PyObject *object)
+
+ Check that the object *object* is an :class:`apt_pkg.Hashes` object
+ and no subclass thereof.
+
+.. cpp:function:: PyObject* PyHashes_FromCpp(Hashes &cpp, bool delete, PyObject *owner)
+
+ Create a new :class:`apt_pkg.Hashes` object from the :cpp:type:`Hashes`
+ reference given by the parameter *cpp*. If the parameter *delete* is
+ true, *cpp* will be deleted when the reference count of the returned
+ object reaches 0.
+
+.. cpp:function:: Hashes& PyHashes_ToCpp(PyObject *object)
+
+ Return the :cpp:type:`Hashes` reference contained in the
+ Python object *object*.
+
+HashString (HashString)
+------------------------
+.. cpp:var:: PyTypeObject PyHashString_Type
+
+ The type object for :class:`apt_pkg.HashString` objects.
+
+.. cpp:function:: int PyHashString_Check(PyObject *object)
+
+ Check that the object *object* is an :class:`apt_pkg.HashString` object, or
+ a subclass thereof.
+
+.. cpp:function:: int PyHashString_CheckExact(PyObject *object)
+
+ Check that the object *object* is an :class:`apt_pkg.HashString` object
+ and no subclass thereof.
+
+.. cpp:function:: PyObject* PyHashString_FromCpp(HashString *cpp, bool delete, PyObject *owner)
+
+ Create a new :class:`apt_pkg.HashString` object from the :cpp:type:`HashString`
+ pointer given by the parameter *cpp*. If the parameter *delete* is
+ true, the object pointed to by *cpp* will be deleted when the reference
+ count of the returned object reaches 0.
+
+.. cpp:function:: HashString* PyHashString_ToCpp(PyObject *object)
+
+ Return the :cpp:type:`HashString` pointer contained in the Python object
+ *object*.
+
+IndexRecords (indexRecords)
+----------------------------
+.. cpp:var:: PyTypeObject PyIndexRecords_Type
+
+ The type object for :class:`apt_pkg.IndexRecords` objects.
+
+.. cpp:function:: int PyIndexRecords_Check(PyObject *object)
+
+ Check that the object *object* is an :class:`apt_pkg.IndexRecords` object, or
+ a subclass thereof.
+
+.. cpp:function:: int PyIndexRecords_CheckExact(PyObject *object)
+
+ Check that the object *object* is an :class:`apt_pkg.IndexRecords` object
+ and no subclass thereof.
+
+.. cpp:function:: PyObject* PyIndexRecords_FromCpp(indexRecords *cpp, bool delete, PyObject *owner)
+
+ Create a new :class:`apt_pkg.IndexRecords` object from the :cpp:type:`indexRecords`
+ pointer given by the parameter *cpp*. If the parameter *delete* is
+ true, the object pointed to by *cpp* will be deleted when the reference
+ count of the returned object reaches 0.
+
+.. cpp:function:: indexRecords* PyIndexRecords_ToCpp(PyObject *object)
+
+ Return the :cpp:type:`indexRecords` pointer contained in the Python object
+ *object*.
+
+
+MetaIndex (metaIndex)
+------------------------
+.. cpp:var:: PyTypeObject PyMetaIndex_Type
+
+ The type object for :class:`apt_pkg.MetaIndex` objects.
+
+.. cpp:function:: int PyMetaIndex_Check(PyObject *object)
+
+ Check that the object *object* is an :class:`apt_pkg.MetaIndex` object, or
+ a subclass thereof.
+
+.. cpp:function:: int PyMetaIndex_CheckExact(PyObject *object)
+
+ Check that the object *object* is an :class:`apt_pkg.MetaIndex` object
+ and no subclass thereof.
+
+.. cpp:function:: PyObject* PyMetaIndex_FromCpp(metaIndex *cpp, bool delete, PyObject *owner)
+
+ Create a new :class:`apt_pkg.MetaIndex` object from the :cpp:type:`metaIndex`
+ pointer given by the parameter *cpp*. If the parameter *delete* is
+ true, the object pointed to by *cpp* will be deleted when the reference
+ count of the returned object reaches 0. The parameter *owner* should be
+ a PyObject of the type :cpp:var:`PySourceList_Type`.
+
+.. cpp:function:: metaIndex* PyMetaIndex_ToCpp(PyObject *object)
+
+ Return the :cpp:type:`metaIndex` pointer contained in the Python object
+ *object*.
+
+Package (pkgCache::PkgIterator)
+----------------------------------
+.. cpp:var:: PyTypeObject PyPackage_Type
+
+ The type object for :class:`apt_pkg.Package` objects.
+
+.. cpp:function:: int PyPackage_Check(PyObject *object)
+
+ Check that the object *object* is an :class:`apt_pkg.Package` object, or
+ a subclass thereof.
+
+.. cpp:function:: int PyPackage_CheckExact(PyObject *object)
+
+ Check that the object *object* is an :class:`apt_pkg.Package` object
+ and no subclass thereof.
+
+.. cpp:function:: PyObject* PyPackage_FromCpp(pkgCache::PkgIterator &cpp, bool delete, PyObject *owner)
+
+ Create a new :class:`apt_pkg.Package` object from the :cpp:type:`pkgCache::PkgIterator`
+ reference given by the parameter *cpp*. If the parameter *delete* is
+ true, *cpp* will be deleted when the reference
+ count of the returned object reaches 0. The parameter *owner* should be
+ a PyObject of the type :cpp:var:`PyCache_Type`.
+
+.. cpp:function:: pkgCache::PkgIterator& PyPackage_ToCpp(PyObject *object)
+
+ Return the :cpp:type:`pkgCache::PkgIterator` reference contained in the
+ Python object *object*.
+
+PackageFile (pkgCache::PkgFileIterator)
+----------------------------------------
+.. cpp:var:: PyTypeObject PyPackageFile_Type
+
+ The type object for :class:`apt_pkg.PackageFile` objects.
+
+.. cpp:function:: int PyPackageFile_Check(PyObject *object)
+
+ Check that the object *object* is an :class:`apt_pkg.PackageFile` object, or
+ a subclass thereof.
+
+.. cpp:function:: int PyPackageFile_CheckExact(PyObject *object)
+
+ Check that the object *object* is an :class:`apt_pkg.PackageFile` object
+ and no subclass thereof.
+
+.. cpp:function:: PyObject* PyPackageFile_FromCpp(pkgCache::PkgFileIterator &cpp, bool delete, PyObject *owner)
+
+ Create a new :class:`apt_pkg.PackageFile` object from the :cpp:type:`pkgCache::PkgFileIterator`
+ reference given by the parameter *cpp*. If the parameter *delete* is
+ true, *cpp* will be deleted when the reference
+ count of the returned object reaches 0. The parameter *owner* should be
+ a PyObject of the type :cpp:var:`PyCache_Type`.
+
+.. cpp:function:: pkgCache::PkgFileIterator& PyPackageFile_ToCpp(PyObject *object)
+
+ Return the :cpp:type:`pkgCache::PkgFileIterator` reference contained in the
+ Python object *object*.
+
+IndexFile (pkgIndexFile)
+--------------------------------------
+.. cpp:var:: PyTypeObject PyIndexFile_Type
+
+ The type object for :class:`apt_pkg.IndexFile` objects.
+
+.. cpp:function:: int PyIndexFile_Check(PyObject *object)
+
+ Check that the object *object* is an :class:`apt_pkg.IndexFile` object, or
+ a subclass thereof.
+
+.. cpp:function:: int PyIndexFile_CheckExact(PyObject *object)
+
+ Check that the object *object* is an :class:`apt_pkg.IndexFile` object
+ and no subclass thereof.
+
+.. cpp:function:: PyObject* PyIndexFile_FromCpp(pkgIndexFile *cpp, bool delete, PyObject *owner)
+
+ Create a new :class:`apt_pkg.IndexFile` object from the :cpp:type:`pkgIndexFile`
+ pointer given by the parameter *cpp*. If the parameter *delete* is
+ true, the object pointed to by *cpp* will be deleted when the reference
+ count of the returned object reaches 0. The parameter *owner* should be
+ a PyObject of the type :cpp:var:`PyMetaIndex_Type`.
+
+.. cpp:function:: pkgIndexFile* PyIndexFile_ToCpp(PyObject *object)
+
+ Return the :cpp:type:`pkgIndexFile` pointer contained in the Python object
+ *object*.
+
+OrderList (pkgOrderList)
+---------------------------
+.. cpp:var:: PyTypeObject PyOrderList_Type
+
+ The type object for :class:`apt_pkg.OrderList` objects.
+
+.. cpp:function:: int PyOrderList_Check(PyObject *object)
+
+ Check that the object *object* is an :class:`apt_pkg.OrderList` object, or
+ a subclass thereof.
+
+.. cpp:function:: int PyOrderList_CheckExact(PyObject *object)
+
+ Check that the object *object* is an :class:`apt_pkg.OrderList` object
+ and no subclass thereof.
+
+.. cpp:function:: PyObject* PyOrderList_FromCpp(pkgOrderList *cpp, bool delete, PyObject *owner)
+
+ Create a new :class:`apt_pkg.OrderList` object from the :cpp:type:`pkgOrderList`
+ pointer given by the parameter *cpp*. If the parameter *delete* is
+ true, the object pointed to by *cpp* will be deleted when the reference
+ count of the returned object reaches 0. The owner must be a
+ :class:`apt_pkg.DepCache` object.
+
+.. cpp:function:: pkgOrderList* PyOrderList_ToCpp(PyObject *object)
+
+ Return the :cpp:type:`pkgOrderList` pointer contained in the Python object
+ *object*.
+
+PackageManager (pkgPackageManager)
+----------------------------------
+.. cpp:var:: PyTypeObject PyPackageManager_Type
+
+ The type object for :class:`apt_pkg.PackageManager` objects.
+
+.. cpp:function:: int PyPackageManager_Check(PyObject *object)
+
+ Check that the object *object* is an :class:`apt_pkg.PackageManager` object, or
+ a subclass thereof.
+
+.. cpp:function:: int PyPackageManager_CheckExact(PyObject *object)
+
+ Check that the object *object* is an :class:`apt_pkg.PackageManager` object
+ and no subclass thereof.
+
+.. cpp:function:: PyObject* PyPackageManager_FromCpp(pkgPackageManager *cpp, bool delete, PyObject *owner)
+
+ Create a new :class:`apt_pkg.PackageManager` object from the :cpp:type:`pkgPackageManager`
+ pointer given by the parameter *cpp*. If the parameter *delete* is
+ true, the object pointed to by *cpp* will be deleted when the reference
+ count of the returned object reaches 0.
+
+.. cpp:function:: pkgPackageManager* PyPackageManager_ToCpp(PyObject *object)
+
+ Return the :cpp:type:`pkgPackageManager` pointer contained in the Python object
+ *object*.
+
+
+Policy (pkgPolicy)
+------------------
+.. cpp:var:: PyTypeObject PyPolicy_Type
+
+ The type object for :class:`apt_pkg.Policy` objects.
+
+.. cpp:function:: int PyPolicy_Check(PyObject *object)
+
+ Check that the object *object* is an :class:`apt_pkg.Policy` object, or
+ a subclass thereof.
+
+.. cpp:function:: int PyPolicy_CheckExact(PyObject *object)
+
+ Check that the object *object* is an :class:`apt_pkg.Policy` object
+ and no subclass thereof.
+
+.. cpp:function:: PyObject* PyPolicy_FromCpp(pkgPolicy *cpp, bool delete, PyObject *owner)
+
+ Create a new :class:`apt_pkg.Policy` object from the :cpp:type:`pkgPolicy`
+ pointer given by the parameter *cpp*. If the parameter *delete* is
+ true, the object pointed to by *cpp* will be deleted when the reference
+ count of the returned object reaches 0. The parameter *owner* must be
+ a PyObject of the type :cpp:var:`PyCache_Type`.
+
+.. cpp:function:: pkgPolicy* PyPolicy_ToCpp(PyObject *object)
+
+ Return the :cpp:type:`pkgPolicy` pointer contained in the Python object
+ *object*.
+
+
+ProblemResolver (pkgProblemResolver)
+--------------------------------------
+.. cpp:var:: PyTypeObject PyProblemResolver_Type
+
+ The type object for :class:`apt_pkg.ProblemResolver` objects.
+
+.. cpp:function:: int PyProblemResolver_Check(PyObject *object)
+
+ Check that the object *object* is an :class:`apt_pkg.ProblemResolver` object, or
+ a subclass thereof.
+
+.. cpp:function:: int PyProblemResolver_CheckExact(PyObject *object)
+
+ Check that the object *object* is an :class:`apt_pkg.ProblemResolver` object
+ and no subclass thereof.
+
+.. cpp:function:: PyObject* PyProblemResolver_FromCpp(pkgProblemResolver *cpp, bool delete, PyObject *owner)
+
+ Create a new :class:`apt_pkg.ProblemResolver` object from the :cpp:type:`pkgProblemResolver`
+ pointer given by the parameter *cpp*. If the parameter *delete* is
+ true, the object pointed to by *cpp* will be deleted when the reference
+ count of the returned object reaches 0. The parameter *owner* must be
+ a PyObject of the type :cpp:var:`PyDepCache_Type`.
+
+.. cpp:function:: pkgProblemResolver* PyProblemResolver_ToCpp(PyObject *object)
+
+ Return the :cpp:type:`pkgProblemResolver` pointer contained in the Python object
+ *object*.
+
+
+
+SourceList (pkgSourceList)
+---------------------------
+.. cpp:var:: PyTypeObject PySourceList_Type
+
+ The type object for :class:`apt_pkg.SourceList` objects.
+
+.. cpp:function:: int PySourceList_Check(PyObject *object)
+
+ Check that the object *object* is an :class:`apt_pkg.SourceList` object, or
+ a subclass thereof.
+
+.. cpp:function:: int PySourceList_CheckExact(PyObject *object)
+
+ Check that the object *object* is an :class:`apt_pkg.SourceList` object
+ and no subclass thereof.
+
+.. cpp:function:: PyObject* PySourceList_FromCpp(pkgSourceList *cpp, bool delete, PyObject *owner)
+
+ Create a new :class:`apt_pkg.SourceList` object from the :cpp:type:`pkgSourceList`
+ pointer given by the parameter *cpp*. If the parameter *delete* is
+ true, the object pointed to by *cpp* will be deleted when the reference
+ count of the returned object reaches 0.
+
+.. cpp:function:: pkgSourceList* PySourceList_ToCpp(PyObject *object)
+
+ Return the :cpp:type:`pkgSourceList` pointer contained in the Python object
+ *object*.
+
+
+TagFile (pkgTagFile)
+----------------------------------
+.. cpp:var:: PyTypeObject PyTagFile_Type
+
+ The type object for :class:`apt_pkg.TagFile` objects.
+
+.. cpp:function:: int PyTagFile_Check(PyObject *object)
+
+ Check that the object *object* is an :class:`apt_pkg.TagFile` object, or
+ a subclass thereof.
+
+.. cpp:function:: int PyTagFile_CheckExact(PyObject *object)
+
+ Check that the object *object* is an :class:`apt_pkg.TagFile` object
+ and no subclass thereof.
+
+.. cpp:function:: PyObject* PyTagFile_FromCpp(pkgTagFile &cpp, bool delete, PyObject *owner)
+
+ Create a new :class:`apt_pkg.TagFile` object from the :cpp:type:`pkgTagFile`
+ reference given by the parameter *cpp*. If the parameter *delete* is
+ true, *cpp* will be deleted when the reference
+ count of the returned object reaches 0. The parameter *owner* may be any
+ Python object.
+
+.. cpp:function:: pkgTagFile& PyTagFile_ToCpp(PyObject *object)
+
+ Return the :cpp:type:`pkgTagFile` reference contained in the
+ Python object *object*.
+
+TagSection (pkgTagSection)
+----------------------------------
+.. cpp:var:: PyTypeObject PyTagSection_Type
+
+ The type object for :class:`apt_pkg.TagSection` objects.
+
+.. cpp:function:: int PyTagSection_Check(PyObject *object)
+
+ Check that the object *object* is an :class:`apt_pkg.TagSection` object, or
+ a subclass thereof.
+
+.. cpp:function:: int PyTagSection_CheckExact(PyObject *object)
+
+ Check that the object *object* is an :class:`apt_pkg.TagSection` object
+ and no subclass thereof.
+
+.. cpp:function:: PyObject* PyTagSection_FromCpp(pkgTagSection &cpp, bool delete, PyObject *owner)
+
+ Create a new :class:`apt_pkg.TagSection` object from the :cpp:type:`pkgTagSection`
+ reference given by the parameter *cpp*. If the parameter *delete* is
+ true, *cpp* will be deleted when the reference
+ count of the returned object reaches 0. The parameter *owner* may be
+ a PyObject of the type :cpp:var:`PyTagFile_Type`.
+
+.. cpp:function:: pkgTagSection& PyTagSection_ToCpp(PyObject *object)
+
+ Return the :cpp:type:`pkgTagSection` reference contained in the
+ Python object *object*.
+
+Version (pkgCache::VerIterator)
+----------------------------------
+.. cpp:var:: PyTypeObject PyVersion_Type
+
+ The type object for :class:`apt_pkg.Version` objects.
+
+.. cpp:function:: int PyVersion_Check(PyObject *object)
+
+ Check that the object *object* is an :class:`apt_pkg.Version` object, or
+ a subclass thereof.
+
+.. cpp:function:: int PyVersion_CheckExact(PyObject *object)
+
+ Check that the object *object* is an :class:`apt_pkg.Version` object
+ and no subclass thereof.
+
+.. cpp:function:: PyObject* PyVersion_FromCpp(pkgCache::VerIterator &cpp, bool delete, PyObject *owner)
+
+ Create a new :class:`apt_pkg.Version` object from the :cpp:type:`pkgCache::VerIterator`
+ reference given by the parameter *cpp*. If the parameter *delete* is
+ true, *cpp* will be deleted when the reference
+ count of the returned object reaches 0. The parameter *owner* must be
+ a PyObject of the type :cpp:var:`PyPackage_Type`.
+
+.. cpp:function:: pkgCache::VerIterator& PyVersion_ToCpp(PyObject *object)
+
+ Return the :cpp:type:`pkgCache::VerIterator` reference contained in the
+ Python object *object*.
diff --git a/doc/source/c++/embedding.rst b/doc/source/c++/embedding.rst
new file mode 100644
index 0000000..cb175f8
--- /dev/null
+++ b/doc/source/c++/embedding.rst
@@ -0,0 +1,34 @@
+.. highlight:: c++
+
+Embedding Python APT
+====================
+This is a very basic tutorial for working with the C++ bindings.
+
+Basics
+-------
+To use the python-apt C++ bindings, first include the
+``python-apt/python-apt.h`` header::
+
+ #include <python-apt/python-apt.h>
+
+Now, the module needs to be initialized. This is done by calling the function
+:c:func:`import_apt_pkg`. This function returns 0 on success and a negative
+value in case of failure::
+
+ if (import_apt_pkg() < 0)
+ return;
+
+Longer example
+--------------
+The following code will create a standalone application which provides a
+module ``client`` with the attribute ``hash`` which stores an object of the
+type :class:`apt_pkg.HashString`:
+
+.. literalinclude:: ../../client-example.cc
+
+
+.. highlight:: sh
+
+If this file were called client-example.cc, you could compile it using::
+
+ g++ -lapt-pkg -lpython2.5 -I/usr/include/python2.5 -o client client-example.cc
diff --git a/doc/source/c++/index.rst b/doc/source/c++/index.rst
new file mode 100644
index 0000000..8f598f3
--- /dev/null
+++ b/doc/source/c++/index.rst
@@ -0,0 +1,8 @@
+Python APT and C++
+==================
+
+.. toctree::
+ :maxdepth: 1
+
+ api
+ embedding
diff --git a/doc/source/conf.py b/doc/source/conf.py
new file mode 100644
index 0000000..079cc50
--- /dev/null
+++ b/doc/source/conf.py
@@ -0,0 +1,245 @@
+#
+# python-apt documentation build configuration file, created by
+# sphinx-quickstart on Wed Jan 7 17:04:36 2009.
+#
+# This file is execfile()d with the current directory set to its containing
+# dir.
+#
+# The contents of this file are pickled, so don't put values in the namespace
+# that aren't pickleable (module imports are okay, they're removed
+# automatically).
+#
+# Note that not all possible configuration values are present in this
+# autogenerated file.
+#
+# All configuration values have a default; values that are commented out
+# serve to show the default.
+import glob
+import os
+import sys
+
+# Find the path to the built apt_pkg and apt_inst extensions
+if os.path.exists("../../build"):
+ version = ".".join(str(x) for x in sys.version_info[:2])
+ for apt_pkg_path in glob.glob("../../build/lib*%s/*.so" % version):
+ sys.path.insert(0, os.path.abspath(os.path.dirname(apt_pkg_path)))
+ try:
+ import apt_pkg
+
+ apt_pkg # pyflakes
+ except ImportError as exc:
+ # Not the correct version
+ sys.stderr.write("W: Ignoring error %s\n" % exc)
+ sys.path.pop(0)
+ else:
+ sys.stdout.write("I: Found apt_pkg.so in %s\n" % sys.path[0])
+ break
+
+
+# General configuration
+# ---------------------
+
+# Add any Sphinx extension module names here, as strings. They can be
+# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
+extensions = [
+ "sphinx.ext.autodoc",
+ "sphinx.ext.doctest",
+ "sphinx.ext.intersphinx",
+ "sphinx.ext.todo",
+]
+intersphinx_mapping = {"http://docs.python.org/": None}
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ["templates"]
+
+# The suffix of source filenames.
+source_suffix = ".rst"
+
+# The encoding of source files.
+# source_encoding = 'utf-8'
+
+# The master toctree document.
+master_doc = "contents"
+
+# General information about the project.
+project = "python-apt"
+copyright = "2009-2010, Julian Andres Klode <jak@debian.org>"
+
+# The version info for the project you're documenting, acts as replacement for
+# |version| and |release|, also used in various other places throughout the
+# built documents.
+#
+
+try:
+ release = os.environ["DEBVER"]
+except KeyError:
+ from subprocess import PIPE, Popen
+
+ p1 = Popen(["dpkg-parsechangelog", "-l../../debian/changelog"], stdout=PIPE)
+ p2 = Popen(["sed", "-n", "s/^Version: //p"], stdin=p1.stdout, stdout=PIPE)
+ release = p2.communicate()[0].decode("utf-8")
+
+
+# Handle the alpha release scheme
+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
+ # version_s[1] = str(int(version_s[1]) + 1)
+ # version_s[2] = "0"
+ # if the version of a 0.X.9Y release should be 0.X+1.0 (0.7.90=>0.8)
+ version_s[2] = "100"
+ version = ".".join(version_s)
+ del version_s
+else:
+ version = ".".join(release.split("~")[0].split(".")[:2])
+del release_raw
+
+# The language for content autogenerated by Sphinx. Refer to documentation
+# for a list of supported languages.
+# language = None
+
+# There are two options for replacing |today|: either, you set today to some
+# non-false value, then it is used:
+# today = ''
+# Else, today_fmt is used as the format for a strftime call.
+# today_fmt = '%B %d, %Y'
+
+# List of documents that shouldn't be included in the build.
+# unused_docs = []
+
+# List of directories, relative to source directory, that shouldn't be searched
+# for source files.
+exclude_trees = []
+
+# The reST default role (used for this markup: `text`) for all documents.
+# default_role = None
+
+# If true, '()' will be appended to :func: etc. cross-reference text.
+# add_function_parentheses = True
+
+# If true, the current module name will be prepended to all description
+# unit titles (such as .. function::).
+# add_module_names = True
+
+# If true, sectionauthor and moduleauthor directives will be shown in the
+# output. They are ignored by default.
+# show_authors = False
+
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = "sphinx"
+
+
+# Options for HTML output
+# -----------------------
+
+# The style sheet to use for HTML and HTML Help pages. A file of that name
+# must exist either in Sphinx' static/ path, or in one of the custom paths
+# given in html_static_path.
+# html_style = 'default.css'
+
+# The name for this set of Sphinx documents. If None, it defaults to
+# "<project> v<release> documentation".
+# html_title = None
+
+# A shorter title for the navigation bar. Default is the same as html_title.
+# html_short_title = None
+
+# The name of an image file (relative to this directory) to place at the top
+# of the sidebar.
+# html_logo = None
+
+# The name of an image file (within the static path) to use as favicon of the
+# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
+# pixels large.
+# html_favicon = None
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+html_static_path = [".static"]
+
+# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
+# using the given strftime format.
+html_last_updated_fmt = None
+
+# If true, SmartyPants will be used to convert quotes and dashes to
+# typographically correct entities.
+# html_use_smartypants = True
+
+# Custom sidebar templates, maps document names to template names.
+# html_sidebars = {}
+
+# Additional templates that should be rendered to pages, maps page names to
+# template names.
+html_additional_pages = {"index": "indexcontent.html"}
+
+# If false, no module index is generated.
+# html_use_modindex = True
+
+# If false, no index is generated.
+# html_use_index = True
+
+# If true, the index is split into individual pages for each letter.
+# html_split_index = False
+
+# If true, the reST sources are included in the HTML build as _sources/<name>.
+# html_copy_source = True
+
+# If true, an OpenSearch description file will be output, and all pages will
+# contain a <link> tag referring to it. The value of this option must be the
+# base URL from which the finished HTML is served.
+# html_use_opensearch = ''
+
+# If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml").
+# html_file_suffix = ''
+
+# Output file base name for HTML help builder.
+htmlhelp_basename = "python-aptdoc"
+
+
+# Options for LaTeX output
+# ------------------------
+
+# The paper size ('letter' or 'a4').
+# latex_paper_size = 'letter'
+
+# The font size ('10pt', '11pt' or '12pt').
+# latex_font_size = '10pt'
+
+# Grouping the document tree into LaTeX files. List of tuples
+# (source index, target name, title, author, document class [howto/manual]).
+latex_documents = [
+ (
+ "contents",
+ "python-apt.tex",
+ "python-apt Documentation",
+ "Julian Andres Klode <jak@debian.org>",
+ "manual",
+ ),
+]
+
+# The name of an image file (relative to this directory) to place at the top of
+# the title page.
+# latex_logo = None
+
+# For "manual" documents, if this is true, then toplevel headings are parts,
+# not chapters.
+# latex_use_parts = False
+
+# Additional stuff for the LaTeX preamble.
+# latex_preamble = ''
+
+# Documents to append as an appendix to all manuals.
+# latex_appendices = []
+
+# If false, no module index is generated.
+# latex_use_modindex = True
+
+todo_include_todos = True
diff --git a/doc/source/contents.rst b/doc/source/contents.rst
new file mode 100644
index 0000000..6c4e161
--- /dev/null
+++ b/doc/source/contents.rst
@@ -0,0 +1,19 @@
+Python APT Documentation contents
+======================================
+
+Contents:
+
+.. toctree::
+
+ whatsnew/index
+ library/index
+ tutorials/index
+ c++/index
+
+
+
+Indices and tables
+==================
+
+* :ref:`genindex`
+* :ref:`search`
diff --git a/doc/source/examples/apt-cdrom.py b/doc/source/examples/apt-cdrom.py
new file mode 100644
index 0000000..13bfb97
--- /dev/null
+++ b/doc/source/examples/apt-cdrom.py
@@ -0,0 +1,79 @@
+#!/usr/bin/python3
+import sys
+
+import apt_pkg
+
+import apt
+
+
+def show_help():
+ print(f"apt {apt_pkg.VERSION} compiled on {apt_pkg.DATE} {apt_pkg.TIME}")
+ if apt_pkg.config.find_b("version"):
+ return 0
+
+ # Copied from apt-cdrom
+ print(
+ "Usage: apt-cdrom [options] command\n"
+ "\n"
+ "apt-cdrom is a tool to add CDROM's to APT's source list. The\n"
+ "CDROM mount point and device information is taken from apt.conf\n"
+ "and /etc/fstab.\n"
+ "\n"
+ "Commands:\n"
+ " add - Add a CDROM\n"
+ " ident - Report the identity of a CDROM\n"
+ "\n"
+ "Options:\n"
+ " -h This help text\n"
+ " -d CD-ROM mount point\n"
+ " -r Rename a recognized CD-ROM\n"
+ " -m No mounting\n"
+ " -f Fast mode, don't check package files\n"
+ " -a Thorough scan mode\n"
+ " -c=? Read this configuration file\n"
+ " -o=? Set an arbitrary configuration option, eg -o "
+ "dir::cache=/tmp\n"
+ "See fstab(5)"
+ )
+ return 0
+
+
+def main(args):
+ arguments = apt_pkg.parse_commandline(
+ apt_pkg.config,
+ [
+ ("h", "help", "help"),
+ ("v", "version", "version"),
+ ("d", "cdrom", "Acquire::cdrom::mount", "HasArg"),
+ ("r", "rename", "APT::CDROM::Rename"),
+ ("m", "no-mount", "APT::CDROM::NoMount"),
+ ("f", "fast", "APT::CDROM::Fast"),
+ ("n", "just-print", "APT::CDROM::NoAct"),
+ ("n", "recon", "APT::CDROM::NoAct"),
+ ("n", "no-act", "APT::CDROM::NoAct"),
+ ("a", "thorough", "APT::CDROM::Thorough"),
+ ("c", "config-file", "", "ConfigFile"),
+ ("o", "option", "", "ArbItem"),
+ ],
+ args,
+ )
+
+ if apt_pkg.config.find_b("help") or apt_pkg.config.find_b("version"):
+ return show_help()
+
+ progress = apt.progress.text.CdromProgress()
+ cdrom = apt_pkg.Cdrom()
+
+ if not arguments:
+ return show_help()
+ elif arguments[0] == "add":
+ cdrom.add(progress)
+ elif arguments[0] == "ident":
+ cdrom.ident(progress)
+ else:
+ sys.stderr.write("E: Invalid operation %s\n" % arguments[0])
+ return 1
+
+
+if __name__ == "__main__":
+ sys.exit(main(sys.argv))
diff --git a/doc/source/examples/cache-packages.py b/doc/source/examples/cache-packages.py
new file mode 100755
index 0000000..14ba85a
--- /dev/null
+++ b/doc/source/examples/cache-packages.py
@@ -0,0 +1,23 @@
+#!/usr/bin/python3
+"""Example for packages. Print all essential and important packages"""
+
+import apt_pkg
+
+
+def main():
+ """Main."""
+ apt_pkg.init_config()
+ apt_pkg.init_system()
+ cache = apt_pkg.Cache()
+ print("Essential packages:")
+ for pkg in cache.packages:
+ if pkg.essential:
+ print(" ", pkg.name)
+ print("Important packages:")
+ for pkg in cache.packages:
+ if pkg.important:
+ print(" ", pkg.name)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/doc/source/examples/cache-pkgfile.py b/doc/source/examples/cache-pkgfile.py
new file mode 100755
index 0000000..4e94a7a
--- /dev/null
+++ b/doc/source/examples/cache-pkgfile.py
@@ -0,0 +1,30 @@
+#!/usr/bin/python3
+import apt_pkg
+
+
+def main():
+ """Example for PackageFile()"""
+ apt_pkg.init()
+ cache = apt_pkg.Cache()
+ for pkgfile in cache.file_list:
+ print("Package-File:", pkgfile.filename)
+ print("Index-Type:", pkgfile.index_type) # 'Debian Package Index'
+ if pkgfile.not_source:
+ print("Source: None")
+ else:
+ if pkgfile.site:
+ # There is a source, and a site, print the site
+ print("Source:", pkgfile.site)
+ else:
+ # It seems to be a local repository
+ print("Source: Local package file")
+ if pkgfile.not_automatic:
+ # The system won't be updated automatically (eg. experimental)
+ print("Automatic: No")
+ else:
+ print("Automatic: Yes")
+ print()
+
+
+if __name__ == "__main__":
+ main()
diff --git a/doc/source/examples/dpkg-contents.py b/doc/source/examples/dpkg-contents.py
new file mode 100755
index 0000000..e6ff620
--- /dev/null
+++ b/doc/source/examples/dpkg-contents.py
@@ -0,0 +1,68 @@
+#!/usr/bin/python3
+"""Emulate dpkg --contents"""
+
+import grp
+import pwd
+import stat
+import sys
+import time
+
+import apt_inst
+
+
+def format_mode(member):
+ """Return the symbolic mode"""
+ mode = member.mode
+ if member.isdir():
+ s_mode = "d"
+ elif member.islnk():
+ s_mode = "h"
+ else:
+ s_mode = "-"
+ s_mode += (mode & stat.S_IRUSR) and "r" or "-"
+ s_mode += (mode & stat.S_IWUSR) and "w" or "-"
+ s_mode += (
+ (mode & stat.S_IXUSR)
+ and (mode & stat.S_ISUID and "s" or "x")
+ or (mode & stat.S_ISUID and "S" or "-")
+ )
+ s_mode += (mode & stat.S_IRGRP) and "r" or "-"
+ s_mode += (mode & stat.S_IWGRP) and "w" or "-"
+ s_mode += (
+ (mode & stat.S_IXGRP)
+ and (mode & stat.S_ISGID and "s" or "x")
+ or (mode & stat.S_ISGID and "S" or "-")
+ )
+ s_mode += (mode & stat.S_IROTH) and "r" or "-"
+ s_mode += (mode & stat.S_IWOTH) and "w" or "-"
+ s_mode += (mode & stat.S_IXOTH) and "x" or "-"
+ return s_mode
+
+
+def callback(member, data):
+ """callback for deb_extract"""
+ s_mode = format_mode(member)
+ s_owner = f"{pwd.getpwuid(member.uid)[0]}/{grp.getgrgid(member.gid)[0]}"
+ s_size = "%9d" % member.size
+ s_time = time.strftime("%Y-%m-%d %H:%M", time.localtime(member.mtime))
+ s_name = member.name if member.name.startswith(".") else ("./" + member.name)
+ if member.islnk():
+ s_name += " link to %s" % member.linkname
+ print(s_mode, s_owner, s_size, s_time, s_name)
+
+
+def main():
+ """Main function"""
+ if len(sys.argv) < 2:
+ print("need filename argumnet", file=sys.stderr)
+ sys.exit(1)
+
+ fobj = open(sys.argv[1])
+ try:
+ apt_inst.DebFile(fobj).data.go(callback)
+ finally:
+ fobj.close()
+
+
+if __name__ == "__main__":
+ main()
diff --git a/doc/source/examples/dpkg-extract.py b/doc/source/examples/dpkg-extract.py
new file mode 100755
index 0000000..02a9fdd
--- /dev/null
+++ b/doc/source/examples/dpkg-extract.py
@@ -0,0 +1,27 @@
+#!/usr/bin/python3
+"""Emulate dpkg --extract package.deb outdir"""
+
+import os
+import sys
+
+import apt_inst
+
+
+def main():
+ """Main function."""
+ if len(sys.argv) < 3:
+ print("Usage: %s package.deb outdir\n" % (__file__), file=sys.stderr)
+ sys.exit(1)
+ if not os.path.exists(sys.argv[2]):
+ print("The directory %s does not exist\n" % (sys.argv[2]), file=sys.stderr)
+ sys.exit(1)
+
+ fobj = open(sys.argv[1])
+ try:
+ apt_inst.DebFile(fobj).data.extractall(sys.argv[2])
+ finally:
+ fobj.close()
+
+
+if __name__ == "__main__":
+ main()
diff --git a/doc/source/examples/dpkg-info.py b/doc/source/examples/dpkg-info.py
new file mode 100755
index 0000000..833c4ed
--- /dev/null
+++ b/doc/source/examples/dpkg-info.py
@@ -0,0 +1,22 @@
+#!/usr/bin/python3
+"""Emulate dpkg --info package.deb control-file"""
+
+import sys
+
+from apt_inst import DebFile
+
+
+def main():
+ """Main function."""
+ if len(sys.argv) < 3:
+ print("Usage: tool file.deb control-file\n", file=sys.stderr)
+ sys.exit(0)
+ fobj = open(sys.argv[1])
+ try:
+ print(DebFile(fobj).control.extractdata(sys.argv[2]))
+ finally:
+ fobj.close()
+
+
+if __name__ == "__main__":
+ main()
diff --git a/doc/source/examples/missing-deps.py b/doc/source/examples/missing-deps.py
new file mode 100755
index 0000000..c3c56b8
--- /dev/null
+++ b/doc/source/examples/missing-deps.py
@@ -0,0 +1,59 @@
+#!/usr/bin/python3
+"""Check the archive for missing dependencies"""
+import apt_pkg
+
+
+def fmt_dep(dep):
+ """Format a Dependency object [of apt_pkg] as a string."""
+ ret = dep.target_pkg.name
+ if dep.target_ver:
+ ret += f" ({dep.comp_type} {dep.target_ver})"
+ return ret
+
+
+def check_version(pkgver):
+ """Check the version of the package"""
+ missing = []
+
+ for or_group in pkgver.depends_list.get(
+ "Pre-Depends", []
+ ) + pkgver.depends_list.get("Depends", []):
+ if not any(dep.all_targets() for dep in or_group):
+ # If none of the or-choices can be satisfied, add it to missing
+ missing.append(or_group)
+
+ if missing:
+ print("Package:", pkgver.parent_pkg.name)
+ print("Version:", pkgver.ver_str)
+ print("Missing:")
+ print(
+ ", ".join(" | ".join(fmt_dep(dep) for dep in or_group))
+ for or_group in missing
+ )
+ print()
+
+
+def main():
+ """The main function."""
+ apt_pkg.init_config()
+ apt_pkg.init_system()
+
+ cache = apt_pkg.Cache()
+
+ for pkg in sorted(cache.packages, key=lambda pkg: pkg.name):
+ # pkg is from a list of packages, sorted by name.
+ for version in pkg.version_list:
+ # Check every version
+ for pfile, _ in version.file_list:
+ if (
+ pfile.origin == "Debian"
+ and pfile.component == "main"
+ and pfile.archive == "unstable"
+ ):
+ # We only want packages from Debian unstable main.
+ check_version(version)
+ break
+
+
+if __name__ == "__main__":
+ main()
diff --git a/doc/source/examples/update-print-uris.py b/doc/source/examples/update-print-uris.py
new file mode 100755
index 0000000..02981f8
--- /dev/null
+++ b/doc/source/examples/update-print-uris.py
@@ -0,0 +1,24 @@
+#!/usr/bin/python3
+"""Print out the URIs of all indexes files.
+
+This behaves somewhat like apt-get --print-uris update."""
+import apt_pkg
+
+
+def main():
+ apt_pkg.init_config()
+ apt_pkg.init_system()
+ acquire = apt_pkg.Acquire()
+ slist = apt_pkg.SourceList()
+ # Read the list
+ slist.read_main_list()
+ # Add all indexes to the fetcher.
+ slist.get_indexes(acquire, True)
+
+ # Now print the URI of every item.
+ for item in acquire.items:
+ print(item.desc_uri)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/doc/source/library/apt.cache.rst b/doc/source/library/apt.cache.rst
new file mode 100644
index 0000000..f85deb2
--- /dev/null
+++ b/doc/source/library/apt.cache.rst
@@ -0,0 +1,83 @@
+:mod:`apt.cache` --- The Cache class
+=====================================
+.. automodule:: apt.cache
+
+The Cache class
+---------------
+
+.. autoclass:: Cache
+ :members:
+ :undoc-members:
+
+ .. describe:: cache[pkgname]
+
+ Return a :class:`Package()` for the package with the name *pkgname*.
+
+Example
+^^^^^^^
+
+The following example shows how to load the cache, update it, and upgrade
+all the packages on the system::
+
+ import apt
+ import apt.progress
+
+ # First of all, open the cache
+ cache = apt.Cache()
+ # Now, lets update the package list
+ cache.update()
+ # We need to re-open the cache because it needs to read the package list
+ cache.open(None)
+ # Now we can do the same as 'apt-get upgrade' does
+ cache.upgrade()
+ # or we can play 'apt-get dist-upgrade'
+ cache.upgrade(True)
+ # Q: Why does nothing happen?
+ # A: You forgot to call commit()!
+ cache.commit(apt.progress.TextFetchProgress(),
+ apt.progress.InstallProgress())
+
+
+
+Working with Filters
+--------------------
+.. autoclass:: Filter
+ :members:
+ :inherited-members:
+ :undoc-members:
+
+.. autoclass:: MarkedChangesFilter
+ :members:
+ :inherited-members:
+ :undoc-members:
+
+.. autoclass:: FilteredCache
+ :members:
+ :inherited-members:
+ :undoc-members:
+
+
+Example
+^^^^^^^
+
+This is an example for a filtered cache, which only allows access to the
+packages whose state has been changed, eg. packages marked for installation::
+
+ >>> from apt.cache import FilteredCache, Cache, MarkedChangesFilter
+ >>> cache = apt.Cache()
+ >>> changed = apt.FilteredCache(cache)
+ >>> changed.set_filter(MarkedChangesFilter())
+ >>> print(len(changed) == len(cache.get_changes())) # Both need to have same length
+ True
+
+The ProblemResolver class
+--------------------------
+
+.. autoclass:: ProblemResolver
+ :members:
+
+Exceptions
+----------
+.. autoexception:: FetchCancelledException
+.. autoexception:: FetchFailedException
+.. autoexception:: LockFailedException
diff --git a/doc/source/library/apt.cdrom.rst b/doc/source/library/apt.cdrom.rst
new file mode 100644
index 0000000..56381f1
--- /dev/null
+++ b/doc/source/library/apt.cdrom.rst
@@ -0,0 +1,7 @@
+:mod:`apt.cdrom` - Functionality like in apt-cdrom
+====================================================
+.. automodule:: apt.cdrom
+ :members:
+
+
+
diff --git a/doc/source/library/apt.debfile.rst b/doc/source/library/apt.debfile.rst
new file mode 100644
index 0000000..7133b5a
--- /dev/null
+++ b/doc/source/library/apt.debfile.rst
@@ -0,0 +1,39 @@
+:mod:`apt.debfile` --- Classes related to debian package files
+==============================================================
+The :mod:`apt.debfile` provides classes to work with locally available
+debian packages, or source packages.
+
+.. module:: apt.debfile
+
+Binary packages
+----------------
+.. autoclass:: DebPackage
+ :members:
+ :inherited-members:
+ :undoc-members:
+
+ The :class:`DebPackage` class is a class for working with '.deb' files,
+ also known as Debian packages.
+
+ It provides methods and attributes to get a list of the files in the
+ package, to install the package and much more.
+
+ If you specify *cache* it has to point to an :class:`apt.cache.Cache()`
+ object.
+
+ .. versionchanged:: 0.7.9
+ Introduce all new methods (everything except for :meth:`open()` and
+ :attr:`filelist`)
+
+
+Source packages
+----------------
+.. autoclass:: DscSrcPackage
+ :members:
+ :inherited-members:
+ :undoc-members:
+
+ Provide functionality to work with locally available source packages,
+ especially with their '.dsc' file.
+
+ .. versionadded:: 0.7.9
diff --git a/doc/source/library/apt.package.rst b/doc/source/library/apt.package.rst
new file mode 100644
index 0000000..ec7ed36
--- /dev/null
+++ b/doc/source/library/apt.package.rst
@@ -0,0 +1,122 @@
+:mod:`apt.package` --- Classes for package handling
+====================================================
+
+
+.. automodule:: apt.package
+
+
+The Package class
+-----------------
+.. autoclass:: Package
+ :members:
+
+ .. note::
+
+ Several methods have been deprecated in version 0.7.9 of python-apt,
+ please see the :class:`Version` class for the new alternatives.
+
+The Version class
+-----------------
+.. autoclass:: Version
+ :members:
+
+
+Dependency Information
+----------------------
+.. autoclass:: BaseDependency
+ :members:
+
+.. class:: Dependency
+
+ The dependency class represents a Or-Group of dependencies. It provides
+ an attribute to access the :class:`BaseDependency` object for the available
+ choices.
+
+ .. attribute:: or_dependencies
+
+ A list of :class:`BaseDependency` objects which could satisfy the
+ requirement of the Or-Group.
+
+
+Origin Information
+-------------------
+.. class:: Origin
+
+ The :class:`Origin` class provides access to the origin of the package.
+ It allows you to check the component, archive, the hostname, and even if
+ this package can be trusted.
+
+ .. attribute:: archive
+
+ The archive (eg. unstable)
+
+ .. attribute:: component
+
+ The component (eg. main)
+
+ .. attribute:: label
+
+ The Label, as set in the Release file
+
+ .. attribute:: origin
+
+ The Origin, as set in the Release file
+
+ .. attribute:: site
+
+ The hostname of the site.
+
+ .. attribute:: trusted
+
+ Boolean value whether this is trustworthy. An origin can be trusted, if
+ it provides a GPG-signed Release file and the GPG-key used is in the
+ keyring used by apt (see apt-key).
+
+
+
+The Record class
+-----------------
+.. autoclass:: Record
+ :members:
+
+ .. note::
+ .. versionchanged:: 0.7.100
+ This class is a subclass of :class:`collections.Mapping` when used
+ in Python 2.6 or newer.
+
+ .. describe:: record[name]
+
+ Return the value of the field with the name *name*.
+
+ .. describe:: name in record
+
+ Return whether a field *name* exists in record.
+
+ .. describe:: len(record)
+
+ The number of fields in the record
+
+ .. describe:: str(record)
+
+ Display the record as a string
+
+
+Examples
+---------
+.. code-block:: python
+
+ import apt
+
+ cache = apt.Cache()
+ pkg = cache['python-apt'] # Access the Package object for python-apt
+ print('python-apt is trusted:', pkg.candidate.origins[0].trusted)
+
+ # Mark python-apt for install
+ pkg.mark_install()
+
+ print('python-apt is marked for install:', pkg.marked_install)
+
+ print('python-apt is (summary):', pkg.candidate.summary)
+
+ # Now, really install it
+ cache.commit()
diff --git a/doc/source/library/apt.progress.base.rst b/doc/source/library/apt.progress.base.rst
new file mode 100644
index 0000000..7d43fe9
--- /dev/null
+++ b/doc/source/library/apt.progress.base.rst
@@ -0,0 +1,335 @@
+:mod:`apt.progress.base` --- Abstract classes for progress reporting
+====================================================================
+.. module:: apt.progress.base
+
+This module provides base classes for progress handlers from which all
+progress classes should inherit from. Progress reporting classes not
+inheriting from those classes may not work and are not supported.
+
+When creating a subclass of one of those classes, all overridden methods should
+call the parent's method first before doing anything else, because the parent
+method may have to set some attributes. Subclasses not doing so may not work
+correctly or may not work at all and are completely unsupported.
+
+AcquireProgress
+---------------
+.. class:: AcquireProgress
+
+ A monitor object for downloads controlled by the Acquire class. This base
+ class does nothing and should only be used as a base class to inherit
+ from. Instances of this class can be passed to the constructor of
+ :class:`apt_pkg.Acquire` and the Acquire object then uses it to report
+ its progress.
+
+ This class provides several methods which may be overridden by subclasses
+ to implement progress reporting:
+
+ .. method:: done(item: apt_pkg.AcquireItemDesc)
+
+ Invoked when an item is successfully and completely fetched.
+
+ .. method:: fail(item: apt_pkg.AcquireItemDesc)
+
+ Invoked when the process of fetching an item encounters a fatal error
+ like a non existing file or no connection to the server.
+
+ .. method:: fetch(item: apt_pkg.AcquireItemDesc)
+
+ Invoked when some of the item's data is fetched. This normally means
+ that the file is being fetched now and e.g. the headers have been
+ retrieved already.
+
+ .. method:: ims_hit(item: apt_pkg.AcquireItemDesc)
+
+ Invoked when an item is confirmed to be up-to-date. For instance,
+ when an HTTP download is informed that the file on the server was
+ not modified.
+
+ .. method:: media_change(media: str, drive: str) -> bool
+
+ Prompt the user to change the inserted removable media. This function
+ is called whenever a media change is needed to ask the user to insert
+ the needed media.
+
+ The parameter *media* decribes the name of the media type that
+ should be changed, whereas the parameter *drive* should be the
+ identifying name of the drive whose media should be changed.
+
+ This method should not return until the user has confirmed to the user
+ interface that the media change is complete. It must return True if
+ the user confirms the media change, or False to cancel it.
+
+ .. method:: pulse(owner: apt_pkg.Acquire) -> bool
+
+ This method gets invoked while the Acquire progress given by the
+ parameter *owner* is underway. It should display information about
+ the current state. It must return ``True`` to continue the acquistion
+ or ``False`` to cancel it. This base implementation always returns
+ ``True``.
+
+ .. method:: start()
+
+ Invoked when the Acquire process starts running.
+
+ .. method:: stop()
+
+ Invoked when the Acquire process stops running.
+
+ In addition to those methods, this class provides several attributes which
+ are set automatically and represent the fetch progress:
+
+ .. attribute:: current_bytes
+
+ The number of bytes fetched.
+
+ .. attribute:: current_cps
+
+ The current rate of download, in bytes per second.
+
+ .. attribute:: current_items
+
+ The number of items that have been successfully downloaded.
+
+ .. attribute:: elapsed_time
+
+ The amount of time that has elapsed since the download started.
+
+ .. attribute:: fetched_bytes
+
+ The total number of bytes accounted for by items that were
+ successfully fetched.
+
+ .. attribute:: last_bytes
+
+ The number of bytes fetched as of the previous call to pulse(),
+ including local items.
+
+ .. attribute:: total_bytes
+
+ The total number of bytes that need to be fetched. This member is
+ inaccurate, as new items might be enqueued while the download is
+ in progress!
+
+ .. attribute:: total_items
+
+ The total number of items that need to be fetched. This member is
+ inaccurate, as new items might be enqueued while the download is
+ in progress!
+
+
+CdromProgress
+-------------
+.. class:: CdromProgress
+
+ Base class for reporting the progress of adding a cdrom which could be
+ used with apt_pkg.Cdrom to produce an utility like apt-cdrom.
+
+ Methods defined here:
+
+ .. method:: ask_cdrom_name() -> str
+
+ Ask for the name of the cdrom. This method is called when a CD-ROM
+ is added (e.g. via :meth:`apt_pkg.Cdrom.add`) and no label for the
+ CD-ROM can be found.
+
+ Implementations should request a label from the user (e.g. via
+ :func:`raw_input`) and return this label from the function. The
+ operation can be cancelled if the function returns ``None`` instead
+ of a string.
+
+ .. method:: change_cdrom() -> bool
+
+ Ask for the CD-ROM to be changed. This method should return ``True``
+ if the CD-ROM has been changed or ``False`` if the CD-ROM has not been
+ changed and the operation should be cancelled. This base implementation
+ returns ``False`` and thus cancels the operation.
+
+ .. method:: update(text: str, current: int)
+
+ Periodically invoked in order to update the interface and give
+ information about the progress of the operation.
+
+ This method has two parameters. The first parameter *text* defines
+ the text which should be displayed to the user as the progress
+ message. The second parameter *current* is an integer describing how
+ many steps have been completed already.
+
+ .. attribute:: total_steps
+
+ The number of total steps, set automatically by python-apt. It may be
+ used in conjunction with the parameter *current* of the :meth:`update`
+ method to show how far the operation progressed.
+
+
+OpProgress
+----------
+.. class:: OpProgress
+
+ OpProgress classes are used for reporting the progress of operations
+ such as opening the cache. It is based on the concept of one operation
+ consisting of a series of sub operations.
+
+ Methods defined here:
+
+ .. method:: done()
+
+ Called once an operation has been completed.
+
+ .. method:: update([percent=None])
+
+ Called periodically to update the user interface. This function should
+ use the attributes defined below to display the progress information.
+
+ The optional parameter *percent* is included for compatibility
+ reasons and may be removed at a later time.
+
+ The following attributes are available and are changed by the classes
+ wanting to emit progress:
+
+ .. attribute:: major_change
+
+ An automatically set boolean value describing whether the current call
+ to update is caused by a major change. In this case, the last operation
+ has finished.
+
+ .. attribute:: op
+
+ An automatically set string which describes the current operation in
+ an human-readable way.
+
+ .. attribute:: percent
+
+ An automatically set float value describing how much of the operation
+ has been completed, in percent.
+
+ .. attribute:: subop
+
+ An automatically set string which describes the current sub-operation
+ in an human-readable way.
+
+
+InstallProgress
+---------------
+.. class:: InstallProgress
+
+ InstallProgress classes make it possible to monitor the progress of dpkg
+ and APT and emit information at certain stages. It uses file descriptors
+ to read the status lines from APT/dpkg and parses them and afterwards calls
+ the callback methods.
+
+ Subclasses should override the following methods in order to implement
+ progress reporting:
+
+ .. method:: conffile(current, new)
+
+ Called when a conffile question from dpkg is detected.
+
+ .. note::
+
+ This part of the API is semi-stable and may be extended with 2 more
+ parameters before the release of 0.7.100.
+
+ .. method:: error(pkg, errormsg)
+
+ (Abstract) Called when a error is detected during the install.
+
+ The following method should be overridden to implement progress reporting
+ for dpkg-based runs i.e. calls to :meth:`run` with a filename:
+
+ .. method:: processing(pkg, stage)
+
+ This method is called just before a processing stage starts. The
+ parameter *pkg* is the name of the package and the parameter *stage*
+ is one of the stages listed in the dpkg manual under the status-fd
+ option, i.e. "upgrade", "install" (both sent before unpacking),
+ "configure", "trigproc", "remove", "purge".
+
+ .. method:: dpkg_status_change(pkg: str, status: str)
+
+ This method is called whenever the dpkg status of the package
+ changes. The parameter *pkg* is the name of the package and the
+ parameter *status* is one of the status strings used in the status
+ file (:file:`/var/lib/dpkg/status`) and documented
+ in :manpage:`dpkg(1)`.
+
+ The following methods should be overridden to implement progress reporting
+ for :meth:`run` calls with an :class:`apt_pkg.PackageManager` object as
+ their parameter:
+
+ .. method:: status_change(pkg, percent, status)
+
+ This method implements progress reporting for package installation by
+ APT and may be extended to dpkg at a later time.
+
+ This method takes two parameters: The parameter *percent* is a float
+ value describing the overall progress and the parameter *status* is a
+ string describing the current status in an human-readable manner.
+
+ .. method:: start_update()
+
+ This method is called before the installation of any package starts.
+
+ .. method:: finish_update()
+
+ This method is called when all changes have been applied.
+
+ There are also several methods which are fully implemented and should not
+ be overridden by subclasses unless the subclass has very special needs:
+
+ .. method:: fork() -> int
+
+ Fork a child process and return 0 to the child process and the PID of
+ the child to the parent process. This implementation just calls
+ :func:`os.fork` and returns its value.
+
+ .. method:: run(obj)
+
+ This method runs install actions. The parameter *obj* may either
+ be a PackageManager object in which case its **do_install()** method is
+ called or the path to a deb file.
+
+ If the object is a :class:`apt_pkg.PackageManager`, the functions
+ returns the result of calling its ``do_install()`` method. Otherwise,
+ the function returns the exit status of dpkg. In both cases, ``0``
+ means that there were no problems and ``!= 0`` means that there were
+ issues.
+
+ .. method:: update_interface()
+
+ This method is responsible for reading the status from dpkg/APT and
+ calling the correct callback methods. Subclasses should not override
+ this method.
+
+ .. method:: wait_child()
+
+ This method is responsible for calling :meth:`update_interface` from
+ time to time. It exits once the child has exited. The return value
+ is the full status returned by :func:`os.waitpid` (not only the
+ return code). Subclasses should not override this method.
+
+ The class also provides several attributes which may be useful:
+
+ .. attribute:: percent
+
+ The percentage of completion as it was in the last call to
+ :meth:`status_change`.
+
+ .. attribute:: status
+
+ The status string passed in the last call to :meth:`status_change`.
+
+ .. attribute:: select_timeout
+
+ Used in :meth:`wait_child` to when calling :func:`select.select`
+ on dpkg's/APT's status descriptor. Subclasses may set their own value
+ if needed.
+
+ .. attribute:: statusfd
+
+ A readable :class:`file` object from which the status information from
+ APT or dpkg is read.
+
+ .. attribute:: writefd
+
+ A writable :class:`file` object to which dpkg or APT write their status
+ information.
diff --git a/doc/source/library/apt.progress.text.rst b/doc/source/library/apt.progress.text.rst
new file mode 100644
index 0000000..4e051e3
--- /dev/null
+++ b/doc/source/library/apt.progress.text.rst
@@ -0,0 +1,21 @@
+:mod:`apt.progress.text` --- Progress reporting for text interfaces
+===================================================================
+.. automodule:: apt.progress.text
+
+
+Acquire Progress Reporting
+--------------------------
+.. autoclass:: AcquireProgress
+ :members:
+
+
+CD-ROM Progress Reporting
+--------------------------
+.. autoclass:: CdromProgress
+ :members:
+
+Operation Progress Reporting
+-----------------------------
+.. autoclass:: OpProgress
+ :members:
+
diff --git a/doc/source/library/apt_inst.rst b/doc/source/library/apt_inst.rst
new file mode 100644
index 0000000..6ba330a
--- /dev/null
+++ b/doc/source/library/apt_inst.rst
@@ -0,0 +1,323 @@
+:mod:`apt_inst` - Working with local Debian packages
+====================================================
+.. module:: apt_inst
+
+This module provides useful classes and functions to work with archives,
+modelled after the :class:`tarfile.TarFile` class. For working with Debian
+packages, the :class:`DebFile` class should be used as it provides easy access
+to the control.tar.* and data.tar.* members.
+
+The classes are mostly modeled after the :class:`tarfile.TarFile` class and
+enhanced with APT-specific methods. Because APT only provides a stream based
+view on a tar archive, this module's :class:`TarFile` class only provides a
+very small subset of those functions.
+
+Exceptions
+----------
+
+.. class:: Error
+
+ This is the same class as :class:`apt_pkg.Error`, provided here for
+ convenience.
+
+AR Archives
+-----------
+.. class:: ArArchive(file)
+
+ An ArArchive object represents an archive in the 4.4 BSD AR format,
+ which is used for e.g. deb packages.
+
+ The parameter *file* may be a string specifying the path of a file, or
+ a :class:`file`-like object providing the :meth:`fileno` method. It may
+ also be an int specifying a file descriptor (returned by e.g.
+ :func:`os.open`). The recommended way is to pass in the path to the file.
+
+ ArArchive (and its subclasses) support the iterator protocol, meaning that
+ an :class:`ArArchive` object can be iterated over yielding the members in
+ the archive (same as :meth:`getmembers`).
+
+ .. describe:: archive[key]
+
+ Return a ArMember object for the member given by *key*. Raise
+ LookupError if there is no ArMember with the given name.
+
+ .. describe:: key in archive
+
+ Return True if a member with the name *key* is found in the archive, it
+ is the same function as :meth:`getmember`.
+
+ .. method:: extract(name[, target: str]) -> bool
+
+ Extract the member given by *name* into the directory given by
+ *target*. If the extraction failed, an error is raised. Otherwise,
+ the method returns True if the owner could be set or False if the
+ owner could not be changed. It may also raise LookupError if there
+ is no member with the given name.
+
+ The parameter *target* is completely optional. If it is not given, the
+ function extracts into the current directory.
+
+ .. method:: extractall([target: str]) -> bool
+
+ Extract all into the directory given by target or the current
+ directory if target is not given. If the extraction failed, an error
+ is raised. Otherwise, the method returns True if the owner could be
+ set or False if the owner could not be changed.
+
+ .. method:: extractdata(name: str) -> bytes
+
+ Return the contents of the member given by *name*, as a bytes object.
+ Raise LookupError if there is no ArMember with the given name.
+
+ .. method:: getmember(name: str) -> ArMember
+
+ Return a ArMember object for the member given by *name*. Raise
+ LookupError if there is no ArMember with the given name.
+
+ .. method:: getmembers() -> list
+
+ Return a list of all members in the AR archive.
+
+ .. method:: getnames() -> list
+
+ Return a list of the names of all members in the AR archive.
+
+ .. method:: gettar(name: str, comp: str) -> TarFile
+
+ Return a TarFile object for the member given by *name* which will be
+ decompressed using the compression algorithm given by *comp*.
+ This is almost equal to::
+
+ member = arfile.getmember(name)
+ tarfile = TarFile(file, member.start, member.size, 'gzip')'
+
+ It just opens a new TarFile on the given position in the stream.
+
+.. class:: ArMember
+
+ An ArMember object represents a single file within an AR archive. For
+ Debian packages this can be e.g. control.tar.gz. This class provides
+ information about this file, such as the mode and size. It has no
+ constructor.
+
+ .. attribute:: gid
+
+ The group id of the owner.
+
+ .. attribute:: mode
+
+ The mode of the file.
+
+ .. attribute:: mtime
+
+ Last time of modification.
+
+ .. attribute:: name
+
+ The name of the file.
+
+ .. attribute:: size
+
+ The size of the files.
+
+ .. attribute:: start
+
+ The offset in the archive where the file starts.
+
+ .. attribute:: uid
+
+ The user id of the owner.
+
+Debian Packages
+---------------
+.. class:: DebFile(file)
+
+ A DebFile object represents a file in the .deb package format. It inherits
+ :class:`ArArchive`. In addition to the attributes and methods from
+ :class:`ArArchive`, DebFile provides the following methods:
+
+ .. attribute:: control
+
+ The :class:`TarFile` object associated with the control.tar.gz member.
+
+ .. attribute:: data
+
+ The :class:`TarFile` object associated with the
+ data.tar.{gz,bz2,lzma,xz} member.
+
+ .. attribute:: debian_binary
+
+ The package version, as contained in debian-binary.
+
+Tar Archives
+-------------
+.. class:: TarFile(file[, min: int, max: int, comp: str])
+
+ A TarFile object represents a single .tar file stream.
+
+ The parameter *file* may be a string specifying the path of a file, or
+ a :class:`file`-like object providing the :meth:`fileno` method. It may
+ also be an int specifying a file descriptor (returned by e.g.
+ :func:`os.open`).
+
+ The parameter *min* describes the offset in the file where the archive
+ begins and the parameter *max* is the size of the archive.
+
+ The compression of the archive is set by the parameter *comp*. It can
+ be set to any program supporting the -d switch, the default being gzip.
+
+ .. method:: extractall([rootdir: str]) -> True
+
+ Extract the archive in the current directory. The argument *rootdir*
+ can be used to change the target directory.
+
+ .. method:: extractdata(member: str) -> bytes
+
+ Return the contents of the member, as a bytes object. Raise
+ LookupError if there is no member with the given name.
+
+ .. method:: go(callback: callable[, member: str]) -> True
+
+ Go through the archive and call the callable *callback* for each
+ member with 2 arguments. The first argument is the :class:`TarMember`
+ and the second one is the data, as bytes.
+
+ The optional parameter *member* can be used to specify the member for
+ which call the callback. If not specified, it will be called for all
+ members. If specified and not found, LookupError will be raised.
+
+.. class:: TarMember
+
+ Represent a single member of a 'tar' archive.
+
+ This class which has been modelled after :class:`tarfile.TarInfo`
+ represents information about a given member in an archive.
+
+ .. method:: isblk()
+
+ Determine whether the member is a block device.
+
+ .. method:: ischr()
+
+ Determine whether the member is a character device.
+
+ .. method:: isdev()
+
+ Determine whether the member is a device (block,character or FIFO).
+
+ .. method:: isdir()
+
+ Determine whether the member is a directory.
+
+ .. method:: isfifo()
+
+ Determine whether the member is a FIFO.
+
+ .. method:: isfile()
+
+ Determine whether the member is a regular file.
+
+ .. method:: islnk()
+
+ Determine whether the member is a hardlink.
+
+ .. method:: isreg()
+
+ Determine whether the member is a regular file, same as isfile().
+
+ .. method:: issym()
+
+ Determine whether the member is a symbolic link.
+
+ .. attribute:: gid
+
+ The owner's group id
+
+ .. attribute:: linkname
+
+ The target of the link.
+
+ .. attribute:: major
+
+ The major ID of the device.
+
+ .. attribute:: minor
+
+ The minor ID of the device.
+
+ .. attribute:: mode
+
+ The mode (permissions).
+
+ .. attribute:: mtime
+
+ Last time of modification.
+
+ .. attribute:: name
+
+ The name of the file.
+
+ .. attribute:: size
+
+ The size of the file.
+
+ .. attribute:: uid
+
+ The owner's user id.
+
+
+
+Removed functions
+---------------------
+The following functions have been removed in python-apt 0.8.
+They are listed here to help developers port their applications to the new
+API which is completely different. For this purpose each function documentation
+includes an example showing how the function can be replaced.
+
+.. function:: arCheckMember(file, membername)
+
+ This function has been replaced by using the :keyword:`in` check on an
+ :class:`ArArchive` object::
+
+ member in ArArchive(file)
+
+.. function:: debExtract(file, func, chunk)
+
+ This function has been replaced by the :meth:`TarFile.go`
+ method. The following example shows the old code and the new code::
+
+ debExtract(open("package.deb"), my_callback, "data.tar.gz") #old
+
+ DebFile("package.deb").data.go(my_callback)
+
+ Please note that the signature of the callback is different in
+ :meth:`TarFile.go`.
+
+.. function:: tarExtract(file,func,comp)
+
+ This function has been replaced by the :meth:`TarFile.go`
+ method. The following example shows the old code and the new code::
+
+ tarExtract(open("archive.tar.gz"), my_callback, "gzip") #old
+ TarFile("archive.tar.gz", 0, 0, "gzip").go(my_callback)
+
+ Please note that the signature of the callback is different in
+ :meth:`TarFile.go`, it now expects a :class:`TarMember` and a bytestring
+ of the data.
+
+.. function:: debExtractArchive(file, rootdir)
+
+ This function has been replaced by :meth:`TarFile.extractall` and
+ :attr:`DebFile.data`::
+
+ debExtractArchive(open("package.deb"), rootdir) # old
+ DebFile("package.deb").data.extractall(rootdir) # new
+
+.. function:: debExtractControl(file[, member='control'])
+
+ This function has been replaced by :attr:`DebFile.control` and
+ :meth:`TarFile.extractdata`. In the following example, both commands
+ return the contents of the control file::
+
+ debExtractControl(open("package.deb"))
+ DebFile("package.deb").control.extractdata("control")
diff --git a/doc/source/library/apt_pkg.rst b/doc/source/library/apt_pkg.rst
new file mode 100644
index 0000000..4290180
--- /dev/null
+++ b/doc/source/library/apt_pkg.rst
@@ -0,0 +1,2904 @@
+:mod:`apt_pkg` --- The low-level bindings for apt-pkg
+=====================================================
+.. module:: apt_pkg
+
+The apt_pkg extensions provides a more low-level way to work with apt. It can
+do everything apt can, and is written in C++. It has been in python-apt since
+the beginning.
+
+Module Initialization
+---------------------
+
+Initialization is needed for most functions, but not for all of them. Some can
+be called without having run init*(), but will not return the expected value.
+
+.. function:: init_config
+
+ Initialize the configuration of apt. This is needed for most operations.
+
+.. function:: init_system
+
+ Initialize the system.
+
+.. function:: init
+
+ A short cut to calling :func:`init_config` and :func:`init_system`. You
+ can use this if you do not use the command line parsing facilities provided
+ by :func:`parse_commandline`, otherwise call :func:`init_config`, parse
+ the commandline afterwards and finally call :func:`init_system`.
+
+
+Exceptions
+----------
+.. autoclass:: Error
+
+.. autoclass:: CacheMismatchError
+
+
+Working with the cache
+----------------------
+.. class:: Cache([progress: apt.progress.base.OpProgress])
+
+ A Cache object represents the cache used by APT which contains information
+ about packages. The object itself provides no means to modify the cache or
+ the installed packages, see the classes :class:`DepCache` and
+ :class:`PackageManager` for such functionality.
+
+ The constructor takes an optional argument which must be a subclass of
+ :class:`apt.progress.base.OpProgress`. This object will then be used to
+ display information during the cache opening process (or possible creation
+ of the cache). It may also be ``None``, in which case no progress will
+ be emitted. If not given, progress will be printed to standard output.
+
+ .. note::
+
+ The cache supports colon-separated name:architecture pairs. For
+ normal architectures, they are equal to a (name, architecture)
+ tuple. For the "any" architecture behavior is different, as
+ "name:any" is equivalent to ("name:any", "any"). This is done so
+ that "name:any" matches all packages with that name which have
+ Multi-Arch: allowed set.
+
+ .. describe:: cache[pkgname]
+
+ Return the :class:`Package()` object for the package name given by
+ *pkgname*. If *pkgname* includes a colon, the part after the colon
+ is used as the architecture.
+
+ .. describe:: cache[name, architecture]
+
+ Return the :class:`Package()` object for the package with the given
+ name and architecture.
+
+ .. versionadded: 0.8.0
+
+ .. describe:: pkgname in cache
+
+ Check whether a package with the name given by *pkgname* exists in
+ the cache for the native architecture. If *pkgname* includes a
+ colon, the part after the colon is used as the architecture.
+
+ .. describe:: (name, architecture) in cache
+
+ Check whether a package with the given name and architecture exists
+ in the cache.
+
+ .. versionadded: 0.8.0
+
+ .. method:: update(progress, sources [, pulse_interval]) -> bool
+
+ Update the index files used by the cache. A call to this method
+ does not affect the current Cache object, instead a new one
+ should be created in order to use the changed index files.
+
+ The parameter *progress* takes an
+ :class:`apt.progress.base.AcquireProgress` object which will display
+ the progress of fetching the index files. The parameter *sources* takes
+ a :class:`SourceList` object which lists the sources. The parameter
+ *progress* takes an integer describing the interval (in microseconds)
+ in which the pulse() method of the *progress* object will be called.
+
+ .. attribute:: depends_count
+
+ The total number of dependencies stored in the cache.
+
+ .. attribute:: file_list
+
+ A list of all :class:`PackageFile` objects stored in the cache.
+
+ .. attribute:: group_count
+
+ The number of groups in the cache.
+
+ .. versionadded: 0.8.0
+
+ .. attribute:: groups
+
+ A sequence of :class:`Group` objects, implemented as a
+ :class:`GroupList` object.
+
+ .. versionadded: 0.8.0
+
+ .. class:: GroupList
+
+ A simple sequence-like object which only provides a length and
+ an implementation of ``__getitem__`` for accessing groups at
+ a certain index. Apart from being iterable, it can be used in
+ the following ways:
+
+ .. versionadded: 0.8.0
+
+ .. describe:: list[index]
+
+ Get the :class:`Group` object for the group at the position
+ given by *index* in the GroupList *list*.
+
+ .. describe:: len(list)
+
+ Return the length of the GroupList object *list*.
+
+
+ .. attribute:: is_multi_arch
+
+ An attribute determining whether the cache supports multi-arch.
+
+ .. versionadded: 0.8.0
+
+ .. attribute:: package_count
+
+ The total number of packages available in the cache. This value is
+ equal to the length of the list provided by the :attr:`packages`
+ attribute.
+
+ .. attribute:: package_file_count
+
+ The total number of Packages files available (the Packages files
+ listing the packages). This is the same as the length of the list in
+ the attribute :attr:`file_list`.
+
+ .. attribute:: packages
+
+ A sequence of :class:`Package` objects, implemented as a
+ :class:`PackageList` object.
+
+ .. class:: PackageList
+
+ A simple sequence-like object which only provides a length and
+ an implementation of ``__getitem__`` for accessing packages at
+ a certain index. Apart from being iterable, it can be used in
+ the following ways:
+
+ .. describe:: list[index]
+
+ Get the :class:`Package` object for the package at the position
+ given by *index* in the PackageList *list*.
+
+ .. describe:: len(list)
+
+ Return the length of the PackageList object *list*.
+
+ .. attribute:: provides_count
+
+ The number of provided packages.
+
+ .. attribute:: ver_file_count
+
+ The total number of ``(Version, PackageFile)`` relations stored in
+ the cache.
+
+ .. attribute:: version_count
+
+ The total number of package versions available in the cache.
+
+Managing the cache with :class:`DepCache`
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+.. class:: DepCache(cache: apt_pkg.Cache)
+
+ A DepCache object provides access to more information about the
+ objects made available by the :class:`Cache` object as well as
+ means to mark packages for removal and installation, among other
+ actions.
+
+ The constructor takes a single argument which specifies the
+ :class:`Cache` object the new object shall be related to. While
+ it is theoretically possible to create multiple DepCache objects
+ for the same cache, they will not be independent from each other
+ since they all access the same underlying C++ object.
+
+ Objects of this type provide several methods. Most of those methods
+ are safe to use and should never raise any exception (all those
+ methods for requesting state information or marking changes). If a
+ method is expected to raise an exception, it will be stated in the
+ description.
+
+ If an object of a different cache is passed, :class:`CacheMismatchError`
+ is raised.
+
+ .. method:: commit(acquire_progress, install_progress)
+
+ Commit all marked changes, while reporting the progress of
+ fetching packages via the :class:`apt.progress.base.AcquireProgress`
+ object given by *acquire_progress* and reporting the installation
+ of the package using the :class:`apt.progress.base.InstallProgress`
+ object given by *install_progress*.
+
+ If this fails, an exception of the type :exc:`SystemError` will
+ be raised.
+
+ .. method:: fix_broken() -> bool
+
+ Try to fix all broken packages in the cache and return ``True`` in
+ case of success. If an error occurred, a :exc:`SystemError`
+ exception is raised.
+
+ .. method:: get_candidate_ver(pkg: Package) -> Version
+
+ Return the candidate version for the package given by the parameter
+ *pkg* as a :class:`Version` object. The default candidate for a
+ package is the version with the highest pin, although a different
+ one may be set using :meth:`set_candidate_ver`. If no candidate
+ can be found, return ``None`` instead.
+
+ .. method:: init(progress: apt.progress.base.OpProgress)
+
+ Initialize the DepCache. This is done automatically when the
+ cache is opened, but sometimes it may be useful to reinitialize
+ the DepCache. Like the constructor of :class:`Cache`, this
+ function takes a single :class:`apt.progress.base.OpProgress`
+ object to display progress information.
+
+ .. method:: read_pinfile(file: str)
+
+ A proxy function which calls the method :meth:`Policy.read_pinfile` of
+ the :class:`Policy` object used by this object. This method raises
+ a :exc:`SystemError` exception if the file could not be parsed.
+
+ .. method:: set_candidate_ver(pkg: Package, version: Version) -> bool
+
+ Set the candidate version of the package given by the :class:`Package`
+ object *pkg* to the version given by the :class:`Version` object
+ *version* and return ``True``. If odd things happen, this function
+ may raise a :exc:`SystemError` exception, but this should not
+ happen in normal usage. See :meth:`get_candidate_ver` for a way
+ to retrieve the candidate version of a package.
+
+ .. method:: upgrade([dist_upgrade=False]) -> bool
+
+ Mark the packages for upgrade under the same conditions
+ :program:`apt-get` does. If *dist_upgrade* is ``True``, also
+ allow packages to be upgraded if they require installation/removal
+ of other packages; just like apt-get dist-upgrade.
+
+ Despite returning a boolean value, this raises :exc:`SystemError` and
+ does not return ``False`` if an error occurred.
+
+ The following methods can mark a single package for installation,
+ removal, etc:
+
+ .. method:: mark_auto(pkg: Package)
+
+ Mark the :class:`Package` *pkg* as automatically installed.
+
+ .. method:: mark_keep(pkg: Package)
+
+ Mark the :class:`Package` *pkg* for keep.
+
+ .. method:: mark_delete(pkg: Package[, purge])
+
+ Mark the :class:`Package` *pkg* for delete. If *purge* is True,
+ the configuration files will be removed as well.
+
+ .. method:: mark_install(pkg: Package[, auto_inst=True[, from_user=True]])
+
+ Mark the :class:`Package` *pkg* for install, and, if *auto_inst*
+ is ``True``, its dependencies as well. If *from_user* is ``True``,
+ the package will **not** be marked as automatically installed.
+
+ .. method:: set_reinstall(pkg: Package)
+
+ Set if the :class:`Package` *pkg* should be reinstalled.
+
+ The following methods can be used to check the state of a package:
+
+ .. method:: is_auto_installed(pkg: Package) -> bool
+
+ Return ``True`` if the package is automatically installed, that
+ is, as a dependency of another package.
+
+ .. method:: is_garbage(pkg: Package) -> bool
+
+ Return ``True`` if the package is garbage, that is, if it was
+ automatically installed and no longer referenced by other packages.
+
+ .. method:: is_inst_broken(pkg: Package) -> bool
+
+ Return ``True`` if the package is broken on the current install. This
+ takes changes which have not been marked not into account.
+
+ .. method:: is_now_broken(pkg: Package) -> bool
+
+ Return ``True`` if the package is now broken, that is, if the package
+ is broken if the marked changes are applied.
+
+ .. method:: is_upgradable(pkg: Package) -> bool
+
+ Return ``True`` if the package is upgradable, the package can then
+ be marked for upgrade by calling the method :meth:`mark_install`.
+
+ .. method:: marked_delete(pkg: Package) -> bool
+
+ Return ``True`` if the package is marked for delete.
+
+ .. method:: marked_downgrade(pkg: Package) -> bool
+
+ Return ``True`` if the package should be downgraded.
+
+ .. method:: marked_install(pkg: Package) -> bool
+
+ Return ``True`` if the package is marked for install.
+
+ .. method:: marked_keep(pkg: Package) -> bool
+
+ Return ``True`` if the package is marked for keep.
+
+ .. method:: marked_reinstall(pkg: Package) -> bool
+
+ Return ``True`` if the package should be reinstalled.
+
+ .. method:: marked_upgrade(pkg: Package) -> bool
+
+ Return ``True`` if the package is marked for upgrade.
+
+ .. method:: phasing_applied(pkg: Package) -> bool
+
+ Return ``True`` if the package update is being phased.
+
+ DepCache objects also provide several attributes containing information
+ on the marked changes:
+
+ .. attribute:: keep_count
+
+ Integer, number of packages marked as keep
+
+ .. attribute:: inst_count
+
+ Integer, number of packages marked for installation.
+
+ .. attribute:: del_count
+
+ Number of packages which should be removed.
+
+ .. attribute:: broken_count
+
+ Number of packages which are broken.
+
+ .. attribute:: usr_size
+
+ The size required for the changes on the filesystem. If you install
+ packages, this is positive, if you remove them its negative.
+
+ .. attribute:: deb_size
+
+ The size of the packages which are needed for the changes to be
+ applied.
+
+ .. attribute:: policy
+
+ The underlying :class:`Policy` object used by the :class:`DepCache` to
+ select candidate versions.
+
+Installing with :class:`PackageManager`
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. class:: PackageManager(depcache)
+
+ Abstraction of a package manager. This object takes care of retrieving
+ packages, ordering the installation, and calling the package manager to
+ do the actual installation.
+
+ .. method:: get_archives(fetcher, list, records) -> bool
+
+ Add all packages marked for installation (or upgrade, anything
+ which needs a download) to the :class:`Acquire` object referenced
+ by *fetcher*.
+
+ The parameter *list* specifies a :class:`SourceList` object which
+ is used to retrieve the information about the archive URI for the
+ packages which will be fetched.
+
+ The parameter *records* takes a :class:`PackageRecords` object which
+ will be used to look up the file name of the package.
+
+ .. method:: do_install(status_fd: int) -> int
+
+ Install the packages and return one of the class constants
+ :attr:`RESULT_COMPLETED`, :attr:`RESULT_FAILED`,
+ :attr:`RESULT_INCOMPLETE`. The argument *status_fd* can be used
+ to specify a file descriptor that APT will write status information
+ on (see README.progress-reporting in the apt source code for
+ information on what will be written there).
+
+ .. method:: fix_missing() -> bool
+
+ Fix the installation if a package could not be downloaded.
+
+ .. attribute:: RESULT_COMPLETED
+
+ A constant for checking whether the result of the call to
+ :meth:`do_install` is 'failed'.
+
+ .. attribute:: RESULT_FAILED
+
+ A constant for checking whether the result of the call to
+ :meth:`do_install` is 'failed'.
+
+ .. attribute:: RESULT_INCOMPLETE
+
+ A constant for checking whether the result of the call to
+ :meth:`do_install` is 'incomplete'.
+
+ All instances of this class also support the following methods:
+
+ .. note::
+
+ This methods are provided mainly for subclassing purposes
+ and should not be used in most programs. This class is a
+ subclass of an internal :class:`_PackageManager` which does
+ not provide that methods. As the public C++ API creates such
+ an object without those methods, you should not rely on those
+ methods to be available unless you used the constructor of
+ :class:`PackageManager` to create the object.
+
+ .. method:: configure(pkg: Package) -> bool
+
+ Notify the package manager that the :class:`Package` given
+ by *pkg* is to be configured. Must return a ``True`` value
+ or ``None`` to continue, or a value which is ``False`` if
+ evaluated as boolean to abort.
+
+ .. versionadded:: 0.8.0
+
+ .. method:: install(pkg: Package, filename: str) -> bool
+
+ Notify the package manager that the :class:`Package` given
+ by *pkg* is to be installed from the .deb located at
+ *filename*. Must return a ``True`` value or ``None`` to
+ continue, or a value which is ``False`` if evaluated as
+ boolean to abort.
+
+
+ .. versionadded:: 0.8.0
+
+ .. method:: remove(pkg: Package, purge: bool) -> bool
+
+ Notify the package manager that the :class:`Package` given
+ by *pkg* is to be removed. If *purge* is ``True``, the package
+ shall be purged. Must return a ``True`` value or ``None`` to
+ continue, or a value which is ``False`` if evaluated as boolean
+ to abort.
+
+
+ .. versionadded:: 0.8.0
+
+ .. method:: go(status_fd: int) -> bool
+
+ Start dpkg, writing status information to the file descriptor
+ given by *status_fd*. Must return a ``True`` value or ``None`` to
+ continue, or a value which is ``False`` if evaluated as boolean
+ to abort.
+
+ .. versionadded:: 0.8.0
+
+ .. method:: reset()
+
+ Reset the package manager for a new round.
+
+ .. versionadded:: 0.8.0
+
+
+Installation ordering with :class:`OrderList`
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. class:: OrderList(depcache: DepCache)
+
+ Represent a :c:type:`pkgOrderList`, used for installation
+ ordering. This class provides several methods and attributes,
+ is complicated and should not be used by normal programs.
+
+ .. versionadded:: 0.8.0
+
+ This class is a sequence and supports the following operations:
+
+ .. describe:: list[index]
+
+ Get the package at the given index in the list. Negative
+ index is supported.
+
+ .. describe:: len(list)
+
+ The length of the list.
+
+ It also supports the append() method from :class:`list`:
+
+ .. method:: append(pkg: Package)
+
+ Append a new package to the end of the list. Please note that
+ you may not append a package twice, as only as much packages
+ as in the cache can be added.
+
+ The class also defines several specific attributes and methods,
+ to be described hereinafter.
+
+ .. method:: score(pkg: Package)
+
+ Return the score of the package. Packages are basically
+ ordered by descending score.
+
+ This class allows flags to be set on packages. Those flags are:
+
+ .. attribute:: FLAG_ADDED
+ .. attribute:: FLAG_ADD_PENDING
+ .. attribute:: FLAG_IMMEDIATE
+ .. attribute:: FLAG_LOOP
+ .. attribute:: FLAG_UNPACKED
+ .. attribute:: FLAG_CONFIGURED
+ .. attribute:: FLAG_REMOVED
+ .. attribute:: FLAG_STATES_MASK
+
+ Same as ``FLAG_UNPACKED | FLAG_CONFIGURED | FLAG_REMOVED``
+
+ .. attribute:: FLAG_IN_LIST
+ .. attribute:: FLAG_AFTER
+
+ The methods to work with those flags are:
+
+ .. method:: flag(pkg: Package, flag: int[, unset_flags: int])
+
+ Flag a package. Sets the flags given in *flag* and unsets
+ any flags given in *unset_flags*.
+
+ .. method:: is_flag(pkg: Package, flag: int)
+
+ Check whether the flags in *flag* are set for the package.
+
+ .. method:: wipe_flags(flags: int)
+
+ Remove the flags in *flags* from all packages.
+
+ .. method:: is_missing(pkg: Package)
+
+ Check if the package is missing (not really usable right now)
+
+ .. method:: is_now(pkg: Package)
+
+ Check if the package is flagged for any state but removal.
+
+ The following methods for ordering are provided:
+
+ .. method:: order_critical()
+
+ Order the packages for critical unpacking; that is, only
+ respect pre-dependencies.
+
+ .. method:: order_unpack()
+
+ Order the packages for unpacking, repecting Pre-Depends and
+ Conflicts.
+
+ .. method:: order_configure()
+
+ Order the packages for configuration, respecting Depends.
+
+Improve performance with :class:`ActionGroup`
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+.. class:: ActionGroup(depcache)
+
+ Create a new :class:`ActionGroup()` object for the :class:`DepCache` object
+ given by the parameter *depcache*.
+
+ :class:`ActionGroup()` objects make operations on the cache faster by
+ delaying certain cleanup operations until the action group is released.
+
+ An action group is also a context manager and therefore supports the
+ :keyword:`with` statement. But because it becomes active as soon as it
+ is created, you should not create an ActionGroup() object before entering
+ the with statement. Thus, you should always use the following form::
+
+ with apt_pkg.ActionGroup(depcache):
+ ...
+
+ For code which has to run on Python versions prior to 2.5, you can also
+ use the traditional way::
+
+ actiongroup = apt_pkg.ActionGroup(depcache)
+ ...
+ actiongroup.release()
+
+ In addition to the methods required to implement the context
+ manager interface, :class:`ActionGroup` objects provide the
+ following method:
+
+ .. method:: release()
+
+ Release the ActionGroup. This will reactive the collection of package
+ garbage.
+
+Resolving Dependencies with :class:`ProblemResolver`
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. class:: ProblemResolver(depcache: DepCache)
+
+ ProblemResolver objects take care of resolving problems with
+ dependencies. They mark packages for installation/removal and
+ try to satisfy all dependencies. The constructor takes a single
+ argument of the type :class:`apt_pkg.DepCache` to determine the
+ cache that shall be manipulated in order to resolve the problems.
+
+ .. method:: clear(pkg: Package)
+
+ Revert the action of calling :meth:`protect` or :meth:`remove` on
+ a package, resetting it to the default state.
+
+ .. method:: install_protect()
+
+ Mark all protected packages for installation.
+
+ .. method:: protect(pkg: Package)
+
+ Mark the package given by *pkg* as protected; that is, its state
+ will not be changed.
+
+ .. method:: remove(pkg: Package)
+
+ Mark the package given by *pkg* for removal in the resolver.
+
+ .. method:: resolve([fix_broken: bool = True]) -> bool
+
+ Try to intelligently resolve problems by installing and removing
+ packages. If *fix_broken* is ``True``, apt will try to repair broken
+ dependencies of installed packages.
+
+ .. method:: resolve_by_keep() -> bool
+
+ Try to resolve the problems without installing or removing packages.
+
+ .. method:: keep_phased_updates() -> bool
+
+ Hold back upgrades to phased versions of already installed
+ packages, unless they are security updates.
+
+:class:`Group` of packages with the same name
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+.. class:: Group(cache: Cache, name: str)
+
+ .. versionadded:: 0.8.0
+
+ A collection of packages in which all packages have the same name. Groups
+ are used in multi-arch environments, where two or more packages have the
+ same name, but different architectures.
+
+ Group objects provide the following parts for sequential access:
+
+ .. describe:: group[index]
+
+ Get the package at the given **index** in the group.
+
+ .. note::
+ Groups are internally implemented using a linked list. The object
+ keeps a pointer to the current object and the first object, so
+ access to the first element, or accesses in order have a
+ complexity of O(1). Random-access complexity is ranges from
+ O(1) to O(n).
+
+ Group objects also provide special methods to find single packages:
+
+ .. method:: find_package(architecture: str) -> Package
+
+ Find a package with the groups name and the architecture given
+ in the argument *architecture*. If no such package exists, return
+ ``None``.
+
+ .. method:: find_preferred_package(prefer_nonvirtual: bool = True) -> Package
+
+ Find the preferred package. This is the package of the native
+ architecture (specified in ``APT::Architecture``) if available,
+ or the package from the first foreign architecture. If no package
+ could be found, return ``None``
+
+ If **prefer_nonvirtual** is ``True``, the preferred package
+ will be a non-virtual package, if one exists.
+
+
+:class:`Package` information
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+.. class:: Package
+
+ Represent a package. A package is uniquely identified by its name and
+ architecture and each package can have zero or more versions which can be
+ accessed via the :attr:`version_list` property. Packages can be
+ installed and removed by a :class:`DepCache` object.
+
+ Attributes:
+
+ .. attribute: architecture
+
+ The architecture of the package. This is relevant on multi-arch
+ systems only. Please note that if a package is Architecture: all,
+ this value is not "all", but the architecture of the package file
+ it comes from.
+
+ .. versionadded:: 0.7.100.3
+
+ .. attribute:: current_ver
+
+ The version currently installed as a :class:`Version` object, or None
+ if the package is not installed.
+
+ .. method:: get_fullname([pretty: bool = False]) -> str
+
+ Get the full name of the package, including the architecture. If
+ *pretty* is ``True``, the architecture is omitted for native packages,
+ that is, an amd64 "apt" package on an amd64 system would give "apt".
+
+ .. versionadded:: 0.7.100.3
+
+ .. attribute:: has_provides
+
+ A boolean value determining whether the list available via the
+ attribute :attr:`provides_list` has at least one element. This
+ value may be used in combination with :attr:`has_versions` to
+ check whether a package is virtual; that is, it has no versions
+ and is provided at least once::
+
+ pkg.has_provides and not pkg.has_versions
+
+ .. attribute:: has_versions
+
+ A boolean value determining whether the list available via the
+ attribute :attr:`version_list` has at least one element. This
+ value may be used in combination with :attr:`has_provides` to
+ check whether a package is virtual; that is, it has no versions
+ and is provided at least once::
+
+ pkg.has_provides and not pkg.has_versions
+
+ .. attribute:: id
+
+ The ID of the package. This can be used to store information about
+ the package. The ID is an int value.
+
+ .. attribute:: name
+
+ This is the name of the package.
+
+ .. attribute:: provides_list
+
+ A list of all package versions providing this package. Each element
+ of the list is a triplet, where the first element is the name of the
+ provided package, the second element the provided version (empty
+ string), and the third element the version providing this package
+ as a :class:`Version` object.
+
+ .. attribute:: rev_depends_list
+
+ An iterator of :class:`Dependency` objects for dependencies on this
+ package. The returned iterator is implemented by the class
+ :class:`DependencyList`:
+
+ .. class:: DependencyList
+
+ A simple list-like type for representing multiple dependency
+ objects in an efficient manner; without having to generate
+ all Dependency objects in advance.
+
+ .. describe:: list[index]
+
+ Return the item at the position *index* in the list.
+
+ .. method:: __len__()
+
+ The length of the list. This method should not be used
+ irectly, instead Python's built-in function :func:`len`
+ should be used.
+
+ .. attribute:: section
+
+ The section of the package, as specified in the record. The list of
+ possible sections is defined in the Policy. This is a string.
+
+ .. deprecated:: 1.0
+
+ A package can have multiple versions with different sections, so
+ the section information should be accessed from the version class.
+
+ .. attribute:: version_list
+
+ A list of :class:`Version` objects for all versions of this package
+ available in the cache.
+
+ **States**:
+
+ .. attribute:: selected_state
+
+ The state we want it to be, ie. if you mark a package for installation,
+ this is :attr:`apt_pkg.SELSTATE_INSTALL`.
+
+ See :ref:`SelStates` for a list of available states.
+
+ .. attribute:: inst_state
+
+ The state the currently installed version is in. This is normally
+ :attr:`apt_pkg.INSTSTATE_OK`, unless the installation failed.
+
+ See :ref:`InstStates` for a list of available states.
+
+ .. attribute:: current_state
+
+ The current state of the package (not installed, unpacked, installed,
+ etc). See :ref:`CurStates` for a list of available states.
+
+ **Flags**:
+
+ .. attribute:: essential
+
+ Whether the package has the 'Essential' flag set; that is,
+ whether it has a field 'Essential: yes' in its record.
+
+ .. attribute:: important
+
+ Whether the package has the (obsolete) 'Important' flag set; that is,
+ whether it has a field 'Important: yes' in its record.
+
+Example:
+~~~~~~~~~
+.. literalinclude:: ../examples/cache-packages.py
+
+
+
+:class:`Version`
+^^^^^^^^^^^^^^^^^
+.. class:: Version
+
+ The version object contains all information related to a specific package
+ version.
+
+ .. attribute:: arch
+
+ The architecture of the package, eg. amd64 or all.
+
+ .. attribute:: depends_list
+
+ This is basically the same as :attr:`depends_list_str`,
+ but instead of the ('pkgname', 'version', 'relation') tuples,
+ it returns :class:`Dependency` objects, which can assist you with
+ useful functions.
+
+ .. attribute:: depends_list_str
+
+ A dictionary of dependencies. The key specifies the type of the
+ dependency ('Depends', 'Recommends', etc.).
+
+ The value is a list, containing items which refer to the or-groups of
+ dependencies. Each of these or-groups is itself a list, containing
+ tuples like ('pkgname', 'version', 'relation') for each or-choice.
+
+ An example return value for a package with a 'Depends: python (>= 2.4)'
+ would be::
+
+ {'Depends': [
+ [
+ ('python', '2.4', '>=')
+ ]
+ ]
+ }
+
+ The same for a dependency on A (>= 1) | B (>= 2)::
+
+ {'Depends': [
+ [
+ ('A', '1', '>='),
+ ('B', '2', '>='),
+ ]
+ ]
+ }
+
+ The comparison operators are not the Debian ones, but the standard
+ comparison operators as used in languages such as C and Python. This
+ means that '>' means "larger than" and '<' means "less than".
+
+ .. attribute:: downloadable
+
+ Whether this package can be downloaded from a remote site.
+
+ .. attribute:: file_list
+
+ A list of (:class:`PackageFile`, int: index) tuples for all Package
+ files containing this version of the package.
+
+ .. attribute:: hash
+
+ An integer hash value used for the internal storage.
+
+ .. attribute:: id
+
+ A numeric identifier which uniquely identifies this version in all
+ versions in the cache.
+
+ .. attribute:: installed_size
+
+ The size of the package (in kilobytes), when unpacked on the disk.
+
+ .. attribute:: multi_arch
+
+ The multi-arch state of the package. Can be one of the following
+ attributes.
+
+ .. attribute:: MULTI_ARCH_NO
+
+ No multi-arch
+
+ .. attribute:: MULTI_ARCH_ALL
+
+ An ``Architecture: all`` package
+
+
+ .. attribute:: MULTI_ARCH_FOREIGN
+
+ Can satisfy dependencies of foreign-architecture
+ packages
+
+ .. attribute:: MULTI_ARCH_ALL_FOREIGN
+
+ :attr:`MULTI_ARCH_FOREIGN` for ``Architecture: all``
+ packages.
+
+ .. attribute:: MULTI_ARCH_SAME
+
+ Multiple versions from different architectures may be
+ installed in parallel, but may only satisfy dependencies
+ of packages from the same architecture
+
+ .. attribute:: MULTI_ARCH_ALLOWED
+
+ Installation in parallel and satisfying ``pkg:any``
+ style dependencies is allowed.
+
+ .. attribute:: MULTI_ARCH_ALL_ALLOWED
+
+ :attr:`MULTI_ARCH_ALLOWED` for ``Architecture: all``
+ packages.
+
+
+
+
+ .. attribute:: parent_pkg
+
+ The :class:`Package` object this version belongs to.
+
+ .. attribute:: priority
+
+ The integer representation of the priority. This can be used to speed
+ up comparisons a lot, compared to :attr:`priority_str`.
+
+ The values are defined in the :mod:`apt_pkg` extension, see
+ :ref:`Priorities` for more information.
+
+ .. attribute:: priority_str
+
+ Return the priority of the package version, as a string, eg.
+ "optional".
+
+ .. attribute:: provides_list
+
+ This returns a list of all packages provided by this version. Like
+ :attr:`Package.provides_list`, it returns a list of tuples
+ of the form ('virtualpkgname', '', :class:`Version`), where as the
+ last item is the same as the object itself.
+
+ .. attribute:: section
+
+ The usual sections (eg. admin, net, etc.). Prefixed with the component
+ name for packages not in main (eg. non-free/admin).
+
+ .. attribute:: size
+
+ The size of the .deb file, in bytes.
+
+ .. attribute:: translated_description
+
+ Return a :class:`Description` object for the translated description
+ of this package version.
+
+ .. attribute:: is_security_update
+
+ Whether this version is a security update.
+
+ .. attribute:: ver_str
+
+ The version, as a string.
+
+
+
+:class:`Dependency`
+^^^^^^^^^^^^^^^^^^^^
+.. class:: Dependency
+
+ Represent a dependency from one package to another one.
+
+ .. method:: all_targets
+
+ A list of all possible target :class:`Version` objects which satisfy
+ this dependency.
+
+ .. attribute:: comp_type
+
+ The type of comparison (<,<=,=,!=,>=,>,), as string. Note that the
+ empty string is a valid string as well, if no version is specified.
+
+ .. attribute:: dep_type
+
+ The type of the dependency, as string, eg. "Depends".
+
+ .. attribute:: dep_type_enum
+
+ The type of the dependency, as an integer which can be compared to
+ one of the TYPE_* constants below.
+
+ .. attribute:: dep_type_untranslated
+
+ The type of the depndency, as an untranslated string.
+
+ .. attribute:: id
+
+ The ID of the package, as integer.
+
+ .. attribute:: parent_pkg
+
+ The :class:`Package` object of the package which declares the
+ dependency. This is the same as using ParentVer.ParentPkg.
+
+ .. attribute:: parent_ver
+
+ The :class:`Version` object of the parent version, ie. the package
+ which declares the dependency.
+
+ .. attribute:: target_pkg
+
+ The :class:`Package` object of the target package.
+
+ .. attribute:: target_ver
+
+ The target version of the dependency, as string. Empty string if the
+ dependency is not versioned.
+
+ The following constants describe all values the attribute *dep_type_enum*
+ can take:
+
+ .. attribute:: TYPE_CONFLICTS
+
+ Constant for checking against dep_type_enum
+
+ .. attribute:: TYPE_DEPENDS
+
+ Constant for checking against dep_type_enum
+
+ .. attribute:: TYPE_DPKG_BREAKS
+
+ Constant for checking against dep_type_enum
+
+ .. attribute:: TYPE_ENHANCES
+
+ Constant for checking against dep_type_enum
+
+ .. attribute:: TYPE_OBSOLETES
+
+ Constant for checking against dep_type_enum
+
+ .. attribute:: TYPE_PREDEPENDS
+
+ Constant for checking against dep_type_enum
+
+ .. attribute:: TYPE_RECOMMENDS
+
+ Constant for checking against dep_type_enum
+
+ .. attribute:: TYPE_REPLACES
+
+ Constant for checking against dep_type_enum
+
+ .. attribute:: TYPE_SUGGESTS
+
+ Constant for checking against dep_type_enum
+
+Example: Find all missing dependencies
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+With the help of Dependency.all_targets(), you can easily find all packages with
+broken dependencies:
+
+.. literalinclude:: ../examples/missing-deps.py
+
+
+:class:`Description`
+^^^^^^^^^^^^^^^^^^^^^
+.. class:: Description
+
+ Represent the description of the package.
+
+ .. attribute:: language_code
+
+ The language code of the description; or, if the description
+ is untranslated, an empty string.
+
+ .. attribute:: md5
+
+ The MD5 checksum of the description.
+
+ .. attribute:: file_list
+
+ A list of tuples ``(packagefile: PackageFile, index: int)``.
+
+Package Pinning with :class:`Policy`
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+.. class:: Policy(cache: apt_pkg.Cache)
+
+ Representation of the policy of the :class:`Cache` object given by
+ *cache*. This provides a superset of policy-related functionality
+ compared to the *DepCache* class. The DepCache can be used for most
+ purposes, but there may be some cases where a special policy class
+ is needed.
+
+ .. method:: create_pin(type: str, pkg: str, data: str, priority: int)
+
+ Create a pin for the policy. The parameter *type* refers to one of the
+ strings 'Version', 'Release', or 'Origin'. The argument *pkg* is the
+ name of the package. The parameter *data* refers to the value (such
+ as 'unstable' for type='Release') and the other possible options.
+ The parameter 'priority' gives the priority of the pin.
+
+ .. automethod:: init_defaults
+
+ .. method:: get_candidate_ver(package: apt_pkg.Package) -> apt_pkg.Version
+
+ Get the best package for the job; that is, the package with the
+ highest pin priority.
+
+ .. method:: get_priority(package: Union[apt_pkg.Version, apt_pkg.PackageFile]) -> int
+
+ Get the pin priority of the package, version, or package file
+ given by *package*.
+
+ .. versionchanged:: 1.7
+
+ Introduce support for per-version pins. Deprecated support
+ for :class:`apt_pkg.Package`.
+
+ .. method:: read_pindir(dirname: str) -> bool
+
+ Read the pin files in the given dir (e.g. '/etc/apt/preferences.d')
+ and add them to the policy.
+
+ .. method:: read_pinfile(filename: str) -> bool
+
+ Read the pin file given by *filename* (e.g. '/etc/apt/preferences')
+ and add it to the policy.
+
+
+Index Files
+-------------
+
+.. class:: MetaIndex
+
+ Represent a Release file as stored in the cache.
+
+ .. attribute:: uri
+
+ The URI the meta index file is located at, as a string.
+
+ .. attribute:: dist
+
+ The distribution stored in the meta index, as a string.
+
+ .. attribute:: is_trusted
+
+ A boolean value determining whether the meta index can be trusted. This
+ is ``True`` for signed Release files.
+
+ .. attribute:: index_files
+
+ A list of all :class:`IndexFile` objects associated with this meta
+ index.
+
+
+.. class:: IndexFile
+
+ Represent an index file, that is, package indexes, translation indexes,
+ and source indexes.
+
+ .. method:: archive_uri(path: str) -> str
+
+ Return the URI to the given path in the archive.
+
+ .. attribute:: label
+
+ The label of the index file.
+
+ .. attribute:: describe
+
+ A string describing this object.
+
+ .. attribute:: exists
+
+ A boolean value determining whether the index file exists.
+
+ .. attribute:: has_packages
+
+ A boolean value determining whether the index file has packages.
+
+ .. attribute:: size
+
+ The size of the file, measured in bytes.
+
+ .. attribute:: is_trusted
+
+ A boolean value determining whether the file can be trusted; that is,
+ because it is from a source with a GPG signed Release file.
+
+
+
+.. class:: PackageFile
+
+ Provide access to an index file stored in the cache, such as
+ :file:`/var/lib/dpkg/status`.
+
+ .. attribute:: architecture
+
+ The architecture of the package file. This attribute normally
+ contains an empty string and is thus not very useful.
+
+ .. attribute:: archive
+
+ The archive of the package file as set in the Release file via
+ the "Suite" field. If there is no Release file, this is an empty
+ string.
+
+ .. attribute:: component
+
+ The component of the package file, if it is provided by a repository
+ using the dists/ hierarchy. For other packages files, this property
+ is an empty string.
+
+ .. attribute:: filename
+
+ The path to the file on the local filesystem.
+
+ .. attribute:: id
+
+ The ID of the package. This is an integer which can be used to store
+ further information about the file [eg. as dictionary key].
+
+ .. attribute:: index_type
+
+ A string describing the type of index. Known values are
+ "Debian Package Index", "Debian Translation Index", and
+ "Debian dpkg status file".
+
+ .. attribute:: label
+
+ The label of the package file as set in the release file
+ via the 'Label' field. If there is no Release file, this
+ attribute is an empty string.
+
+ .. attribute:: not_automatic
+
+ Whether packages from this list will be updated automatically. The
+ default for example is False.
+
+ .. attribute:: not_source
+
+ Whether the file has no source from which it can be updated. In such a
+ case, the value is ``True``; else ``False``. For example, it is
+ ``False`` for :file:`/var/lib/dpkg/status`.
+
+ Example::
+
+ for pkgfile in cache.file_list:
+ if pkgfile.not_source:
+ print('The file %s has no source.' % pkgfile.filename)
+
+ .. attribute:: origin
+
+ The Origin, as set in the Release file
+
+ .. attribute:: site
+
+ The hostname of the site.
+
+ .. attribute:: size
+
+ The size of the file.
+
+ .. attribute:: version
+
+ The version, as set in the release file (eg. "4.0" for "Etch")
+
+
+The following example shows how to use PackageFile:
+
+.. literalinclude:: ../examples/cache-pkgfile.py
+
+
+Records (Release files, Packages, Sources)
+------------------------------------------
+
+.. class:: IndexRecords()
+
+ Represent a Release file and provide means to read information from
+ the file. This class provides several methods:
+
+ .. method:: get_dist() -> str
+
+ Return the distribution set in the Release file.
+
+ .. method:: load(filename: str)
+
+ Load the file located at the path given by *filename*.
+
+ .. method:: lookup(key: str) -> (HashString, int)
+
+ Look up the filename given by *key* and return a tuple (hash, size),
+ where the first element *hash* is a :class:`HashString` object
+ and the second element *size* is an int object.
+
+
+.. class:: PackageRecords(cache: apt_pkg.Cache)
+
+ Provide further information about the packages in the :class:`Cache` object
+ *cache*. This efficiently parses the package files to provide information
+ not available in the cache, such as maintainer, hash sums, description,
+ and the file name of the package. It also provides the complete record
+ of the package.
+
+ .. method:: lookup(verfile_iter: (PackageFile, int)) -> bool
+
+ Change the actual package to the package given by the verfile_iter.
+
+ The parameter *verfile_iter* refers to a tuple consisting
+ of (:class:`PackageFile()`, int: index), as returned by various
+ ``file_list`` attributes such as :attr:`Version.file_list`.
+
+ Example (shortened)::
+
+ cand = depcache.get_candidate_ver(cache['python-apt'])
+ records.lookup(cand.file_list[0])
+ # Now you can access the record
+ print(records.source_pkg) # == python-apt
+
+ .. describe:: section[key]
+
+ Return the value of the field at *key*. If *key* is not available,
+ raise :exc:`KeyError`.
+ Raises AttributeError if not yet looked up.
+
+ .. versionadded:: 1.7
+
+ .. describe:: key in section
+
+ Return ``True`` if *section* has a key *key*, else ``False``.
+ Raises AttributeError if not yet looked up.
+
+ .. versionadded:: 1.7
+
+ .. attribute:: filename
+
+ Return the field 'Filename' of the record. This is the path to the
+ package, relative to the base path of the archive.
+
+ .. attribute:: hashes
+
+ A :class:`apt_pkg.HashStringList` of all hashes.
+
+ .. versionadded:: 1.1
+
+ .. attribute:: md5_hash
+
+ Return the MD5 hashsum of the package This refers to the field
+ 'MD5Sum' in the raw record.
+
+ .. deprecated:: 1.1
+
+ Use :attr:`hashes` instead.
+
+ .. attribute:: sha1_hash
+
+ Return the SHA1 hashsum of the package. This refers to the field 'SHA1'
+ in the raw record.
+
+ .. deprecated:: 1.1
+
+ Use :attr:`hashes` instead.
+
+ .. attribute:: sha256_hash
+
+ Return the SHA256 hashsum of the package. This refers to the field
+ 'SHA256' in the raw record.
+
+ .. versionadded:: 0.7.9
+
+ .. deprecated:: 1.1
+
+ Use :attr:`hashes` instead.
+
+ .. attribute:: source_pkg
+
+ The name of the source package, if different from the name of the
+ binary package. This information is retrieved from the 'Source' field.
+
+ .. attribute:: source_ver
+
+ The version of the source package, if it differs from the version
+ of the binary package. Just like 'source_pkg', this information
+ is retrieved from the 'Source' field.
+
+ .. attribute:: maintainer
+
+ Return the maintainer of the package.
+
+ .. attribute:: short_desc
+
+ Return the short description. This is the summary on the first line of
+ the 'Description' field.
+
+ .. attribute:: long_desc
+
+ Return the long description. These are lines 2-END from the
+ 'Description' field.
+
+ .. attribute:: name
+
+ Return the name of the package. This is the 'Package' field.
+
+ .. attribute:: homepage
+
+ Return the Homepage. This is the 'Homepage' field.
+
+ .. attribute:: record
+
+ Return the whole record as a string. If you want to access fields of
+ the record not available as an attribute, you can use
+ :class:`apt_pkg.TagSection` to parse the record and access the field
+ name.
+
+ .. deprecated:: 1.7
+
+ This property can be considered deprecated for simple string
+ lookups, as keys can now be looked up in the record itself.
+
+ Example::
+
+ section = apt_pkg.TagSection(records.record)
+ print(section['SHA256']) # Use records.sha256_hash instead
+
+.. class:: SourceRecords
+
+ Provide an easy way to look up the records of source packages and
+ provide easy attributes for some widely used fields of the record.
+
+ .. note::
+
+ If the Lookup failed, because no package could be found, no error is
+ raised. Instead, the attributes listed below are simply not existing
+ anymore (same applies when no Lookup has been made, or when it has
+ been restarted).
+
+ .. method:: lookup(pkgname: str) -> bool
+
+ Look up the source package with the given name. Each call moves
+ the position of the records parser forward. If there are no
+ more records, return None. If the lookup failed this way,
+ access to any of the attributes will result in an
+ :exc:`AttributeError`.
+
+ Imagine a package P with two versions X, Y. The first ``lookup(P)``
+ would set the record to version X and the second ``lookup(P)`` to
+ version Y. A third call would return ``None`` and access to any
+ of the below attributes will result in an :exc:`AttributeError`
+
+ .. method:: restart()
+
+ Restart the lookup process. This moves the parser to the first
+ package and lookups can now be made just like on a new object.
+
+ Imagine a package P with two versions X, Y. The first ``Lookup(P)``
+ would set the record to version X and the second ``Lookup(P)`` to
+ version Y. If you now call ``restart()``, the internal position
+ will be cleared. Now you can call ``lookup(P)`` again to move to X.
+
+ .. attribute:: binaries
+
+ Return a list of strings describing the package names of the binaries
+ created by the source package. This matches the 'Binary' field in the
+ raw record.
+
+ .. attribute:: build_depends
+
+ Return a dictionary representing the build-time dependencies of the
+ package. The format is the same as for :attr:`Version.depends_list_str`
+ and possible keys being ``"Build-Depends"``, ``"Build-Depends-Indep"``,
+ ``"Build-Conflicts"`` or ``"Build-Conflicts-Indep"``.
+
+ .. attribute:: files
+
+ The list of files. This returns a list of :class:`SourceRecordsFile`
+
+ .. versionchanged:: 1.6
+
+ Used to be a list of tuples, see :class:`SourceRecordFile` for the tuple
+ layout.
+
+ .. attribute:: index
+
+ A list of :class:`IndexFile` objects associated with this
+ source package record.
+
+ .. attribute:: maintainer
+
+ A string describing the name of the maintainer.
+
+ .. attribute:: package
+
+ The name of the source package.
+
+ .. attribute:: record
+
+ The whole record, as a string. You can use :func:`apt_pkg.ParseSection`
+ if you need to parse it. You need to parse the record to access
+ fields not available via the attributes such as 'Standards-Version'
+
+ .. attribute:: section
+
+ A string describing the section.
+
+ .. attribute:: version
+
+ A string describing the version of the source package.
+
+.. class:: SourceRecordsFile
+
+ Represents a file in a source record.
+
+ .. versionadded:: 1.6
+
+ Before 1.6, this was a tuple `(md5, size, path, type)`.
+
+ .. attribute:: hashes
+
+ A :class:`HashStringList` of the file's hashes.
+
+ .. attribute:: path
+
+ The path to the file
+
+ .. attribute:: size
+
+ The size of the file
+
+ .. attribute:: type
+
+ The type of the file. Can be 'diff' (includes .debian.tar.gz), 'dsc', or 'tar'.
+
+The Acquire interface
+----------------------
+The Acquire Interface is responsible for all sorts of downloading in apt. All
+packages, index files, etc. downloading is done using the Acquire functionality.
+
+The :mod:`apt_pkg` module provides a subset of this functionality which allows
+you to implement file downloading in your applications. Together with the
+:class:`PackageManager` class you can also fetch all the packages marked for
+installation.
+
+.. class:: Acquire([progress: apt.progress.base.AcquireProgress])
+
+ Coordinate the retrieval of files via network or local file system
+ (using ``copy://path/to/file`` style URIs). Items can be added to
+ an Acquire object using various means such as creating instances
+ of :class:`AcquireFile` or the methods :meth:`SourceList.get_indexes`
+ and :meth:`PackageManager.get_archives`.
+
+ Acquire objects maintain a list of items which will be fetched or have
+ been fetched already during the lifetime of this object. To add new items
+ to this list, you can create new :class:`AcquireFile` objects which allow
+ you to add single files.
+
+ The constructor takes an optional parameter *progress* which takes an
+ :class:`apt.progress.base.AcquireProgress` object. This object may then
+ report progress information (see :mod:`apt.progress.text` for reporting
+ progress to a I/O stream).
+
+ Acquire items have two methods to start and stop the fetching:
+
+ .. method:: run() -> int
+
+ Fetch all the items which have been added by :class:`AcquireFile` and
+ return one of the constants :attr:`RESULT_CANCELLED`,
+ :attr:`RESULT_CONTINUE`, :attr:`RESULT_FAILED` to describe the
+ result of the run.
+
+ .. method:: shutdown()
+
+ Shut the fetcher down. This removes all items from the queue and
+ makes all :class:`AcquireItem`, :class:`AcquireWorker`,
+ :class:`AcquireItemDesc` objects useless. Accessing an object of one
+ of those types can cause a segfault then.
+
+ Removing an item does not mean that the already fetched data will
+ be removed from the destination. Instead, APT might use the partial
+ result and continue from thereon.
+
+ Furthermore, they provide three attributes which provide information
+ on how much data is already available and how much data still needs
+ to be fetched:
+
+ .. attribute:: fetch_needed
+
+ The amount of data that has to be fetched in order to fetch all
+ queued items.
+
+ .. attribute:: partial_present
+
+ The amount of data which is already available.
+
+ .. attribute:: total_needed
+
+ The total amount of bytes needed (including those of files which are
+ already present).
+
+ They also provide two attributes representing the items being processed
+ and the workers fetching them:
+
+ .. attribute:: items
+
+ A list of :class:`AcquireItem` objects which are attached to the
+ to this Acquire object. This includes all items ever attached to
+ this object (except if they were removed using, for example,
+ :meth:`shutdown()` or by deleting an :class:`AcquireFile` object.)
+
+ .. attribute:: workers
+
+ A list of :class:`AcquireWorker` objects which are currently active
+ on this instance.
+
+ The Acquire class comes with three constants which represents the results
+ of the :meth:`run` method:
+
+ .. attribute:: RESULT_CANCELLED
+
+ The fetching has been aborted, e.g. due to a progress class returning
+ ``False`` in its :meth:`pulse()` method.
+
+ .. attribute:: RESULT_CONTINUE
+
+ All items have been fetched successfully or failed transiently
+ and the process has not been canceled.
+
+ You need to look at the status of each item and check if it has not
+ failed transiently to discover errors like a Not Found when acquiring
+ packages.
+
+ .. attribute:: RESULT_FAILED
+
+ An item failed to fetch due to some reasons.
+
+
+.. class:: AcquireItem
+
+ An AcquireItem object represents a single item of an :class:`Acquire`
+ object. It is an abstract class to represent various types of items
+ which are implemented as subclasses. The only exported subclass is
+ :class:`AcquireFile` which can be used to fetch files.
+
+ .. attribute:: complete
+
+ A boolean value which is True only if the item has been
+ fetched successfully.
+
+ .. attribute:: desc_uri
+
+ An URI describing where the item is located at.
+
+ .. attribute:: destfile
+
+ The path to the local location where the fetched data will be
+ stored at.
+
+ .. attribute:: error_text
+
+ The error message. For example, when a file does not exist on a HTTP
+ server, this will contain a 404 error message.
+
+ .. attribute:: filesize
+
+ The size of the file, in bytes. If the size of the to be fetched file
+ is unknown, this attribute is set to ``0``.
+
+ .. attribute:: id
+
+ The ID of the item. This attribute is normally set to ``0``, users may
+ set a custom value here, for instance in an overridden
+ :meth:`apt.progress.base.AcquireProgress.fetch` method (the progress
+ class could keep a counter, increase it by one for every :meth:`fetch`
+ call and assign the current value to this attribute).
+
+ .. attribute:: is_trusted
+
+ A boolean value determining whether the file is trusted. Only ``True``
+ if the item represents a package coming from a repository which is
+ signed by one of the keys in APT's keyring.
+
+ .. attribute:: local
+
+ A boolean value determining whether this file is locally available
+ (``True``) or whether it has to be fetched from a remote source
+ (``False``).
+
+ .. attribute:: mode
+
+ Old name for active_subprocess
+
+ .. deprecated:: 1.0
+
+ .. attribute:: active_subprocess
+
+ The name of the active subprocess (for instance, 'gzip', 'rred' or 'gpgv').
+
+ .. versionadded:: 1.0
+
+ **Status**:
+
+ The following attribute represents the status of the item. This class
+ provides several constants for comparing against this value which are
+ listed here as well.
+
+ .. attribute:: status
+
+ Integer, representing the status of the item. This attribute can be
+ compared against the following constants to gain useful information
+ on the item's status.
+
+ .. attribute:: STAT_AUTH_ERROR
+
+ An authentication error occurred while trying to fetch the item.
+
+ .. attribute:: STAT_DONE
+
+ The item is completely fetched and there have been no problems
+ while fetching the item.
+
+ .. attribute:: STAT_ERROR
+
+ An error occurred while trying to fetch the item. This error is
+ normally not related to authentication problems, as thus are
+ dealt with using :attr:`STAT_AUTH_ERROR`.
+
+ .. attribute:: STAT_FETCHING
+
+ The item is being fetched currently.
+
+ .. attribute:: STAT_IDLE
+
+ The item is yet to be fetched.
+
+ .. attribute:: STAT_TRANSIENT_NETWORK_ERROR
+
+ There was a network error.
+
+
+.. class:: AcquireFile(owner, uri[, hash, size, descr, short_descr, destdir, destfile])
+
+ Create a new :class:`AcquireFile()` object and register it with *acquire*,
+ so it will be fetched. You must always keep around a reference to the
+ object, otherwise it will be removed from the Acquire queue again.
+
+ The parameter *owner* refers to an :class:`Acquire()` object as returned
+ by :func:`GetAcquire`. The file will be added to the Acquire queue
+ automatically.
+
+ The parameter *uri* refers to the location of the file, any protocol
+ of apt is supported.
+
+ The parameter *hash* refers to the hash of the file. If this is set
+ libapt will check the file after downloading. This should be an instance
+ of :class:`apt_pkg.HashStringList`.
+
+ The parameter *size* can be used to specify the size of the package,
+ which can then be used to calculate the progress and validate the download.
+
+ The parameter *descr* is a description of the download. It may be
+ used to describe the item in the progress class. *short_descr* is the
+ short form of it.
+
+ The parameters *descr* and *short_descr* can be used to specify
+ descriptions for the item. The string passed to *descr* should
+ describe the file and its origin (e.g. "http://localhost sid/main
+ python-apt 0.7.94.2") and the string passed to *short_descr* should
+ be one word such as the name of a package.
+
+ Normally, the file will be stored in the current directory using the
+ file name given in the URI. This directory can be changed by passing
+ the name of a directory to the *destdir* parameter. It is also possible
+ to set a path to a file using the *destfile* parameter, but both can
+ not be specified together.
+
+ In terms of attributes, this class is a subclass of :class:`AcquireItem`
+ and thus inherits all its attributes.
+
+ .. versionchanged:: 1.9.1
+
+ The *hash* parameter now accepts an :class:`apt_pkg.HashStringList`,
+ the old *md5* parameter has been removed.
+
+.. class:: AcquireWorker
+
+ An :class:`AcquireWorker` object represents a sub-process responsible for
+ fetching files from remote locations. There is no possibility to create
+ instances of this class from within Python, but a list of objects of
+ currently active workers is provided by :attr:`Acquire.workers`.
+
+ Objects of this type provide several attributes which give information
+ about the worker's current activity.
+
+ .. attribute:: current_item
+
+ The item which is currently being fetched. This returns an
+ :class:`AcquireItemDesc` object.
+
+ .. attribute:: current_size
+
+ How many bytes of the file have been downloaded. Zero if the current
+ progress of the file cannot be determined.
+
+ .. attribute:: resumepoint
+
+ The amount of data which was already available when the download was
+ started.
+
+ .. attribute:: status
+
+ The most recent (localized) status string received from the
+ sub-process.
+
+ .. attribute:: total_size
+
+ The total number of bytes to be downloaded for the item. Zero if the
+ total size is unknown.
+
+.. class:: AcquireItemDesc
+
+ An :class:`AcquireItemDesc` object stores information about the item which
+ can be used to describe the item. Objects of this class are used in the
+ progress classes, see the :class:`apt.progress.base.AcquireProgress`
+ documentation for information how.
+
+ .. attribute:: description
+
+ The long description given to the item.
+
+ .. attribute:: owner
+
+ The :class:`AcquireItem` object owning this object.
+
+ .. attribute:: shortdesc
+
+ A short description which has been given to this item.
+
+ .. attribute:: uri
+
+ The URI from which this item would be downloaded.
+
+
+Hashes
+------
+The apt_pkg module also provides several hash functions. If you develop
+applications with python-apt it is often easier to use these functions instead
+of the ones provides in Python's :mod:`hashlib` module.
+
+The module provides the two classes :class:`Hashes` and :class:`HashString` for
+generic hash support:
+
+.. autoclass:: Hashes
+ :members:
+
+.. class:: HashString(type: str[, hash: str])
+
+ HashString objects store the type of a hash and the corresponding hash.
+ They are used by e.g :meth:`IndexRecords.lookup`. The first parameter,
+ *type* refers to one of "MD5Sum", "SHA1" and "SHA256". The second parameter
+ *hash* is the corresponding hash.
+
+ You can also use a combined form by passing a string with type and hash
+ separated by a colon as the only argument. For example::
+
+ HashString("MD5Sum:d41d8cd98f00b204e9800998ecf8427e")
+
+
+ .. describe:: str(hashstring)
+
+ Convert the HashString to a string by joining the hash type and the
+ hash using ':', e.g. ``"MD5Sum:d41d8cd98f00b204e9800998ecf8427e"``.
+
+ .. attribute:: hashtype
+
+ The type of the hash, as a string. This may be "MD5Sum", "SHA1",
+ "SHA256" or "SHA512".
+
+ .. autoattribute:: hashvalue
+
+ .. autoattribute:: usable
+
+ .. method:: verify_file(filename: str) -> bool
+
+ Verify that the file given by the parameter *filename* matches the
+ hash stored in this object.
+
+.. autoclass:: HashStringList
+ :members:
+
+ .. describe:: len(list)
+
+ Return the length of the list
+
+ .. describe:: list[index]
+
+ Get the :class:`HashString` object at the specified index.
+
+The :mod:`apt_pkg` module also provides the functions :func:`md5sum`,
+:func:`sha1sum` and :func:`sha256sum` for creating a single hash from a
+:class:`bytes` or :class:`file` object:
+
+.. function:: md5sum(object)
+
+ Return the md5sum of the object. *object* may either be a string, in
+ which case the md5sum of the string is returned, or a :class:`file()`
+ object (or a file descriptor), in which case the md5sum of its contents is
+ returned.
+
+ .. versionchanged:: 0.7.100
+ Added support for using file descriptors.
+
+ .. deprecated:: 1.9
+
+ Use :class:`apt_pkg.Hashes` instead. This function will be removed
+ in a later release.
+
+.. function:: sha1sum(object)
+
+ Return the sha1sum of the object. *object* may either be a string, in
+ which case the sha1sum of the string is returned, or a :class:`file()`
+ object (or a file descriptor), in which case the sha1sum of its contents
+ is returned.
+
+ .. versionchanged:: 0.7.100
+ Added support for using file descriptors.
+
+ .. deprecated:: 1.9
+
+ Use :class:`apt_pkg.Hashes` instead. This function will be removed
+ in a later release.
+
+.. function:: sha256sum(object)
+
+ Return the sha256sum of the object. *object* may either be a string, in
+ which case the sha256sum of the string is returned, or a :class:`file()`
+ object (or a file descriptor), in which case the sha256sum of its contents
+ is returned.
+
+ .. versionchanged:: 0.7.100
+ Added support for using file descriptors.
+
+ .. deprecated:: 1.9
+
+ Use :class:`apt_pkg.Hashes` instead. This function will be removed
+ in a later release.
+
+Debian control files
+--------------------
+Debian control files are files containing multiple stanzas of :RFC:`822`-style
+header sections. They are widely used in the Debian community, and can represent
+many kinds of information. One example for such a file is the
+:file:`/var/lib/dpkg/status` file which contains a list of the currently
+installed packages.
+
+The :mod:`apt_pkg` module provides two classes to read those files and parts
+thereof and provides a function :func:`RewriteSection` which takes a
+:class:`TagSection()` object and sorting information and outputs a sorted
+section as a string.
+
+.. class:: TagFile(file, bytes: bool = False)
+
+ An object which represents a typical debian control file. Can be used for
+ Packages, Sources, control, Release, etc.
+
+ The *file* argument shall be a path name or an open file object. The
+ argument *bytes* specifies whether the file shall be represented using
+ bytes (``True``) or unicode (``False``) strings.
+
+ It is a context manager that can be used with a with statement or the
+ :meth:`close` method.
+
+ .. describe:: with TagFile(...) as ...:
+
+ Use the :class:`TagFile` as a context manager. This will automatically
+ close the file after the body finished execution.
+
+ .. versionadded:: 1.0
+
+ .. method:: close()
+
+ Close the file. It's recommended to use the context manager
+ instead (that is, the `with` statement).
+
+ .. versionadded:: 1.0
+
+ It provides two kinds of API which should not be used together:
+
+ The first API implements the iterator protocol and should be used whenever
+ possible because it has less side effects than the other one. It may be
+ used e.g. with a for loop::
+
+ with apt_pkg.TagFile('/var/lib/dpkg/status') as tagfile:
+ for section in tagfile:
+ print(section['Package'])
+
+ .. versionchanged:: 0.7.100
+ Added support for using gzip files, via :class:`gzip.GzipFile` or any
+ file containing a compressed gzip stream.
+
+ .. versionadded:: 0.8.5
+
+ Added support for using bytes instead of str in Python 3
+
+ .. method:: next()
+
+ A TagFile is its own iterator. This method is part of the iterator
+ protocol and returns a :class:`TagSection` object for the next
+ section in the file. If there is no further section, this method
+ raises the :exc:`StopIteration` exception.
+
+ From Python 3 on, this method is not available anymore, and the
+ global function ``next()`` replaces it.
+
+ The second API uses a shared :class:`TagSection` object which is exposed
+ through the :attr:`section` attribute. This object is modified by calls
+ to :meth:`step` and :meth:`jump`. This API provides more control and may
+ use less memory, but is not recommended because it works by modifying
+ one object. It can be used like this::
+
+ with apt_pkg.TagFile('/var/lib/dpkg/status') as tagf:
+ tagf.step()
+ print tagf.section['Package']
+
+ .. method:: step() -> bool
+
+ Step forward to the next section. This simply returns ``True`` if OK,
+ and ``False`` if there is no section.
+
+ .. method:: offset() -> int
+
+ Return the current offset (in bytes) from the beginning of the file.
+
+ .. method:: jump(offset) -> bool
+
+ Jump back/forward to *offset*. Use ``jump(0)`` to jump to the
+ beginning of the file again. Returns ``True`` if a section could
+ be parsed or ``False`` if not.
+
+ .. attribute:: section
+
+ This is the current :class:`TagSection()` instance.
+
+.. class:: TagSection(text)
+
+ Represent a single section of a debian control file.
+
+ .. describe:: section[key]
+
+ Return the value of the field at *key*. If *key* is not available,
+ raise :exc:`KeyError`.
+
+ .. describe:: key in section
+
+ Return ``True`` if *section* has a key *key*, else ``False``.
+
+ .. versionadded:: 0.7.100
+
+ .. method:: bytes() -> int
+
+ The number of bytes in the section.
+
+ .. method:: find(key: str, default: str = '') -> str
+
+ Return the value of the field at the key *key* if available,
+ else return *default*.
+
+ .. method:: find_flag(key: str) -> bool
+
+ Find a yes/no value for the key *key*. An example for such a
+ field is 'Essential'.
+
+ .. method:: find_raw(key: str, default: str = '') -> str
+
+ Similar to :meth:`find`, but instead of returning just the value,
+ it returns the complete field consisting of 'key: value'.
+
+ .. method:: get(key: str, default: str = '')
+
+ Return the value of the field at the key *key* if available, else
+ return *default*.
+
+ .. method:: keys()
+
+ Return a list of keys in the section.
+
+
+ .. automethod:: write
+
+
+A function can be rewritten by using tag classes:
+
+.. autoclass:: Tag
+ :members:
+
+ The following static members can be used to determine the meaning of
+ :attr:`action`:
+
+ .. data:: REWRITE
+
+ Change the field value to the value of :attr:`data`
+
+ .. data:: RENAME
+
+ Rename the tag to a new tag stored in :attr:`data`.
+
+ .. data:: REMOVE
+
+ Remove the tag.
+
+ Apart from this, the class provides access to several attributes.
+
+.. autoclass:: TagRewrite
+
+.. autoclass:: TagRemove
+
+.. autoclass:: TagRename
+
+Pre-defined ordering for tag sections are:
+
+.. data:: REWRITE_PACKAGE_ORDER
+
+ The order in which the information for binary packages should be rewritten,
+ i.e. the order in which the fields should appear.
+
+.. data:: REWRITE_SOURCE_ORDER
+
+ The order in which the information for source packages should be rewritten,
+ i.e. the order in which the fields should appear.
+
+
+Dependencies
+------------
+.. function:: check_dep(pkgver: str, op: str, depver: str) -> bool
+
+ Check that the given requirement is fulfilled; that is, that the version
+ string given by *pkg_ver* matches the version string *dep_ver* under
+ the condition specified by the operator 'dep_op' (<,<=,=,>=,>).
+
+ Return True if *pkg_ver* matches *dep_ver* under the condition 'dep_op';
+ for example::
+
+ >>> apt_pkg.check_dep("1.0", ">=", "1")
+ True
+
+The following two functions provide the ability to parse dependencies. They
+use the same format as :attr:`Version.depends_list_str`.
+
+.. function:: parse_depends(depends, strip_multiarch=True, architecture)
+
+ Parse the string *depends* which contains dependency information as
+ specified in Debian Policy, Section 7.1.
+
+ Returns a list. The members of this list are lists themselves and contain
+ one or more tuples in the format ``(package,version,operation)`` for every
+ 'or'-option given, e.g.::
+
+ >>> apt_pkg.parse_depends("PkgA (>= VerA) | PkgB (>= VerB)")
+ [[('PkgA', 'VerA', '>='), ('PkgB', 'VerB', '>=')]]
+
+ Note that multiarch dependency information is stripped off by default.
+ You can force the full dependency info (including the multiarch info)
+ by passing "False" as a additional parameter to this function.
+
+ You can specify an optional argument *architecture* that treats the given
+ architecture as the native architecture for purposes of parsing the
+ dependency.
+
+ .. note::
+
+ The behavior of this function is different than the behavior of the
+ old function :func:`ParseDepends()`, because the third field
+ ``operation`` uses `>` instead of `>>` and `<` instead of `<<` which
+ is specified in control files.
+
+
+.. function:: parse_src_depends(depends, strip_multiarch=True, architecture)
+
+ Parse the string *depends* which contains dependency information as
+ specified in Debian Policy, Section 7.1.
+
+ Returns a list. The members of this list are lists themselves and contain
+ one or more tuples in the format ``(package,version,operation)`` for every
+ 'or'-option given, e.g.::
+
+ >>> apt_pkg.parse_depends("PkgA (>= VerA) | PkgB (>= VerB)")
+ [[('PkgA', 'VerA', '>='), ('PkgB', 'VerB', '>=')]]
+
+
+ Furthemore, this function also supports to limit the architectures, as
+ used in e.g. Build-Depends::
+
+ >>> apt_pkg.parse_src_depends("a (>= 01) [i386 amd64]")
+ [[('a', '01', '>=')]]
+
+ Note that multiarch dependency information is stripped off by default.
+ You can force the full dependency info (including the multiarch info)
+ by passing "False" as a additional parameter to this function.
+
+ You can specify an optional argument *architecture* that treats the given
+ architecture as the native architecture for purposes of parsing the
+ dependency.
+
+ .. note::
+
+ The behavior of this function is different than the behavior of the
+ old function :func:`ParseDepends()`, because the third field
+ ``operation`` uses `>` instead of `>>` and `<` instead of `<<` which
+ is specified in control files.
+
+
+Configuration and Command-line parsing
+--------------------------------------
+
+.. class:: Configuration()
+
+ Provide access to and manipulation of APT's configuration which is
+ used by many classes and functions in this module to define their
+ behavior. There are options to install recommends, change the root
+ directory and much more. For an (incomplete) list of available options,
+ see the :manpage:`apt.conf(5)` manual page.
+
+ The most important Configuration object is the one available by the
+ module's :attr:`apt_pkg.config` attribute. It stores the global
+ configuration which affects the behavior of most functions and is
+ initialized by a call to the function :func:`init_config`. While
+ possible, it is generally not needed to create other instances of
+ this class.
+
+ For accessing and manipulating the configuration space, objects
+ of this type provide an interface which resembles Python mapping
+ types like :class:`dict`.
+
+ .. describe:: key in conf
+
+ Return ``True`` if *conf* has a key *key*, else ``False``.
+
+ .. describe:: conf[key]
+
+ Return the value of the option given key *key*. If it does not
+ exist, raise :exc:`KeyError`.
+
+ .. describe:: conf[key] = value
+
+ Set the option at *key* to *value*.
+
+ .. describe del conf[key]
+
+ Delete the option with the name *key* in the configuration object
+ *conf*.
+
+ .. method:: get(key[, default='']) -> str
+
+ Find the value for the given key and return it. If the given key does
+ not exist, return *default* instead.
+
+ In addition, they provide methods to resemble the interface provided
+ by the C++ class and some more mapping methods which have been enhanced
+ to support some more advanced configuration features:
+
+ .. method:: clear(key: str)
+
+ Remove the option at *key* and all of its children.
+
+ .. method:: dump() -> str
+
+ Return a string containing the values in the configuration object,
+ in the standard :manpage:`apt.conf(5)` format.
+
+ .. versionadded:: 0.7.100
+
+ .. method:: exists(key)
+
+ Check whether an option named *key* exists in the configuration.
+
+ .. method:: find(key[, default='']) -> str
+
+ Return the value stored at the option named *key*, or the value
+ given by the string *default* if the option in question is not
+ set.
+
+ .. method:: find_b(key[, default=False]) -> bool
+
+ Return the boolean value stored at *key*, or the value given by
+ the :class:`bool` object *default* if the requested option is
+ not set.
+
+ .. method:: find_file(key[, default='']) -> str
+ find_dir(key[, default='/']) -> str
+
+ Locate the given key using :meth:`find` and return the path to the
+ file/directory. This uses a special algorithms which moves upwards
+ in the configuration space and prepends the values of the options
+ to the result. These methods are generally used for the options
+ stored in the 'Dir' section of the configuration.
+
+ As an example of how this works, take a look at the following options
+ and their values:
+
+ .. table::
+
+ ============== ===========================
+ Option Value
+ ============== ===========================
+ Dir /
+ Dir::Etc etc/apt/
+ Dir::Etc::main apt.conf
+ ============== ===========================
+
+ A call to :meth:`find_file` would now return ``/etc/apt/apt.conf``
+ because it prepends the values of "Dir::Etc" and "Dir" to the value
+ of "Dir::Etc::main"::
+
+ >>> apt_pkg.config.find_file("Dir::Etc::main")
+ '/etc/apt/apt.conf'
+
+ If the special configuration variable "RootDir" is set, this value
+ would be prepended to every return value, even if the path is already
+ absolute. If not, the function ends as soon as an absolute path is
+ created (once an option with a value starting with "/" is read).
+
+ The method :meth:`find_dir` does exactly the same thing as
+ :meth:`find_file`, but adds a trailing forward slash before
+ returning the value.
+
+ .. method:: find_i(key[, default=0]) -> int
+
+ Return the integer value stored at *key*, or the value given by
+ the integer *default* if the requested option is not set.
+
+ .. method:: keys([key])
+
+ Return a recursive list of all configuration options or, if *key*
+ is given, a list of all its children. This method is comparable
+ to the **keys** method of a mapping object, but additionally
+ provides the parameter *key*.
+
+ .. method:: list([key])
+
+ Return a non-recursive list of all configuration options. If *key*
+ is not given, this returns a list of options like "Apt", "Dir", and
+ similar. If *key* is given, a list of the names of its child options
+ will be returned instead.
+
+ .. method:: my_tag()
+
+ Return the tag name of the current tree. Normally (for
+ :data:`apt_pkg.config`) this is an empty string, but for
+ sub-trees it is the key of the sub-tree.
+
+ .. method:: set(key: str, value: str)
+
+ Set the option named *key* to the value given by the argument
+ *value*. It is possible to store objects of the types :class:`int`
+ and :class:`bool` by calling :func:`str` on them to convert them
+ to a string object. They can then be retrieved again by using the
+ methods :meth:`find_i` or :meth:`find_b`.
+
+ .. method:: subtree(key)
+
+ Return a new apt_pkg.Configuration object which starts at the
+ given option. Example::
+
+ apttree = config.subtree('APT')
+ apttree['Install-Suggests'] = config['APT::Install-Suggests']
+
+ The configuration space is shared with the main object which means
+ that all modifications in one object appear in the other one as
+ well.
+
+ .. method:: value_list([key])
+
+ This is the opposite of the :meth:`list` method in that it returns the
+ values instead of the option names.
+
+.. data:: config
+
+ This variable contains the global configuration which is used by
+ all classes and functions in this module. After importing the
+ module, this object should be initialized by calling the module's
+ :func:`init_config` function.
+
+.. function:: read_config_file(configuration: Configuration, filename: str)
+
+ Read the configuration file *filename* and set the appropriate
+ options in the configuration object *configuration*.
+
+.. function:: read_config_dir(configuration, dirname)
+
+ Read all configuration files in the dir given by 'dirname' in the
+ correct order.
+
+
+.. function:: read_config_file_isc(configuration, filename)
+
+ Read the configuration file *filename* and set the appropriate
+ options in the configuration object *configuration*. This function
+ requires a slightly different format than APT configuration files,
+ if you are unsure, do not use it.
+
+.. function:: parse_commandline(configuration, options, argv)
+
+ Parse the command line in *argv* into the configuration space. The
+ list *options* contains a list of 3-tuples or 4-tuples in the form::
+
+ (short_option: str, long_option: str, variable: str[, type: str])
+
+ The element *short_option* is one character, the *long_option* element
+ is the name of the long option, the element *variable* the name of the
+ configuration option the result will be stored in and *type* is one of
+ 'HasArg', 'IntLevel', 'Boolean', 'InvBoolean', 'ConfigFile',
+ 'ArbItem'. The default type is 'Boolean'.
+
+ .. table:: Overview of all possible types
+
+ =========== =====================================================
+ Type What happens if the option is given
+ =========== =====================================================
+ HasArg The argument given to the option is stored in
+ the target.
+ IntLevel The integer value in the target is increased by one
+ Boolean The target variable is set to True.
+ InvBoolean The target variable is set to False.
+ ConfigFile The file given as an argument to this option is read
+ in and all configuration options are added to the
+ configuration object (APT's '-c' option).
+ ArbItem The option takes an argument *key*=*value*, and the
+ configuration option at *key* is set to the value
+ *value* (APT's '-o' option).
+ =========== =====================================================
+
+
+Locking
+--------
+When working on the global cache, it is important to lock the cache so other
+programs do not modify it. This module provides two context managers for
+locking the package system or file-based locking.
+
+.. class:: SystemLock
+
+ Context manager for locking the package system. The lock is established
+ as soon as the method __enter__() is called. It is released when
+ __exit__() is called. If the lock can not be acquired or can not be
+ released an exception is raised.
+
+ This should be used via the 'with' statement. For example::
+
+ with apt_pkg.SystemLock():
+ ... # Do your stuff here.
+ ... # Now it's unlocked again
+
+ Once the block is left, the lock is released automatically. The object
+ can be used multiple times::
+
+ lock = apt_pkg.SystemLock()
+ with lock:
+ ...
+ with lock:
+ ...
+
+.. class:: FileLock(filename: str)
+
+ Context manager for locking using a file. The lock is established
+ as soon as the method __enter__() is called. It is released when
+ __exit__() is called. If the lock can not be acquired or can not be
+ released, an exception is raised.
+
+ This should be used via the 'with' statement. For example::
+
+ with apt_pkg.FileLock(filename):
+ ...
+
+ Once the block is left, the lock is released automatically. The object
+ can be used multiple times::
+
+ lock = apt_pkg.FileLock(filename)
+ with lock:
+ ...
+ with lock:
+ ...
+
+For Python versions prior to 2.5, similar functionality is provided by the
+following three functions:
+
+.. function:: get_lock(filename: str, errors=False) -> int
+
+ Create an empty file at the path specified by the parameter *filename* and
+ lock it. If this fails and *errors* is **True**, the function raises an
+ error. If *errors* is **False**, the function returns -1.
+
+ The lock can be acquired multiple times within the same process, and can be
+ released by calling :func:`os.close` on the return value which is the file
+ descriptor of the created file.
+
+.. function:: pkgsystem_lock()
+
+ Lock the global pkgsystem. The lock should be released by calling
+ :func:`pkgsystem_unlock` again. If this function is called n-times, the
+ :func:`pkgsystem_unlock` function must be called n-times as well to release
+ all acquired locks.
+
+.. function:: pkgsystem_unlock()
+
+ Unlock the global pkgsystem. This reverts the effect of
+ :func:`pkgsystem_lock`.
+
+Since version 1.7, APT switches to the frontend locking approach where
+dpkg has two lock files, :file:`lock-frontend` and :file:`lock`, the
+latter being called the inner lock in apt.
+When running dpkg, the inner lock must be released before calling dpkg
+and reacquired afterwards. When not using APT functions to run dpkg,
+the variable `DPKG_FRONTEND_LOCKED` must be set to tell dpkg to not
+acquire the :file:`lock-frontend` lock.
+These functions usually do not need to be used by external code.
+
+.. function:: pkgsystem_unlock_inner()
+
+ Release the :file:`lock` lock file to allow dpkg to be run.
+
+ .. versionadded:: 1.7
+
+.. function:: pkgsystem_lock_inner()
+
+ Release the :file:`lock` lock file after a dpkg run.
+
+ .. versionadded:: 1.7
+
+.. function:: pkgsystem_is_locked()
+
+ Returns true if the global lock is hold. Can be used to check whether
+ :meth:`pkgsystem_unlock_inner` needs to be called.
+
+ .. versionadded:: 1.7
+
+
+
+Other classes
+--------------
+.. class:: Cdrom()
+
+ A Cdrom object identifies Debian installation media and adds them to
+ :file:`/etc/apt/sources.list`. The C++ version of this class is used by
+ the apt-cdrom tool and using this class, you can re-implement apt-cdrom
+ in Python, see :doc:`../tutorials/apt-cdrom`.
+
+ The class :class:`apt.cdrom.Cdrom` is a subclass of this class and
+ provides some additional functionality for higher level use and some
+ shortcuts for setting some related configuration options.
+
+ This class provides two functions which take an instance of
+ :class:`apt.progress.base.CdromProgress` as their argument.
+
+ .. method:: add(progress: apt.progress.base.CdromProgress) -> bool
+
+ Search for a Debian installation media and add it to the list of
+ sources stored in :file:`/etc/apt/sources.list`. On success, the
+ boolean value ``True`` is returned. If the process failed or was
+ canceled by the progress class, :exc:`SystemError` is raised or
+ ``False`` is returned.
+
+ .. method:: ident(progress: apt.progress.base.CdromProgress) -> str
+
+ Identify the installation media and return a string which describes
+ its identity. If no media could be identified, :exc:`SystemError` is
+ raised or ``None`` is returned.
+
+.. class:: SourceList
+
+ Represent the list of sources stored in files such as
+ :file:`/etc/apt/sources.list`.
+
+ .. method:: find_index(pkgfile: PackageFile) -> IndexFile
+
+ Return the :class:`IndexFile` object for the :class:`PackageFile`
+ object given by the argument *pkgfile*. If no index could be found,
+ return ``None``.
+
+ .. method:: get_indexes(acquire: Acquire[, all: bool = False]) -> bool
+
+ Add all indexes to the :class:`Acquire` object given by the argument
+ *acquire*. If *all* is ``True``, all indexes will be added, otherwise
+ only the meta indexes (Release files) will be added and others are
+ fetched as needed.
+
+ .. method:: read_main_list() -> bool
+
+ Read the files configured in Dir::Etc::SourceList and
+ Dir::Etc::sourceparts; that is (on normal system),
+ :file:`/etc/apt/sources.list` and the files in
+ :file:`/etc/apt/sources.list.d`.
+
+ .. attribute:: list
+
+ A list of :class:`MetaIndex` objects.
+
+String functions
+----------------
+.. function:: base64_encode(value: bytes) -> str
+
+ Encode the given bytes string (which may not contain a null byte)
+ using base64, for example, on Python 3 and newer::
+
+ >>> apt_pkg.base64_encode(b"A")
+ 'QQ=='
+
+ on Python versions prior to 3, the 'b' before the string has to be
+ omitted.
+
+.. function:: check_domain_list(host, list)
+
+ See if the host name given by *host* is one of the domains given in the
+ comma-separated list *list* or a subdomain of one of them.
+
+ >>> apt_pkg.check_domain_list("alioth.debian.org","debian.net,debian.org")
+ True
+
+.. function:: dequote_string(string: str)
+
+ Dequote the string specified by the parameter *string*, e.g.::
+
+ >>> apt_pkg.dequote_string("%61%70%74%20is%20cool")
+ 'apt is cool'
+
+.. function:: quote_string(string, repl)
+
+ Escape the string *string*, replacing any character not allowed in a URL
+ or specified by *repl* with its ASCII value preceded by a percent sign
+ (so for example ' ' becomes '%20').
+
+ >>> apt_pkg.quote_string("apt is cool","apt")
+ '%61%70%74%20is%20cool'
+
+.. function:: size_to_str(size: int)
+
+ Return a string describing the size in a human-readable manner using
+ SI prefix and base-10 units, e.g. '1k' for 1000, '1M' for 1000000, etc.
+
+ Example::
+
+ >>> apt_pkg.size_to_str(10000)
+ '10.0k'
+
+.. function:: string_to_bool(input)
+
+ Parse the string *input* and return one of **-1**, **0**, **1**.
+
+ .. table:: Return values
+
+ ===== =============================================
+ Value Meaning
+ ===== =============================================
+ -1 The string *input* is not recognized.
+ 0 The string *input* evaluates to **False**.
+ +1 The string *input* evaluates to **True**.
+ ===== =============================================
+
+ Example::
+
+ >>> apt_pkg.string_to_bool("yes")
+ 1
+ >>> apt_pkg.string_to_bool("no")
+ 0
+ >>> apt_pkg.string_to_bool("not-recognized")
+ -1
+
+
+.. function:: str_to_time(rfc_time)
+
+ Convert the :rfc:`1123` conforming string *rfc_time* to the unix time, and
+ return the integer. This is the opposite of :func:`TimeRFC1123`.
+
+ Example::
+
+ >> apt_pkg.str_to_time('Thu, 01 Jan 1970 00:00:00 GMT')
+ 0
+
+.. function:: time_rfc1123(seconds: int) -> str
+
+ Format the unix time specified by the integer *seconds*, according to the
+ requirements of :rfc:`1123`.
+
+ Example::
+
+ >>> apt_pkg.time_rfc1123(0)
+ 'Thu, 01 Jan 1970 00:00:00 GMT'
+
+
+.. function:: time_to_str(seconds: int) -> str
+
+ Format a given duration in a human-readable manner. The parameter *seconds*
+ refers to a number of seconds, given as an integer. The return value is a
+ string with a unit like 's' for seconds.
+
+ Example::
+
+ >>> apt_pkg.time_to_str(3601)
+ '1h0min1s'
+
+.. function:: upstream_version(version: str) -> str
+
+ Return the upstream version for the Debian package version given by
+ *version*.
+
+.. function:: uri_to_filename(uri: str) -> str
+
+ Take a string *uri* as parameter and return a filename which can be used to
+ store the file, based on the URI.
+
+ Example::
+
+ >>> apt_pkg.uri_to_filename('http://debian.org/index.html')
+ 'debian.org_index.html'
+
+
+.. function:: version_compare(a: str, b: str) -> int
+
+ Compare two versions, *a* and *b*, and return an integer value which has
+ the same meaning as the built-in :func:`cmp` function's return value has,
+ see the following table for details.
+
+ .. table:: Return values
+
+ ===== =============================================
+ Value Meaning
+ ===== =============================================
+ > 0 The version *a* is greater than version *b*.
+ = 0 Both versions are equal.
+ < 0 The version *a* is less than version *b*.
+ ===== =============================================
+
+
+Module Constants
+----------------
+.. _CurStates:
+
+Package States
+^^^^^^^^^^^^^^^
+.. data:: CURSTATE_CONFIG_FILES
+
+ Only the configuration files of the package exist on the system.
+
+.. data:: CURSTATE_HALF_CONFIGURED
+
+ The package is unpacked and configuration has been started, but not
+ yet completed.
+
+.. data:: CURSTATE_HALF_INSTALLED
+
+ The installation of the package has been started, but not completed.
+
+.. data:: CURSTATE_INSTALLED
+
+ The package is unpacked, configured and OK.
+
+.. data:: CURSTATE_NOT_INSTALLED
+
+ The package is not installed.
+
+.. data:: CURSTATE_UNPACKED
+
+ The package is unpacked, but not configured.
+
+.. _InstStates:
+
+Installed states
+^^^^^^^^^^^^^^^^
+.. data:: INSTSTATE_HOLD
+
+ The package is put on hold.
+
+.. data:: INSTSTATE_HOLD_REINSTREQ
+
+ The package is put on hold, but broken and has to be reinstalled.
+
+.. data:: INSTSTATE_OK
+
+ The package is OK.
+
+.. data:: INSTSTATE_REINSTREQ
+
+ The package is broken and has to be reinstalled.
+
+.. _Priorities:
+
+Priorities
+^^^^^^^^^^^
+.. data:: PRI_EXTRA
+
+ The integer representation of the priority 'extra'.
+
+.. data:: PRI_IMPORTANT
+
+ The integer representation of the priority 'important'.
+
+.. data:: PRI_OPTIONAL
+
+ The integer representation of the priority 'optional'.
+
+.. data:: PRI_REQUIRED
+
+ The integer representation of the priority 'required'.
+
+.. data:: PRI_STANDARD
+
+ The integer representation of the priority 'standard'.
+
+
+.. _SelStates:
+
+Package selection states
+^^^^^^^^^^^^^^^^^^^^^^^^
+.. data:: SELSTATE_DEINSTALL
+
+ The package is selected for deinstallation.
+
+.. data:: SELSTATE_HOLD
+
+ The package is marked to be on hold and will not be modified.
+
+.. data:: SELSTATE_INSTALL
+
+ The package is selected for installation.
+
+.. data:: SELSTATE_PURGE
+
+ The package is selected to be purged.
+
+.. data:: SELSTATE_UNKNOWN
+
+ The package is in an unknown state.
+
+
+Build information
+^^^^^^^^^^^^^^^^^
+.. data:: DATE
+
+ The date on which this extension has been compiled.
+
+.. data:: LIB_VERSION
+
+ The version of the apt_pkg library. This is **not** the version of apt,
+ nor the version of python-apt.
+
+.. data:: TIME
+
+ The time this extension has been built.
+
+.. data:: VERSION
+
+ The version of apt (not of python-apt).
diff --git a/doc/source/library/aptsources.distinfo.rst b/doc/source/library/aptsources.distinfo.rst
new file mode 100644
index 0000000..033ef48
--- /dev/null
+++ b/doc/source/library/aptsources.distinfo.rst
@@ -0,0 +1,11 @@
+:mod:`aptsources.distinfo` --- provide meta information for distro repositories
+===============================================================================
+.. note::
+
+ This part of the documentation is created automatically.
+
+
+.. automodule:: aptsources.distinfo
+ :members:
+ :undoc-members:
+
diff --git a/doc/source/library/aptsources.distro.rst b/doc/source/library/aptsources.distro.rst
new file mode 100644
index 0000000..6ebe438
--- /dev/null
+++ b/doc/source/library/aptsources.distro.rst
@@ -0,0 +1,11 @@
+:mod:`aptsources.distro` --- Distribution abstraction of the sources.list
+===============================================================================
+.. note::
+
+ This part of the documentation is created automatically.
+
+
+.. automodule:: aptsources.distro
+ :members:
+ :undoc-members:
+
diff --git a/doc/source/library/aptsources.sourceslist.rst b/doc/source/library/aptsources.sourceslist.rst
new file mode 100644
index 0000000..79b8dd0
--- /dev/null
+++ b/doc/source/library/aptsources.sourceslist.rst
@@ -0,0 +1,11 @@
+:mod:`aptsources.sourceslist` --- Provide an abstraction of the sources.list
+============================================================================
+.. note::
+
+ This part of the documentation is created automatically.
+
+
+.. automodule:: aptsources.sourceslist
+ :members:
+ :undoc-members:
+
diff --git a/doc/source/library/index.rst b/doc/source/library/index.rst
new file mode 100644
index 0000000..0b048c8
--- /dev/null
+++ b/doc/source/library/index.rst
@@ -0,0 +1,35 @@
+Python APT Library
+==================
+Python APT's library provides access to almost every functionality supported
+by the underlying apt-pkg and apt-inst libraries. This means that it is
+possible to rewrite frontend programs like apt-cdrom in Python, and this is
+relatively easy, as can be seen in e.g. :doc:`../tutorials/apt-cdrom`.
+
+When going through the library, the first two modules are :mod:`apt_pkg` and
+:mod:`apt_inst`. These modules are more or less straight bindings to the
+apt-pkg and apt-inst libraries and the base for the rest of python-apt.
+
+Going forward, the :mod:`apt` package appears. This package is using
+:mod:`apt_pkg` and :mod:`apt_inst` to provide easy to use ways to manipulate
+the cache, fetch packages, or install new packages. It also provides useful
+progress classes, currently only for text interfaces. The last package is
+:mod:`aptsources`. The aptsources package provides classes and functions to
+read files like :file:`/etc/apt/sources.list` and to modify them.
+
+.. toctree::
+ :maxdepth: 1
+
+ apt_pkg
+ apt_inst
+
+ apt.cache
+ apt.cdrom
+ apt.debfile
+ apt.package
+ apt.progress.base
+ apt.progress.text
+
+ aptsources.distinfo
+ aptsources.distro
+ aptsources.sourceslist
+
diff --git a/doc/source/templates/indexcontent.html b/doc/source/templates/indexcontent.html
new file mode 100644
index 0000000..be5277e
--- /dev/null
+++ b/doc/source/templates/indexcontent.html
@@ -0,0 +1,50 @@
+{% extends "layout.html" %}
+{% block body %}
+ <h1>{{ docstitle|e }}</h1>
+ <p>
+ Welcome! This is
+ {% block description %}the documentation for {{ project|e }}
+ {{ release|e }}{% if last_updated %}, last updated {{ last_updated|e }}{% endif %}{% endblock %}.
+ </p>
+
+ <p>
+ This documentation has been created using Sphinx and reStructuredText files
+ written by Julian Andres Klode &lt;jak@debian.org&gt;.
+ </p>
+
+
+
+
+ <p><strong>Parts of the documentation:</strong></p>
+ <table class="contentstable" align="center"><tr>
+ <td width="50%">
+ <p class="biglink"><a class="biglink" href="{{ pathto("whatsnew/" + version) }}">What's new in Python APT {{ version }}?</a><br/>
+ <span class="linkdescr">or <a href="{{ pathto("whatsnew/index") }}">all "What's new" documents</a></span></span></p>
+ <p class="biglink"><a class="biglink" href="{{ pathto("library/index") }}">Library Reference</a><br/>
+ <span class="linkdescr">keep this under your pillow</span></p>
+ <p class="biglink"><a class="biglink" href="{{ pathto("tutorials/index") }}">Tutorials</a><br/>
+ <span class="linkdescr">examples and more...</span></p>
+ </td><td width="50%">
+ <p class="biglink"><a class="biglink" href="{{ pathto("c++/embedding") }}">Embedding</a><br/>
+ <span class="linkdescr">tutorial for C++ programmers</span></p>
+ <p class="biglink"><a class="biglink" href="{{ pathto("c++/api") }}">C++ API</a><br/>
+ <span class="linkdescr">reference for C++ programmers</span></p>
+ </td></tr>
+ </table>
+
+ <p><strong>Indices and tables:</strong></p>
+ <table class="contentstable" align="center"><tr>
+ <td width="50%">
+ <p class="biglink"><a class="biglink" href="{{ pathto("py-modindex") }}">Global Module Index</a><br/>
+ <span class="linkdescr">quick access to all modules</span></p>
+ <p class="biglink"><a class="biglink" href="{{ pathto("genindex") }}">General Index</a><br/>
+ <span class="linkdescr">all functions, classes, terms</span></p>
+ </td><td width="50%">
+ <p class="biglink"><a class="biglink" href="{{ pathto("search") }}">Search page</a><br/>
+ <span class="linkdescr">search this documentation</span></p>
+ <p class="biglink"><a class="biglink" href="{{ pathto("contents") }}">Complete Table of Contents</a><br/>
+ <span class="linkdescr">lists all sections and subsections</span></p>
+ </td></tr>
+ </table>
+
+{% endblock %}
diff --git a/doc/source/templates/layout.html b/doc/source/templates/layout.html
new file mode 100644
index 0000000..04a3e0d
--- /dev/null
+++ b/doc/source/templates/layout.html
@@ -0,0 +1,4 @@
+{% extends "!layout.html" %}
+{% block rootrellink %}
+ <li><a href="{{ pathto('index') }}">{{ shorttitle }}</a>{{ reldelim1 }}</li>
+{% endblock %}
diff --git a/doc/source/tutorials/apt-cdrom.rst b/doc/source/tutorials/apt-cdrom.rst
new file mode 100644
index 0000000..7e1d794
--- /dev/null
+++ b/doc/source/tutorials/apt-cdrom.rst
@@ -0,0 +1,156 @@
+Writing your own apt-cdrom
+==========================
+:Author: Julian Andres Klode <jak@debian.org>
+:Release: |release|
+:Date: |today|
+
+This article explains how to utilise python-apt to build your own clone of the
+:command:`apt-cdrom` command. To do this, we will take a look at the
+:mod:`apt.cdrom` and :mod:`apt.progress.text` modules, and we will learn how
+to use apt_pkg.parse_commandline to parse commandline arguments. The code shown
+here works on Python 2 and Python 3.
+
+Basics
+------
+The first step in building your own :command:`apt-cdrom` clone is to import the
+:mod:`apt` package, which will import :mod:`apt.cdrom` and
+:mod:`apt.progress.text`::
+
+ import apt
+
+Now we have to create a new :class:`apt.cdrom.Cdrom` object and pass to it an
+:class:`apt.progress.text.CdromProgress` object, which is responsible for
+displaying the progress and asking questions::
+
+ cdrom = apt.Cdrom(apt.progress.text.CdromProgress())
+
+Now we have to choose the action, depending on the given options on the
+command line. For now, we simply use the value of ``sys.argv[1]``::
+
+ import sys
+ if sys.argv[1] == 'add':
+ cdrom.add()
+ elif sys.argv[1] == 'ident':
+ cdrom.ident()
+
+Now we have a basic :command:`apt-cdrom` clone which can add and identify
+CD-ROMs::
+
+ import sys
+
+ import apt
+
+ cdrom = apt.Cdrom(apt.progress.text.CdromProgress())
+ if sys.argv[1] == 'add':
+ cdrom.add()
+ elif sys.argv[1] == 'ident':
+ cdrom.ident()
+
+Advanced example with command-line parsing
+-------------------------------------------
+Our example clearly misses a way to parse the commandline in a correct
+manner. Luckily, :mod:`apt_pkg` provides us with a function to do this:
+:func:`apt_pkg.parse_commandline`. To use it, we add ``import apt_pkg`` right
+after import apt::
+
+ import sys
+
+ import apt_pkg
+ import apt
+
+
+:func:`apt_pkg.parse_commandline` is similar to :mod:`getopt` functions, it
+takes a list of recognized options and the arguments and returns all unknown
+arguments. If it encounters an unknown argument which starts with a leading
+'-', the function raises an error indicating that the option is unknown. The
+major difference is that this function manipulates the apt configuration space.
+
+The function takes 3 arguments. The first argument is an
+:class:`apt_pkg.Configuration` object. The second argument is a list of tuples
+of the form ``(shortopt, longopt, config, type)``, whereas *shortopt* is a
+character indicating the short option name, *longopt* a string indicating the
+corresponding long option (e.g. ``"--help"``), *config* the name of the
+configuration item which should be set and *type* the type of the argument.
+
+For apt-cdrom, we can use the following statement::
+
+ arguments = apt_pkg.parse_commandline(apt_pkg.config,
+ [('h', "help", "help"),
+ ('v', "version", "version"),
+ ('d', "cdrom", "Acquire::cdrom::mount", "HasArg"),
+ ('r', "rename", "APT::CDROM::Rename"),
+ ('m', "no-mount", "APT::CDROM::NoMount"),
+ ('f', "fast", "APT::CDROM::Fast"),
+ ('n', "just-print", "APT::CDROM::NoAct"),
+ ('n', "recon", "APT::CDROM::NoAct"),
+ ('n', "no-act", "APT::CDROM::NoAct"),
+ ('a', "thorough", "APT::CDROM::Thorough"),
+ ('c', "config-file", "", "ConfigFile"),
+ ('o', "option", "", "ArbItem")], args)
+
+
+This allows us to support all options supported by apt-cdrom. The first option
+is --help. As you can see, it omits the fourth field of the tuple; which means
+it is a boolean argument. Afterwards you could use
+``apt_pkg.config.find_b("help")`` to see whether ``--help`` was specified. In
+``('d',"cdrom","Acquire::cdrom::mount","HasArg")`` the fourth field is
+``"HasArg"``. This means that the option has an argument, in this case the
+location of the mount point. ``('c',"config-file","","ConfigFile")`` shows how
+to include configuration files. This option takes a parameter which points to
+a configuration file which will be added to the configuration space.
+``('o',"option","","ArbItem")`` is yet another type of option, which allows users
+to set configuration options on the commandline.
+
+Now we have to check whether help or version is specified, and print a message
+and exit afterwards. To do this, we use :meth:`apt_pkg.Configuration.find_b`
+which returns ``True`` if the configuration option exists and evaluates to
+``True``::
+
+ if apt_pkg.config.find_b("help"):
+ print("This should be a help message")
+ sys.exit(0)
+ elif apt_pkg.config.find_b("version"):
+ print("Version blah.")
+ sys.exit(0)
+
+
+Now we are ready to create our progress object and our cdrom object. Instead
+of using :class:`apt.Cdrom` like in the first example, we will use
+:class:`apt_pkg.Cdrom` which provides a very similar interface. We could also
+use :class:`apt.Cdrom`, but `apt.Cdrom` provides options like *nomount* which
+conflict with our commandline parsing::
+
+ progress = apt.progress.text.CdromProgress()
+ cdrom = apt_pkg.Cdrom()
+
+
+Now we have to do the action requested by the user on the commandline. To see
+which option was requested, we check the list ``arguments`` which was returned
+by ``apt_pkg.parse_commandline`` above, and afterwards call ``cdrom.add`` or
+``cdrom.ident``::
+
+ if apt_pkg.config.find_b("help"):
+ print("This should be a help message")
+ sys.exit(0)
+ elif apt_pkg.config.find_b("version"):
+ print("Version blah.")
+ sys.exit(0)
+
+ if not arguments:
+ sys.stderr.write('E: No operation specified\n')
+ sys.exit(1)
+ elif arguments[0] == 'add':
+ cdrom.add(progress)
+ elif arguments[0] == 'ident':
+ cdrom.ident(progress)
+ else:
+ sys.stderr.write('E: Invalid operation %s\n' % arguments[0])
+ sys.exit(1)
+
+
+After putting all our actions into a main() function, we get a completely
+working apt-cdrom clone, which just misses useful ``--help`` and ``--version``
+options. If we add a function show_help(), we get an even more complete
+apt-cdrom clone:
+
+.. literalinclude:: ../examples/apt-cdrom.py
diff --git a/doc/source/tutorials/apt-get.rst b/doc/source/tutorials/apt-get.rst
new file mode 100644
index 0000000..26ebc3d
--- /dev/null
+++ b/doc/source/tutorials/apt-get.rst
@@ -0,0 +1,46 @@
+Doing stuff :command:`apt-get` does
+===================================
+:Author: Julian Andres Klode <jak@debian.org>
+:Release: |release|
+:Date: |today|
+
+The following article will show how you can use python-apt to do actions done
+by the :command:`apt-get` command.
+
+
+Printing the URIs of all index files
+------------------------------------
+We all now that we can print the URIs of all our index files by running a
+simple ``apt-get --print-uris update``. We can do the same. Responsible for
+the source entries is the class :class:`apt_pkg.SourceList`, which can be
+combined with an :class:`apt_pkg.Acquire` object using :meth:`get_indexes`.
+
+First of all, we have to create the objects::
+
+ acquire = apt_pkg.Acquire()
+ slist = apt_pkg.SourceList()
+
+Now we have to parse /etc/apt/sources.list and its friends, by using
+:meth:`apt_pkg.SourceList.read_main_list`::
+
+ slist.read_main_list()
+
+The **slist** object now knows about the location of the indexes. We now have
+to load those indexes into the *acquire* object by calling
+:meth:`apt_pkg.SourceList.get_indexes`::
+
+ slist.get_indexes(acquire, True)
+
+The first argument is the acquire object into which we will load these indexes,
+and the second argument means that we want to fetch all indexes. Now the only
+thing left to do is iterating over the list of items and printing out their
+URIs. Luckily, there is :attr:`apt_pkg.Acquire.items` which allows us to
+iterate over the items::
+
+ for item in acquire.items:
+ print(item.desc_uri)
+
+In the end a program could look like this:
+
+.. literalinclude:: ../examples/update-print-uris.py
+
diff --git a/doc/source/tutorials/contributing.rst b/doc/source/tutorials/contributing.rst
new file mode 100644
index 0000000..33f1654
--- /dev/null
+++ b/doc/source/tutorials/contributing.rst
@@ -0,0 +1,315 @@
+Contributing to python-apt
+==========================
+:Author: Julian Andres Klode <jak@debian.org>
+:Release: |release|
+:Date: |today|
+
+Let's say you need a new feature, you can develop it, and you want to get it
+included in python-apt. Then be sure to follow the following guidelines.
+
+Available branches
+-------------------
+First of all, let's talk a bit about the git branches of python-apt. In the
+following parts, we will assume that you use git to create your changes and
+submit them.
+
+Repositories
+^^^^^^^^^^^^
+
+https://salsa.debian.org/apt-team/python-apt.git
+
+ This is the official Debian repository of python-apt.
+ You can clone it using git by doing::
+
+ git clone git://salsa.debian.org/apt-team/python-apt.git
+
+
+ All code which will be uploaded to Debian is here.
+ There are also branches for Ubuntu releases, but those may not be up-to-date.
+
+ Branch names consist of the distribution vendor, followed by a slash,
+ followed by the release of that distribution, for example: ``debian/sid``.
+
+ The current working branch is usually pointed to by ``HEAD``, it is
+ either ``debian/sid`` or ``debian/experimental``.
+
+ If both sid and experimental are active, bug fixes are either cherry-picked from
+ ``debian/experimental`` to ``debian/sid``, or a new release is cut on the sid branch
+ and then merged into experimental.
+
+ Updates to stable release branches, such as ``debian/wheezy``, are almost always
+ cherry-picked or backported from the ``debian/sid`` branch.
+
+
+.. highlight:: cpp
+
+C++ Coding style
+----------------
+This document gives coding conventions for the C++ code comprising
+the C++ extensions of Python APT. Please see the companion
+informational PEP describing style guidelines for Python code (:PEP:`8`).
+
+Note, rules are there to be broken. Two good reasons to break a
+particular rule:
+
+ (1) When applying the rule would make the code less readable, even
+ for someone who is used to reading code that follows the rules.
+
+ (2) To be consistent with surrounding code that also breaks it
+ (maybe for historic reasons) -- although this is also an
+ opportunity to clean up someone else's mess (in true XP style).
+
+This part of the document is derived from :PEP:`7` which was written by
+Guido van Rossum.
+
+
+C++ dialect
+^^^^^^^^^^^
+
+- Use ISO standard C++ (the 2011 version of the standard), headers
+ should also adhere to the 1998 version of the standard.
+
+- Use C++ style // one-line comments for single-line comments.
+
+- No compiler warnings with ``gcc -std=c++11 -Wall -Wno-write-strings``. There
+ should also be no errors with ``-pedantic`` added.
+
+
+Code lay-out
+^^^^^^^^^^^^
+
+- Use 3-space indents, in files that already use them. In new source files,
+ that were created after this rule was introduced, use 4-space indents.
+
+ At some point, the whole codebase may be converted to use only
+ 4-space indents.
+
+- No line should be longer than 79 characters. If this and the
+ previous rule together don't give you enough room to code, your
+ code is too complicated -- consider using subroutines.
+
+- No line should end in whitespace. If you think you need
+ significant trailing whitespace, think again -- somebody's
+ editor might delete it as a matter of routine.
+
+- Function definition style: function name in column 2, outermost
+ curly braces in column 1, blank line after local variable
+ declarations::
+
+ static int extra_ivars(PyTypeObject *type, PyTypeObject *base)
+ {
+ int t_size = PyType_BASICSIZE(type);
+ int b_size = PyType_BASICSIZE(base);
+
+ assert(t_size >= b_size); /* type smaller than base! */
+ ...
+ return 1;
+ }
+
+- Code structure: one space between keywords like 'if', 'for' and
+ the following left paren; no spaces inside the paren; braces as
+ shown::
+
+ if (mro != NULL) {
+ ...
+ }
+ else {
+ ...
+ }
+
+- The return statement should *not* get redundant parentheses::
+
+ return Py_None; /* correct */
+ return(Py_None); /* incorrect */
+
+- Function and macro call style: ``foo(a, b, c)`` -- no space before
+ the open paren, no spaces inside the parens, no spaces before
+ commas, one space after each comma.
+
+- Always put spaces around assignment, Boolean and comparison
+ operators. In expressions using a lot of operators, add spaces
+ around the outermost (lowest-priority) operators.
+
+- Breaking long lines: if you can, break after commas in the
+ outermost argument list. Always indent continuation lines
+ appropriately, e.g.::
+
+ PyErr_Format(PyExc_TypeError,
+ "cannot create '%.100s' instances",
+ type->tp_name);
+
+- When you break a long expression at a binary operator, the
+ operator goes at the end of the previous line, e.g.::
+
+ if (type->tp_dictoffset != 0 && base->tp_dictoffset == 0 &&
+ type->tp_dictoffset == b_size &&
+ (size_t)t_size == b_size + sizeof(PyObject *))
+ return 0; /* "Forgive" adding a __dict__ only */
+
+- Put blank lines around functions, structure definitions, and
+ major sections inside functions.
+
+- Comments go before the code they describe.
+
+- All functions and global variables should be declared static
+ unless they are to be part of a published interface
+
+
+Naming conventions
+^^^^^^^^^^^^^^^^^^
+
+- Use a ``Py`` prefix for public functions; never for static
+ functions. The ``Py_`` prefix is reserved for global service
+ routines like ``Py_FatalError``; specific groups of routines
+ (e.g. specific object type APIs) use a longer prefix,
+ e.g. ``PyString_`` for string functions.
+
+- Public functions and variables use MixedCase with underscores,
+ like this: ``PyObject_GetAttr``, ``Py_BuildValue``, ``PyExc_TypeError``.
+
+- Internal functions and variables use lowercase with underscores, like
+ this: ``hashes_get_sha1.``
+
+- Occasionally an "internal" function has to be visible to the
+ loader; we use the _Py prefix for this, e.g.: ``_PyObject_Dump``.
+
+- Macros should have a MixedCase prefix and then use upper case,
+ for example: ``PyString_AS_STRING``, ``Py_PRINT_RAW``.
+
+
+Documentation Strings
+^^^^^^^^^^^^^^^^^^^^^
+- The first line of each function docstring should be a "signature
+ line" that gives a brief synopsis of the arguments and return
+ value. For example::
+
+ PyDoc_STRVAR(myfunction__doc__,
+ "myfunction(name: str, value) -> bool\n\n"
+ "Determine whether name and value make a valid pair.");
+
+ The signature line should be formatted using the format for function
+ annotations described in :PEP:`3107`, whereas the annotations shall reflect
+ the name of the type (e.g. ``str``). The leading ``def`` and the trailing
+ ``:`` as used for function definitions must not be included.
+
+ Always include a blank line between the signature line and the
+ text of the description.
+
+ If the return value for the function is always ``None`` (because
+ there is no meaningful return value), do not include the
+ indication of the return type.
+
+- When writing multi-line docstrings, be sure to always use
+ string literal concatenation::
+
+ PyDoc_STRVAR(myfunction__doc__,
+ "myfunction(name, value) -> bool\n\n"
+ "Determine whether name and value make a valid pair.");
+
+
+Python Coding Style
+-------------------
+The coding style for all code written in python is :PEP:`8`. Exceptions from
+this rule are the documentation, where code is sometimes formatted differently
+to explain aspects.
+
+When writing code, use tools like pylint, pyflakes, pychecker and pycodestyle
+(all available from Debian/Ubuntu) to verify that your code is
+OK. Fix all the problems which seem reasonable, and mention the unfixed issues
+when asking for merge.
+
+All code must work on both Python 2 and Python 3.
+
+Submitting your patch
+---------------------
+First of all, the patch you create should be based against the most current
+branch of python-apt (debian/sid or debian/experimental). If it is a bugfix,
+you should probably use debian/sid. If you choose the wrong branch, we will
+ask you to rebase your patches against the correct one.
+
+Once you have made your change, check that it:
+
+ * conforms to :PEP:`8` (checked with pycodestyle). It should, at least not
+ introduce new errors. (and never have whitespace at end of line)
+ * produces no new errors in pychecker, pyflakes and pylint (unless you
+ can't fix them, but please tell so when requesting the merge, so it can
+ be fixed before hitting one of the main branches).
+ * does not change the behaviour of existing code in a non-compatible way.
+ * works on both Python 2 and Python 3.
+
+If your change follows all points of the checklist, you can commit it to your
+repository. (You could commit it first, and check later, and then commit the
+fixes, but commits should be logical and it makes no sense to have to commits
+for one logical unit).
+
+The changelog message should follow standard git format. At the end of the
+message, tags understood by gbp-dch and other tags may be added. An example
+commit message could be:
+
+.. code-block:: none
+
+ apt.package: Fix blah blah
+
+ Fix a small bug where foo is doing bar, but should be doing baz
+ instead.
+
+ Closes: #bugnumber
+ LP: #ubuntu-bug-number
+ Reported-By: Bug Reporter Name <email@example.com>
+
+
+Once you have made all your changes, you can run ``git format-patch``,
+specifying the upstream commit or branch you want to create patches
+against. Then you can either:
+
+* report a bug against the python-apt package, attach the patches
+ you created in the previous step, and tag it with 'patch'. It might also be
+ a good idea to prefix the bug report with '[PATCH]'.
+
+* send the patches via ``git send-email``.
+
+For larger patch series, you can also publish a git branch on a
+public repository and request it to be pulled.
+
+If you choose that approach, you may want to base your patches against
+the latest release, and not against some random commit, for the sake of
+preserving a sane git history.
+
+Be prepared to rebase such a branch, and close any bugs you fix in the
+branch by mentioning them in the commit message using a Closes or LP
+tag.
+
+
+Documentation updates
+---------------------
+If you want to update the documentation, please follow the procedure as written
+above. You can send your content in plain text, but reStructuredText is the
+preferred format. I (Julian Andres Klode) will review your patch and include
+it.
+
+.. highlight:: sh
+
+Example patch session
+----------------------
+In the following example, we edit a file, create a patch (an enhanced
+patch), and report a wishlist bug with this patch against the python-apt
+package::
+
+ user@ pc:~$ git clone git://anonscm.debian.org/apt/python-apt.git
+ user@pc:~$ cd python-apt
+ user@pc:~/python-apt$ editor FILES
+ user@pc:~/python-apt$ pycodestyle FILES # Check with pycodestyle
+ user@pc:~/python-apt$ pylint -e FILES # Check with pylint
+ user@pc:~/python-apt$ pyflakes FILES # Check with pyflakes
+ user@pc:~/python-apt$ pychecker FILES # Check with pychecker
+ user@pc:~/python-apt$ git commit -p
+ user@pc:~/python-apt$ git format-patch origin/HEAD
+ user@pc:~/python-apt$ reportbug --severity=wishlist --tag=patch --attach=<patch> ... python-apt
+
+You may also send the patches to the mailing list instead of
+reporting the bug::
+
+ user@pc:~/python-apt$ git send-email --to=deity@lists.debian.org <patches created by format-patch>
+
+You can even push your changes to your own repository and request
+a pull request.
diff --git a/doc/source/tutorials/index.rst b/doc/source/tutorials/index.rst
new file mode 100644
index 0000000..06d31c6
--- /dev/null
+++ b/doc/source/tutorials/index.rst
@@ -0,0 +1,8 @@
+Tutorials
+=========
+
+.. toctree::
+ :maxdepth: 1
+ :glob:
+
+ *
diff --git a/doc/source/whatsnew/0.7.100.rst b/doc/source/whatsnew/0.7.100.rst
new file mode 100644
index 0000000..eda2764
--- /dev/null
+++ b/doc/source/whatsnew/0.7.100.rst
@@ -0,0 +1,211 @@
+What's New In python-apt 0.7.100
+================================
+Python-apt 0.7.100 is a new major release of the python bindings for the APT
+package management libraries. It provides support for Python 3, new language
+features and an API conforming to :PEP:`8`.
+
+Despite the many changes made in python-apt 0.7.100, the release still provides
+backwards compatibility to the 0.7 series. This makes it possible to run your
+old applications.
+
+This documents describes the important changes introduced since the release
+of python-apt 0.7.10.3, starting with the first development release 0.7.90
+from April 2009.
+
+.. note::
+
+ Applications using the old API should be updated to the new API because
+ the old ones will be dropped in a future release. To build a python-apt
+ variant without the deprecated API, build it without the -DCOMPAT_0_7
+ compiler flag.
+
+Support for Python 3
+--------------------
+Python-apt is the first Debian package to support the third major release of
+Python. The port is straight forward and integrates as nicely in Python 3 as
+the Python 2 builds integrate in Python 2.
+
+Please be aware that python-apt builds for Python 3 are built without the
+compatibility options enabled for Python 2 builds. They also do not provide
+methods like :meth:`has_key` on mapping objects, because it has been removed
+in Python 3.
+
+Python 3 support may be disabled by distributions.
+
+Real classes in :mod:`apt_pkg`
+------------------------------
+The 0.7.100 release introduces real classes in the :mod:`apt_pkg` extension. This
+is an important step forward and makes writing code much easier, because you
+can see the classes without having to create an object first. It also makes
+it easier to talk about those classes, because they have a real name now.
+
+The 0.7 series shipped many functions for creating new objects, because the
+classes were not exported. In 0.7.100, the classes themselves replace those
+functions, as you can see in the following table.
+
+.. table::
+
+ ===================================== =================================
+ Function Replacing class
+ ===================================== =================================
+ :func:`apt_pkg.GetAcquire` :class:`apt_pkg.Acquire`
+ :func:`apt_pkg.GetCache()` :class:`apt_pkg.Cache`
+ :func:`apt_pkg.GetCdrom()` :class:`apt_pkg.Cdrom`
+ :func:`apt_pkg.GetDepCache()` :class:`apt_pkg.DepCache`
+ :func:`apt_pkg.GetPackageManager` :class:`apt_pkg.PackageManager`
+ :func:`apt_pkg.GetPkgAcqFile` :class:`apt_pkg.AcquireFile`
+ :func:`apt_pkg.GetPkgActionGroup` :class:`apt_pkg.ActionGroup`
+ :func:`apt_pkg.GetPkgProblemResolver` :class:`apt_pkg.ProblemResolver`
+ :func:`apt_pkg.GetPkgRecords` :class:`apt_pkg.PackageRecords`
+ :func:`apt_pkg.GetPkgSourceList` :class:`apt_pkg.SourceList`
+ :func:`apt_pkg.GetPkgSrcRecords` :class:`apt_pkg.SourceRecords`
+ :func:`apt_pkg.ParseSection` :class:`apt_pkg.TagSection`
+ :func:`apt_pkg.ParseTagFile` :class:`apt_pkg.TagFile`
+ ===================================== =================================
+
+Complete rename of functions, methods and attributes
+-----------------------------------------------------
+In May 2008, Ben Finney reported bug 481061 against the python-apt package,
+asking for PEP8 conformant names. With the release of python-apt 0.7.100, this
+is finally happening.
+
+Context managers for the :keyword:`with` statement
+--------------------------------------------------
+This is not a real big change, but it's good to have it:
+:class:`apt_pkg.ActionGroup` can now be used as a context manager for the
+:keyword:`with` statement. This makes it more obvious that you are using an
+action group, and is just cooler::
+
+ with apt_pkg.ActionGroup(depcache):
+ for package in my_selected_packages:
+ depcache.mark_install(package)
+
+This also works for :class:`apt.Cache`::
+
+ with cache.actiongroup(): # cache is an Instance of apt.Cache
+ for package in my_selected_packages:
+ package.mark_install() # Instance of apt.Package
+
+Yet another context manager is available for locking the package system::
+
+ with apt_pkg.SystemLock():
+ # do your stuff here
+ pass
+
+There is also one for file based locking::
+
+ with apt_pkg.FileLock(filename):
+ # do your stuff here
+ pass
+
+
+Unification of dependency handling
+----------------------------------
+In apt 0.7.XX, there were three different return types of functions parsing
+dependencies.
+
+First of all, there were :func:`apt_pkg.ParseDepends()` and
+:func:`apt_pkg.ParseSrcDepends()` which returned a list of or groups (which
+are lists themselves) which contain tuples in the format ``(package,ver,op)``,
+whereas op is one of "<=",">=","<<",">>","=","!=".
+
+Secondly, there was Package.DependsListStr which returned a dictionary mapping
+the type of the dependency (e.g. 'Depends', 'Recommends') to a list similar to
+those of :func:`apt_pkg.ParseDepends()`. The only difference was that the
+values ">>", "<<" of op are ">", "<" instead.
+
+Thirdly, there was SourceRecords.BuildDepends, which returned a simple list
+of tuples in the format ``(package, version, op, type)``, whereas ``op`` was
+the integer representation of those ">>", "<<" actions and ``type`` an integer
+representing the type of the dependency (e.g. 'Build-Depends'). The whole
+format was almost useless from the Python perspective because the string
+representations or constants for checking the values were not exported.
+
+python-apt 0.7.100 puts an end to this confusion and uses one basic format, which
+is the format known from Package.DependsListStr. The format change only applies
+to the new functions and attributes, i.e. :attr:`SourceRecords.build_depends`
+will now return a dict, whereas :attr:`SourceRecords.BuildDepends` will still
+return the classic format. The functions :func:`apt_pkg.parse_depends` and
+:func:`apt_pkg.parse_src_depends` now use the same values for ``op`` as
+:attr:`Package.DependsListStr` does.
+
+Example::
+
+ >>> s = apt_pkg.SourceRecords()
+ >>> s.lookup("apt")
+ 1
+ >>> s.build_depends
+ {'Build-Depends': [[('debhelper', '5.0', '>=')],
+ [('libdb-dev', '', '')],
+ [('gettext', '0.12', '>=')],
+ [('libcurl4-gnutls-dev', '', ''),
+ ('libcurl3-gnutls-dev', '7.15.5', '>=')],
+ [('debiandoc-sgml', '', '')],
+ [('docbook-utils', '0.6.12', '>=')],
+ [('xsltproc', '', '')],
+ [('docbook-xsl', '', '')],
+ [('xmlto', '', '')]]}
+ >>> s.BuildDepends
+ [('debhelper', '5.0', 2, 0),
+ ('libdb-dev', '', 0, 0),
+ ('gettext', '0.12', 2, 0),
+ ('libcurl4-gnutls-dev', '', 16, 0),
+ ('libcurl3-gnutls-dev', '7.15.5', 2, 0),
+ ('debiandoc-sgml', '', 0, 0),
+ ('docbook-utils', '0.6.12', 2, 0),
+ ('xsltproc', '', 0, 0),
+ ('docbook-xsl', '', 0, 0),
+ ('xmlto', '', 0, 0)]
+
+C++ headers
+------------
+The 0.7.100 release introduces python-apt-dev which provides headers for
+developers to provide Python support in the libapt-pkg-using application.
+
+Redesign of :mod:`apt_inst`
+---------------------------
+The 0.7.100 series redesigns the :mod:`apt_inst` module to provide
+more flexible classes replacing the older functions. The older functions
+are still available in Python 2 builds, but are deprecated and will be
+removed in the future.
+
+Other changes
+-------------
+This release of python-apt also features several other, smaller changes:
+
+ * Reduced memory usage by making :class:`apt.Cache` create
+ :class:`apt.Package()` object dynamically, instead of creating all of
+ them during the cache initialization.
+ * Support to set the candidate version in :class:`apt.package.Package`
+ * Support for reading gzip-compressed files in apt_pkg.TagFile.
+ * Various changes to :mod:`apt.debfile` have been merged from gdebi.
+
+There have been various other changes, see the changelog for a complete list
+of changes.
+
+
+Porting your applications to the new python-apt API
+----------------------------------------------------
+Porting your application to the new python-apt API may be trivial. You
+should download the source tarball of python-apt and run the tool
+utils/migrate-0.8 over your code::
+
+ utils/migrate-0.8.py -c myapp.py mypackage/
+
+This will search your code for places where possibly deprecated names are
+used. Using the argument ``-c``, you can turn colorized output on.
+
+Now that you know which parts of your code have to be changed, you have to know
+how to do this. For classes, please look at the table. For all attributes,
+methods, functions, and their parameters the following rules apply:
+
+ 1. Replace leading [A-Z] with [a-z] (e.g DescURI => descURI)
+ 2. Replace multiple [A-Z] with [A-Z][a-z] (e.g. descURI => descUri)
+ 3. Replace every [A-Z] with the corresponding [a-z] (descUri => desc_uri)
+
+As an exception, refixes such as 'de' (e.g. 'dequote') or 'un' (e.g. 'unlock')
+are normally not separated by underscores from the next word. There are also
+some other exceptions which are listed here, and apply to any name containing
+this word: **filename**, **filesize**, **destdir**, **destfile**, **dequote**,
+**unlock**, **reinstall**, **pinfile**, **REINSTREQ**, **UNPACKED**,
+**parse_commandline**.
diff --git a/doc/source/whatsnew/0.8.0.rst b/doc/source/whatsnew/0.8.0.rst
new file mode 100644
index 0000000..2eeb135
--- /dev/null
+++ b/doc/source/whatsnew/0.8.0.rst
@@ -0,0 +1,38 @@
+What's New In python-apt 0.8
+============================
+Python-apt 0.8 is a new major release of the python bindings for the APT
+package management libraries.
+
+
+Removal of old API
+------------------
+The old API that was deprecated in 0.7.100 is no longer available. Applications
+that have not yet updated to the new API should do so.
+
+Multi-arch support
+------------------
+This version of python-apt introduces multi-arch support:
+
+ * A new class, :class:`apt_pkg.Group` has been added.
+ * :class:`apt_pkg.Cache` can now be indexed by ``(name, architecture)``
+ tuples
+
+Features for mancoosi
+----------------------
+Several new features related to ordering have been added on request
+of the mancoosi project:
+
+ * A new class :class:`apt_pkg.OrderList` has been added
+ * The :class:`apt_pkg.PackageManager` class now provides new methods
+ for registering install/remove/configure actions which can be
+ subclassed to check ordering.
+
+Other changes
+-------------
+This release of python-apt also features several other, smaller changes:
+
+ * apt_pkg.Cache() now takes None for the progress parameter, preventing
+ progress reporting.
+
+There have been various other changes, see the changelog for a complete list
+of changes.
diff --git a/doc/source/whatsnew/0.9.4.rst b/doc/source/whatsnew/0.9.4.rst
new file mode 100644
index 0000000..617ef08
--- /dev/null
+++ b/doc/source/whatsnew/0.9.4.rst
@@ -0,0 +1,17 @@
+What's New In python-apt 0.9.4
+==============================
+Python-apt 0.9.4 is a maintenance update.
+
+New features
+------------
+
+ * Support for apt_pkg.sha512sum()
+ * Support for apt_pkg.maybe_open_clear_signed_file()
+ * Use apt_pkg.open_maybe_clear_signed_file() when opening a .dsc file
+ * add MULTI_ARCH_NO constant (MULTI_ARCH_NONE is deprecated)
+
+Maintenance
+-----------
+
+ * Add Ubuntu Wily
+ * Update examples
diff --git a/doc/source/whatsnew/1.0.rst b/doc/source/whatsnew/1.0.rst
new file mode 100644
index 0000000..b3364ad
--- /dev/null
+++ b/doc/source/whatsnew/1.0.rst
@@ -0,0 +1,75 @@
+What's New In python-apt 1.0
+==============================
+Python-Apt 1.0 fixes several issues and use of deprecated methods. Most
+importantly, it introduces large file support
+
+New features
+------------
+* :class:`apt_pkg.AcquireFile` can now take a hash string that is not an
+ md5 value, using the new `hash` argument.
+* A new a :meth:`apt_pkg.TagFile.close` method was added
+* :class:`apt_pkg.TagFile` is now a context manager
+
+* The high-level cache class, :class:`apt.cache.Cache` and it's companion
+ :class:`apt.cache.FilteredCache` now support package
+ names with special architecture qualifiers such as :all and :native.
+
+* The method :meth:`apt.cache.Cache.connect2` allows connecting callbacks on
+ cache changes that take the cache as their first argument, reducing the
+ potential for reference cycles.
+
+* The property :attr:`apt.package.Version.is_installed` was added.
+* The properties :attr:`apt.package.BaseDependency.installed_target_versions`
+ and :attr:`apt.package.Dependency.installed_target_versions` were added.
+
+* The property :class:`apt.Dependency.rawtype` was added to give the raw type
+ of a dependency, such as 'Depends'.
+
+* The attribute :attr:`apt_pkg.Dependency.comp_type_deb` and the property
+ :attr:`apt.Dependency.relation_deb` were added, they return a Debian-style
+ comparison operator instead of a mathematical-style one.
+
+* A new filter for filtered caches is provided, :class:`apt.cache.InstalledFilter`.
+
+Backward-incompatible changes
+-----------------------------
+* :class:`apt.Version` now compares package names in addition to version only
+ when checking for equality. This was broken previously.
+
+Deprecated
+----------
+The following features are deprecated, starting with this release:
+
+* The `section` member of :class:`apt_pkg.Package`
+* The `files` member of of :class:`apt_pkg.SourceRecords`
+* The `md5` argument to :class:`apt_pkg.AcquireFile`, it is replaced by
+ the `hash` argument.
+* The method :meth:`apt.cache.Cache.connect` has been deprecated. It is
+ replaced by :meth:`apt.cache.Cache.connect2` which is more flexible and
+ less prone to reference cycles.
+* The attribute :attr:`apt_pkg.AcquireItem.mode` has been replaced by
+ :attr:`apt_pkg.AcquireItem.active_subprocess`
+* The class :class:`apt_pkg.IndexRecords` has been deprecated and will
+ be removed in the next release.
+
+Removed
+-------
+* The module :mod:`apt.progress.gtk2` has been removed. There were no
+ users in the Debian archive, its last update was in 2013, and it was buggy
+ already. Apart from that, it suggested that it is OK to run a graphical
+ application as root, and used the unmaintained GTK+ 2 version.
+
+ Therefore, there is no replacement, please use PackageKit or aptdaemon
+ for installation in graphical environments.
+* The attribute :attr:`apt_pkg.Package.auto` was not set anymore, and thus
+ removed.
+
+Maintenance
+-----------
+* The classes :class:`apt.cache.Cache` and :class:`apt.cache.FilteredCache` no
+ longer store cyclic references to/between them. This fixes a huge issue,
+ because a cache can have tens of open file descriptors, causing the maximum
+ of file descriptors to be reached easily.
+
+* :mod:`apt_inst` now supports ar and tar archives that are larger than 4 GiB
+* Various smaller bug fixes
diff --git a/doc/source/whatsnew/1.1.rst b/doc/source/whatsnew/1.1.rst
new file mode 100644
index 0000000..5a4f5c3
--- /dev/null
+++ b/doc/source/whatsnew/1.1.rst
@@ -0,0 +1,28 @@
+What's New In python-apt 1.1
+==============================
+This release is built against APT 1.1
+
+Highlights
+----------
+* Code that previously raised :class:`SystemError` now raises
+ :class:`apt_pkg.Error`.
+
+Removed
+-------
+* The class :class:`apt_pkg.IndexRecords` has been removed, as it was removed
+ in APT 1.1
+* :attr:`apt_pkg.Dependency.smart_target_pkg` has been removed.
+
+Added
+------
+* The class :class:`apt_pkg.HashStringList` has been added.
+* The class :class:`apt_pkg.Error` and an alias :class:`apt_inst.Error` has
+ been added.
+
+
+Deprecated
+----------
+* :attr:`apt_pkg.PackageRecords.md5_hash`,
+ :attr:`apt_pkg.PackageRecords.sha1_hash`, and
+ :attr:`apt_pkg.PackageRecords.sha256_hash`
+ are replaced by :attr:`apt_pkg.PackageRecords.hashes`.
diff --git a/doc/source/whatsnew/1.4.rst b/doc/source/whatsnew/1.4.rst
new file mode 100644
index 0000000..fa3f95d
--- /dev/null
+++ b/doc/source/whatsnew/1.4.rst
@@ -0,0 +1,16 @@
+What's New In python-apt 1.4
+============================
+This release is built against APT 1.4, see :doc:`1.1` for the other changes
+since 1.0, the last series with a feature-complete release. There are no 1.2
+or 1.3 series.
+
+Added
+------
+* The methods :meth:`apt_pkg.parse_depends` and :meth:`apt_pkg.parse_src_depends`
+ gained a new parameter *architecture* to change the architecture the dependency lines
+ are interpreted for, matching the change in apt 1.4~beta3.
+
+ This only really makes sense for the latter option right now, as it only
+ affects the parsing of architecture lists.
+
+ By default, the host architecture is used.
diff --git a/doc/source/whatsnew/1.6.rst b/doc/source/whatsnew/1.6.rst
new file mode 100644
index 0000000..2015bee
--- /dev/null
+++ b/doc/source/whatsnew/1.6.rst
@@ -0,0 +1,26 @@
+What's New In python-apt 1.6
+============================
+
+Changed
+-------
+* Methods of :class:`apt_pkg.DepCache` now raise an exception if passed
+ objects belonging to a different cache, in order to avoid segmentation
+ faults or wrong behavior.
+
+ .. versionchanged:: 1.6.1
+
+ Starting with 1.6.1 and 1.7~alpha1, the exception raised is
+ :class:`apt_pkg.CacheMismatchError`, and :class:`apt.cache.Cache` will
+ automatically remap open packages and versions to a new cache.
+
+* Initial type hints
+
+* :attr:`apt_pkg.SourceRecords.files` now returns a
+ :class:`apt_pkg.SourceRecordsFile` object with getters instead of
+ a tuple (but it also emulates the tuple).
+
+Bugfixes
+--------
+* Various other fixes for segmentation faults
+* apt/auth.py: Protect against race with gpg when removing tmpdir
+ (Closes: #871585)
diff --git a/doc/source/whatsnew/1.7.rst b/doc/source/whatsnew/1.7.rst
new file mode 100644
index 0000000..38485f7
--- /dev/null
+++ b/doc/source/whatsnew/1.7.rst
@@ -0,0 +1,42 @@
+What's New In python-apt 1.7
+============================
+
+Changed
+--------
+* Starting with 1.6.1 and 1.7~alpha1, the exception raised when
+ passing objects of a different cache to :class:`apt_pkg.DepCache`
+ is :class:`apt_pkg.CacheMismatchError`, and :class:`apt.cache.Cache` will
+ automatically remap open packages and versions to a new cache.
+
+* :meth:`apt_pkg.Policy.get_priority()` now accepts :class:`apt_pkg.Version`
+ objects in addition to :class:`apt_pkg.Package` and :class:`apt_pkg.PackageFile`
+ ones.
+
+* :attr:`apt.package.Version.policy_priority` now returns the priority
+ for that version rather than the highest priority for one of its
+ package files.
+
+* :meth:`apt.Cache.commit` and :meth:`apt_pkg.DepCache.commit` now use
+ frontend locking to run dpkg.
+
+Added
+------
+* The class :class:`apt_pkg.PackageRecords` can now lookup custom fields
+ using ``records[key]`` and ``key in records``.
+
+
+* All code is now statically typed. Some methods from :mod:`apt_pkg`
+ and :mod:`apt_inst` might still be missing or more strict than
+ necessary.
+
+* A new method :meth:`apt.cache.Cache.fix_broken` has been added.
+
+* New methods for frontend locking have been added:
+ :meth:`apt_pkg.pkgsystem_lock_inner`,
+ :meth:`apt_pkg.pkgsystem_unlock_inner`,
+ :meth:`apt_pkg.pkgsystem_is_locked` (starting in alpha 3).
+
+Deprecated
+----------
+* :meth:`apt_pkg.Policy.get_priority()` accepting :class:`apt_pkg.Package`
+ is deprecated.
diff --git a/doc/source/whatsnew/1.8.rst b/doc/source/whatsnew/1.8.rst
new file mode 100644
index 0000000..0f9704f
--- /dev/null
+++ b/doc/source/whatsnew/1.8.rst
@@ -0,0 +1,8 @@
+What's New In python-apt 1.8
+============================
+
+
+Added
+------
+* A new method :meth:`apt_pkg.Policy.init_defaults` has been added
+ in 1.8.2.
diff --git a/doc/source/whatsnew/2.0.rst b/doc/source/whatsnew/2.0.rst
new file mode 100644
index 0000000..ed2b063
--- /dev/null
+++ b/doc/source/whatsnew/2.0.rst
@@ -0,0 +1,37 @@
+What's New In python-apt 2.0
+============================
+Changes since 1.8.
+
+Added
+-----
+* The method :meth:`apt_pkg.TagSection.write()` has been added
+* The attribute :attr:`apt_pkg.HashString.hashvalue` has been added
+* The constructor :class:`apt_pkg.AcquireFile` now accepts an
+ :class:`apt_pkg.HashStringList` as the *hash* argument.
+
+* The classes :class:`apt_pkg.HashString` and :class:`apt_pkg.HashStringList`
+ gained a new ``usable`` property.
+
+Removed
+-------
+* The methods called `install_protect` have been removed
+* The `section` attribute has been removed from :class:`apt_pkg.Package`
+ and :class:`apt.package.Package`
+* The method :meth:`apt_pkg.rewrite_section` has been removed
+* The attributes :attr:`apt_pkg.Hashes.md5`, :attr:`apt_pkg.Hashes.sha1`, :attr:`apt_pkg.Hashes.sha256` have been removed
+* The method :meth:`apt_pkg.Policy.get_match` has been removed.
+* The constructor :class:`apt_pkg.AcquireFile` no longer takes an *md5* argument.
+
+Changed
+-------
+* In :class:`apt_pkg.SourceRecords`, the tuple view of files now always contains
+ None where it previously contained the md5 hash.
+* The method :meth:`apt_pkg.Policy.get_priority()` no longer accepts :class:`apt_pkg.Package` instances.
+* Instances of :class:`apt_pkg.HashString` can now be compared for equality
+* :class:`apt.progress.base.InstallProgress` is now a context manager, use it in
+ a ``with`` statement to avoid leaking file descriptors.
+
+Bug fixes
+---------
+
+* Fixed unterminated ``char*`` array in :class:`apt_pkg.TagRemove` constructor.
diff --git a/doc/source/whatsnew/2.1.rst b/doc/source/whatsnew/2.1.rst
new file mode 100644
index 0000000..ecbd995
--- /dev/null
+++ b/doc/source/whatsnew/2.1.rst
@@ -0,0 +1,7 @@
+What's New In python-apt 2.1
+============================
+2.1 is the development series for 2.2
+
+Removed
+-------
+* Support for Python 2 (2.1.0)
diff --git a/doc/source/whatsnew/index.rst b/doc/source/whatsnew/index.rst
new file mode 100644
index 0000000..cc270a1
--- /dev/null
+++ b/doc/source/whatsnew/index.rst
@@ -0,0 +1,9 @@
+What's new in python-apt
+========================
+
+.. toctree::
+ :maxdepth: 2
+ :glob:
+
+ *
+