diff options
| -rw-r--r-- | debian/changelog | 2 | ||||
| -rw-r--r-- | doc/source/library/apt_pkg.rst | 25 | ||||
| -rw-r--r-- | python/cache.cc | 46 |
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 = |
