summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--debian/changelog2
-rw-r--r--doc/source/library/apt_pkg.rst25
-rw-r--r--python/cache.cc46
3 files changed, 54 insertions, 19 deletions
diff --git a/debian/changelog b/debian/changelog
index 55c97813..f241e749 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -5,6 +5,8 @@ python-apt (0.8.0~exp1) UNRELEASED; urgency=low
* Add apt_pkg.Group class, wrapping pkgCache::GrpIterator
* Change apt_pkg.Cache() so that passing None for 'progress' results in
no progress output
+ * Support (name, arch) tuples in apt_pkg.Cache mappings, wrapping
+ FindPkg() with two string parameters.
-- Julian Andres Klode <jak@debian.org> Tue, 05 Apr 2011 10:33:54 +0200
diff --git a/doc/source/library/apt_pkg.rst b/doc/source/library/apt_pkg.rst
index 709648ac..74bba8db 100644
--- a/doc/source/library/apt_pkg.rst
+++ b/doc/source/library/apt_pkg.rst
@@ -43,15 +43,36 @@ Working with the cache
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-seperated name:architecture pairs. For
+ normal architectures, they are equal to a (name, architecture)
+ tuple. For the 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*.
+ *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.
.. describe:: pkgname in cache
Check whether a package with the name given by *pkgname* exists in
- the cache.
+ 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.
.. method:: update(progress, sources [, pulse_interval]) -> bool
diff --git a/python/cache.cc b/python/cache.cc
index 6f1585e5..cb877eee 100644
--- a/python/cache.cc
+++ b/python/cache.cc
@@ -249,24 +249,37 @@ static PyGetSetDef PkgCacheGetSet[] = {
{}
};
+// Helper to call FindPkg(name) or FindPkg(name, architecture)
+static pkgCache::PkgIterator CacheFindPkg(PyObject *self, PyObject *arg)
+{
+ const char *name;
+ const char *architecture;
+ pkgCache *cache = GetCpp<pkgCache *>(self);
+ name = PyObject_AsString(arg);
-// Map access, operator []
-static PyObject *CacheMapOp(PyObject *Self,PyObject *Arg)
-{
- pkgCache *Cache = GetCpp<pkgCache *>(Self);
+ if (name != NULL)
+ return cache->FindPkg(name);
- // Get the name of the package, unicode and normal strings.
- const char *Name = PyObject_AsString(Arg);
- if (Name == NULL)
- return 0;
+ PyErr_Clear();
+ if (PyArg_ParseTuple(arg, "ss", &name, &architecture) == 0) {
+ PyErr_Clear();
+ PyErr_Format(PyExc_TypeError, "Expected a string or a pair of strings");
+ return pkgCache::PkgIterator();
+ }
- // Search for the package
- pkgCache::PkgIterator Pkg = Cache->FindPkg(Name);
+ return cache->FindPkg(name, architecture);
+}
+
+// Map access, operator []
+static PyObject *CacheMapOp(PyObject *Self,PyObject *Arg)
+{
+ pkgCache::PkgIterator Pkg = CacheFindPkg(Self, Arg);
if (Pkg.end() == true)
{
- PyErr_SetString(PyExc_KeyError,Name);
+ if (!PyErr_Occurred())
+ PyErr_SetObject(PyExc_KeyError,Arg);
return 0;
}
@@ -276,11 +289,9 @@ static PyObject *CacheMapOp(PyObject *Self,PyObject *Arg)
// Check whether the cache contains a package with a given name.
static int CacheContains(PyObject *Self,PyObject *Arg)
{
- // Get the name of the package, unicode and normal strings.
- const char *Name = PyObject_AsString(Arg);
- if (Name == NULL)
- return 0;
- return (GetCpp<pkgCache *>(Self)->FindPkg(Name).end() == false);
+ bool res = (CacheFindPkg(Self, Arg).end() == false);
+ PyErr_Clear();
+ return res;
}
static PyObject *PkgCacheNew(PyTypeObject *type,PyObject *Args,PyObject *kwds)
@@ -356,7 +367,8 @@ static char *doc_PkgCache = "Cache([progress]) -> Cache() object.\n\n"
"human-readable text to standard output. If it is None, no output\n"
"will be made.\n\n"
"The cache can be used like a mapping from package names to Package\n"
- "objects (although only getting items is supported).";
+ "objects (although only getting items is supported). Instead of a name,\n"
+ "a tuple of a name and an architecture may be used.";
static PySequenceMethods CacheSeq = {0,0,0,0,0,0,0,CacheContains,0,0};
static PyMappingMethods CacheMap = {CacheMapLen,CacheMapOp,0};
PyTypeObject PyCache_Type =