From 21c9ebb9717ed7b157c697a57d1b6ce3225eb9d6 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Tue, 5 Apr 2011 11:23:09 +0200 Subject: Disable the old-style API, and break all packages using it --- debian/changelog | 6 ++++++ debian/control | 30 +++++++++++++++++++++++++++++- debian/rules | 3 ++- 3 files changed, 37 insertions(+), 2 deletions(-) diff --git a/debian/changelog b/debian/changelog index 9f2cefaa..5dd9d69e 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +python-apt (0.8.0~exp1) UNRELEASED; urgency=low + + * Disable the old-style API, and break all packages using it + + -- Julian Andres Klode Tue, 05 Apr 2011 10:33:54 +0200 + python-apt (0.7.100.3) unstable; urgency=low [ Barry Warsaw ] diff --git a/debian/control b/debian/control index 9985a685..0997ab3a 100644 --- a/debian/control +++ b/debian/control @@ -23,7 +23,35 @@ Package: python-apt Architecture: any Depends: ${python:Depends}, ${shlibs:Depends}, ${misc:Depends}, python-apt-common Recommends: lsb-release, iso-codes, python2.6 -Breaks: debdelta (<< 0.28~), packagekit-backend-apt (<= 0.4.8-0ubuntu4) +Breaks: packagekit-backend-apt (<= 0.4.8-0ubuntu4), + computer-janitor (<< 1.14.1-1+), + debdelta (<< 0.41+), + python-dogtail (<< 0.6.1-3.1+), + python-debian (<< 0.1.18+), + python-software-properties (<< 0.70.debian-1+), + aptdaemon (<< 0.11+bzr343-1~), + apt-forktracer (<< 0.3), + apt-listchanges (<< 2.85), + aptoncd (<< 0.1.98+bzr117), + apt-p2p (<< 0.1.6), + apt-xapian-index (<< 0.25), + bcfg2 (<< 1.0.1), + bzr-builddeb (<< 2.4), + debpartial-mirror (<< 0.2.98), + debsecan (<< 0.4.14), + gdebi (<< 0.6.1), + germinate (<< 1.21), + gnome-codec-install (<< 0.4.5), + mini-dinstall (<< 0.6.28), + python-cdd (<< 0.0.10), + rebuildd (<< 0.3.9), + software-center (<< 1.1.21debian2), + tla-buildpackage (<< 0.9.14), + ubuntu-dev-tools (<< 0.93debian1), + unattended-upgrades (<< 0.42debian2), + update-manager (<< 0.200.2-1), + update-notifier (<< 0.99.3debian1), + wajig (<< 2.0.46) Provides: ${python:Provides} Suggests: python-apt-dbg, python-gtk2, python-vte, python-apt-doc XB-Python-Version: ${python:Versions} diff --git a/debian/rules b/debian/rules index 5428375d..0b60bf9f 100755 --- a/debian/rules +++ b/debian/rules @@ -1,7 +1,8 @@ #!/usr/bin/make -f # Should be include-links, but that somehow fails. export DEBVER=$(shell dpkg-parsechangelog | sed -n -e 's/^Version: //p') -export CFLAGS=-Wno-write-strings -DCOMPAT_0_7 +# For compatibility, add -DCOMPAT_0_7 +export CFLAGS=-Wno-write-strings export PATH :=$(CURDIR)/utils:$(PATH) export SHELL = env PATH=$(PATH) sh -- cgit v1.2.3 From f7adc2d7205e2fdbff7d808e8e4c262b65e3e05d Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Tue, 5 Apr 2011 11:27:04 +0200 Subject: Add an 'is_multi_arch' attribute to apt_pkg.Cache --- debian/changelog | 1 + doc/source/library/apt_pkg.rst | 4 ++++ python/cache.cc | 7 +++++++ 3 files changed, 12 insertions(+) diff --git a/debian/changelog b/debian/changelog index 5dd9d69e..48ce8f71 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,6 +1,7 @@ python-apt (0.8.0~exp1) UNRELEASED; urgency=low * Disable the old-style API, and break all packages using it + * Add an 'is_multi_arch' attribute to apt_pkg.Cache -- Julian Andres Klode 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 426cb97e..16593fe8 100644 --- a/doc/source/library/apt_pkg.rst +++ b/doc/source/library/apt_pkg.rst @@ -73,6 +73,10 @@ Working with the cache A list of all :class:`PackageFile` objects stored in the cache. + .. attribute:: is_multi_arch + + An attribute determining whether the cache supports multi-arch. + .. attribute:: package_count The total number of packages available in the cache. This value is diff --git a/python/cache.cc b/python/cache.cc index 190d4f27..b5ebcce4 100644 --- a/python/cache.cc +++ b/python/cache.cc @@ -222,11 +222,18 @@ static PyObject *PkgCacheGetFileList(PyObject *Self, void*) { return List; } +static PyObject *PkgCacheGetIsMultiArch(PyObject *Self, void*) { + pkgCache *Cache = GetCpp(Self); + PyBool_FromLong(Cache->MultiArchCache()); +} + static PyGetSetDef PkgCacheGetSet[] = { {"depends_count",PkgCacheGetDependsCount,0, "The number of apt_pkg.Dependency objects stored in the cache."}, {"file_list",PkgCacheGetFileList,0, "A list of apt_pkg.PackageFile objects stored in the cache."}, + {"is_multi_arch", PkgCacheGetIsMultiArch, 0, + "Whether the cache supports multi-arch."}, {"package_count",PkgCacheGetPackageCount,0, "The number of apt_pkg.Package objects stored in the cache."}, {"package_file_count",PkgCacheGetPackageFileCount,0, -- cgit v1.2.3 From 4548cac388f26cec60f1cef028421db910385565 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Tue, 5 Apr 2011 14:37:16 +0200 Subject: Add apt_pkg.Group class, wrapping pkgCache::GrpIterator --- debian/changelog | 3 +- doc/source/c++/api.rst | 30 +++++++ doc/source/library/apt_pkg.rst | 41 +++++++++ python/apt_pkgmodule.cc | 4 + python/apt_pkgmodule.h | 3 + python/cachegroup.cc | 188 +++++++++++++++++++++++++++++++++++++++++ python/python-apt-helpers.cc | 1 + python/python-apt.h | 8 ++ setup.py | 3 +- tests/test_group.py | 27 ++++++ 10 files changed, 306 insertions(+), 2 deletions(-) create mode 100644 python/cachegroup.cc create mode 100644 tests/test_group.py diff --git a/debian/changelog b/debian/changelog index 48ce8f71..99043a95 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,7 +1,8 @@ python-apt (0.8.0~exp1) UNRELEASED; urgency=low * Disable the old-style API, and break all packages using it - * Add an 'is_multi_arch' attribute to apt_pkg.Cache + * Add an 'is_multi_arch' attribute to apt_pkg.Cache + * Add apt_pkg.Group class, wrapping pkgCache::GrpIterator -- Julian Andres Klode Tue, 05 Apr 2011 10:33:54 +0200 diff --git a/doc/source/c++/api.rst b/doc/source/c++/api.rst index 97ab24d1..4922d272 100644 --- a/doc/source/c++/api.rst +++ b/doc/source/c++/api.rst @@ -389,6 +389,36 @@ Description (pkgCache::DescIterator) Return the :ctype:`pkgCache::DescIterator` reference contained in the Python object *object*. + +Group (pkgCache::GrpIterator) +---------------------------------- +.. cvar:: PyTypeObject PyGroup_Type + + The type object for :class:`apt_pkg.Group` objects. + +.. cfunction:: int PyGroup_Check(PyObject *object) + + Check that the object *object* is an :class:`apt_pkg.Group` object, or + a subclass thereof. + +.. cfunction:: int PyGroup_CheckExact(PyObject *object) + + Check that the object *object* is an :class:`apt_pkg.Group` object + and no subclass thereof. + +.. cfunction:: PyObject* PyGroup_FromCpp(pkgCache::GrpIterator &cpp, bool delete, PyObject *owner) + + Create a new :class:`apt_pkg.Group` object from the :ctype:`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 :cdata:`PyCache_Type`. + +.. cfunction:: pkgCache::GrpIterator& PyGroup_ToCpp(PyObject *object) + + Return the :ctype:`pkgCache::GrpIterator` reference contained in the + Python object *object*. + Hashes (Hashes) ---------------------------------- .. cvar:: PyTypeObject PyHashes_Type diff --git a/doc/source/library/apt_pkg.rst b/doc/source/library/apt_pkg.rst index 16593fe8..1b75a154 100644 --- a/doc/source/library/apt_pkg.rst +++ b/doc/source/library/apt_pkg.rst @@ -436,6 +436,47 @@ Resolving Dependencies with :class:`ProblemResolver` Try to resolve the problems without installing or removing packages. +: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 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/python/apt_pkgmodule.cc b/python/apt_pkgmodule.cc index d1ac33e0..e14677b1 100644 --- a/python/apt_pkgmodule.cc +++ b/python/apt_pkgmodule.cc @@ -732,6 +732,9 @@ static struct _PyAptPkgAPIStruct API = { &PyVersion_Type, // version_type &PyVersion_FromCpp, // version_tocpp &PyVersion_ToCpp, // version_tocpp + &PyGroup_Type, // group_type + &PyGroup_FromCpp, // group_fromcpp + &PyGroup_ToCpp // group_tocpp }; @@ -811,6 +814,7 @@ extern "C" void initapt_pkg() ADDTYPE(Module,"DependencyList",&PyDependencyList_Type); // NO __new__(), internal ADDTYPE(Module,"Package",&PyPackage_Type); // NO __new__() ADDTYPE(Module,"Version",&PyVersion_Type); // NO __new__() + ADDTYPE(Module,"Group", &PyGroup_Type); /* ============================ cdrom.cc ============================ */ ADDTYPE(Module,"Cdrom",&PyCdrom_Type); /* ========================= configuration.cc ========================= */ diff --git a/python/apt_pkgmodule.h b/python/apt_pkgmodule.h index da647c3f..0081a1a9 100644 --- a/python/apt_pkgmodule.h +++ b/python/apt_pkgmodule.h @@ -70,6 +70,7 @@ extern PyTypeObject PyCache_Type; extern PyTypeObject PyCacheFile_Type; extern PyTypeObject PyPackageList_Type; extern PyTypeObject PyDescription_Type; +extern PyTypeObject PyGroup_Type; extern PyTypeObject PyPackage_Type; extern PyTypeObject PyPackageFile_Type; extern PyTypeObject PyDependency_Type; @@ -149,6 +150,7 @@ extern PyTypeObject PyFileLock_Type; # define PyDependency_ToCpp GetCpp # define PyDependencyList_ToCpp GetCpp // TODO # define PyDescription_ToCpp GetCpp +# define PyGroup_ToCpp GetCpp # define PyHashes_ToCpp GetCpp # define PyHashString_ToCpp GetCpp # define PyIndexRecords_ToCpp GetCpp @@ -186,6 +188,7 @@ PyObject* PyHashString_FromCpp(HashString* const &obj, bool Delete, PyObject *Ow PyObject* PyIndexRecords_FromCpp(indexRecords* const &obj, bool Delete, PyObject *Owner); PyObject* PyMetaIndex_FromCpp(metaIndex* const &obj, bool Delete, PyObject *Owner); PyObject* PyPackage_FromCpp(pkgCache::PkgIterator const &obj, bool Delete, PyObject *Owner); +PyObject* PyGroup_FromCpp(pkgCache::GrpIterator const &obj, bool Delete, PyObject *Owner); PyObject* PyIndexFile_FromCpp(pkgIndexFile* const &obj, bool Delete, PyObject *Owner); PyObject* PyPackageFile_FromCpp(pkgCache::PkgFileIterator const &obj, bool Delete, PyObject *Owner); //PyObject* PyPackageList_FromCpp(PkgListStruct const &obj, bool Delete, PyObject *Owner); diff --git a/python/cachegroup.cc b/python/cachegroup.cc new file mode 100644 index 00000000..4fc6c378 --- /dev/null +++ b/python/cachegroup.cc @@ -0,0 +1,188 @@ +/* + * cachegroup.cc - Wrapper around pkgCache::GrpIterator + * + * Copyright 2011 Julian Andres Klode + * + * 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 +#include "apt_pkgmodule.h" +#include "generic.h" +#include + +struct PyGroup : CppPyObject { + pkgCache::PkgIterator current; + int nextIndex; +}; + +static PyObject *group_new(PyTypeObject *type,PyObject *args, + PyObject *kwds) +{ + PyObject *pyCache; + char *name; + char *kwlist[] = {"cache", "name", NULL}; + if (PyArg_ParseTupleAndKeywords(args, kwds, "O!s", kwlist, + &PyCache_Type, &pyCache, + &name) == 0) + return 0; + + pkgCache *cache = GetCpp(pyCache); + + pkgCache::GrpIterator grp = cache->FindGrp(name); + + if (!grp.end()) { + return PyGroup_FromCpp(grp, true, pyCache); + } else { + PyErr_SetString(PyExc_KeyError, name); + return NULL; + } +} + +static const char group_find_package_doc[] = + "find_package(architecture: str) -> Package\n\n" + "Return a package for the given architecture, or None if none exists"; +static PyObject *group_find_package(PyObject *self,PyObject *args) +{ + pkgCache::GrpIterator grp = GetCpp(self); + PyObject *owner = GetOwner(self); + + char *architecture; + if (PyArg_ParseTuple(args, "s", &architecture) == 0) + return 0; + + pkgCache::PkgIterator pkg = grp.FindPkg(architecture); + + if (pkg.end()) { + Py_RETURN_NONE; + } else { + return PyPackage_FromCpp(pkg, true, owner ? owner : self); + } +} + +static const char group_find_preferred_package_doc[] = + "find_preferred_package(prefer_non_virtual: bool = True) -> Package\n\n" + "Return a package for the best architecture, either the native one\n" + "or the first found one. If none exists, return None. If non_virtual\n" + "is True, prefer non-virtual packages over virtual ones."; +static PyObject *group_find_preferred_package(PyObject *self,PyObject *args, + PyObject *kwds) +{ + pkgCache::GrpIterator grp = GetCpp(self); + PyObject *owner = GetOwner(self); + char nonvirtual = 1; + char *kwlist[] = {"prefer_non_virtual", NULL}; + if (PyArg_ParseTupleAndKeywords(args, kwds, "|b", kwlist, &nonvirtual) == 0) + return 0; + pkgCache::PkgIterator pkg = grp.FindPreferredPkg(nonvirtual); + + if (pkg.end()) { + Py_RETURN_NONE; + } else { + return PyPackage_FromCpp(pkg, true, owner); + } +} + +static PyMethodDef group_methods[] = { + {"find_package",group_find_package,METH_VARARGS,group_find_package_doc}, + {"find_preferred_package",(PyCFunction) group_find_preferred_package, + METH_VARARGS|METH_KEYWORDS,group_find_preferred_package_doc}, + {} +}; + +static PyObject *group_seq_item(PyObject *pySelf,Py_ssize_t index) +{ + PyGroup *self = static_cast(pySelf); + pkgCache::GrpIterator grp = GetCpp(self); + PyObject *owner = GetOwner(self); + + if (self->nextIndex > index || self->nextIndex == 0) { + self->nextIndex = 1; + new (&self->current) pkgCache::PkgIterator(grp.PackageList()); + } + + if (self->nextIndex != index + 1) { + while (self->nextIndex <= index && !self->current.end()) { + self->current = grp.NextPkg(self->current); + self->nextIndex++; + } + } + + if (self->current.end()) + return PyErr_Format(PyExc_IndexError, "Out of range: %zd", index); + + return PyPackage_FromCpp(self->current, true, owner); +} + + +static PySequenceMethods group_as_sequence = +{ + 0, + 0, // concat + 0, // repeat + group_seq_item, + 0, // slice + 0, // assign item + 0 // assign slice +}; + + +static const char group_doc[] = "Group(cache, name)\n\n" + "Group of packages with the same name.\n\n" + "Provides access to all packages sharing a name. Can be used this\n" + "like a list, or by using the special find_*() methods. If you use\n" + "it as a sequence, make sure to access it linearly, as this uses a\n" + "linked list internally."; +PyTypeObject PyGroup_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "apt_pkg.Group", // tp_name + sizeof(PyGroup), // tp_basicsize + 0, // tp_itemsize + // Methods + CppDealloc, // tp_dealloc + 0, // tp_print + 0, // tp_getattr + 0, // tp_setattr + 0, // tp_compare + 0, // tp_repr + 0, // tp_as_number + &group_as_sequence, // tp_as_sequence + 0, // tp_as_mapping + 0, // tp_hash + 0, // tp_call + 0, // tp_str + 0, // tp_getattro + 0, // tp_setattro + 0, // tp_as_buffer + Py_TPFLAGS_DEFAULT, // tp_flags + group_doc, // tp_doc + 0, // tp_traverse + 0, // tp_clear + 0, // tp_richcompare + 0, // tp_weaklistoffset + 0, // tp_iter + 0, // tp_iternext + group_methods, // tp_methods + 0, // tp_members + 0, // tp_getset + 0, // tp_base + 0, // tp_dict + 0, // tp_descr_get + 0, // tp_descr_set + 0, // tp_dictoffset + 0, // tp_init + 0, // tp_alloc + group_new, // tp_new +}; diff --git a/python/python-apt-helpers.cc b/python/python-apt-helpers.cc index 7a0f20c4..f50f62c4 100644 --- a/python/python-apt-helpers.cc +++ b/python/python-apt-helpers.cc @@ -52,6 +52,7 @@ NEW_FROM(PyHashString_FromCpp,&PyHashString_Type,HashString*) NEW_FROM(PyIndexRecords_FromCpp,&PyIndexRecords_Type,indexRecords*) NEW_FROM(PyMetaIndex_FromCpp,&PyMetaIndex_Type,metaIndex*) NEW_FROM(PyPackage_FromCpp,&PyPackage_Type,pkgCache::PkgIterator) +NEW_FROM(PyGroup_FromCpp,&PyGroup_Type,pkgCache::GrpIterator) NEW_FROM(PyIndexFile_FromCpp,&PyIndexFile_Type,pkgIndexFile*) NEW_FROM(PyPackageFile_FromCpp,&PyPackageFile_Type,pkgCache::PkgFileIterator) //NEW_FROM(PyPackageList_FromCpp,&PyPackageList_Type,PkgListStruct) diff --git a/python/python-apt.h b/python/python-apt.h index b9fc9212..ca8b557b 100644 --- a/python/python-apt.h +++ b/python/python-apt.h @@ -167,6 +167,9 @@ struct _PyAptPkgAPIStruct { PyObject* (*version_fromcpp)(pkgCache::VerIterator const &obj, bool Delete, PyObject *Owner); pkgCache::VerIterator& (*version_tocpp)(PyObject *self); + PyTypeObject *group_type; + PyObject* (*group_fromcpp)(pkgCache::GrpIterator const &obj, bool Delete, PyObject *Owner); + pkgCache::GrpIterator& (*group_tocpp)(PyObject *self); }; // Checking macros. @@ -184,6 +187,7 @@ struct _PyAptPkgAPIStruct { # define PyDependency_Check(op) PyObject_TypeCheck(op, &PyDependency_Type) # define PyDependencyList_Check(op) PyObject_TypeCheck(op, &PyDependencyList_Type) # define PyDescription_Check(op) PyObject_TypeCheck(op, &PyDescription_Type) +# define PyGroup_Check(op) PyObject_TypeCheck(op, &PyGroup_Type) # define PyHashes_Check(op) PyObject_TypeCheck(op, &PyHashes_Type) # define PyHashString_Check(op) PyObject_TypeCheck(op, &PyHashString_Type) # define PyIndexRecords_Check(op) PyObject_TypeCheck(op, &PyIndexRecords_Type) @@ -217,6 +221,7 @@ struct _PyAptPkgAPIStruct { # define PyDependencyList_CheckExact(op) (op->op_type == &PyDependencyList_Type) # define PyDescription_CheckExact(op) (op->op_type == &PyDescription_Type) # define PyHashes_CheckExact(op) (op->op_type == &PyHashes_Type) +# define PyGroup_CheckExact(op) (op->op_type == &PyGroup_Type) # define PyHashString_CheckExact(op) (op->op_type == &PyHashString_Type) # define PyIndexRecords_CheckExact(op) (op->op_type == &PyIndexRecords_Type) # define PyMetaIndex_CheckExact(op) (op->op_type == &PyMetaIndex_Type) @@ -260,6 +265,7 @@ static int import_apt_pkg(void) { # define PyDependency_Type *(_PyAptPkg_API->dependency_type) # define PyDependencyList_Type *(_PyAptPkg_API->dependencylist_type) # define PyDescription_Type *(_PyAptPkg_API->description_type) +# define PyGroup_Type *(_PyAptPkg_API->group_type) # define PyHashes_Type *(_PyAptPkg_API->hashes_type) # define PyHashString_Type *(_PyAptPkg_API->hashstring_type) # define PyIndexRecords_Type *(_PyAptPkg_API->indexrecords_type) @@ -292,6 +298,7 @@ static int import_apt_pkg(void) { # define PyDependency_ToCpp _PyAptPkg_API->dependency_tocpp # define PyDependencyList_ToCpp _PyAptPkg_API->dependencylist_tocpp // NULL # define PyDescription_ToCpp _PyAptPkg_API->description_tocpp +# define PyGroup_ToCpp _PyAptPkg_API->group_tocpp # define PyHashes_ToCpp _PyAptPkg_API->hashes_tocpp # define PyHashString_ToCpp _PyAptPkg_API->hashstring_tocpp # define PyIndexRecords_ToCpp _PyAptPkg_API->indexrecords_tocpp @@ -324,6 +331,7 @@ static int import_apt_pkg(void) { # define PyDependency_FromCpp _PyAptPkg_API->dependency_fromcpp # define PyDependencyList_FromCpp _PyAptPkg_API->dependencylist_fromcpp // NULL # define PyDescription_FromCpp _PyAptPkg_API->description_fromcpp +# define PyGroup_FromCpp _PyAptPkg_API->group_fromcpp # define PyHashes_FromCpp _PyAptPkg_API->hashes_fromcpp # define PyHashString_FromCpp _PyAptPkg_API->hashstring_fromcpp # define PyIndexRecords_FromCpp _PyAptPkg_API->indexrecords_fromcpp diff --git a/setup.py b/setup.py index 9c6eda60..7f832673 100644 --- a/setup.py +++ b/setup.py @@ -33,7 +33,8 @@ files = ['apt_pkgmodule.cc', 'acquire.cc', 'cache.cc', 'cdrom.cc', 'hashstring.cc', 'indexfile.cc', 'indexrecords.cc', 'metaindex.cc', 'pkgmanager.cc', 'pkgrecords.cc', 'pkgsrcrecords.cc', 'policy.cc', 'progress.cc', 'sourcelist.cc', 'string.cc', 'tag.cc', - 'lock.cc', 'acquire-item.cc', 'python-apt-helpers.cc'] + 'lock.cc', 'acquire-item.cc', 'python-apt-helpers.cc', + 'cachegroup.cc'] files = sorted(['python/' + fname for fname in files], key=lambda s: s[:-3]) apt_pkg = Extension("apt_pkg", files, libraries=["apt-pkg"]) diff --git a/tests/test_group.py b/tests/test_group.py new file mode 100644 index 00000000..b705d90e --- /dev/null +++ b/tests/test_group.py @@ -0,0 +1,27 @@ +import unittest + +import apt_pkg + + +class TestGroup(unittest.TestCase): + + def setUp(self): + apt_pkg.init() + self.cache = apt_pkg.Cache() + + def test_pkgingroup(self): + """Check that each package belongs to the corresponding group""" + for pkg in self.cache.packages: + group = apt_pkg.Group(self.cache, pkg.name) + assert any(pkg.id == p.id for p in group) + + def test_iteration(self): + """Check that iteration works correctly.""" + for pkg in self.cache.packages: + group = apt_pkg.Group(self.cache, pkg.name) + + list(group) == list(group) + + +if __name__ == "__main__": + unittest.main() -- cgit v1.2.3 From 5cc6fcb55f1fa50094a56644178c5e728deb83a4 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Tue, 5 Apr 2011 14:46:16 +0200 Subject: Change apt_pkg.Cache() so that passing None for 'progress' results in no progress output --- debian/changelog | 2 ++ doc/source/library/apt_pkg.rst | 3 ++- python/cache.cc | 9 +++++++-- tests/test_apt_cache.py | 2 +- tests/test_cache_invocation.py | 4 ++-- tests/test_group.py | 2 +- 6 files changed, 15 insertions(+), 7 deletions(-) diff --git a/debian/changelog b/debian/changelog index 99043a95..55c97813 100644 --- a/debian/changelog +++ b/debian/changelog @@ -3,6 +3,8 @@ python-apt (0.8.0~exp1) UNRELEASED; urgency=low * Disable the old-style API, and break all packages using it * Add an 'is_multi_arch' attribute to apt_pkg.Cache * Add apt_pkg.Group class, wrapping pkgCache::GrpIterator + * Change apt_pkg.Cache() so that passing None for 'progress' results in + no progress output -- Julian Andres Klode 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 1b75a154..709648ac 100644 --- a/doc/source/library/apt_pkg.rst +++ b/doc/source/library/apt_pkg.rst @@ -40,7 +40,8 @@ Working with the cache 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). + 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. .. describe:: cache[pkgname] diff --git a/python/cache.cc b/python/cache.cc index b5ebcce4..6f1585e5 100644 --- a/python/cache.cc +++ b/python/cache.cc @@ -299,7 +299,11 @@ static PyObject *PkgCacheNew(PyTypeObject *type,PyObject *Args,PyObject *kwds) pkgCacheFile *Cache = new pkgCacheFile(); - if(pyCallbackInst != 0) { + if (pyCallbackInst == Py_None) { + OpProgress Prog; + if (Cache->Open(Prog,false) == false) + return HandleErrors(); + } else if(pyCallbackInst != 0) { // sanity check for the progress object, see #497049 if (PyObject_HasAttrString(pyCallbackInst, "done") != true) { PyErr_SetString(PyExc_ValueError, @@ -349,7 +353,8 @@ static char *doc_PkgCache = "Cache([progress]) -> Cache() object.\n\n" "apt.progress.base.OpProgress() object (or similar) which reports\n" "progress information while the cache is being opened. If this\n" "parameter is not supplied, the progress will be reported in simple,\n" - "human-readable text to standard output.\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)."; static PySequenceMethods CacheSeq = {0,0,0,0,0,0,0,CacheContains,0,0}; diff --git a/tests/test_apt_cache.py b/tests/test_apt_cache.py index cccfc9c8..b4cc650d 100644 --- a/tests/test_apt_cache.py +++ b/tests/test_apt_cache.py @@ -70,7 +70,7 @@ class TestAptCache(unittest.TestCase): def test_low_level_pkg_provides(self): # low level cache provides list of the pkg - cache = apt_pkg.Cache() + cache = apt_pkg.Cache(progress=None) l = cache["mail-transport-agent"].provides_list # arbitrary number, just needs to be higher enough self.assertTrue(len(l), 5) diff --git a/tests/test_cache_invocation.py b/tests/test_cache_invocation.py index 6f4014de..a89ef557 100644 --- a/tests/test_cache_invocation.py +++ b/tests/test_cache_invocation.py @@ -14,7 +14,7 @@ class TestCache(unittest.TestCase): def test_wrong_invocation(self): """cache_invocation: Test wrong invocation.""" - apt_cache = apt_pkg.Cache(apt.progress.base.OpProgress()) + apt_cache = apt_pkg.Cache(progress=None) self.assertRaises(ValueError, apt_pkg.Cache, apt_cache) self.assertRaises(ValueError, apt_pkg.Cache, @@ -23,7 +23,7 @@ class TestCache(unittest.TestCase): def test_proper_invocation(self): """cache_invocation: Test correct invocation.""" - apt_cache = apt_pkg.Cache(apt.progress.base.OpProgress()) + apt_cache = apt_pkg.Cache(progress=None) apt_depcache = apt_pkg.DepCache(apt_cache) if __name__ == "__main__": diff --git a/tests/test_group.py b/tests/test_group.py index b705d90e..c69e4dbb 100644 --- a/tests/test_group.py +++ b/tests/test_group.py @@ -7,7 +7,7 @@ class TestGroup(unittest.TestCase): def setUp(self): apt_pkg.init() - self.cache = apt_pkg.Cache() + self.cache = apt_pkg.Cache(progress=None) def test_pkgingroup(self): """Check that each package belongs to the corresponding group""" -- cgit v1.2.3 From 1c6ecaa6776498d27bcce81fa769a677a587215a Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Tue, 5 Apr 2011 15:18:12 +0200 Subject: Support (name, arch) tuples in apt_pkg.Cache mappings, wrapping FindPkg() with two string parameters. --- debian/changelog | 2 ++ doc/source/library/apt_pkg.rst | 25 +++++++++++++++++++++-- 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 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(self); + name = PyObject_AsString(arg); -// Map access, operator [] -static PyObject *CacheMapOp(PyObject *Self,PyObject *Arg) -{ - pkgCache *Cache = GetCpp(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(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 = -- cgit v1.2.3 From 6ae5009c6cfe56b66a22848f80eff6239245f1e7 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Tue, 5 Apr 2011 15:56:14 +0200 Subject: Introduce apt_pkg.Cache.groups and apt_pkg.Cache.group_count --- debian/changelog | 1 + doc/source/library/apt_pkg.rst | 26 +++++++ python/apt_pkgmodule.cc | 1 + python/apt_pkgmodule.h | 1 + python/cache.cc | 153 +++++++++++++++++++++++++++++++++-------- tests/test_group.py | 5 ++ 6 files changed, 160 insertions(+), 27 deletions(-) diff --git a/debian/changelog b/debian/changelog index f241e749..275d8cad 100644 --- a/debian/changelog +++ b/debian/changelog @@ -7,6 +7,7 @@ python-apt (0.8.0~exp1) UNRELEASED; urgency=low no progress output * Support (name, arch) tuples in apt_pkg.Cache mappings, wrapping FindPkg() with two string parameters. + * Introduce apt_pkg.Cache.groups and apt_pkg.Cache.group_count -- Julian Andres Klode 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 74bba8db..22225aa4 100644 --- a/doc/source/library/apt_pkg.rst +++ b/doc/source/library/apt_pkg.rst @@ -95,6 +95,32 @@ Working with the cache A list of all :class:`PackageFile` objects stored in the cache. + .. attribute:: group_count + + The number of groups in the cache. + + .. attribute:: groups + + A sequence of :class:`Group` objects, implemented as a + :class:`GroupList` object. + + .. 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: + + .. 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. diff --git a/python/apt_pkgmodule.cc b/python/apt_pkgmodule.cc index e14677b1..0fac664b 100644 --- a/python/apt_pkgmodule.cc +++ b/python/apt_pkgmodule.cc @@ -815,6 +815,7 @@ extern "C" void initapt_pkg() ADDTYPE(Module,"Package",&PyPackage_Type); // NO __new__() ADDTYPE(Module,"Version",&PyVersion_Type); // NO __new__() ADDTYPE(Module,"Group", &PyGroup_Type); + ADDTYPE(Module,"GroupList", &PyGroupList_Type); /* ============================ cdrom.cc ============================ */ ADDTYPE(Module,"Cdrom",&PyCdrom_Type); /* ========================= configuration.cc ========================= */ diff --git a/python/apt_pkgmodule.h b/python/apt_pkgmodule.h index 0081a1a9..7a04204c 100644 --- a/python/apt_pkgmodule.h +++ b/python/apt_pkgmodule.h @@ -71,6 +71,7 @@ extern PyTypeObject PyCacheFile_Type; extern PyTypeObject PyPackageList_Type; extern PyTypeObject PyDescription_Type; extern PyTypeObject PyGroup_Type; +extern PyTypeObject PyGroupList_Type; /* internal */ extern PyTypeObject PyPackage_Type; extern PyTypeObject PyPackageFile_Type; extern PyTypeObject PyDependency_Type; diff --git a/python/cache.cc b/python/cache.cc index cb877eee..a27bf6f5 100644 --- a/python/cache.cc +++ b/python/cache.cc @@ -39,13 +39,57 @@ const char *UntranslatedDepTypes[] = }; /*}}}*/ -struct PkgListStruct + +template struct IterListStruct { - pkgCache::PkgIterator Iter; + T Iter; unsigned long LastIndex; - PkgListStruct(pkgCache::PkgIterator const &I) : Iter(I), LastIndex(0) {} - PkgListStruct() {abort();}; // G++ Bug.. + IterListStruct(T const &I) : Iter(I), LastIndex(0) {} + IterListStruct() {}; + + bool move(unsigned long Index) { + if (Index < 0 || (unsigned)Index >= Count()) + { + PyErr_SetNone(PyExc_IndexError); + return false; + } + + if ((unsigned)Index < LastIndex) + { + LastIndex = 0; + Iter = Begin(); + } + + while ((unsigned)Index > LastIndex) + { + LastIndex++; + Iter++; + if (Iter.end() == true) + { + PyErr_SetNone(PyExc_IndexError); + return false; + } + } + return true; + } + + virtual unsigned Count() = 0; + virtual T Begin() = 0; + +}; + +struct PkgListStruct : public IterListStruct { + unsigned Count() { return Iter.Cache()->HeaderP->PackageCount; } + pkgCache::PkgIterator Begin() { return Iter.Cache()->PkgBegin(); } + + PkgListStruct(pkgCache::PkgIterator const &I) { Iter = I; } +}; + +struct GrpListStruct : public IterListStruct { + unsigned Count() { return Iter.Cache()->HeaderP->GroupCount; } + pkgCache::GrpIterator Begin() { return Iter.Cache()->GrpBegin(); } + GrpListStruct(pkgCache::GrpIterator const &I) { Iter = I; } }; struct RDepListStruct @@ -175,6 +219,16 @@ static PyMethodDef PkgCacheMethods[] = {} }; +static PyObject *PkgCacheGetGroupCount(PyObject *Self, void*) { + pkgCache *Cache = GetCpp(Self); + return Py_BuildValue("i",Cache->HeaderP->GroupCount); +} + +static PyObject *PkgCacheGetGroups(PyObject *Self, void*) { + pkgCache *Cache = GetCpp(Self); + return CppPyObject_NEW(Self,&PyGroupList_Type,Cache->GrpBegin()); +} + static PyObject *PkgCacheGetPackages(PyObject *Self, void*) { pkgCache *Cache = GetCpp(Self); return CppPyObject_NEW(Self,&PyPackageList_Type,Cache->PkgBegin()); @@ -232,6 +286,9 @@ static PyGetSetDef PkgCacheGetSet[] = { "The number of apt_pkg.Dependency objects stored in the cache."}, {"file_list",PkgCacheGetFileList,0, "A list of apt_pkg.PackageFile objects stored in the cache."}, + {"group_count",PkgCacheGetGroupCount,0, + "The number of apt_pkg.Group objects stored in the cache."}, + {"groups", PkgCacheGetGroups, 0, "A list of Group objects in the cache"}, {"is_multi_arch", PkgCacheGetIsMultiArch, 0, "Whether the cache supports multi-arch."}, {"package_count",PkgCacheGetPackageCount,0, @@ -442,7 +499,7 @@ PyTypeObject PyCacheFile_Type = 0, // tp_as_buffer Py_TPFLAGS_DEFAULT, // tp_flags }; - /*}}}*/ + // Package List Class /*{{{*/ // --------------------------------------------------------------------- static Py_ssize_t PkgListLen(PyObject *Self) @@ -453,29 +510,9 @@ static Py_ssize_t PkgListLen(PyObject *Self) static PyObject *PkgListItem(PyObject *iSelf,Py_ssize_t Index) { PkgListStruct &Self = GetCpp(iSelf); - if (Index < 0 || (unsigned)Index >= Self.Iter.Cache()->HeaderP->PackageCount) - { - PyErr_SetNone(PyExc_IndexError); - return 0; - } - - if ((unsigned)Index < Self.LastIndex) - { - Self.LastIndex = 0; - Self.Iter = Self.Iter.Cache()->PkgBegin(); - } - - while ((unsigned)Index > Self.LastIndex) - { - Self.LastIndex++; - Self.Iter++; - if (Self.Iter.end() == true) - { - PyErr_SetNone(PyExc_IndexError); - return 0; - } - } + if (!Self.move(Index)) + return 0; return CppPyObject_NEW(GetOwner(iSelf),&PyPackage_Type, Self.Iter); } @@ -525,6 +562,68 @@ PyTypeObject PyPackageList_Type = CppClear, // tp_clear }; +/* The same for groups */ +static Py_ssize_t GrpListLen(PyObject *Self) +{ + return GetCpp(Self).Iter.Cache()->HeaderP->GroupCount; +} + +static PyObject *GrpListItem(PyObject *iSelf,Py_ssize_t Index) +{ + GrpListStruct &Self = GetCpp(iSelf); + + if (!Self.move(Index)) + return 0; + return CppPyObject_NEW(GetOwner(iSelf),&PyGroup_Type, + Self.Iter); +} + +static PySequenceMethods GrpListSeq = +{ + GrpListLen, + 0, // concat + 0, // repeat + GrpListItem, + 0, // slice + 0, // assign item + 0 // assign slice +}; + +static const char *grouplist_doc = + "A GroupList is an internally used structure to represent\n" + "the 'groups' attribute of apt_pkg.Cache objects in a more\n" + "efficient manner by creating Group objects only when they\n" + "are accessed."; + +PyTypeObject PyGroupList_Type = +{ + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "apt_pkg.GroupList", // tp_name + sizeof(CppPyObject), // tp_basicsize + 0, // tp_itemsize + // Methods + CppDealloc, // tp_dealloc + 0, // tp_print + 0, // tp_getattr + 0, // tp_setattr + 0, // tp_compare + 0, // tp_repr + 0, // tp_as_number + &GrpListSeq, // tp_as_sequence + 0, // tp_as_mapping + 0, // tp_hash + 0, // tp_call + 0, // tp_str + 0, // tp_getattro + 0, // tp_setattro + 0, // tp_as_buffer + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, // tp_flags + grouplist_doc, // tp_doc + CppTraverse, // tp_traverse + CppClear, // tp_clear +}; + + #define Owner (GetOwner(Self)) #define MkGet(PyFunc,Ret) static PyObject *PyFunc(PyObject *Self,void*) \ { \ diff --git a/tests/test_group.py b/tests/test_group.py index c69e4dbb..3c3a5b7a 100644 --- a/tests/test_group.py +++ b/tests/test_group.py @@ -23,5 +23,10 @@ class TestGroup(unittest.TestCase): list(group) == list(group) + def test_cache_groups(self): + """group: Iterate over all groups""" + assert len(list(self.cache.groups)) == self.cache.group_count + + if __name__ == "__main__": unittest.main() -- cgit v1.2.3 From d260631958f70b4ea973d40b6eee10a53abdc73a Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Tue, 5 Apr 2011 16:06:32 +0200 Subject: Fix debian/rules to work correctly with tilde in version number --- debian/changelog | 1 + debian/rules | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/debian/changelog b/debian/changelog index 275d8cad..85714048 100644 --- a/debian/changelog +++ b/debian/changelog @@ -8,6 +8,7 @@ python-apt (0.8.0~exp1) UNRELEASED; urgency=low * Support (name, arch) tuples in apt_pkg.Cache mappings, wrapping FindPkg() with two string parameters. * Introduce apt_pkg.Cache.groups and apt_pkg.Cache.group_count + * Fix debian/rules to work correctly with tilde in version number -- Julian Andres Klode Tue, 05 Apr 2011 10:33:54 +0200 diff --git a/debian/rules b/debian/rules index 0b60bf9f..c6c3e053 100755 --- a/debian/rules +++ b/debian/rules @@ -3,8 +3,8 @@ export DEBVER=$(shell dpkg-parsechangelog | sed -n -e 's/^Version: //p') # For compatibility, add -DCOMPAT_0_7 export CFLAGS=-Wno-write-strings -export PATH :=$(CURDIR)/utils:$(PATH) -export SHELL = env PATH=$(PATH) sh +export PATH := $(CURDIR)/utils:$(PATH) +export pyversions := $(CURDIR)/utils/pyversions %: dh --with python2,python3 $@ @@ -36,7 +36,7 @@ override_dh_compress: # We ignore failures on hurd, since its locking is broken override_dh_auto_test: ifeq (,$(findstring nocheck, $(DEB_BUILD_OPTIONS))) - set -e; for python in $(shell pyversions -r); do \ + set -e; for python in $(shell $(pyversions) -r); do \ $$python tests/test_all.py -q || [ "$(DEB_BUILD_ARCH_OS)" = "hurd" ]; \ done; else -- cgit v1.2.3 From 58b57b320c88cbb3e7df0a12fb47f057ab5da0b1 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Tue, 5 Apr 2011 16:11:34 +0200 Subject: doc: Add versionadded for the new features --- doc/source/c++/api.rst | 2 ++ doc/source/library/apt_pkg.rst | 12 ++++++++++++ 2 files changed, 14 insertions(+) diff --git a/doc/source/c++/api.rst b/doc/source/c++/api.rst index 4922d272..25cfcd9e 100644 --- a/doc/source/c++/api.rst +++ b/doc/source/c++/api.rst @@ -392,6 +392,8 @@ Description (pkgCache::DescIterator) Group (pkgCache::GrpIterator) ---------------------------------- +.. versionadded:: 0.8.0 + .. cvar:: PyTypeObject PyGroup_Type The type object for :class:`apt_pkg.Group` objects. diff --git a/doc/source/library/apt_pkg.rst b/doc/source/library/apt_pkg.rst index 22225aa4..72ca5ecc 100644 --- a/doc/source/library/apt_pkg.rst +++ b/doc/source/library/apt_pkg.rst @@ -63,6 +63,8 @@ Working with the cache 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 @@ -74,6 +76,8 @@ Working with the 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 @@ -99,11 +103,15 @@ Working with the cache 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 @@ -111,6 +119,8 @@ Working with the cache 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 @@ -125,6 +135,8 @@ Working with the cache 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 -- cgit v1.2.3 From 12c1f3293bc257a325dc4eb16dac2f385340c89e Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Tue, 5 Apr 2011 16:18:26 +0200 Subject: What's new in 0.8 document --- doc/source/whatsnew/0.8.0.rst | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 doc/source/whatsnew/0.8.0.rst diff --git a/doc/source/whatsnew/0.8.0.rst b/doc/source/whatsnew/0.8.0.rst new file mode 100644 index 00000000..fda53443 --- /dev/null +++ b/doc/source/whatsnew/0.8.0.rst @@ -0,0 +1,28 @@ +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 + +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. -- cgit v1.2.3 From ef797f74a1948be2231a28786d2c40d047f9c49d Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Tue, 5 Apr 2011 16:22:04 +0200 Subject: Release 0.8.0~exp1 to experimental --- debian/changelog | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/debian/changelog b/debian/changelog index 85714048..6cad29e2 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,4 +1,4 @@ -python-apt (0.8.0~exp1) UNRELEASED; urgency=low +python-apt (0.8.0~exp1) experimental; urgency=low * Disable the old-style API, and break all packages using it * Add an 'is_multi_arch' attribute to apt_pkg.Cache @@ -10,7 +10,7 @@ python-apt (0.8.0~exp1) UNRELEASED; urgency=low * Introduce apt_pkg.Cache.groups and apt_pkg.Cache.group_count * Fix debian/rules to work correctly with tilde in version number - -- Julian Andres Klode Tue, 05 Apr 2011 10:33:54 +0200 + -- Julian Andres Klode Tue, 05 Apr 2011 16:21:45 +0200 python-apt (0.7.100.3) unstable; urgency=low -- cgit v1.2.3 From 82bd14484ffa3fbe0b68777402cb31000bd7dd22 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Wed, 6 Apr 2011 10:09:19 +0200 Subject: aptsources: Parse multi-arch sources.list files correctly --- aptsources/sourceslist.py | 24 ++++++++++++++++++++++-- debian/changelog | 6 ++++++ tests/data/aptsources/sources.list | 5 ++++- tests/test_aptsources.py | 19 +++++++++++++++++-- 4 files changed, 49 insertions(+), 5 deletions(-) diff --git a/aptsources/sourceslist.py b/aptsources/sourceslist.py index 76bea43a..3cfe1791 100644 --- a/aptsources/sourceslist.py +++ b/aptsources/sourceslist.py @@ -81,6 +81,7 @@ class SourceEntry(object): self.invalid = False # is the source entry valid self.disabled = False # is it disabled ('#' in front) self.type = "" # what type (deb, deb-src) + self.architectures = [] # architectures self.uri = "" # base-uri self.dist = "" # distribution (dapper, edgy, etc) self.comps = [] # list of available componetns @@ -113,7 +114,7 @@ class SourceEntry(object): p_found = False space_found = False for i in range(len(line)): - if line[i] == "[": + if line[i] == "[" and not space_found: p_found=True tmp += line[i] elif line[i] == "]": @@ -169,6 +170,20 @@ class SourceEntry(object): if self.type not in ("deb", "deb-src", "rpm", "rpm-src"): self.invalid = True return + + if pieces[1].strip()[0] == "[": + options = pieces.pop(1).strip("[]").split(";") + for option in options: + try: + key, value = option.split("=", 1) + except Exception: + self.invalid = True + else: + if key == "arch": + self.architectures = value.split(",") + else: + self.invalid = True + # URI self.uri = pieces[1].strip() if len(self.uri) < 1: @@ -204,7 +219,12 @@ class SourceEntry(object): line = "" if self.disabled: line = "# " - line += "%s %s %s" % (self.type, self.uri, self.dist) + + line += self.type + + if self.architectures: + line += " [arch=%s]" % ",".join(self.architectures) + line += " %s %s" % (self.uri, self.dist) if len(self.comps) > 0: line += " " + " ".join(self.comps) if self.comment != "": diff --git a/debian/changelog b/debian/changelog index 6cad29e2..c942278d 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +python-apt (0.8.0~exp2) UNRELEASED; urgency=low + + * aptsources: Parse multi-arch sources.list files correctly + + -- Julian Andres Klode Wed, 06 Apr 2011 09:46:52 +0200 + python-apt (0.8.0~exp1) experimental; urgency=low * Disable the old-style API, and break all packages using it diff --git a/tests/data/aptsources/sources.list b/tests/data/aptsources/sources.list index 5481d4f0..376d6961 100644 --- a/tests/data/aptsources/sources.list +++ b/tests/data/aptsources/sources.list @@ -3,4 +3,7 @@ deb http://de.archive.ubuntu.com/ubuntu/ edgy main # comment 2 deb http://de.archive.ubuntu.com/ubuntu/ edgy restricted # comment 3 -deb http://de.archive.ubuntu.com/ubuntu/ edgy universe \ No newline at end of file +deb http://de.archive.ubuntu.com/ubuntu/ edgy universe + +# multi-arch +deb [arch=amd64,i386] http://de.archive.ubuntu.com/ubuntu/ natty main diff --git a/tests/test_aptsources.py b/tests/test_aptsources.py index 331df935..aeb2ce31 100644 --- a/tests/test_aptsources.py +++ b/tests/test_aptsources.py @@ -39,11 +39,11 @@ class TestAptSources(unittest.TestCase): apt_pkg.config.set("Dir::Etc::sourcelist", "data/aptsources/" "sources.list") sources = aptsources.sourceslist.SourcesList(True, self.templates) - self.assertEqual(len(sources.list), 6) + self.assertEqual(len(sources.list), 9) # test load sources.list = [] sources.load("data/aptsources/sources.list") - self.assertEqual(len(sources.list), 6) + self.assertEqual(len(sources.list), 9) def testSourcesListAdding(self): """aptsources: Test additions to sources.list""" @@ -108,6 +108,21 @@ class TestAptSources(unittest.TestCase): if not s.template: self.fail("source entry '%s' has no matcher" % s) + def testMultiArch(self): + """aptsources: Test multi-arch parsing""" + + apt_pkg.config.set("Dir::Etc::sourcelist", "data/aptsources/" + "sources.list") + sources = aptsources.sourceslist.SourcesList(True, self.templates) + + assert sources.list[8].invalid == False + assert sources.list[8].type == "deb" + assert sources.list[8].architectures == ["amd64", "i386"] + assert sources.list[8].uri == "http://de.archive.ubuntu.com/ubuntu/" + assert sources.list[8].dist == "natty" + assert sources.list[8].comps == ["main"] + assert sources.list[8].line.strip() == str(sources.list[8]) + def testDistribution(self): """aptsources: Test distribution detection.""" apt_pkg.config.set("Dir::Etc::sourcelist", "data/aptsources/" -- cgit v1.2.3 From 30a0dff267d9e99c25d5902e296fd115746e05c9 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Wed, 6 Apr 2011 10:22:53 +0200 Subject: aptsources: Allow insertion of new multi-arch entries --- aptsources/sourceslist.py | 17 +++++++++++++---- debian/changelog | 1 + tests/test_aptsources.py | 36 ++++++++++++++++++++++++++++++++++++ 3 files changed, 50 insertions(+), 4 deletions(-) diff --git a/aptsources/sourceslist.py b/aptsources/sourceslist.py index 3cfe1791..85db2de9 100644 --- a/aptsources/sourceslist.py +++ b/aptsources/sourceslist.py @@ -275,12 +275,14 @@ class SourcesList(object): yield entry raise StopIteration - def add(self, type, uri, dist, orig_comps, comment="", pos=-1, file=None): + def add(self, type, uri, dist, orig_comps, comment="", pos=-1, file=None, architectures=[]): """ Add a new source to the sources.list. The method will search for existing matching repos and will try to reuse them as far as possible """ + + architectures = set(architectures) # create a working copy of the component list so that # we can modify it later comps = orig_comps[:] @@ -288,7 +290,8 @@ class SourcesList(object): for source in self.list: if not source.disabled and not source.invalid and \ source.type == type and uri == source.uri and \ - source.dist == dist: + source.dist == dist and \ + set(source.architectures) == architectures: for new_comp in comps: if new_comp in source.comps: # we have this component already, delete it @@ -301,19 +304,25 @@ class SourcesList(object): # components if not source.disabled and not source.invalid and \ source.type == type and uri == source.uri and \ - source.dist == dist: + source.dist == dist and \ + set(source.architectures) == architectures: comps = uniq(source.comps + comps) source.comps = comps return source # if there is a corresponding repo which is disabled, enable it elif source.disabled and not source.invalid and \ source.type == type and uri == source.uri and \ + set(source.architectures) == architectures and \ source.dist == dist and \ len(set(source.comps) & set(comps)) == len(comps): source.disabled = False return source # there isn't any matching source, so create a new line and parse it - line = "%s %s %s" % (type, uri, dist) + + line = type + if architectures: + line += " [arch=%s]" % ",".join(architectures) + line += " %s %s" % (uri, dist) for c in comps: line = line + " " + c if comment != "": diff --git a/debian/changelog b/debian/changelog index c942278d..7ceda2ce 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,6 +1,7 @@ python-apt (0.8.0~exp2) UNRELEASED; urgency=low * aptsources: Parse multi-arch sources.list files correctly + * aptsources: Allow insertion of new multi-arch entries -- Julian Andres Klode Wed, 06 Apr 2011 09:46:52 +0200 diff --git a/tests/test_aptsources.py b/tests/test_aptsources.py index aeb2ce31..1597674e 100644 --- a/tests/test_aptsources.py +++ b/tests/test_aptsources.py @@ -62,6 +62,14 @@ class TestAptSources(unittest.TestCase): "edgy", ["restricted"]) self.assertTrue(sources.list == before.list) + + before = copy.deepcopy(sources) + sources.add("deb", "http://de.archive.ubuntu.com/ubuntu/", + "natty", + ["main"], architectures=["amd64", "i386"]) + self.assertTrue(sources.list == before.list) + + # test to add something new: multiverse sources.add("deb", "http://de.archive.ubuntu.com/ubuntu/", "edgy", @@ -74,6 +82,34 @@ class TestAptSources(unittest.TestCase): "multiverse" in entry.comps): found = True self.assertTrue(found) + + # add a new natty entry without architecture specification + sources.add("deb", "http://de.archive.ubuntu.com/ubuntu/", + "natty", + ["multiverse"]) + found = False + for entry in sources: + if (entry.type == "deb" and + entry.uri == "http://de.archive.ubuntu.com/ubuntu/" and + entry.dist == "natty" and + entry.architectures == [] and + "multiverse" in entry.comps): + found = True + self.assertTrue(found) + + # Add universe to existing multi-arch line + sources.add("deb", "http://de.archive.ubuntu.com/ubuntu/", + "natty", + ["universe"], architectures=["i386", "amd64"]) + found = False + for entry in sources: + if (entry.type == "deb" and + entry.uri == "http://de.archive.ubuntu.com/ubuntu/" and + entry.dist == "natty" and + set(entry.architectures) == set(["amd64", "i386"]) and + set(entry.comps) == set(["main", "universe"])): + found = True + self.assertTrue(found) # test to add something new: multiverse *and* # something that is already there before = copy.deepcopy(sources) -- cgit v1.2.3 From b766dc001aeea1c18b0c17c1d5029673ef539ef0 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Wed, 6 Apr 2011 10:42:38 +0200 Subject: aptsources: Various cleanup work --- aptsources/sourceslist.py | 53 +++++++++++++++++++++++------------------------ debian/changelog | 1 + 2 files changed, 27 insertions(+), 27 deletions(-) diff --git a/aptsources/sourceslist.py b/aptsources/sourceslist.py index 85db2de9..38831e9c 100644 --- a/aptsources/sourceslist.py +++ b/aptsources/sourceslist.py @@ -275,6 +275,12 @@ class SourcesList(object): yield entry raise StopIteration + def __find(self, *predicates, **attrs): + for source in self.list: + if (all(getattr(source, key) == attrs[key] for key in attrs) and + all(predicate(source) for predicate in predicates)): + yield source + def add(self, type, uri, dist, orig_comps, comment="", pos=-1, file=None, architectures=[]): """ Add a new source to the sources.list. @@ -286,39 +292,32 @@ class SourcesList(object): # create a working copy of the component list so that # we can modify it later comps = orig_comps[:] + sources = self.__find(lambda s: set(s.architectures) == architectures, + disabled=False, invalid=False, type=type, uri=uri, + dist=dist) # check if we have this source already in the sources.list - for source in self.list: - if not source.disabled and not source.invalid and \ - source.type == type and uri == source.uri and \ - source.dist == dist and \ - set(source.architectures) == architectures: - for new_comp in comps: - if new_comp in source.comps: - # we have this component already, delete it - # from the new_comps list - del comps[comps.index(new_comp)] - if len(comps) == 0: - return source - for source in self.list: + for source in sources: + for new_comp in comps: + if new_comp in source.comps: + # we have this component already, delete it + # from the new_comps list + del comps[comps.index(new_comp)] + if len(comps) == 0: + return source + + sources = self.__find(lambda s: set(s.architectures) == architectures, + invalid=False, type=type, uri=uri, dist=dist) + + for source in sources: # if there is a repo with the same (type, uri, dist) just add the # components - if not source.disabled and not source.invalid and \ - source.type == type and uri == source.uri and \ - source.dist == dist and \ - set(source.architectures) == architectures: - comps = uniq(source.comps + comps) - source.comps = comps - return source - # if there is a corresponding repo which is disabled, enable it - elif source.disabled and not source.invalid and \ - source.type == type and uri == source.uri and \ - set(source.architectures) == architectures and \ - source.dist == dist and \ - len(set(source.comps) & set(comps)) == len(comps): + if source.disabled and set(source.comps) == comps: source.disabled = False return source + elif not source.disabled: + source.comps = uniq(source.comps + comps) + return source # there isn't any matching source, so create a new line and parse it - line = type if architectures: line += " [arch=%s]" % ",".join(architectures) diff --git a/debian/changelog b/debian/changelog index 7ceda2ce..2864126a 100644 --- a/debian/changelog +++ b/debian/changelog @@ -2,6 +2,7 @@ python-apt (0.8.0~exp2) UNRELEASED; urgency=low * aptsources: Parse multi-arch sources.list files correctly * aptsources: Allow insertion of new multi-arch entries + * aptsources: Various cleanup work -- Julian Andres Klode Wed, 06 Apr 2011 09:46:52 +0200 -- cgit v1.2.3 From 5ad927a38cad08a2d79f327e7bb3cc46316fa6a4 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Wed, 6 Apr 2011 11:15:47 +0200 Subject: all: Fix all instances of ResourceWarning about unclosed files --- apt/cache.py | 2 +- apt/cdrom.py | 7 +- apt/debfile.py | 2 +- apt/package.py | 12 ++-- aptsources/distinfo.py | 170 ++++++++++++++++++++++++---------------------- aptsources/sourceslist.py | 30 ++++---- debian/changelog | 1 + tests/test_apt_cache.py | 23 +++---- tests/test_hashes.py | 7 +- tests/test_progress.py | 3 +- 10 files changed, 134 insertions(+), 123 deletions(-) diff --git a/apt/cache.py b/apt/cache.py index bfa41edc..3bbae923 100644 --- a/apt/cache.py +++ b/apt/cache.py @@ -107,7 +107,7 @@ class Cache(object): os.makedirs(rootdir + d) for f in files: if not os.path.exists(rootdir + f): - open(rootdir + f, "w") + open(rootdir + f, "w").close() def _run_callbacks(self, name): """ internal helper to run a callback """ diff --git a/apt/cdrom.py b/apt/cdrom.py index 01caa12f..9688de9e 100644 --- a/apt/cdrom.py +++ b/apt/cdrom.py @@ -79,9 +79,10 @@ class Cdrom(apt_pkg.Cdrom): src.append(apt_pkg.config.find_file("Dir::Etc::sourcelist")) # Check each file for fname in src: - for line in open(fname): - if not line.lstrip().startswith("#") and cd_id in line: - return True + with open(fname) as fobj: + for line in fobj: + if not line.lstrip().startswith("#") and cd_id in line: + return True return False if apt_pkg._COMPAT_0_7: diff --git a/apt/debfile.py b/apt/debfile.py index fb4312a1..d0f41def 100644 --- a/apt/debfile.py +++ b/apt/debfile.py @@ -64,7 +64,7 @@ class DebPackage(object): self._installed_conflicts = set() self._failure_string = "" self.filename = filename - self._debfile = apt_inst.DebFile(open(self.filename)) + self._debfile = apt_inst.DebFile(self.filename) control = self._debfile.control.extractdata("control") self._sections = apt_pkg.TagSection(control) self.pkgname = self._sections["Package"] diff --git a/apt/package.py b/apt/package.py index d7d5d167..54ef1c01 100644 --- a/apt/package.py +++ b/apt/package.py @@ -50,9 +50,9 @@ __all__ = ('BaseDependency', 'Dependency', 'Origin', 'Package', 'Record', def _file_is_same(path, size, md5): """Return ``True`` if the file is the same.""" - if (os.path.exists(path) and os.path.getsize(path) == size and - apt_pkg.md5sum(open(path)) == md5): - return True + if os.path.exists(path) and os.path.getsize(path) == size: + with open(path) as fobj: + return apt_pkg.md5sum(fobj) == md5 class FetchError(Exception): @@ -994,11 +994,8 @@ class Package(object): """ path = "/var/lib/dpkg/info/%s.list" % self.name try: - file_list = open(path, "rb") - try: + with open(path, "rb") as file_list: return file_list.read().decode("utf-8").split(u"\n") - finally: - file_list.close() except EnvironmentError: return [] @@ -1104,6 +1101,7 @@ class Package(object): # Check if the download was canceled if cancel_lock and cancel_lock.isSet(): return u"" + # FIXME: python3.2: Should be closed manually changelog_file = urllib2.urlopen(uri) # do only get the lines that are new changelog = u"" diff --git a/aptsources/distinfo.py b/aptsources/distinfo.py index 6374f185..48a72719 100644 --- a/aptsources/distinfo.py +++ b/aptsources/distinfo.py @@ -176,89 +176,93 @@ class DistInfo(object): map_mirror_sets = {} dist_fname = "%s/%s.info" % (base_dir, dist) - dist_file = open(dist_fname) - if not dist_file: - return - template = None - component = None - for line in dist_file: - tokens = line.split(':', 1) - if len(tokens) < 2: - continue - field = tokens[0].strip() - value = tokens[1].strip() - if field == 'ChangelogURI': - self.changelogs_uri = _(value) - elif field == 'MetaReleaseURI': - self.metarelease_uri = value - elif field == 'Suite': - self.finish_template(template, component) - component=None - template = Template() - template.name = value - template.distribution = dist - template.match_name = "^%s$" % value - elif field == 'MatchName': - template.match_name = value - elif field == 'ParentSuite': - template.child = True - for nanny in self.templates: - # look for parent and add back ref to it - if nanny.name == value: - template.parents.append(nanny) - nanny.children.append(template) - elif field == 'Available': - template.available = apt_pkg.string_to_bool(value) - elif field == 'Official': - template.official = apt_pkg.string_to_bool(value) - elif field == 'RepositoryType': - template.type = value - elif field == 'BaseURI' and not template.base_uri: - template.base_uri = value - elif field == 'BaseURI-%s' % self.arch: - template.base_uri = value - elif field == 'MatchURI' and not template.match_uri: - template.match_uri = value - elif field == 'MatchURI-%s' % self.arch: - template.match_uri = value - elif (field == 'MirrorsFile' or - field == 'MirrorsFile-%s' % self.arch): - # Make the path absolute. - value = os.path.isabs(value) and value or \ - os.path.abspath(os.path.join(base_dir, value)) - if value not in map_mirror_sets: - mirror_set = {} - try: - mirror_data = filter(match_mirror_line.match, - [x.strip() for x in open(value)]) - except Exception: - print "WARNING: Failed to read mirror file" - mirror_data = [] - for line in mirror_data: - if line.startswith("#LOC:"): - location = match_loc.sub(r"\1", line) - continue - (proto, hostname, dir) = split_url(line) - if hostname in mirror_set: - mirror_set[hostname].add_repository(proto, dir) - else: - mirror_set[hostname] = Mirror( - proto, hostname, dir, location) - map_mirror_sets[value] = mirror_set - template.mirror_set = map_mirror_sets[value] - elif field == 'Description': - template.description = _(value) - elif field == 'Component': - if component and not template.has_component(component.name): - template.components.append(component) - component = Component(value) - elif field == 'CompDescription': - component.set_description(_(value)) - elif field == 'CompDescriptionLong': - component.set_description_long(_(value)) - self.finish_template(template, component) - template=None - component=None + with open(dist_fname) as dist_file: + + + + template = None + component = None + for line in dist_file: + tokens = line.split(':', 1) + if len(tokens) < 2: + continue + field = tokens[0].strip() + value = tokens[1].strip() + if field == 'ChangelogURI': + self.changelogs_uri = _(value) + elif field == 'MetaReleaseURI': + self.metarelease_uri = value + elif field == 'Suite': + self.finish_template(template, component) + component=None + template = Template() + template.name = value + template.distribution = dist + template.match_name = "^%s$" % value + elif field == 'MatchName': + template.match_name = value + elif field == 'ParentSuite': + template.child = True + for nanny in self.templates: + # look for parent and add back ref to it + if nanny.name == value: + template.parents.append(nanny) + nanny.children.append(template) + elif field == 'Available': + template.available = apt_pkg.string_to_bool(value) + elif field == 'Official': + template.official = apt_pkg.string_to_bool(value) + elif field == 'RepositoryType': + template.type = value + elif field == 'BaseURI' and not template.base_uri: + template.base_uri = value + elif field == 'BaseURI-%s' % self.arch: + template.base_uri = value + elif field == 'MatchURI' and not template.match_uri: + template.match_uri = value + elif field == 'MatchURI-%s' % self.arch: + template.match_uri = value + elif (field == 'MirrorsFile' or + field == 'MirrorsFile-%s' % self.arch): + # Make the path absolute. + value = os.path.isabs(value) and value or \ + os.path.abspath(os.path.join(base_dir, value)) + if value not in map_mirror_sets: + mirror_set = {} + try: + with open(value) as value_f: + mirror_data = filter(match_mirror_line.match, + [x.strip() for x in + value_f]) + except Exception: + print "WARNING: Failed to read mirror file" + mirror_data = [] + for line in mirror_data: + if line.startswith("#LOC:"): + location = match_loc.sub(r"\1", line) + continue + (proto, hostname, dir) = split_url(line) + if hostname in mirror_set: + mirror_set[hostname].add_repository(proto, dir) + else: + mirror_set[hostname] = Mirror( + proto, hostname, dir, location) + map_mirror_sets[value] = mirror_set + template.mirror_set = map_mirror_sets[value] + elif field == 'Description': + template.description = _(value) + elif field == 'Component': + if (component and not + template.has_component(component.name)): + template.components.append(component) + component = Component(value) + elif field == 'CompDescription': + component.set_description(_(value)) + elif field == 'CompDescriptionLong': + component.set_description_long(_(value)) + self.finish_template(template, component) + template=None + component=None def finish_template(self, template, component): " finish the current tempalte " diff --git a/aptsources/sourceslist.py b/aptsources/sourceslist.py index 38831e9c..22770c10 100644 --- a/aptsources/sourceslist.py +++ b/aptsources/sourceslist.py @@ -368,15 +368,12 @@ class SourcesList(object): def load(self, file): """ (re)load the current sources """ try: - f = open(file, "r") - lines = f.readlines() - for line in lines: - source = SourceEntry(line, file) - self.list.append(source) + with open(file, "r") as f: + for line in f: + source = SourceEntry(line, file) + self.list.append(source) except: print "could not open file '%s'" % file - else: - f.close() def save(self): """ save the current sources """ @@ -388,14 +385,19 @@ class SourcesList(object): "## See sources.list(5) for more information, especialy\n" "# Remember that you can only use http, ftp or file URIs\n" "# CDROMs are managed through the apt-cdrom tool.\n") - open(path, "w").write(header) + + with open(path, "w") as f: + f.write(header) return - for source in self.list: - if source.file not in files: - files[source.file] = open(source.file, "w") - files[source.file].write(source.str()) - for f in files: - files[f].close() + + try: + for source in self.list: + if source.file not in files: + files[source.file] = open(source.file, "w") + files[source.file].write(source.str()) + finally: + for f in files: + files[f].close() def check_for_relations(self, sources_list): """get all parent and child channels in the sources list""" diff --git a/debian/changelog b/debian/changelog index 2864126a..cbe92343 100644 --- a/debian/changelog +++ b/debian/changelog @@ -3,6 +3,7 @@ python-apt (0.8.0~exp2) UNRELEASED; urgency=low * aptsources: Parse multi-arch sources.list files correctly * aptsources: Allow insertion of new multi-arch entries * aptsources: Various cleanup work + * all: Fix all instances of ResourceWarning about unclosed files -- Julian Andres Klode Wed, 06 Apr 2011 09:46:52 +0200 diff --git a/tests/test_apt_cache.py b/tests/test_apt_cache.py index b4cc650d..151a20e2 100644 --- a/tests/test_apt_cache.py +++ b/tests/test_apt_cache.py @@ -89,17 +89,17 @@ class TestAptCache(unittest.TestCase): tmpdir = tempfile.mkdtemp() dpkg_dir = os.path.join(tmpdir,"var","lib","dpkg") os.makedirs(os.path.join(dpkg_dir,"updates")) - open(os.path.join(dpkg_dir,"status"), "w") + open(os.path.join(dpkg_dir,"status"), "w").close() apt_pkg.config.set("Dir::State::status", os.path.join(dpkg_dir,"status")) cache = apt.Cache() # test empty self.assertFalse(cache.dpkg_journal_dirty) # that is ok, only [0-9] are dpkg jounral entries - open(os.path.join(dpkg_dir,"updates","xxx"), "w") + open(os.path.join(dpkg_dir,"updates","xxx"), "w").close() self.assertFalse(cache.dpkg_journal_dirty) # that is a dirty journal - open(os.path.join(dpkg_dir,"updates","000"), "w") + open(os.path.join(dpkg_dir,"updates","000"), "w").close() self.assertTrue(cache.dpkg_journal_dirty) # reset config value apt_pkg.config.set("Dir::State::status", old_status) @@ -121,20 +121,19 @@ class TestAptCache(unittest.TestCase): apt_pkg.config.set("dir::etc::sourceparts", "xxx") # main sources.list sources_list = base_sources - f=open(sources_list, "w") - repo = os.path.abspath("./data/test-repo2") - f.write("deb copy:%s /\n" % repo) - f.close() + with open(sources_list, "w") as f: + repo = os.path.abspath("./data/test-repo2") + f.write("deb copy:%s /\n" % repo) # test single sources.list fetching sources_list = os.path.join(rootdir, "test.list") - f=open(sources_list, "w") - repo_dir = os.path.abspath("./data/test-repo") - f.write("deb copy:%s /\n" % repo_dir) - f.close() + with open(sources_list, "w") as f: + repo_dir = os.path.abspath("./data/test-repo") + f.write("deb copy:%s /\n" % repo_dir) + self.assertTrue(os.path.exists(sources_list)) # write marker to ensure listcleaner is not run - open("./data/tmp/var/lib/apt/lists/marker", "w") + open("./data/tmp/var/lib/apt/lists/marker", "w").close() # update a single sources.list cache = apt.Cache() diff --git a/tests/test_hashes.py b/tests/test_hashes.py index e0aabe09..660373cb 100644 --- a/tests/test_hashes.py +++ b/tests/test_hashes.py @@ -82,11 +82,16 @@ class TestHashString(unittest.TestCase): def setUp(self): """Prepare the test by reading the file.""" - self.hashes = apt_pkg.Hashes(open(apt_pkg.__file__)) + self.file = open(apt_pkg.__file__) + self.hashes = apt_pkg.Hashes(self.file) self.md5 = apt_pkg.HashString("MD5Sum", self.hashes.md5) self.sha1 = apt_pkg.HashString("SHA1", self.hashes.sha1) self.sha256 = apt_pkg.HashString("SHA256", self.hashes.sha256) + def tearDown(self): + """Cleanup, Close the file object used for the tests.""" + self.file.close() + def test_md5(self): """hashes: Test apt_pkg.HashString().md5""" self.assertEqual("MD5Sum:%s" % self.hashes.md5, str(self.md5)) diff --git a/tests/test_progress.py b/tests/test_progress.py index ffab5bc0..73853dfa 100644 --- a/tests/test_progress.py +++ b/tests/test_progress.py @@ -34,7 +34,8 @@ class TestProgress(unittest.TestCase): apt_pkg.config.set("Dir::state::lists", "./tmp") # create artifical line deb_line = "deb file:%s/data/fake-packages/ /\n" % basedir - open("fetch_sources.list","w").write(deb_line) + with open("fetch_sources.list","w") as fobj: + fobj.write(deb_line) apt_pkg.config.set("Dir::Etc::sourcelist", "fetch_sources.list") def test_acquire_progress(self): -- cgit v1.2.3 From fedfc6ec4584f43364e13e35326d051f5526700b Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Wed, 6 Apr 2011 11:17:40 +0200 Subject: tests/test_apt_cache.py: Use assertTrue() instead of assert_() --- debian/changelog | 1 + tests/test_apt_cache.py | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/debian/changelog b/debian/changelog index cbe92343..9d708753 100644 --- a/debian/changelog +++ b/debian/changelog @@ -4,6 +4,7 @@ python-apt (0.8.0~exp2) UNRELEASED; urgency=low * aptsources: Allow insertion of new multi-arch entries * aptsources: Various cleanup work * all: Fix all instances of ResourceWarning about unclosed files + * tests/test_apt_cache.py: Use assertTrue() instead of assert_() -- Julian Andres Klode Wed, 06 Apr 2011 09:46:52 +0200 diff --git a/tests/test_apt_cache.py b/tests/test_apt_cache.py index 151a20e2..aaa9f601 100644 --- a/tests/test_apt_cache.py +++ b/tests/test_apt_cache.py @@ -48,9 +48,9 @@ class TestAptCache(unittest.TestCase): # tons of seek operations r = pkg.candidate.record self.assertEqual(r['Package'], pkg.shortname) - self.assert_('Version' in r) - self.assert_(len(r['Description']) > 0) - self.assert_(str(r).startswith('Package: %s\n' % pkg.shortname)) + self.assertTrue('Version' in r) + self.assertTrue(len(r['Description']) > 0) + self.assertTrue(str(r).startswith('Package: %s\n' % pkg.shortname)) def test_get_provided_packages(self): cache = apt.Cache() -- cgit v1.2.3 From d5e763e1920eadf0bc0d460abbf686c65db2a3b4 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Mon, 11 Apr 2011 10:13:15 +0200 Subject: apt_pkg: Raise error when parse_commandline gets empty argv (LP: #707416) --- debian/changelog | 1 + python/configuration.cc | 4 ++++ tests/test_configuration.py | 30 ++++++++++++++++++++++++++++++ 3 files changed, 35 insertions(+) create mode 100644 tests/test_configuration.py diff --git a/debian/changelog b/debian/changelog index 9d708753..e71cd63a 100644 --- a/debian/changelog +++ b/debian/changelog @@ -5,6 +5,7 @@ python-apt (0.8.0~exp2) UNRELEASED; urgency=low * aptsources: Various cleanup work * all: Fix all instances of ResourceWarning about unclosed files * tests/test_apt_cache.py: Use assertTrue() instead of assert_() + * apt_pkg: Raise error when parse_commandline gets empty argv (LP: #707416) -- Julian Andres Klode Wed, 06 Apr 2011 09:46:52 +0200 diff --git a/python/configuration.cc b/python/configuration.cc index 93e92efa..b6a44b44 100644 --- a/python/configuration.cc +++ b/python/configuration.cc @@ -438,6 +438,10 @@ PyObject *ParseCommandLine(PyObject *Self,PyObject *Args) return 0; } + if (PySequence_Length(Pargv) < 1) { + PyErr_SetString(PyExc_ValueError,"argv is an empty sequence"); + return 0; + } // Convert the option list int Length = PySequence_Length(POList); CommandLine::Args *OList = new CommandLine::Args[Length+1]; diff --git a/tests/test_configuration.py b/tests/test_configuration.py new file mode 100644 index 00000000..80509cff --- /dev/null +++ b/tests/test_configuration.py @@ -0,0 +1,30 @@ +#!/usr/bin/python +# +# Copyright (C) 2011 Julian Andres Klode +# +# Copying and distribution of this file, with or without modification, +# are permitted in any medium without royalty provided the copyright +# notice and this notice are preserved. +"""Unit tests for verifying the correctness of apt_pkg.Configuration""" +import unittest + +import apt_pkg + + +class TestConfiguration(unittest.TestCase): + """Test various configuration things""" + + def setUp(self): + """Prepare the tests, create reference values...""" + apt_pkg.init_config() + + def test_lp707416(self): + """configuration: Test empty arguments (LP: #707416)""" + self.assertRaises(ValueError, apt_pkg.parse_commandline, + apt_pkg.config,[], []) + self.assertRaises(SystemError, apt_pkg.parse_commandline, + apt_pkg.config,[], ["cmd", "--arg0"]) + + +if __name__ == "__main__": + unittest.main() -- cgit v1.2.3 From 2a0f97e8ad0ed8ac7456b8dc785071bf1c3a1847 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Mon, 11 Apr 2011 11:44:20 +0200 Subject: apt_pkg: Fix time_to_str, time_rfc1123 to accept more correct values (time_to_str accepts unsigned long, time_rfc1123 long long, y2k31-correct). --- debian/changelog | 2 ++ python/string.cc | 10 +++++----- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/debian/changelog b/debian/changelog index e71cd63a..2272462a 100644 --- a/debian/changelog +++ b/debian/changelog @@ -6,6 +6,8 @@ python-apt (0.8.0~exp2) UNRELEASED; urgency=low * all: Fix all instances of ResourceWarning about unclosed files * tests/test_apt_cache.py: Use assertTrue() instead of assert_() * apt_pkg: Raise error when parse_commandline gets empty argv (LP: #707416) + * apt_pkg: Fix time_to_str, time_rfc1123 to accept more correct values + (time_to_str accepts unsigned long, time_rfc1123 long long, y2k31-correct). -- Julian Andres Klode Wed, 06 Apr 2011 09:46:52 +0200 diff --git a/python/string.cc b/python/string.cc index 6a1ce4e2..a5016103 100644 --- a/python/string.cc +++ b/python/string.cc @@ -28,11 +28,11 @@ PyObject *Python(PyObject *Self,PyObject *Args) \ return CppPyString(CFunc(Str)); \ } -#define MkInt(Python,CFunc) \ +#define MkInt(Python,CFunc, ctype, pytype) \ PyObject *Python(PyObject *Self,PyObject *Args) \ { \ - int Val = 0; \ - if (PyArg_ParseTuple(Args,"i",&Val) == 0) \ + ctype Val = 0; \ + if (PyArg_ParseTuple(Args,pytype,&Val) == 0) \ return 0; \ return CppPyString(CFunc(Val)); \ } @@ -56,8 +56,8 @@ PyObject *StrBase64Encode(PyObject *Self,PyObject *Args) { MkStr(StrURItoFileName,URItoFileName); //MkFloat(StrSizeToStr,SizeToStr); -MkInt(StrTimeToStr,TimeToStr); -MkInt(StrTimeRFC1123,TimeRFC1123); +MkInt(StrTimeToStr,TimeToStr, unsigned long, "k"); +MkInt(StrTimeRFC1123,TimeRFC1123, long long, "L"); /*}}}*/ // Other String functions /*{{{*/ -- cgit v1.2.3 From 30bde83a45ebe2b8c401ef72f8bac3f4058614ab Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Mon, 11 Apr 2011 11:54:15 +0200 Subject: apt.progress: Use long for ETA, natural type for size (LP: #377375) --- apt/progress/old.py | 5 +++-- apt/progress/text.py | 5 ++--- debian/changelog | 1 + 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/apt/progress/old.py b/apt/progress/old.py index 4bd79f2e..364cd2ce 100644 --- a/apt/progress/old.py +++ b/apt/progress/old.py @@ -149,10 +149,11 @@ class TextFetchProgress(FetchProgress): Return True to continue or False to cancel. """ FetchProgress.pulse(self) + if self.currentCPS > 0: s = "[%2.f%%] %sB/s %s" % (self.percent, - apt_pkg.size_to_str(int(self.currentCPS)), - apt_pkg.time_to_str(int(self.eta))) + apt_pkg.size_to_str(self.currentCPS), + apt_pkg.time_to_str(long(self.eta))) else: s = "%2.f%% [Working]" % (self.percent) print "\r%s" % (s), diff --git a/apt/progress/text.py b/apt/progress/text.py index d777837c..c5eec092 100644 --- a/apt/progress/text.py +++ b/apt/progress/text.py @@ -157,11 +157,10 @@ class AcquireProgress(base.AcquireProgress, TextProgress): shown = False tval = '%i%%' % percent - end = "" if self.current_cps: - eta = int(float(self.total_bytes - self.current_bytes) / - self.current_cps) + eta = long(float(self.total_bytes - self.current_bytes) / + self.current_cps) end = " %sB/s %s" % (apt_pkg.size_to_str(self.current_cps), apt_pkg.time_to_str(eta)) diff --git a/debian/changelog b/debian/changelog index 2272462a..4d5c6225 100644 --- a/debian/changelog +++ b/debian/changelog @@ -8,6 +8,7 @@ python-apt (0.8.0~exp2) UNRELEASED; urgency=low * apt_pkg: Raise error when parse_commandline gets empty argv (LP: #707416) * apt_pkg: Fix time_to_str, time_rfc1123 to accept more correct values (time_to_str accepts unsigned long, time_rfc1123 long long, y2k31-correct). + * apt.progress: Use long for ETA, natural type for size (LP: #377375) -- Julian Andres Klode Wed, 06 Apr 2011 09:46:52 +0200 -- cgit v1.2.3 From a9161a7868bc7e97fa0938dd4d5eab5ae379e3ee Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Mon, 11 Apr 2011 12:00:05 +0200 Subject: aptsources/sourceslist.py: s/aptsource.py/sourceslist.py/ (LP: #309603) --- aptsources/sourceslist.py | 2 +- debian/changelog | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/aptsources/sourceslist.py b/aptsources/sourceslist.py index 22770c10..353cce2d 100644 --- a/aptsources/sourceslist.py +++ b/aptsources/sourceslist.py @@ -1,4 +1,4 @@ -# aptsource.py - Provide an abstraction of the sources.list +# sourceslist.py - Provide an abstraction of the sources.list # # Copyright (c) 2004-2009 Canonical Ltd. # Copyright (c) 2004 Michiel Sikkes diff --git a/debian/changelog b/debian/changelog index 4d5c6225..2032eeae 100644 --- a/debian/changelog +++ b/debian/changelog @@ -9,6 +9,7 @@ python-apt (0.8.0~exp2) UNRELEASED; urgency=low * apt_pkg: Fix time_to_str, time_rfc1123 to accept more correct values (time_to_str accepts unsigned long, time_rfc1123 long long, y2k31-correct). * apt.progress: Use long for ETA, natural type for size (LP: #377375) + * aptsources/sourceslist.py: s/aptsource.py/sourceslist.py/ (LP: #309603) -- Julian Andres Klode Wed, 06 Apr 2011 09:46:52 +0200 -- cgit v1.2.3 From 91603aac68593f6749428825d7e94b75873927f4 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Mon, 11 Apr 2011 12:05:15 +0200 Subject: doc/examples: Add example on how to get architecture names (LP: #194374) --- debian/changelog | 1 + doc/examples/architecture.py | 12 ++++++++++++ 2 files changed, 13 insertions(+) create mode 100644 doc/examples/architecture.py diff --git a/debian/changelog b/debian/changelog index 2032eeae..ae57e18b 100644 --- a/debian/changelog +++ b/debian/changelog @@ -10,6 +10,7 @@ python-apt (0.8.0~exp2) UNRELEASED; urgency=low (time_to_str accepts unsigned long, time_rfc1123 long long, y2k31-correct). * apt.progress: Use long for ETA, natural type for size (LP: #377375) * aptsources/sourceslist.py: s/aptsource.py/sourceslist.py/ (LP: #309603) + * doc/examples: Add example on how to get architecture names (LP: #194374) -- Julian Andres Klode Wed, 06 Apr 2011 09:46:52 +0200 diff --git a/doc/examples/architecture.py b/doc/examples/architecture.py new file mode 100644 index 00000000..75afb2d1 --- /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() -- cgit v1.2.3 From f441b008883170d6a8c4cfeb814b0c07a27e6afd Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Tue, 12 Apr 2011 11:38:25 +0200 Subject: apt_pkg: Fix unsigned/long-vs-int issues (LP: #610820) This fix is large, but simple in concept. Instead of relying on Py_BuildValue and type signatures, or type-specific conversion functions, create a new set of overloaded MkPyNumber() functions that automatically do the right thing for each numerical type. --- debian/changelog | 1 + python/acquire-item.cc | 10 ++++---- python/acquire.cc | 14 +++++----- python/apt_pkgmodule.cc | 68 ++++++++++++++++++++++++------------------------- python/arfile.cc | 12 ++++----- python/cache.cc | 44 ++++++++++++++++---------------- python/configuration.cc | 2 +- python/depcache.cc | 12 ++++----- python/generic.h | 16 ++++++++++++ python/indexfile.cc | 2 +- python/indexrecords.cc | 2 +- python/pkgmanager.cc | 2 +- python/pkgsrcrecords.cc | 10 +++++--- python/policy.cc | 2 +- python/progress.cc | 60 +++++++++++++++++++++---------------------- python/string.cc | 4 +-- python/tag.cc | 5 ++-- python/tarfile.cc | 14 +++++----- 18 files changed, 150 insertions(+), 130 deletions(-) diff --git a/debian/changelog b/debian/changelog index ae57e18b..1460acce 100644 --- a/debian/changelog +++ b/debian/changelog @@ -11,6 +11,7 @@ python-apt (0.8.0~exp2) UNRELEASED; urgency=low * apt.progress: Use long for ETA, natural type for size (LP: #377375) * aptsources/sourceslist.py: s/aptsource.py/sourceslist.py/ (LP: #309603) * doc/examples: Add example on how to get architecture names (LP: #194374) + * apt_pkg: Fix unsigned/long-vs-int issues (LP: #610820) -- Julian Andres Klode Wed, 06 Apr 2011 09:46:52 +0200 diff --git a/python/acquire-item.cc b/python/acquire-item.cc index 895d4a21..5e7423ab 100644 --- a/python/acquire-item.cc +++ b/python/acquire-item.cc @@ -65,13 +65,13 @@ static PyObject *acquireitem_get_error_text(PyObject *self, void *closure) static PyObject *acquireitem_get_filesize(PyObject *self, void *closure) { pkgAcquire::Item *item = acquireitem_tocpp(self); - return item ? Py_BuildValue("K", item->FileSize) : 0; + return item ? MkPyNumber(item->FileSize) : 0; } static PyObject *acquireitem_get_id(PyObject *self, void *closure) { pkgAcquire::Item *item = acquireitem_tocpp(self); - return item ? Py_BuildValue("k", item->ID) : 0; + return item ? MkPyNumber(item->ID) : 0; } static PyObject *acquireitem_get_mode(PyObject *self, void *closure) @@ -95,13 +95,13 @@ static PyObject *acquireitem_get_local(PyObject *self, void *closure) static PyObject *acquireitem_get_partialsize(PyObject *self, void *closure) { pkgAcquire::Item *item = acquireitem_tocpp(self); - return item ? Py_BuildValue("K", item->PartialSize) : 0; + return item ? MkPyNumber(item->PartialSize) : 0; } static PyObject *acquireitem_get_status(PyObject *self, void *closure) { pkgAcquire::Item *item = acquireitem_tocpp(self); - return item ? Py_BuildValue("i", item->Status) : 0; + return item ? MkPyNumber(item->Status) : 0; } static int acquireitem_set_id(PyObject *self, PyObject *value, void *closure) @@ -110,7 +110,7 @@ static int acquireitem_set_id(PyObject *self, PyObject *value, void *closure) if (Itm == 0) return -1; if (PyLong_Check(value)) { - Itm->ID = PyLong_AsLong(value); + Itm->ID = PyLong_AsUnsignedLong(value); } else if (PyInt_Check(value)) { Itm->ID = PyInt_AsLong(value); diff --git a/python/acquire.cc b/python/acquire.cc index ab90bbdd..6169ff40 100644 --- a/python/acquire.cc +++ b/python/acquire.cc @@ -51,17 +51,17 @@ static PyObject *acquireworker_get_status(PyObject *self, void *closure) static PyObject *acquireworker_get_current_size(PyObject *self, void *closure) { - return Py_BuildValue("k",GetCpp(self)->CurrentSize); + return MkPyNumber(GetCpp(self)->CurrentSize); } static PyObject *acquireworker_get_total_size(PyObject *self, void *closure) { - return Py_BuildValue("k",GetCpp(self)->TotalSize); + return MkPyNumber(GetCpp(self)->TotalSize); } static PyObject *acquireworker_get_resumepoint(PyObject *self, void *closure) { - return Py_BuildValue("k",GetCpp(self)->ResumePoint); + return MkPyNumber(GetCpp(self)->ResumePoint); } static PyGetSetDef acquireworker_getset[] = { @@ -225,7 +225,7 @@ static PyObject *PkgAcquireRun(PyObject *Self,PyObject *Args) pkgAcquire::RunResult run = fetcher->Run(pulseInterval); - return HandleErrors(Py_BuildValue("i",run)); + return HandleErrors(MkPyNumber(run)); } @@ -259,15 +259,15 @@ static PyMethodDef PkgAcquireMethods[] = { #define fetcher (GetCpp(Self)) static PyObject *PkgAcquireGetTotalNeeded(PyObject *Self,void*) { - return Py_BuildValue("L", fetcher->TotalNeeded()); + return MkPyNumber(fetcher->TotalNeeded()); } static PyObject *PkgAcquireGetFetchNeeded(PyObject *Self,void*) { - return Py_BuildValue("L", fetcher->FetchNeeded()); + return MkPyNumber(fetcher->FetchNeeded()); } static PyObject *PkgAcquireGetPartialPresent(PyObject *Self,void*) { - return Py_BuildValue("L", fetcher->PartialPresent()); + return MkPyNumber(fetcher->PartialPresent()); } #undef fetcher diff --git a/python/apt_pkgmodule.cc b/python/apt_pkgmodule.cc index 0fac664b..2394b0f8 100644 --- a/python/apt_pkgmodule.cc +++ b/python/apt_pkgmodule.cc @@ -83,7 +83,7 @@ static PyObject *VersionCompare(PyObject *Self,PyObject *Args) return 0; } - return Py_BuildValue("i",_system->VS->DoCmpVersion(A,A+LenA,B,B+LenB)); + return MkPyNumber(_system->VS->DoCmpVersion(A,A+LenA,B,B+LenB)); } static char *doc_CheckDep = @@ -459,7 +459,7 @@ static PyObject *GetLock(PyObject *Self,PyObject *Args) int fd = GetLock(file, errors); - return HandleErrors(Py_BuildValue("i", fd)); + return HandleErrors(MkPyNumber(fd)); } static char *doc_PkgSystemLock = @@ -854,82 +854,82 @@ extern "C" void initapt_pkg() // Acquire constants. // some constants PyDict_SetItemString(PyAcquire_Type.tp_dict, "RESULT_CANCELLED", - Py_BuildValue("i", pkgAcquire::Cancelled)); + MkPyNumber(pkgAcquire::Cancelled)); PyDict_SetItemString(PyAcquire_Type.tp_dict, "RESULT_CONTINUE", - Py_BuildValue("i", pkgAcquire::Continue)); + MkPyNumber(pkgAcquire::Continue)); PyDict_SetItemString(PyAcquire_Type.tp_dict, "RESULT_FAILED", - Py_BuildValue("i", pkgAcquire::Failed)); + MkPyNumber(pkgAcquire::Failed)); #ifdef COMPAT_0_7 PyDict_SetItemString(PyAcquire_Type.tp_dict, "ResultCancelled", - Py_BuildValue("i", pkgAcquire::Cancelled)); + MkPyNumber(pkgAcquire::Cancelled)); PyDict_SetItemString(PyAcquire_Type.tp_dict, "ResultContinue", - Py_BuildValue("i", pkgAcquire::Continue)); + MkPyNumber(pkgAcquire::Continue)); PyDict_SetItemString(PyAcquire_Type.tp_dict, "ResultFailed", - Py_BuildValue("i", pkgAcquire::Failed)); + MkPyNumber(pkgAcquire::Failed)); #endif // Dependency constants PyDict_SetItemString(PyDependency_Type.tp_dict, "TYPE_DEPENDS", - Py_BuildValue("i", pkgCache::Dep::Depends)); + MkPyNumber(pkgCache::Dep::Depends)); PyDict_SetItemString(PyDependency_Type.tp_dict, "TYPE_PREDEPENDS", - Py_BuildValue("i", pkgCache::Dep::PreDepends)); + MkPyNumber(pkgCache::Dep::PreDepends)); PyDict_SetItemString(PyDependency_Type.tp_dict, "TYPE_SUGGESTS", - Py_BuildValue("i", pkgCache::Dep::Suggests)); + MkPyNumber(pkgCache::Dep::Suggests)); PyDict_SetItemString(PyDependency_Type.tp_dict, "TYPE_RECOMMENDS", - Py_BuildValue("i", pkgCache::Dep::Suggests)); + MkPyNumber(pkgCache::Dep::Suggests)); PyDict_SetItemString(PyDependency_Type.tp_dict, "TYPE_CONFLICTS", - Py_BuildValue("i", pkgCache::Dep::Conflicts)); + MkPyNumber(pkgCache::Dep::Conflicts)); PyDict_SetItemString(PyDependency_Type.tp_dict, "TYPE_REPLACES", - Py_BuildValue("i", pkgCache::Dep::Replaces)); + MkPyNumber(pkgCache::Dep::Replaces)); PyDict_SetItemString(PyDependency_Type.tp_dict, "TYPE_OBSOLETES", - Py_BuildValue("i", pkgCache::Dep::Obsoletes)); + MkPyNumber(pkgCache::Dep::Obsoletes)); PyDict_SetItemString(PyDependency_Type.tp_dict, "TYPE_DPKG_BREAKS", - Py_BuildValue("i", pkgCache::Dep::DpkgBreaks)); + MkPyNumber(pkgCache::Dep::DpkgBreaks)); PyDict_SetItemString(PyDependency_Type.tp_dict, "TYPE_ENHANCES", - Py_BuildValue("i", pkgCache::Dep::Enhances)); + MkPyNumber(pkgCache::Dep::Enhances)); // PackageManager constants PyDict_SetItemString(PyPackageManager_Type.tp_dict, "RESULT_COMPLETED", - Py_BuildValue("i", pkgPackageManager::Completed)); + MkPyNumber(pkgPackageManager::Completed)); PyDict_SetItemString(PyPackageManager_Type.tp_dict, "RESULT_FAILED", - Py_BuildValue("i", pkgPackageManager::Failed)); + MkPyNumber(pkgPackageManager::Failed)); PyDict_SetItemString(PyPackageManager_Type.tp_dict, "RESULT_INCOMPLETE", - Py_BuildValue("i", pkgPackageManager::Incomplete)); + MkPyNumber(pkgPackageManager::Incomplete)); #ifdef COMPAT_0_7 PyDict_SetItemString(PyPackageManager_Type.tp_dict, "ResultCompleted", - Py_BuildValue("i", pkgPackageManager::Completed)); + MkPyNumber(pkgPackageManager::Completed)); PyDict_SetItemString(PyPackageManager_Type.tp_dict, "ResultFailed", - Py_BuildValue("i", pkgPackageManager::Failed)); + MkPyNumber(pkgPackageManager::Failed)); PyDict_SetItemString(PyPackageManager_Type.tp_dict, "ResultIncomplete", - Py_BuildValue("i", pkgPackageManager::Incomplete)); + MkPyNumber(pkgPackageManager::Incomplete)); #endif // AcquireItem Constants. PyDict_SetItemString(PyAcquireItem_Type.tp_dict, "STAT_IDLE", - Py_BuildValue("i", pkgAcquire::Item::StatIdle)); + MkPyNumber(pkgAcquire::Item::StatIdle)); PyDict_SetItemString(PyAcquireItem_Type.tp_dict, "STAT_FETCHING", - Py_BuildValue("i", pkgAcquire::Item::StatFetching)); + MkPyNumber(pkgAcquire::Item::StatFetching)); PyDict_SetItemString(PyAcquireItem_Type.tp_dict, "STAT_DONE", - Py_BuildValue("i", pkgAcquire::Item::StatDone)); + MkPyNumber(pkgAcquire::Item::StatDone)); PyDict_SetItemString(PyAcquireItem_Type.tp_dict, "STAT_TRANSIENT_NETWORK_ERROR", - Py_BuildValue("i", pkgAcquire::Item::StatTransientNetworkError)); + MkPyNumber(pkgAcquire::Item::StatTransientNetworkError)); PyDict_SetItemString(PyAcquireItem_Type.tp_dict, "STAT_ERROR", - Py_BuildValue("i", pkgAcquire::Item::StatError)); + MkPyNumber(pkgAcquire::Item::StatError)); PyDict_SetItemString(PyAcquireItem_Type.tp_dict, "STAT_AUTH_ERROR", - Py_BuildValue("i", pkgAcquire::Item::StatAuthError)); + MkPyNumber(pkgAcquire::Item::StatAuthError)); #ifdef COMPAT_0_7 PyDict_SetItemString(PyAcquireItem_Type.tp_dict, "StatIdle", - Py_BuildValue("i", pkgAcquire::Item::StatIdle)); + MkPyNumber(pkgAcquire::Item::StatIdle)); PyDict_SetItemString(PyAcquireItem_Type.tp_dict, "StatFetching", - Py_BuildValue("i", pkgAcquire::Item::StatFetching)); + MkPyNumber(pkgAcquire::Item::StatFetching)); PyDict_SetItemString(PyAcquireItem_Type.tp_dict, "StatDone", - Py_BuildValue("i", pkgAcquire::Item::StatDone)); + MkPyNumber(pkgAcquire::Item::StatDone)); PyDict_SetItemString(PyAcquireItem_Type.tp_dict, "StatError", - Py_BuildValue("i", pkgAcquire::Item::StatError)); + MkPyNumber(pkgAcquire::Item::StatError)); PyDict_SetItemString(PyAcquireItem_Type.tp_dict, "StatAuthError", - Py_BuildValue("i", pkgAcquire::Item::StatAuthError)); + MkPyNumber(pkgAcquire::Item::StatAuthError)); #endif #if PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION >= 1 diff --git a/python/arfile.cc b/python/arfile.cc index 5377ca8d..c3aa74d1 100644 --- a/python/arfile.cc +++ b/python/arfile.cc @@ -39,32 +39,32 @@ static PyObject *armember_get_name(PyObject *self, void *closure) static PyObject *armember_get_mtime(PyObject *self, void *closure) { - return Py_BuildValue("k", GetCpp(self)->MTime); + return MkPyNumber(GetCpp(self)->MTime); } static PyObject *armember_get_uid(PyObject *self, void *closure) { - return Py_BuildValue("k", GetCpp(self)->UID); + return MkPyNumber(GetCpp(self)->UID); } static PyObject *armember_get_gid(PyObject *self, void *closure) { - return Py_BuildValue("k", GetCpp(self)->GID); + return MkPyNumber(GetCpp(self)->GID); } static PyObject *armember_get_mode(PyObject *self, void *closure) { - return Py_BuildValue("k", GetCpp(self)->Mode); + return MkPyNumber(GetCpp(self)->Mode); } static PyObject *armember_get_size(PyObject *self, void *closure) { - return Py_BuildValue("k", GetCpp(self)->Size); + return MkPyNumber(GetCpp(self)->Size); } static PyObject *armember_get_start(PyObject *self, void *closure) { - return Py_BuildValue("k", GetCpp(self)->Start); + return MkPyNumber(GetCpp(self)->Start); } static PyObject *armember_repr(PyObject *self) diff --git a/python/cache.cc b/python/cache.cc index a27bf6f5..160fd208 100644 --- a/python/cache.cc +++ b/python/cache.cc @@ -221,7 +221,7 @@ static PyMethodDef PkgCacheMethods[] = static PyObject *PkgCacheGetGroupCount(PyObject *Self, void*) { pkgCache *Cache = GetCpp(Self); - return Py_BuildValue("i",Cache->HeaderP->GroupCount); + return MkPyNumber(Cache->HeaderP->GroupCount); } static PyObject *PkgCacheGetGroups(PyObject *Self, void*) { @@ -236,31 +236,31 @@ static PyObject *PkgCacheGetPackages(PyObject *Self, void*) { static PyObject *PkgCacheGetPackageCount(PyObject *Self, void*) { pkgCache *Cache = GetCpp(Self); - return Py_BuildValue("i",Cache->HeaderP->PackageCount); + return MkPyNumber((int)Cache->HeaderP->PackageCount); } static PyObject *PkgCacheGetVersionCount(PyObject *Self, void*) { pkgCache *Cache = GetCpp(Self); - return Py_BuildValue("i",Cache->HeaderP->VersionCount); + return MkPyNumber(Cache->HeaderP->VersionCount); } static PyObject *PkgCacheGetDependsCount(PyObject *Self, void*) { pkgCache *Cache = GetCpp(Self); - return Py_BuildValue("i",Cache->HeaderP->DependsCount); + return MkPyNumber(Cache->HeaderP->DependsCount); } static PyObject *PkgCacheGetPackageFileCount(PyObject *Self, void*) { pkgCache *Cache = GetCpp(Self); - return Py_BuildValue("i",Cache->HeaderP->PackageFileCount); + return MkPyNumber(Cache->HeaderP->PackageFileCount); } static PyObject *PkgCacheGetVerFileCount(PyObject *Self, void*) { pkgCache *Cache = GetCpp(Self); - return Py_BuildValue("i",Cache->HeaderP->VerFileCount); + return MkPyNumber(Cache->HeaderP->VerFileCount); } static PyObject *PkgCacheGetProvidesCount(PyObject *Self, void*) { pkgCache *Cache = GetCpp(Self); - return Py_BuildValue("i",Cache->HeaderP->ProvidesCount); + return MkPyNumber(Cache->HeaderP->ProvidesCount); } static PyObject *PkgCacheGetFileList(PyObject *Self, void*) { @@ -637,10 +637,10 @@ MkGet(PackageGetSection,Safe_FromString(Pkg.Section())) MkGet(PackageGetRevDependsList,CppPyObject_NEW(Owner, &PyDependencyList_Type, Pkg.RevDependsList())) MkGet(PackageGetProvidesList,CreateProvides(Owner,Pkg.ProvidesList())) -MkGet(PackageGetSelectedState,Py_BuildValue("i",Pkg->SelectedState)) -MkGet(PackageGetInstState,Py_BuildValue("i",Pkg->InstState)) -MkGet(PackageGetCurrentState,Py_BuildValue("i",Pkg->CurrentState)) -MkGet(PackageGetID,Py_BuildValue("i",Pkg->ID)) +MkGet(PackageGetSelectedState,MkPyNumber(Pkg->SelectedState)) +MkGet(PackageGetInstState,MkPyNumber(Pkg->InstState)) +MkGet(PackageGetCurrentState,MkPyNumber(Pkg->CurrentState)) +MkGet(PackageGetID,MkPyNumber(Pkg->ID)) # MkGet(PackageGetAuto,PyBool_FromLong((Pkg->Flags & pkgCache::Flag::Auto) != 0)) MkGet(PackageGetEssential,PyBool_FromLong((Pkg->Flags & pkgCache::Flag::Essential) != 0)) @@ -837,7 +837,7 @@ static PyObject *DescriptionGetFileList(PyObject *Self,void*) PyObject *DescFile; PyObject *Obj; DescFile = CppPyObject_NEW(Owner,&PyPackageFile_Type,I.File()); - Obj = Py_BuildValue("Nl",DescFile,I.Index()); + Obj = Py_BuildValue("NN",DescFile,MkPyNumber(I.Index())); PyList_Append(List,Obj); Py_DECREF(Obj); } @@ -992,7 +992,7 @@ static PyObject *VersionGetFileList(PyObject *Self, void*) { PyObject *PkgFile; PyObject *Obj; PkgFile = CppPyObject_NEW(Owner,&PyPackageFile_Type,I.File()); - Obj = Py_BuildValue("Nl",PkgFile,I.Index()); + Obj = Py_BuildValue("NN",PkgFile,MkPyNumber(I.Index())); PyList_Append(List,Obj); Py_DECREF(Obj); } @@ -1019,19 +1019,19 @@ static PyObject *VersionGetProvidesList(PyObject *Self, void*) { return CreateProvides(Owner,Version_GetVer(Self).ProvidesList()); } static PyObject *VersionGetSize(PyObject *Self, void*) { - return Py_BuildValue("i", Version_GetVer(Self)->Size); + return MkPyNumber(Version_GetVer(Self)->Size); } static PyObject *VersionGetInstalledSize(PyObject *Self, void*) { - return Py_BuildValue("i", Version_GetVer(Self)->InstalledSize); + return MkPyNumber(Version_GetVer(Self)->InstalledSize); } static PyObject *VersionGetHash(PyObject *Self, void*) { - return Py_BuildValue("i", Version_GetVer(Self)->Hash); + return MkPyNumber(Version_GetVer(Self)->Hash); } static PyObject *VersionGetID(PyObject *Self, void*) { - return Py_BuildValue("i", Version_GetVer(Self)->ID); + return MkPyNumber(Version_GetVer(Self)->ID); } static PyObject *VersionGetPriority(PyObject *Self, void*) { - return Py_BuildValue("i",Version_GetVer(Self)->Priority); + return MkPyNumber(Version_GetVer(Self)->Priority); } static PyObject *VersionGetPriorityStr(PyObject *Self, void*) { return Safe_FromString(Version_GetVer(Self).PriorityType()); @@ -1241,7 +1241,7 @@ static PyObject *PackageFile_GetIndexType(PyObject *Self,void*) static PyObject *PackageFile_GetSize(PyObject *Self,void*) { pkgCache::PkgFileIterator &File = GetCpp(Self); - return Py_BuildValue("i",File->Size); + return MkPyNumber(File->Size); } static PyObject *PackageFile_GetNotSource(PyObject *Self,void*) @@ -1258,7 +1258,7 @@ static PyObject *PackageFile_GetNotAutomatic(PyObject *Self,void*) static PyObject *PackageFile_GetID(PyObject *Self,void*) { pkgCache::PkgFileIterator &File = GetCpp(Self); - return Py_BuildValue("i",File->ID); + return MkPyNumber(File->ID); } #define S(s) (s == NULL ? "" : s) @@ -1467,13 +1467,13 @@ static PyObject *DependencyGetDepTypeUntranslated(PyObject *Self,void*) static PyObject *DependencyGetDepTypeEnum(PyObject *Self,void*) { pkgCache::DepIterator &Dep = GetCpp(Self); - return Py_BuildValue("i", Dep->Type); + return MkPyNumber(Dep->Type); } static PyObject *DependencyGetID(PyObject *Self,void*) { pkgCache::DepIterator &Dep = GetCpp(Self); - return Py_BuildValue("i",Dep->ID); + return MkPyNumber(Dep->ID); } static PyGetSetDef DependencyGetSet[] = { diff --git a/python/configuration.cc b/python/configuration.cc index b6a44b44..9000f71f 100644 --- a/python/configuration.cc +++ b/python/configuration.cc @@ -92,7 +92,7 @@ static PyObject *CnfFindI(PyObject *Self,PyObject *Args) int Default = 0; if (PyArg_ParseTuple(Args,"s|i",&Name,&Default) == 0) return 0; - return Py_BuildValue("i",GetSelf(Self).FindI(Name,Default)); + return MkPyNumber(GetSelf(Self).FindI(Name,Default)); } static const char *doc_FindB = diff --git a/python/depcache.cc b/python/depcache.cc index 12c13a73..e6113429 100644 --- a/python/depcache.cc +++ b/python/depcache.cc @@ -668,22 +668,22 @@ static PyMethodDef PkgDepCacheMethods[] = #define depcache (GetCpp(Self)) static PyObject *PkgDepCacheGetKeepCount(PyObject *Self,void*) { - return Py_BuildValue("l", depcache->KeepCount()); + return MkPyNumber(depcache->KeepCount()); } static PyObject *PkgDepCacheGetInstCount(PyObject *Self,void*) { - return Py_BuildValue("l", depcache->InstCount()); + return MkPyNumber(depcache->InstCount()); } static PyObject *PkgDepCacheGetDelCount(PyObject *Self,void*) { - return Py_BuildValue("l", depcache->DelCount()); + return MkPyNumber(depcache->DelCount()); } static PyObject *PkgDepCacheGetBrokenCount(PyObject *Self,void*) { - return Py_BuildValue("l", depcache->BrokenCount()); + return MkPyNumber(depcache->BrokenCount()); } static PyObject *PkgDepCacheGetUsrSize(PyObject *Self,void*) { - return Py_BuildValue("L", depcache->UsrSize()); + return MkPyNumber(depcache->UsrSize()); } static PyObject *PkgDepCacheGetDebSize(PyObject *Self,void*) { - return Py_BuildValue("L", depcache->DebSize()); + return MkPyNumber(depcache->DebSize()); } #undef depcache diff --git a/python/generic.h b/python/generic.h index ce9e5091..f9680ca5 100644 --- a/python/generic.h +++ b/python/generic.h @@ -57,6 +57,7 @@ typedef int Py_ssize_t; #define PyString_Type PyUnicode_Type #define PyInt_Check PyLong_Check #define PyInt_AsLong PyLong_AsLong +#define PyInt_FromLong PyLong_FromLong // Force 0.7 compatibility to be off in Python 3 builds #undef COMPAT_0_7 #else @@ -231,6 +232,21 @@ PyObject *HandleErrors(PyObject *Res = 0); const char **ListToCharChar(PyObject *List,bool NullTerm = false); PyObject *CharCharToList(const char **List,unsigned long Size = 0); +/* Happy number conversion, thanks to overloading */ +inline PyObject *MkPyNumber(unsigned long long o) { return PyLong_FromUnsignedLongLong(o); } +inline PyObject *MkPyNumber(unsigned long o) { return PyLong_FromUnsignedLong(o); } +inline PyObject *MkPyNumber(unsigned int o) { return PyLong_FromUnsignedLong(o); } +inline PyObject *MkPyNumber(unsigned short o) { return PyInt_FromLong(o); } +inline PyObject *MkPyNumber(unsigned char o) { return PyInt_FromLong(o); } + +inline PyObject *MkPyNumber(long long o) { return PyLong_FromLongLong(o); } +inline PyObject *MkPyNumber(long o) { return PyInt_FromLong(o); } +inline PyObject *MkPyNumber(int o) { return PyInt_FromLong(o); } +inline PyObject *MkPyNumber(short o) { return PyInt_FromLong(o); } +inline PyObject *MkPyNumber(char o) { return PyInt_FromLong(o); } + +inline PyObject *MkPyNumber(double o) { return PyFloat_FromDouble(o); } + # ifdef COMPAT_0_7 PyObject *_PyAptObject_getattro(PyObject *self, PyObject *attr); # else diff --git a/python/indexfile.cc b/python/indexfile.cc index 037be210..bf0df516 100644 --- a/python/indexfile.cc +++ b/python/indexfile.cc @@ -47,7 +47,7 @@ static PyObject *IndexFileGetHasPackages(PyObject *Self,void*) { return PyBool_FromLong((File->HasPackages())); } static PyObject *IndexFileGetSize(PyObject *Self,void*) { - return Py_BuildValue("i",(File->Size())); + return MkPyNumber((File->Size())); } static PyObject *IndexFileGetIsTrusted(PyObject *Self,void*) { return PyBool_FromLong((File->IsTrusted())); diff --git a/python/indexrecords.cc b/python/indexrecords.cc index d6a3263c..c7623cfd 100644 --- a/python/indexrecords.cc +++ b/python/indexrecords.cc @@ -63,7 +63,7 @@ static PyObject *indexrecords_lookup(PyObject *self,PyObject *args) // Copy the HashString(), to prevent crashes and to not require the // indexRecords object to exist. PyObject *py_hash = PyHashString_FromCpp(new HashString(result->Hash), true, NULL); - PyObject *value = Py_BuildValue("(Oi)",py_hash,result->Size); + PyObject *value = Py_BuildValue("(ON)",py_hash,MkPyNumber(result->Size)); Py_DECREF(py_hash); return value; } diff --git a/python/pkgmanager.cc b/python/pkgmanager.cc index 95e8c27e..a65c88f8 100644 --- a/python/pkgmanager.cc +++ b/python/pkgmanager.cc @@ -79,7 +79,7 @@ static PyObject *PkgManagerDoInstall(PyObject *Self,PyObject *Args) pkgPackageManager::OrderResult res = pm->DoInstall(status_fd); - return HandleErrors(Py_BuildValue("i",res)); + return HandleErrors(MkPyNumber(res)); } static PyObject *PkgManagerFixMissing(PyObject *Self,PyObject *Args) diff --git a/python/pkgsrcrecords.cc b/python/pkgsrcrecords.cc index aad3ef7e..4c889129 100644 --- a/python/pkgsrcrecords.cc +++ b/python/pkgsrcrecords.cc @@ -147,9 +147,9 @@ static PyObject *PkgSrcRecordsGetFiles(PyObject *Self,void*) { PyObject *v; for(unsigned int i=0;i(self); if (PyObject_TypeCheck(arg, &PyPackage_Type)) { pkgCache::PkgIterator pkg = GetCpp(arg); - return Py_BuildValue("i", policy->GetPriority(pkg)); + return MkPyNumber(policy->GetPriority(pkg)); } else { PyErr_SetString(PyExc_TypeError,"Argument must be of Package()."); return 0; diff --git a/python/progress.cc b/python/progress.cc index 5700a1b6..bd3c2ad6 100644 --- a/python/progress.cc +++ b/python/progress.cc @@ -92,12 +92,12 @@ void PyOpProgress::Update() setattr(callbackInst, "op", "s", Op.c_str()); setattr(callbackInst, "subop", "s", SubOp.c_str()); setattr(callbackInst, "major_change", "b", MajorChange); - setattr(callbackInst, "percent", "f", Percent); + setattr(callbackInst, "percent", "N", MkPyNumber(Percent)); #ifdef COMPAT_0_7 setattr(callbackInst, "Op", "s", Op.c_str()); setattr(callbackInst, "subOp", "s", SubOp.c_str()); setattr(callbackInst, "majorChange", "b", MajorChange); - PyObject *arglist = Py_BuildValue("(f)", Percent); + PyObject *arglist = Py_BuildValue("(N)", MkPyNumber(Percent)); RunSimpleCallback("update", arglist); #else RunSimpleCallback("update"); @@ -156,19 +156,19 @@ void PyFetchProgress::UpdateStatus(pkgAcquire::ItemDesc &Itm, int status) // Added object file size and object partial size to // parameters that are passed to updateStatus. // -- Stephan - PyObject *arglist = Py_BuildValue("(sssikk)", Itm.URI.c_str(), + PyObject *arglist = Py_BuildValue("(sssNNN)", Itm.URI.c_str(), Itm.Description.c_str(), Itm.ShortDesc.c_str(), - status, - Itm.Owner->FileSize, - Itm.Owner->PartialSize); + MkPyNumber(status), + MkPyNumber(Itm.Owner->FileSize), + MkPyNumber(Itm.Owner->PartialSize)); RunSimpleCallback("update_status_full", arglist); // legacy version of the interface - arglist = Py_BuildValue("(sssi)", Itm.URI.c_str(), Itm.Description.c_str(), - Itm.ShortDesc.c_str(), status); + arglist = Py_BuildValue("(sssN)", Itm.URI.c_str(), Itm.Description.c_str(), + Itm.ShortDesc.c_str(), MkPyNumber(status)); if(PyObject_HasAttrString(callbackInst, "updateStatus")) RunSimpleCallback("updateStatus", arglist); @@ -240,11 +240,11 @@ void PyFetchProgress::Start() pkgAcquireStatus::Start(); #ifdef COMPAT_0_7 - setattr(callbackInst, "currentCPS", "d", 0); - setattr(callbackInst, "currentBytes", "d", 0); - setattr(callbackInst, "currentItems", "k", 0); - setattr(callbackInst, "totalItems", "k", 0); - setattr(callbackInst, "totalBytes", "d", 0); + setattr(callbackInst, "currentCPS", "N", MkPyNumber(0)); + setattr(callbackInst, "currentBytes", "N", MkPyNumber(0)); + setattr(callbackInst, "currentItems", "N", MkPyNumber(0)); + setattr(callbackInst, "totalItems", "N", MkPyNumber(0)); + setattr(callbackInst, "totalBytes", "N", MkPyNumber(0)); #endif RunSimpleCallback("start"); @@ -280,14 +280,14 @@ bool PyFetchProgress::Pulse(pkgAcquire * Owner) return false; } - setattr(callbackInst, "last_bytes", "d", LastBytes); - setattr(callbackInst, "current_cps", "d", CurrentCPS); - setattr(callbackInst, "current_bytes", "d", CurrentBytes); - setattr(callbackInst, "total_bytes", "d", TotalBytes); - setattr(callbackInst, "fetched_bytes", "d", FetchedBytes); - setattr(callbackInst, "elapsed_time", "k", ElapsedTime); - setattr(callbackInst, "current_items", "k", CurrentItems); - setattr(callbackInst, "total_items", "k", TotalItems); + setattr(callbackInst, "last_bytes", "N", MkPyNumber(LastBytes)); + setattr(callbackInst, "current_cps", "N", MkPyNumber(CurrentCPS)); + setattr(callbackInst, "current_bytes", "N", MkPyNumber(CurrentBytes)); + setattr(callbackInst, "total_bytes", "N", MkPyNumber(TotalBytes)); + setattr(callbackInst, "fetched_bytes", "N", MkPyNumber(FetchedBytes)); + setattr(callbackInst, "elapsed_time", "N", MkPyNumber(ElapsedTime)); + setattr(callbackInst, "current_items", "N", MkPyNumber(CurrentItems)); + setattr(callbackInst, "total_items", "N", MkPyNumber(TotalItems)); // New style if (!PyObject_HasAttrString(callbackInst, "updateStatus")) { @@ -313,12 +313,12 @@ bool PyFetchProgress::Pulse(pkgAcquire * Owner) return true; } #ifdef COMPAT_0_7 - setattr(callbackInst, "currentCPS", "d", CurrentCPS); - setattr(callbackInst, "currentBytes", "d", CurrentBytes); - setattr(callbackInst, "totalBytes", "d", TotalBytes); - setattr(callbackInst, "fetchedBytes", "d", FetchedBytes); - setattr(callbackInst, "currentItems", "k", CurrentItems); - setattr(callbackInst, "totalItems", "k", TotalItems); + setattr(callbackInst, "currentCPS", "N", MkPyNumber(CurrentCPS)); + setattr(callbackInst, "currentBytes", "N", MkPyNumber(CurrentBytes)); + setattr(callbackInst, "totalBytes", "N", MkPyNumber(TotalBytes)); + setattr(callbackInst, "fetchedBytes", "N", MkPyNumber(FetchedBytes)); + setattr(callbackInst, "currentItems", "N", MkPyNumber(CurrentItems)); + setattr(callbackInst, "totalItems", "N", MkPyNumber(TotalItems)); // Go through the list of items and add active items to the // activeItems vector. map activeItemMap; @@ -351,11 +351,11 @@ bool PyFetchProgress::Pulse(pkgAcquire * Owner) pkgAcquire::Worker *worker = iter->first; pkgAcquire::ItemDesc *itm = iter->second; - PyObject *itmTuple = Py_BuildValue("(ssskk)", itm->URI.c_str(), + PyObject *itmTuple = Py_BuildValue("(sssNN)", itm->URI.c_str(), itm->Description.c_str(), itm->ShortDesc.c_str(), - worker->TotalSize, - worker->CurrentSize); + MkPyNumber(worker->TotalSize), + MkPyNumber(worker->CurrentSize)); PyTuple_SetItem(itemsTuple, tuplePos, itmTuple); } diff --git a/python/string.cc b/python/string.cc index a5016103..7abe2d17 100644 --- a/python/string.cc +++ b/python/string.cc @@ -91,7 +91,7 @@ PyObject *StrStringToBool(PyObject *Self,PyObject *Args) char *Str = 0; if (PyArg_ParseTuple(Args,"s",&Str) == 0) return 0; - return Py_BuildValue("i",StringToBool(Str)); + return MkPyNumber(StringToBool(Str)); } PyObject *StrStrToTime(PyObject *Self,PyObject *Args) @@ -107,7 +107,7 @@ PyObject *StrStrToTime(PyObject *Self,PyObject *Args) return Py_None; } - return Py_BuildValue("i",Result); + return MkPyNumber(Result); } PyObject *StrCheckDomainList(PyObject *Self,PyObject *Args) diff --git a/python/tag.cc b/python/tag.cc index 44cd06af..94554400 100644 --- a/python/tag.cc +++ b/python/tag.cc @@ -247,7 +247,7 @@ static PyObject *TagSecBytes(PyObject *Self,PyObject *Args) if (PyArg_ParseTuple(Args,"") == 0) return 0; - return Py_BuildValue("i",GetCpp(Self).size()); + return MkPyNumber(GetCpp(Self).size()); } static PyObject *TagSecStr(PyObject *Self) @@ -319,7 +319,8 @@ static PyObject *TagFileOffset(PyObject *Self,PyObject *Args) { if (PyArg_ParseTuple(Args,"") == 0) return 0; - return Py_BuildValue("i",((TagFileData *)Self)->Object.Offset()); + return MkPyNumber(((TagFileData *)Self)->Object.Offset()); + } static char *doc_Jump = diff --git a/python/tarfile.cc b/python/tarfile.cc index 215d3a8c..cdfe0a7c 100644 --- a/python/tarfile.cc +++ b/python/tarfile.cc @@ -189,35 +189,35 @@ static PyObject *tarmember_get_linkname(PyObject *self, void *closure) static PyObject *tarmember_get_mode(PyObject *self, void *closure) { - return Py_BuildValue("k", GetCpp(self).Mode); + return MkPyNumber(GetCpp(self).Mode); } static PyObject *tarmember_get_uid(PyObject *self, void *closure) { - return Py_BuildValue("k", GetCpp(self).UID); + return MkPyNumber(GetCpp(self).UID); } static PyObject *tarmember_get_gid(PyObject *self, void *closure) { - return Py_BuildValue("k", GetCpp(self).GID); + return MkPyNumber(GetCpp(self).GID); } static PyObject *tarmember_get_size(PyObject *self, void *closure) { - return Py_BuildValue("k", GetCpp(self).Size); + return MkPyNumber(GetCpp(self).Size); } static PyObject *tarmember_get_mtime(PyObject *self, void *closure) { - return Py_BuildValue("k", GetCpp(self).MTime); + return MkPyNumber(GetCpp(self).MTime); } static PyObject *tarmember_get_major(PyObject *self, void *closure) { - return Py_BuildValue("k", GetCpp(self).Major); + return MkPyNumber(GetCpp(self).Major); } static PyObject *tarmember_get_minor(PyObject *self, void *closure) { - return Py_BuildValue("k", GetCpp(self).Minor); + return MkPyNumber(GetCpp(self).Minor); } static PyObject *tarmember_repr(PyObject *self) -- cgit v1.2.3 From 287e27e498516dd00aba1b78aea92a12ec079886 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Tue, 12 Apr 2011 14:33:39 +0200 Subject: apt.cache: Document that update() may need an open() (Closes: #622342) --- apt/cache.py | 4 ++++ debian/changelog | 1 + 2 files changed, 5 insertions(+) diff --git a/apt/cache.py b/apt/cache.py index 3bbae923..373bb91d 100644 --- a/apt/cache.py +++ b/apt/cache.py @@ -339,6 +339,10 @@ class Cache(object): raise_on_error=True, sources_list=None): """Run the equivalent of apt-get update. + You probably want to call open() afterwards, in order to utilise the + new cache. Otherwise, the old cache will be used which can lead to + strange bugs. + The first parameter *fetch_progress* may be set to an instance of apt.progress.FetchProgress, the default is apt.progress.FetchProgress() . diff --git a/debian/changelog b/debian/changelog index 1460acce..f89de6de 100644 --- a/debian/changelog +++ b/debian/changelog @@ -12,6 +12,7 @@ python-apt (0.8.0~exp2) UNRELEASED; urgency=low * aptsources/sourceslist.py: s/aptsource.py/sourceslist.py/ (LP: #309603) * doc/examples: Add example on how to get architecture names (LP: #194374) * apt_pkg: Fix unsigned/long-vs-int issues (LP: #610820) + * apt.cache: Document that update() may need an open() (Closes: #622342) -- Julian Andres Klode Wed, 06 Apr 2011 09:46:52 +0200 -- cgit v1.2.3 From d206a03cc50d3c0fee56b8dbd6a915eadc7038cf Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Tue, 12 Apr 2011 14:51:08 +0200 Subject: apt.cache: Add a fetch_archives() method (Closes: #622347) --- apt/cache.py | 22 ++++++++++++++++++++++ debian/changelog | 1 + 2 files changed, 23 insertions(+) diff --git a/apt/cache.py b/apt/cache.py index 373bb91d..339de763 100644 --- a/apt/cache.py +++ b/apt/cache.py @@ -288,6 +288,28 @@ class Cache(object): finally: os.close(lock) + def fetch_archives(self, progress=None, fetcher=None): + """Fetch the archives for all packages marked for install/upgrade. + + You can specify either an :class:`apt.progress.base.AcquireProgress()` + object for the parameter *progress*, or specify an already + existing :class:`apt_pkg.Acquire` object for the parameter *fetcher*. + + The return value of the function is undefined. If an error occured, + an exception of type :class:`FetchFailedException` or + :class:`FetchCancelledException` is raised. + """ + if progress is not None and fetcher is not None: + raise ValueError("Takes a progress or a an Acquire object") + if progress is None: + progress = apt.progress.text.AcquireProgress() + if fetcher is None: + fetcher = apt_pkg.Acquire(progress) + + + return self._fetch_archives(fetcher, + apt_pkg.PackageManager(self._depcache)) + def is_virtual_package(self, pkgname): """Return whether the package is a virtual package.""" try: diff --git a/debian/changelog b/debian/changelog index f89de6de..bd87c411 100644 --- a/debian/changelog +++ b/debian/changelog @@ -13,6 +13,7 @@ python-apt (0.8.0~exp2) UNRELEASED; urgency=low * doc/examples: Add example on how to get architecture names (LP: #194374) * apt_pkg: Fix unsigned/long-vs-int issues (LP: #610820) * apt.cache: Document that update() may need an open() (Closes: #622342) + * apt.cache: Add a fetch_archives() method (Closes: #622347) -- Julian Andres Klode Wed, 06 Apr 2011 09:46:52 +0200 -- cgit v1.2.3 From eca3d533b98ab1987557b2ebe8752b20b6af41a2 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Tue, 12 Apr 2011 14:57:35 +0200 Subject: doc: Fix a minor formatting error, patch by Jakub Wilk (Closes: #608914) --- debian/changelog | 1 + doc/source/tutorials/apt-cdrom.rst | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/debian/changelog b/debian/changelog index bd87c411..ebe2de3f 100644 --- a/debian/changelog +++ b/debian/changelog @@ -14,6 +14,7 @@ python-apt (0.8.0~exp2) UNRELEASED; urgency=low * apt_pkg: Fix unsigned/long-vs-int issues (LP: #610820) * apt.cache: Document that update() may need an open() (Closes: #622342) * apt.cache: Add a fetch_archives() method (Closes: #622347) + * doc: Fix a minor formatting error, patch by Jakub Wilk (Closes: #608914) -- Julian Andres Klode Wed, 06 Apr 2011 09:46:52 +0200 diff --git a/doc/source/tutorials/apt-cdrom.rst b/doc/source/tutorials/apt-cdrom.rst index 0561e082..5dd88743 100644 --- a/doc/source/tutorials/apt-cdrom.rst +++ b/doc/source/tutorials/apt-cdrom.rst @@ -98,7 +98,7 @@ it is a boolean argument. Afterwards you could use location of the mount pint. ``('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 +``('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 -- cgit v1.2.3 From da11ffd96bbd58f51c54857dc72e18f3c2d6b998 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Tue, 12 Apr 2011 15:02:22 +0200 Subject: apt/cache.py: Add versionadded --- apt/cache.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/apt/cache.py b/apt/cache.py index 339de763..3bbf5a51 100644 --- a/apt/cache.py +++ b/apt/cache.py @@ -298,6 +298,8 @@ class Cache(object): The return value of the function is undefined. If an error occured, an exception of type :class:`FetchFailedException` or :class:`FetchCancelledException` is raised. + + .. versionadded:: 0.8.0 """ if progress is not None and fetcher is not None: raise ValueError("Takes a progress or a an Acquire object") -- cgit v1.2.3 From 16955bcd8717b3e2c10496968765c3a4ea252b1f Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Tue, 12 Apr 2011 15:23:17 +0200 Subject: apt.package: Add 'tasks' to Version, improve doc (Closes: #619574) --- apt/package.py | 38 ++++++++++++++++++++++++++++++++++---- debian/changelog | 1 + doc/source/library/apt.package.rst | 29 +++++++++++++++++++++++++++++ 3 files changed, 64 insertions(+), 4 deletions(-) diff --git a/apt/package.py b/apt/package.py index 54ef1c01..14e80594 100644 --- a/apt/package.py +++ b/apt/package.py @@ -162,10 +162,23 @@ class Origin(object): class Record(Mapping): - """Represent a pkgRecord. + """Record in a Packages file + + Represent a record as stored in a Packages file. You can use this like + a dictionary mapping the field names of the record to their values:: + + >>> record = Record("Package: python-apt\\nVersion: 0.8.0\\n\\n") + >>> record["Package"] + 'python-apt' + >>> record["Version"] + '0.8.0' + + For example, to get the tasks of a package from a cache, you could do:: + + package.candidate.record["Tasks"].split() + + Of course, you can also use the :attr:`Version.tasks` property. - It can be accessed like a dictionary and can also give the original package - record if accessed as a string. """ def __init__(self, record_str): @@ -209,6 +222,9 @@ class Record(Mapping): class Version(object): """Representation of a package version. + The Version class contains all information related to a + specific package version. + .. versionadded:: 0.7.9 """ @@ -393,7 +409,11 @@ class Version(object): @property def record(self): - """Return a Record() object for this version.""" + """Return a Record() object for this version. + + Return a Record() object for this version which provides access + to the raw attributes of the candidate version + """ return Record(self._records.record) def get_dependencies(self, *types): @@ -474,6 +494,16 @@ class Version(object): """ return self._records.sha256_hash + @property + def tasks(self): + """Get the tasks of the package. + + A set of the names of the tasks this package belongs to. + + .. versionadded:: 0.8.0 + """ + return set(self.record["Task"].split()) + def _uris(self): """Return an iterator over all available urls. diff --git a/debian/changelog b/debian/changelog index ebe2de3f..c8b47acc 100644 --- a/debian/changelog +++ b/debian/changelog @@ -15,6 +15,7 @@ python-apt (0.8.0~exp2) UNRELEASED; urgency=low * apt.cache: Document that update() may need an open() (Closes: #622342) * apt.cache: Add a fetch_archives() method (Closes: #622347) * doc: Fix a minor formatting error, patch by Jakub Wilk (Closes: #608914) + * apt.package: Add 'tasks' to Version, improve doc (Closes: #619574) -- Julian Andres Klode Wed, 06 Apr 2011 09:46:52 +0200 diff --git a/doc/source/library/apt.package.rst b/doc/source/library/apt.package.rst index 4b143b8a..d8731ea8 100644 --- a/doc/source/library/apt.package.rst +++ b/doc/source/library/apt.package.rst @@ -90,6 +90,35 @@ Origin Information 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 -- cgit v1.2.3 From d2af9ab5144d6a6af9e92a8758c76209e27d22c7 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Tue, 12 Apr 2011 15:24:47 +0200 Subject: doc: Fix documentation of BaseDependency.relation (Closes: #607031) --- debian/changelog | 1 + doc/source/library/apt.package.rst | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/debian/changelog b/debian/changelog index c8b47acc..6c19fc44 100644 --- a/debian/changelog +++ b/debian/changelog @@ -16,6 +16,7 @@ python-apt (0.8.0~exp2) UNRELEASED; urgency=low * apt.cache: Add a fetch_archives() method (Closes: #622347) * doc: Fix a minor formatting error, patch by Jakub Wilk (Closes: #608914) * apt.package: Add 'tasks' to Version, improve doc (Closes: #619574) + * doc: Fix documentation of BaseDependency.relation (Closes: #607031) -- Julian Andres Klode Wed, 06 Apr 2011 09:46:52 +0200 diff --git a/doc/source/library/apt.package.rst b/doc/source/library/apt.package.rst index d8731ea8..01a26973 100644 --- a/doc/source/library/apt.package.rst +++ b/doc/source/library/apt.package.rst @@ -34,7 +34,7 @@ Dependency Information .. attribute:: relation - The relation (>>,>=,==,<<,<=,) + The relation (>,>=,==,<,<=,) .. attribute:: version -- cgit v1.2.3 From e4c1c8610e9a9a120c02713a3567b68f73c246e8 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Tue, 12 Apr 2011 15:25:52 +0200 Subject: Release 0.8.0~exp2 to experimental --- debian/changelog | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/debian/changelog b/debian/changelog index 6c19fc44..3397f85d 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,4 +1,4 @@ -python-apt (0.8.0~exp2) UNRELEASED; urgency=low +python-apt (0.8.0~exp2) experimental; urgency=low * aptsources: Parse multi-arch sources.list files correctly * aptsources: Allow insertion of new multi-arch entries @@ -18,7 +18,7 @@ python-apt (0.8.0~exp2) UNRELEASED; urgency=low * apt.package: Add 'tasks' to Version, improve doc (Closes: #619574) * doc: Fix documentation of BaseDependency.relation (Closes: #607031) - -- Julian Andres Klode Wed, 06 Apr 2011 09:46:52 +0200 + -- Julian Andres Klode Tue, 12 Apr 2011 15:25:38 +0200 python-apt (0.8.0~exp1) experimental; urgency=low -- cgit v1.2.3 From 9d00ce840131092e7a7ae26cd0b0279c7646a7a5 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Tue, 12 Apr 2011 17:20:37 +0200 Subject: Update enable_component to also apply to -src entries (LP: #758732) --- aptsources/distro.py | 3 +++ debian/changelog | 7 +++++++ 2 files changed, 10 insertions(+) diff --git a/aptsources/distro.py b/aptsources/distro.py index 23192f50..15806c5c 100644 --- a/aptsources/distro.py +++ b/aptsources/distro.py @@ -336,6 +336,9 @@ class Distribution(object): for source in sources: add_component_only_once(source, comps_per_dist) + for source in self.source_code_sources: + add_component_only_once(source, comps_per_sdist) + # check if there is a main source code source at all if self.get_source_code == True: if len(self.source_code_sources) < 1: diff --git a/debian/changelog b/debian/changelog index 3397f85d..c2377956 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,10 @@ +python-apt (0.8.0~exp3) UNRELEASED; urgency=low + + [ Stéphane Graber ] + * Update enable_component to also apply to -src entries (LP: #758732) + + -- Julian Andres Klode Tue, 12 Apr 2011 17:19:49 +0200 + python-apt (0.8.0~exp2) experimental; urgency=low * aptsources: Parse multi-arch sources.list files correctly -- cgit v1.2.3 From 16166e89fb1d1243ac92017f03d7bdada904cd38 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Thu, 21 Apr 2011 14:21:22 +0200 Subject: apt_pkg: Add apt_pkg.Version.multi_arch and friends --- debian/changelog | 3 +++ doc/source/library/apt_pkg.rst | 43 ++++++++++++++++++++++++++++++++++++++++++ python/apt_pkgmodule.cc | 14 ++++++++++++++ python/cache.cc | 8 ++++++++ 4 files changed, 68 insertions(+) diff --git a/debian/changelog b/debian/changelog index c2377956..3b2a739a 100644 --- a/debian/changelog +++ b/debian/changelog @@ -2,6 +2,9 @@ python-apt (0.8.0~exp3) UNRELEASED; urgency=low [ Stéphane Graber ] * Update enable_component to also apply to -src entries (LP: #758732) + + [ Julian Andres Klode ] + * apt_pkg: Add apt_pkg.Version.multi_arch and friends -- Julian Andres Klode Tue, 12 Apr 2011 17:19:49 +0200 diff --git a/doc/source/library/apt_pkg.rst b/doc/source/library/apt_pkg.rst index 72ca5ecc..28914395 100644 --- a/doc/source/library/apt_pkg.rst +++ b/doc/source/library/apt_pkg.rst @@ -758,6 +758,49 @@ Example: .. 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_NONE + + 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 diff --git a/python/apt_pkgmodule.cc b/python/apt_pkgmodule.cc index 2394b0f8..a8b8d2f4 100644 --- a/python/apt_pkgmodule.cc +++ b/python/apt_pkgmodule.cc @@ -905,6 +905,20 @@ extern "C" void initapt_pkg() MkPyNumber(pkgPackageManager::Incomplete)); #endif + PyDict_SetItemString(PyVersion_Type.tp_dict, "MULTI_ARCH_NONE", + MkPyNumber(pkgCache::Version::None)); + PyDict_SetItemString(PyVersion_Type.tp_dict, "MULTI_ARCH_ALL", + MkPyNumber(pkgCache::Version::All)); + PyDict_SetItemString(PyVersion_Type.tp_dict, "MULTI_ARCH_FOREIGN", + MkPyNumber(pkgCache::Version::Foreign)); + PyDict_SetItemString(PyVersion_Type.tp_dict, "MULTI_ARCH_SAME", + MkPyNumber(pkgCache::Version::Same)); + PyDict_SetItemString(PyVersion_Type.tp_dict, "MULTI_ARCH_ALLOWED", + MkPyNumber(pkgCache::Version::Allowed)); + PyDict_SetItemString(PyVersion_Type.tp_dict, "MULTI_ARCH_ALL_FOREIGN", + MkPyNumber(pkgCache::Version::AllForeign)); + PyDict_SetItemString(PyVersion_Type.tp_dict, "MULTI_ARCH_ALL_ALLOWED", + MkPyNumber(pkgCache::Version::AllAllowed)); // AcquireItem Constants. PyDict_SetItemString(PyAcquireItem_Type.tp_dict, "STAT_IDLE", MkPyNumber(pkgAcquire::Item::StatIdle)); diff --git a/python/cache.cc b/python/cache.cc index 160fd208..b263d320 100644 --- a/python/cache.cc +++ b/python/cache.cc @@ -1047,6 +1047,11 @@ static PyObject *VersionGetTranslatedDescription(PyObject *Self, void*) { Ver.TranslatedDescription()); } +static PyObject *VersionGetMultiArch(PyObject *Self, void*) +{ + return MkPyNumber(Version_GetVer(Self)->MultiArch); +} + #if 0 // FIXME: enable once pkgSourceList is stored somewhere static PyObject *VersionGetIsTrusted(PyObject *Self, void*) { else if (strcmp("IsTrusted", Name) == 0) @@ -1122,6 +1127,9 @@ static PyGetSetDef VersionGetSet[] = { "The numeric ID of the package."}, {"installed_size",VersionGetInstalledSize,0, "The installed size of this package version."}, + {"multi_arch",VersionGetMultiArch,0, + "Multi-arch state of this package, as an integer. See\n" + "the various MULTI_ARCH_* members."}, {"parent_pkg",VersionGetParentPkg,0, "The parent package of this version."}, {"priority",VersionGetPriority,0, -- cgit v1.2.3 From 58cebce48503e2478f59cbfe0e1f9849156d6337 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Thu, 21 Apr 2011 15:34:01 +0200 Subject: Release 0.8.0~exp3 --- debian/changelog | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/debian/changelog b/debian/changelog index 3b2a739a..702a69d4 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,4 +1,4 @@ -python-apt (0.8.0~exp3) UNRELEASED; urgency=low +python-apt (0.8.0~exp3) experimental; urgency=low [ Stéphane Graber ] * Update enable_component to also apply to -src entries (LP: #758732) @@ -6,7 +6,7 @@ python-apt (0.8.0~exp3) UNRELEASED; urgency=low [ Julian Andres Klode ] * apt_pkg: Add apt_pkg.Version.multi_arch and friends - -- Julian Andres Klode Tue, 12 Apr 2011 17:19:49 +0200 + -- Julian Andres Klode Thu, 21 Apr 2011 15:33:38 +0200 python-apt (0.8.0~exp2) experimental; urgency=low -- cgit v1.2.3 From 6282a925c2e32aeaa342b789470a01b6dcf70890 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Wed, 27 Apr 2011 13:08:20 +0200 Subject: apt_pkg: Add OrderList, wanted for mancoosi (Closes: #623485) --- debian/changelog | 6 + doc/source/c++/api.rst | 28 ++++ doc/source/library/apt_pkg.rst | 93 ++++++++++++ doc/source/whatsnew/0.8.0.rst | 2 + python/apt_pkgmodule.cc | 18 ++- python/apt_pkgmodule.h | 3 + python/orderlist.cc | 317 +++++++++++++++++++++++++++++++++++++++++ python/python-apt-helpers.cc | 1 + python/python-apt.h | 8 ++ setup.py | 2 +- 10 files changed, 476 insertions(+), 2 deletions(-) create mode 100644 python/orderlist.cc diff --git a/debian/changelog b/debian/changelog index 702a69d4..ab1839d2 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +python-apt (0.8.0~exp4) UNRELEASED; urgency=low + + * apt_pkg: Add OrderList, wanted for mancoosi (Closes: #623485) + + -- Julian Andres Klode Wed, 27 Apr 2011 12:55:59 +0200 + python-apt (0.8.0~exp3) experimental; urgency=low [ Stéphane Graber ] diff --git a/doc/source/c++/api.rst b/doc/source/c++/api.rst index 25cfcd9e..63ed1599 100644 --- a/doc/source/c++/api.rst +++ b/doc/source/c++/api.rst @@ -622,6 +622,34 @@ IndexFile (pkgIndexFile) Return the :ctype:`pkgIndexFile` pointer contained in the Python object *object*. +OrderList (pkgOrderList) +--------------------------- +.. cvar:: PyTypeObject PyOrderList_Type + + The type object for :class:`apt_pkg.OrderList` objects. + +.. cfunction:: int PyOrderList_Check(PyObject *object) + + Check that the object *object* is an :class:`apt_pkg.OrderList` object, or + a subclass thereof. + +.. cfunction:: int PyOrderList_CheckExact(PyObject *object) + + Check that the object *object* is an :class:`apt_pkg.OrderList` object + and no subclass thereof. + +.. cfunction:: PyObject* PyOrderList_FromCpp(pkgOrderList *cpp, bool delete, PyObject *owner) + + Create a new :class:`apt_pkg.OrderList` object from the :ctype:`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. + +.. cfunction:: pkgOrderList* PyOrderList_ToCpp(PyObject *object) + + Return the :ctype:`pkgOrderList` pointer contained in the Python object + *object*. PackageManager (pkgPackageManager) ---------------------------------- diff --git a/doc/source/library/apt_pkg.rst b/doc/source/library/apt_pkg.rst index 28914395..fce4f804 100644 --- a/doc/source/library/apt_pkg.rst +++ b/doc/source/library/apt_pkg.rst @@ -422,6 +422,99 @@ Installing with :class:`PackageManager` A constant for checking whether the the result of the call to :meth:`do_install` is 'incomplete'. + +Installation ordering with :class:`OrderList` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. class:: OrderList(depcache: DepCache) + + Represent a :ctype:`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` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/doc/source/whatsnew/0.8.0.rst b/doc/source/whatsnew/0.8.0.rst index fda53443..fa58a022 100644 --- a/doc/source/whatsnew/0.8.0.rst +++ b/doc/source/whatsnew/0.8.0.rst @@ -23,6 +23,8 @@ This release of python-apt also features several other, smaller changes: * apt_pkg.Cache() now takes None for the progress parameter, preventing progress reporting. + * A new class :class:`apt_pkg.OrderList` has been added on request + of the mancoosi project. There have been various other changes, see the changelog for a complete list of changes. diff --git a/python/apt_pkgmodule.cc b/python/apt_pkgmodule.cc index a8b8d2f4..139ff016 100644 --- a/python/apt_pkgmodule.cc +++ b/python/apt_pkgmodule.cc @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -734,7 +735,10 @@ static struct _PyAptPkgAPIStruct API = { &PyVersion_ToCpp, // version_tocpp &PyGroup_Type, // group_type &PyGroup_FromCpp, // group_fromcpp - &PyGroup_ToCpp // group_tocpp + &PyGroup_ToCpp, // group_tocpp + &PyOrderList_Type, // orderlist_type + &PyOrderList_FromCpp, // orderlist_fromcpp + &PyOrderList_ToCpp // orderlist_tocpp }; @@ -843,6 +847,7 @@ extern "C" void initapt_pkg() ADDTYPE(Module,"AcquireItemDesc",&PyAcquireItemDesc_Type); ADDTYPE(Module,"SystemLock",&PySystemLock_Type); ADDTYPE(Module,"FileLock",&PyFileLock_Type); + ADDTYPE(Module,"OrderList",&PyOrderList_Type); // Tag file constants PyModule_AddObject(Module,"REWRITE_PACKAGE_ORDER", CharCharToList(TFRewritePackageOrder)); @@ -850,6 +855,16 @@ extern "C" void initapt_pkg() PyModule_AddObject(Module,"REWRITE_SOURCE_ORDER", CharCharToList(TFRewriteSourceOrder)); + PyDict_SetItemString(PyOrderList_Type.tp_dict, "FLAG_ADDED", MkPyNumber(pkgOrderList::Added)); + PyDict_SetItemString(PyOrderList_Type.tp_dict, "FLAG_ADD_PENDIG", MkPyNumber(pkgOrderList::AddPending)); + PyDict_SetItemString(PyOrderList_Type.tp_dict, "FLAG_IMMEDIATE", MkPyNumber(pkgOrderList::Immediate)); + PyDict_SetItemString(PyOrderList_Type.tp_dict, "FLAG_LOOP", MkPyNumber(pkgOrderList::Loop)); + PyDict_SetItemString(PyOrderList_Type.tp_dict, "FLAG_UNPACKED", MkPyNumber(pkgOrderList::UnPacked)); + PyDict_SetItemString(PyOrderList_Type.tp_dict, "FLAG_CONFIGURED", MkPyNumber(pkgOrderList::Configured)); + PyDict_SetItemString(PyOrderList_Type.tp_dict, "FLAG_REMOVED", MkPyNumber(pkgOrderList::Removed)); + PyDict_SetItemString(PyOrderList_Type.tp_dict, "FLAG_IN_LIST", MkPyNumber(pkgOrderList::InList)); + PyDict_SetItemString(PyOrderList_Type.tp_dict, "FLAG_AFTER", MkPyNumber(pkgOrderList::After)); + PyDict_SetItemString(PyOrderList_Type.tp_dict, "FLAG_STATES_MASK", MkPyNumber(pkgOrderList::States)); // Acquire constants. // some constants @@ -983,6 +998,7 @@ extern "C" void initapt_pkg() PyModule_AddIntConstant(Module,"INSTSTATE_HOLD",pkgCache::State::Hold); PyModule_AddIntConstant(Module,"INSTSTATE_HOLD_REINSTREQ",pkgCache::State::HoldReInstReq); + // DEPRECATED API #ifdef COMPAT_0_7 PyModule_AddObject(Module,"RewritePackageOrder", diff --git a/python/apt_pkgmodule.h b/python/apt_pkgmodule.h index 7a04204c..89179551 100644 --- a/python/apt_pkgmodule.h +++ b/python/apt_pkgmodule.h @@ -134,6 +134,7 @@ extern PyTypeObject PyAcquireItemDesc_Type; extern PyTypeObject PyAcquireWorker_Type; extern PyTypeObject PySystemLock_Type; extern PyTypeObject PyFileLock_Type; +extern PyTypeObject PyOrderList_Type; // Functions to be exported in the public API. @@ -159,6 +160,7 @@ extern PyTypeObject PyFileLock_Type; # define PyPackage_ToCpp GetCpp # define PyPackageFile_ToCpp GetCpp # define PyIndexFile_ToCpp GetCpp +# define PyOrderList_ToCpp GetCpp # define PyPackageList_ToCpp GetCpp // TODO # define PyPackageManager_ToCpp GetCpp # define PyPackageRecords_ToCpp GetCpp // TODO @@ -191,6 +193,7 @@ PyObject* PyMetaIndex_FromCpp(metaIndex* const &obj, bool Delete, PyObject *Owne PyObject* PyPackage_FromCpp(pkgCache::PkgIterator const &obj, bool Delete, PyObject *Owner); PyObject* PyGroup_FromCpp(pkgCache::GrpIterator const &obj, bool Delete, PyObject *Owner); PyObject* PyIndexFile_FromCpp(pkgIndexFile* const &obj, bool Delete, PyObject *Owner); +PyObject* PyOrderList_FromCpp(pkgOrderList* const &obj, bool Delete, PyObject *Owner); PyObject* PyPackageFile_FromCpp(pkgCache::PkgFileIterator const &obj, bool Delete, PyObject *Owner); //PyObject* PyPackageList_FromCpp(PkgListStruct const &obj, bool Delete, PyObject *Owner); PyObject* PyPackageManager_FromCpp(pkgPackageManager* const &obj, bool Delete, PyObject *Owner); diff --git a/python/orderlist.cc b/python/orderlist.cc new file mode 100644 index 00000000..9fbed5f2 --- /dev/null +++ b/python/orderlist.cc @@ -0,0 +1,317 @@ +/* + * orderlist.cc - Wrapper around pkgOrderList + * + * Copyright 2011 Julian Andres Klode + * + * 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 +#include "apt_pkgmodule.h" +#include "generic.h" +#include + +struct PyOrderList : CppPyObject { + pkgCache::PkgIterator current; + int nextIndex; +}; + +static PyObject *order_list_new(PyTypeObject *type,PyObject *args, + PyObject *kwds) +{ + PyObject *pyDepCache = NULL; + char *kwlist[] = {"depcache", NULL}; + if (PyArg_ParseTupleAndKeywords(args, kwds, "O!", kwlist, + &PyDepCache_Type, &pyDepCache) + == 0) + return 0; + + pkgDepCache *depCache = PyDepCache_ToCpp(pyDepCache); + return PyOrderList_FromCpp(new pkgOrderList(depCache), true, + pyDepCache); +} + +static const char order_list_append_doc[] = + "append(pkg: Package)\n\n" + "Append a package to the end of the list."; +static PyObject *order_list_append(PyObject *self,PyObject *args) +{ + pkgOrderList *list = GetCpp(self); + PyObject *pyPackage = NULL; + if (PyArg_ParseTuple(args, "O!", &PyPackage_Type, &pyPackage) == 0) + return 0; + + list->push_back(PyPackage_ToCpp(pyPackage)); + Py_RETURN_NONE; +} + +static const char order_list_score_doc[] = + "score(pkg: Package) -> int\n\n" + "Return the score of the package."; +static PyObject *order_list_score(PyObject *self,PyObject *args) +{ + pkgOrderList *list = GetCpp(self); + PyObject *pyPackage = NULL; + if (PyArg_ParseTuple(args, "O!", &PyPackage_Type, &pyPackage) == 0) + return 0; + + return MkPyNumber(list->Score(PyPackage_ToCpp(pyPackage))); +} + +static const char order_list_order_critical_doc[] = + "order_critical()\n\n" + "Order by PreDepends only (critical unpack order)."; +static PyObject *order_list_order_critical(PyObject *self,PyObject *args) +{ + pkgOrderList *list = GetCpp(self); + if (PyArg_ParseTuple(args, "") == 0) + return 0; + + list->OrderCritical(); + + Py_INCREF(Py_None); + return HandleErrors(Py_None); +} + +static const char order_list_order_unpack_doc[] = + "order_unpack()\n\n" + "Order the packages for unpacking (see Debian Policy)."; +static PyObject *order_list_order_unpack(PyObject *self,PyObject *args) +{ + pkgOrderList *list = GetCpp(self); + if (PyArg_ParseTuple(args, "") == 0) + return 0; + + list->OrderUnpack(); + Py_INCREF(Py_None); + return HandleErrors(Py_None); +} + +static const char order_list_order_configure_doc[] = + "order_configure()\n\n" + "Order the packages for configuration (see Debian Policy)."; +static PyObject *order_list_order_configure(PyObject *self,PyObject *args) +{ + pkgOrderList *list = GetCpp(self); + if (PyArg_ParseTuple(args, "") == 0) + return 0; + + list->OrderConfigure(); + + Py_INCREF(Py_None); + return HandleErrors(Py_None); +} + +static bool valid_flags(unsigned int flags) { + return (flags & ~pkgOrderList::Added + & ~pkgOrderList::AddPending + & ~pkgOrderList::Immediate + & ~pkgOrderList::Loop + & ~pkgOrderList::UnPacked + & ~pkgOrderList::Configured + & ~pkgOrderList::Removed + & ~pkgOrderList::InList + & ~pkgOrderList::After + & ~pkgOrderList::States) == 0; +} + +static const char order_list_flag_doc[] = + "flag(pkg: Package, flag: int[, unset_flags: int])\n\n" + "Flag the package, set flags in 'flag' and remove flags in\n" + "'unset_flags'."; +static PyObject *order_list_flag(PyObject *self,PyObject *args) +{ + pkgOrderList *list = GetCpp(self); + + PyObject *pyPkg = NULL; + unsigned int flags = 0; + unsigned int unset_flags = 0; + if (PyArg_ParseTuple(args, "O!I|I", &PyPackage_Type, &pyPkg, + &flags, &unset_flags) == 0) + return 0; + + if (!valid_flags(flags)) + return PyErr_Format(PyExc_ValueError, "flags (%u) is" + " not a valid combination of flags.", + flags); + if (!valid_flags(unset_flags)) + return PyErr_Format(PyExc_ValueError, "unset_flags (%u) is" + " not a valid combination of flags.", + unset_flags); + + list->Flag(PyPackage_ToCpp(pyPkg), flags, unset_flags); + + Py_RETURN_NONE; +} + +static const char order_list_is_flag_doc[] = + "is_flag(pkg: Package, flag: int)\n\n" + "Check if the flag(s) are set."; +static PyObject *order_list_is_flag(PyObject *self,PyObject *args) +{ + pkgOrderList *list = GetCpp(self); + PyObject *pyPkg = NULL; + unsigned int flags = 0; + if (PyArg_ParseTuple(args, "O!I", &PyPackage_Type, &pyPkg, + &flags) == 0) + return 0; + + if (!valid_flags(flags)) + return PyErr_Format(PyExc_ValueError, "flags (%u) is" + " not a valid combination of flags.", + flags); + + return PyBool_FromLong(list->IsFlag(PyPackage_ToCpp(pyPkg), flags)); +} + +static const char order_list_wipe_flags_doc[] = + "wipe_flags(flags: int)\n\n" + "Remove the flags in 'flags' from all packages in this list"; +static PyObject *order_list_wipe_flags(PyObject *self,PyObject *args) +{ + pkgOrderList *list = GetCpp(self); + unsigned int flags = 0; + if (PyArg_ParseTuple(args, "I", &flags) == 0) + return 0; + + if (!valid_flags(flags)) + return PyErr_Format(PyExc_ValueError, "flags (%u) is" + " not a valid combination of flags.", + flags); + + list->WipeFlags(flags); + Py_RETURN_NONE; +} + +static const char order_list_is_now_doc[] = + "is_now(pkg: Package)\n\n" + "Check if the package is flagged for any state but removal."; +static PyObject *order_list_is_now(PyObject *self,PyObject *args) +{ + pkgOrderList *list = GetCpp(self); + PyObject *pyPkg = NULL; + if (PyArg_ParseTuple(args, "O!", &PyPackage_Type, &pyPkg) == 0) + return 0; + + return PyBool_FromLong(list->IsNow(PyPackage_ToCpp(pyPkg))); +} + +static const char order_list_is_missing_doc[] = + "is_now(pkg: Package)\n\n" + "Check if the package is marked for install."; +static PyObject *order_list_is_missing(PyObject *self,PyObject *args) +{ + pkgOrderList *list = GetCpp(self); + PyObject *pyPkg = NULL; + if (PyArg_ParseTuple(args, "O!", &PyPackage_Type, &pyPkg) == 0) + return 0; + + return PyBool_FromLong(list->IsMissing(PyPackage_ToCpp(pyPkg))); +} + + +#define METHOD(name) {#name, order_list_##name, METH_VARARGS,\ + order_list_##name##_doc} + +static PyMethodDef order_list_methods[] = { + METHOD(append), + METHOD(score), + METHOD(order_critical), + METHOD(order_unpack), + METHOD(order_configure), + METHOD(flag), + METHOD(is_flag), + METHOD(is_now), + METHOD(is_missing), + METHOD(wipe_flags), + {} +}; + +static PyObject *order_list_seq_item(PyObject *self,Py_ssize_t index) +{ + pkgOrderList *list = GetCpp(self); + PyObject *owner = GetOwner(self); + PyObject *pycache = GetOwner(owner); + pkgCache *cache = PyCache_ToCpp(pycache); + + if (index < 0 || index >= list->size()) + return PyErr_Format(PyExc_IndexError, "Out of range: %zd", index); + + return PyPackage_FromCpp(pkgCache::PkgIterator(*cache, + *(list->begin() + index)), + true, owner); +} + +Py_ssize_t order_list_seq_length(PyObject *self) +{ + return GetCpp(self)->size(); +} + +static PySequenceMethods order_list_as_sequence = +{ + order_list_seq_length, // sq_length + 0, // sq_concat + 0, // sq_repeat + order_list_seq_item, // sq_item + 0, // sq_ass_item + 0, // sq_contains + 0, // sq_inplace_concat + 0 // sq_inplace_repeat +}; + +static const char order_list_doc[] = "OrderList(depcache: DepCache)\n\n" + "Sequence type for packages with special ordering methods."; +PyTypeObject PyOrderList_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "apt_pkg.OrderList", // tp_name + sizeof(CppPyObject), // tp_basicsize + 0, // tp_itemsize + // Methods + CppDeallocPtr, // tp_dealloc + 0, // tp_print + 0, // tp_getattr + 0, // tp_setattr + 0, // tp_compare + 0, // tp_repr + 0, // tp_as_number + &order_list_as_sequence, // tp_as_sequence + 0, // tp_as_mapping + 0, // tp_hash + 0, // tp_call + 0, // tp_str + 0, // tp_getattro + 0, // tp_setattro + 0, // tp_as_buffer + Py_TPFLAGS_DEFAULT, // tp_flags + order_list_doc, // tp_doc + 0, // tp_traverse + 0, // tp_clear + 0, // tp_richcompare + 0, // tp_weaklistoffset + 0, // tp_iter + 0, // tp_iternext + order_list_methods, // tp_methods + 0, // tp_members + 0, // tp_getset + 0, // tp_base + 0, // tp_dict + 0, // tp_descr_get + 0, // tp_descr_set + 0, // tp_dictoffset + 0, // tp_init + 0, // tp_alloc + order_list_new, // tp_new +}; diff --git a/python/python-apt-helpers.cc b/python/python-apt-helpers.cc index f50f62c4..079b93cf 100644 --- a/python/python-apt-helpers.cc +++ b/python/python-apt-helpers.cc @@ -54,6 +54,7 @@ NEW_FROM(PyMetaIndex_FromCpp,&PyMetaIndex_Type,metaIndex*) NEW_FROM(PyPackage_FromCpp,&PyPackage_Type,pkgCache::PkgIterator) NEW_FROM(PyGroup_FromCpp,&PyGroup_Type,pkgCache::GrpIterator) NEW_FROM(PyIndexFile_FromCpp,&PyIndexFile_Type,pkgIndexFile*) +NEW_FROM(PyOrderList_FromCpp,&PyOrderList_Type,pkgOrderList*) NEW_FROM(PyPackageFile_FromCpp,&PyPackageFile_Type,pkgCache::PkgFileIterator) //NEW_FROM(PyPackageList_FromCpp,&PyPackageList_Type,PkgListStruct) NEW_FROM(PyPackageManager_FromCpp,&PyPackageManager_Type,pkgPackageManager*) diff --git a/python/python-apt.h b/python/python-apt.h index ca8b557b..6f2a02df 100644 --- a/python/python-apt.h +++ b/python/python-apt.h @@ -170,6 +170,10 @@ struct _PyAptPkgAPIStruct { PyTypeObject *group_type; PyObject* (*group_fromcpp)(pkgCache::GrpIterator const &obj, bool Delete, PyObject *Owner); pkgCache::GrpIterator& (*group_tocpp)(PyObject *self); + + PyTypeObject *orderlist_type; + PyObject* (*orderlist_fromcpp)(pkgOrderList* const &obj, bool Delete, PyObject *Owner); + pkgOrderList*& (*orderlist_tocpp)(PyObject *self); }; // Checking macros. @@ -228,6 +232,7 @@ struct _PyAptPkgAPIStruct { # define PyPackage_CheckExact(op) (op->op_type == &PyPackage_Type) # define PyPackageFile_CheckExact(op) (op->op_type == &PyPackageFile_Type) # define PyIndexFile_CheckExact(op) (op->op_type == &PyIndexFile_Type) +# define PyOrderList_CheckExact(op) (op->op_type == &PyOrderList_Type) # define PyPackageList_CheckExact(op) (op->op_type == &PyPackageList_Type) # define PyPackageManager_CheckExact(op) (op->op_type == &PyPackageManager_Type) # define PyPackageRecords_CheckExact(op) (op->op_type == &PyPackageRecords_Type) @@ -273,6 +278,7 @@ static int import_apt_pkg(void) { # define PyPackage_Type *(_PyAptPkg_API->package_type) # define PyPackageFile_Type *(_PyAptPkg_API->packagefile_type) # define PyIndexFile_Type *(_PyAptPkg_API->packageindexfile_type) +# define PyOrderList_Type *(_PyAptPkg_API->orderlist_type) # define PyPackageList_Type *(_PyAptPkg_API->packagelist_type) # define PyPackageManager_Type *(_PyAptPkg_API->packagemanager_type) # define PyPackageRecords_Type *(_PyAptPkg_API->packagerecords_type) @@ -306,6 +312,7 @@ static int import_apt_pkg(void) { # define PyPackage_ToCpp _PyAptPkg_API->package_tocpp # define PyPackageFile_ToCpp _PyAptPkg_API->packagefile_tocpp # define PyIndexFile_ToCpp _PyAptPkg_API->packageindexfile_tocpp +# define PyOrderList_ToCpp _PyAptPkg_API->orderlist_tocpp // NULL # define PyPackageList_ToCpp _PyAptPkg_API->packagelist_tocpp // NULL # define PyPackageManager_ToCpp _PyAptPkg_API->packagemanager_tocpp # define PyPackageRecords_ToCpp _PyAptPkg_API->packagerecords_tocpp @@ -339,6 +346,7 @@ static int import_apt_pkg(void) { # define PyPackage_FromCpp _PyAptPkg_API->package_fromcpp # define PyPackageFile_FromCpp _PyAptPkg_API->packagefile_fromcpp # define PyIndexFile_FromCpp _PyAptPkg_API->packageindexfile_fromcpp +# define PyOrderList_FromCpp _PyAptPkg_API->orderlist_fromcpp // NULL # define PyPackageList_FromCpp _PyAptPkg_API->packagelist_fromcpp // NULL # define PyPackageManager_FromCpp _PyAptPkg_API->packagemanager_fromcpp # define PyPackageRecords_FromCpp _PyAptPkg_API->packagerecords_fromcpp diff --git a/setup.py b/setup.py index 7f832673..eff78379 100644 --- a/setup.py +++ b/setup.py @@ -34,7 +34,7 @@ files = ['apt_pkgmodule.cc', 'acquire.cc', 'cache.cc', 'cdrom.cc', 'pkgmanager.cc', 'pkgrecords.cc', 'pkgsrcrecords.cc', 'policy.cc', 'progress.cc', 'sourcelist.cc', 'string.cc', 'tag.cc', 'lock.cc', 'acquire-item.cc', 'python-apt-helpers.cc', - 'cachegroup.cc'] + 'cachegroup.cc', 'orderlist.cc'] files = sorted(['python/' + fname for fname in files], key=lambda s: s[:-3]) apt_pkg = Extension("apt_pkg", files, libraries=["apt-pkg"]) -- cgit v1.2.3 From 8c23a5f32378cc25f6a4480b4b58c6bb71d6862c Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Fri, 29 Apr 2011 11:04:34 +0200 Subject: apt.cache: Emit change signals in ProblemResolver --- apt/cache.py | 5 +++++ debian/changelog | 1 + 2 files changed, 6 insertions(+) diff --git a/apt/cache.py b/apt/cache.py index 3bbf5a51..920a3023 100644 --- a/apt/cache.py +++ b/apt/cache.py @@ -576,6 +576,7 @@ class ProblemResolver(object): def __init__(self, cache): self._resolver = apt_pkg.ProblemResolver(cache._depcache) + self._cache = cache def clear(self, package): """Reset the package to the default state.""" @@ -595,11 +596,15 @@ class ProblemResolver(object): def resolve(self): """Resolve dependencies, try to remove packages where needed.""" + self._cache.cache_pre_change() self._resolver.resolve() + self._cache.cache_post_change() def resolve_by_keep(self): """Resolve dependencies, do not try to remove packages.""" + self._cache.cache_pre_change() self._resolver.resolve_by_keep() + self._cache.cache_post_change() # ----------------------------- experimental interface diff --git a/debian/changelog b/debian/changelog index ab1839d2..1d9391a1 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,6 +1,7 @@ python-apt (0.8.0~exp4) UNRELEASED; urgency=low * apt_pkg: Add OrderList, wanted for mancoosi (Closes: #623485) + * apt.cache: Emit change signals in ProblemResolver -- Julian Andres Klode Wed, 27 Apr 2011 12:55:59 +0200 -- cgit v1.2.3 From 4775b948dcda187f03b765d7da2c00ea27834e9c Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Fri, 29 Apr 2011 11:05:40 +0200 Subject: apt.Cache: Add a _changes_count member for later use --- apt/cache.py | 9 +++++++++ debian/changelog | 1 + 2 files changed, 10 insertions(+) diff --git a/apt/cache.py b/apt/cache.py index 920a3023..be137b76 100644 --- a/apt/cache.py +++ b/apt/cache.py @@ -66,7 +66,11 @@ class Cache(object): self._weakref = weakref.WeakValueDictionary() self._set = set() self._fullnameset = set() + self._changes_count = -1 self._sorted_set = None + + self.connect("cache_post_open", self._inc_changes_count) + self.connect("cache_post_change", self._inc_changes_count) if memonly: # force apt to build its caches in memory apt_pkg.config.set("Dir::Cache::pkgcache", "") @@ -87,6 +91,11 @@ class Cache(object): # recognized (LP: #320665) apt_pkg.init_system() self.open(progress) + + + def _inc_changes_count(self): + """Increase the number of changes""" + self._changes_count += 1 def _check_and_create_required_dirs(self, rootdir): """ diff --git a/debian/changelog b/debian/changelog index 1d9391a1..ff07fc21 100644 --- a/debian/changelog +++ b/debian/changelog @@ -2,6 +2,7 @@ python-apt (0.8.0~exp4) UNRELEASED; urgency=low * apt_pkg: Add OrderList, wanted for mancoosi (Closes: #623485) * apt.cache: Emit change signals in ProblemResolver + * apt.Cache: Add a _changes_count member for later use -- Julian Andres Klode Wed, 27 Apr 2011 12:55:59 +0200 -- cgit v1.2.3 From 750f432e42c605747d86826886c29b76d19269a3 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Fri, 29 Apr 2011 12:24:46 +0200 Subject: apt_pkg: Add subclassing fun to PackageManager, for #623485 as well --- debian/changelog | 1 + doc/source/library/apt_pkg.rst | 59 +++++++++ doc/source/whatsnew/0.8.0.rst | 12 +- python/apt_pkgmodule.cc | 3 +- python/apt_pkgmodule.h | 1 + python/pkgmanager.cc | 277 +++++++++++++++++++++++++++++++++++------ 6 files changed, 313 insertions(+), 40 deletions(-) diff --git a/debian/changelog b/debian/changelog index ff07fc21..b6f3da51 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,6 +1,7 @@ python-apt (0.8.0~exp4) UNRELEASED; urgency=low * apt_pkg: Add OrderList, wanted for mancoosi (Closes: #623485) + * apt_pkg: Add subclassing fun to PackageManager, for #623485 as well * apt.cache: Emit change signals in ProblemResolver * apt.Cache: Add a _changes_count member for later use diff --git a/doc/source/library/apt_pkg.rst b/doc/source/library/apt_pkg.rst index fce4f804..81f2d408 100644 --- a/doc/source/library/apt_pkg.rst +++ b/doc/source/library/apt_pkg.rst @@ -423,6 +423,65 @@ Installing with :class:`PackageManager` A constant for checking whether the 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` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/doc/source/whatsnew/0.8.0.rst b/doc/source/whatsnew/0.8.0.rst index fa58a022..2eeb135e 100644 --- a/doc/source/whatsnew/0.8.0.rst +++ b/doc/source/whatsnew/0.8.0.rst @@ -16,6 +16,16 @@ 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 ------------- @@ -23,8 +33,6 @@ This release of python-apt also features several other, smaller changes: * apt_pkg.Cache() now takes None for the progress parameter, preventing progress reporting. - * A new class :class:`apt_pkg.OrderList` has been added on request - of the mancoosi project. There have been various other changes, see the changelog for a complete list of changes. diff --git a/python/apt_pkgmodule.cc b/python/apt_pkgmodule.cc index 139ff016..e8490b4e 100644 --- a/python/apt_pkgmodule.cc +++ b/python/apt_pkgmodule.cc @@ -833,7 +833,8 @@ extern "C" void initapt_pkg() /* ========================= metaindex.cc ========================= */ ADDTYPE(Module,"MetaIndex",&PyMetaIndex_Type); // NO __new__() /* ========================= pkgmanager.cc ========================= */ - ADDTYPE(Module,"PackageManager",&PyPackageManager_Type); + ADDTYPE(Module,"_PackageManager",&PyPackageManager_Type); + ADDTYPE(Module,"PackageManager",&PyPackageManager2_Type); /* ========================= pkgrecords.cc ========================= */ ADDTYPE(Module,"PackageRecords",&PyPackageRecords_Type); /* ========================= pkgsrcrecords.cc ========================= */ diff --git a/python/apt_pkgmodule.h b/python/apt_pkgmodule.h index 89179551..b3534a30 100644 --- a/python/apt_pkgmodule.h +++ b/python/apt_pkgmodule.h @@ -102,6 +102,7 @@ PyObject *GetPkgAcqFile(PyObject *Self, PyObject *Args, PyObject *kwds); // packagemanager extern PyTypeObject PyPackageManager_Type; +extern PyTypeObject PyPackageManager2_Type; PyObject *GetPkgManager(PyObject *Self,PyObject *Args); diff --git a/python/pkgmanager.cc b/python/pkgmanager.cc index a65c88f8..b7bed658 100644 --- a/python/pkgmanager.cc +++ b/python/pkgmanager.cc @@ -17,36 +17,10 @@ #include #include #include +#include #include -static PyObject *PkgManagerNew(PyTypeObject *type,PyObject *Args,PyObject *kwds) -{ - PyObject *Owner; - char *kwlist[] = {"depcache",0}; - if (PyArg_ParseTupleAndKeywords(Args,kwds,"O!",kwlist,&PyDepCache_Type, - &Owner) == 0) - return 0; - - pkgPackageManager *pm = _system->CreatePM(GetCpp(Owner)); - - CppPyObject *PkgManagerObj = - CppPyObject_NEW(NULL, type,pm); - - return PkgManagerObj; -} - -#ifdef COMPAT_0_7 -PyObject *GetPkgManager(PyObject *Self,PyObject *Args) -{ - PyErr_WarnEx(PyExc_DeprecationWarning, "apt_pkg.GetPackageManager() is " - "deprecated. Please see apt_pkg.PackageManager() for the " - "replacement.", 1); - return PkgManagerNew(&PyPackageManager_Type,Args,0); -} -#endif - - static PyObject *PkgManagerGetArchives(PyObject *Self,PyObject *Args) { pkgPackageManager *pm = GetCpp(Self); @@ -114,17 +88,16 @@ static PyMethodDef PkgManagerMethods[] = {} }; - static const char *packagemanager_doc = - "PackageManager(depcache: apt_pkg.DepCache)\n\n" - "PackageManager objects allow the fetching of packages marked for\n" - "installation and the installation of those packages. The parameter\n" - "'depcache' specifies an apt_pkg.DepCache object where information\n" - "about the package selections is retrieved from."; + "_PackageManager objects allow the fetching of packages marked for\n" + "installation and the installation of those packages.\n" + "This is an abstract base class that cannot be subclassed\n" + "in Python. The only subclass is apt_pkg.PackageManager. This\n" + "class is an implementation-detail and not part of the API."; PyTypeObject PyPackageManager_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) - "apt_pkg.PackageManager", // tp_name + "apt_pkg._PackageManager", // tp_name sizeof(CppPyObject), // tp_basicsize 0, // tp_itemsize // Methods @@ -143,8 +116,7 @@ PyTypeObject PyPackageManager_Type = _PyAptObject_getattro, // tp_getattro 0, // tp_setattro 0, // tp_as_buffer - (Py_TPFLAGS_DEFAULT | // tp_flags - Py_TPFLAGS_BASETYPE), + Py_TPFLAGS_DEFAULT, // tp_flag, packagemanager_doc, // tp_doc 0, // tp_traverse 0, // tp_clear @@ -162,9 +134,240 @@ PyTypeObject PyPackageManager_Type = 0, // tp_dictoffset 0, // tp_init 0, // tp_alloc - PkgManagerNew, // tp_new + 0, // tp_new +}; + + +struct CppPyRef { + PyObject *o; + CppPyRef(const CppPyRef &o) { Py_XINCREF(o); this->o = o; } + CppPyRef(PyObject *o) : o(o) {} + ~CppPyRef() { Py_XDECREF(o); } + operator PyObject *() const { return o; } + PyObject *operator->() const { return o; } }; +class PyPkgManager : public pkgDPkgPM { + bool res(CppPyRef result) { + if (result == NULL) { + std::cerr << "Error in function: " << std::endl; + PyErr_Print(); + PyErr_Clear(); + return false; + } + return (result != NULL && + (result == Py_None || PyObject_IsTrue(result) == 1)); + } + + + PyObject *GetPyPkg(const PkgIterator &Pkg) { + PyObject *depcache = NULL; + PyObject *cache = NULL; + + depcache = GetOwner(pyinst); + if (depcache != NULL && PyDepCache_Check(depcache)) + cache = GetOwner(depcache); + + return PyPackage_FromCpp(Pkg, true, cache); + } + + /* Call through to Python */ + virtual bool Install(PkgIterator Pkg,string File) { + return res(PyObject_CallMethod(pyinst, "install", "(NN)", + GetPyPkg(Pkg), + CppPyString(File))); + } + virtual bool Configure(PkgIterator Pkg) { + return res(PyObject_CallMethod(pyinst, "configure", "(N)", + GetPyPkg(Pkg))); + } + virtual bool Remove(PkgIterator Pkg,bool Purge = false) { + return res(PyObject_CallMethod(pyinst, "remove", "(NN)", + GetPyPkg(Pkg), + PyBool_FromLong(Purge))); + } + virtual bool Go(int StatusFd=-1) { + return res(PyObject_CallMethod(pyinst, "go", "(i)", + StatusFd)); + } + virtual void Reset() { + CppPyRef(PyObject_CallMethod(pyinst, "reset", NULL)); + } + +public: + /* Those call the protected functions from the parent class */ + bool callInstall(PkgIterator Pkg,string File) { return pkgDPkgPM::Install(Pkg, File); } + bool callRemove(PkgIterator Pkg, bool Purge) { return pkgDPkgPM::Remove(Pkg, Purge); } + bool callGo(int StatusFd=-1) { return pkgDPkgPM::Go(StatusFd); } + void callReset() { return pkgDPkgPM::Reset(); } + bool callConfigure(PkgIterator Pkg) { return pkgDPkgPM::Configure(Pkg); } + pkgOrderList *getOrderList() { return pkgPackageManager::List; } + + PyPkgManager(pkgDepCache *Cache) : pkgDPkgPM(Cache) {}; + PyObject *pyinst; +}; + +static PyObject *PkgManagerNew(PyTypeObject *type,PyObject *Args,PyObject *kwds) +{ + PyObject *Owner; + char *kwlist[] = {"depcache",0}; + if (PyArg_ParseTupleAndKeywords(Args,kwds,"O!",kwlist,&PyDepCache_Type, + &Owner) == 0) + return 0; + + PyPkgManager *pm = new PyPkgManager(GetCpp(Owner)); + + CppPyObject *PkgManagerObj = + CppPyObject_NEW(NULL, type,pm); + + pm->pyinst = PkgManagerObj; + + return PkgManagerObj; +} + +#ifdef COMPAT_0_7 +PyObject *GetPkgManager(PyObject *Self,PyObject *Args) +{ + PyErr_WarnEx(PyExc_DeprecationWarning, "apt_pkg.GetPackageManager() is " + "deprecated. Please see apt_pkg.PackageManager() for the " + "replacement.", 1); + return PkgManagerNew(&PyPackageManager2_Type,Args,0); +} +#endif + +static PyObject *PkgManagerInstall(PyObject *Self,PyObject *Args) +{ + PyPkgManager *pm = GetCpp(Self); + PyObject *pkg; + const char *file; + + if (PyArg_ParseTuple(Args, "O!s", &PyPackage_Type,&pkg, &file) == 0) + return 0; + + return HandleErrors(PyBool_FromLong(pm->callInstall(PyPackage_ToCpp(pkg), file))); +} + + +static PyObject *PkgManagerConfigure(PyObject *Self,PyObject *Args) +{ + PyPkgManager *pm = GetCpp(Self); + PyObject *pkg; + + if (PyArg_ParseTuple(Args, "O!", &PyPackage_Type,&pkg) == 0) + return 0; + + return HandleErrors(PyBool_FromLong(pm->callConfigure(PyPackage_ToCpp(pkg)))); +} + +static PyObject *PkgManagerRemove(PyObject *Self,PyObject *Args) +{ + PyPkgManager *pm = GetCpp(Self); + PyObject *pkg; + char purge; + + if (PyArg_ParseTuple(Args, "O!b", &PyPackage_Type,&pkg, &purge) == 0) + return 0; + + return HandleErrors(PyBool_FromLong(pm->callRemove(PyPackage_ToCpp(pkg), purge))); +} + +static PyObject *PkgManagerGo(PyObject *Self,PyObject *Args) +{ + PyPkgManager *pm = GetCpp(Self); + int fd; + + if (PyArg_ParseTuple(Args, "i", &fd) == 0) + return 0; + + return HandleErrors(PyBool_FromLong(pm->callGo(fd))); +} + +static PyObject *PkgManagerReset(PyObject *Self,PyObject *Args) +{ + PyPkgManager *pm = GetCpp(Self); + + pm->callReset(); + Py_INCREF(Py_None); + return HandleErrors(Py_None); +} + +static PyMethodDef PkgManager2Methods[] = +{ + {"install",PkgManagerInstall,METH_VARARGS, + "install(pkg: Package, filename: str) -> bool \n\n" + "Add a install action. Can be overriden in subclasses.\n\n" + "New in version 0.8.0."}, + {"configure",PkgManagerConfigure,METH_VARARGS, + "configure(pkg: Package) -> bool \n\n" + "Add a configure action. Can be overriden in subclasses.\n\n" + "New in version 0.8.0."}, + {"remove",PkgManagerRemove,METH_VARARGS, + "remove(pkg: Package, purge: bool) -> bool \n\n" + "Add a removal action. Can be overriden in subclasses.\n\n" + "New in version 0.8.0."}, + {"go",PkgManagerGo,METH_VARARGS, + "go(status_fd: int) -> bool \n\n" + "Start dpkg. Can be overriden in subclasses.\n\n" + "New in version 0.8.0."}, + {"reset",PkgManagerReset,METH_VARARGS, + "reset()\n\n" + "Reset the package manager for a new round.\n" + "Can be overriden in subclasses.\n\n" + "New in version 0.8.0."}, + {} +}; + +static const char *packagemanager2_doc = + "PackageManager(depcache: apt_pkg.DepCache)\n\n" + "PackageManager objects allow the fetching of packages marked for\n" + "installation and the installation of those packages. The parameter\n" + "'depcache' specifies an apt_pkg.DepCache object where information\n" + "about the package selections is retrieved from.\n\n" + "Methods in this class can be overriden in sub classes\n" + "to implement behavior different from APT's dpkg implementation."; +PyTypeObject PyPackageManager2_Type = +{ + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "apt_pkg.PackageManager", // tp_name + sizeof(CppPyObject), // tp_basicsize + 0, // tp_itemsize + // Methods + CppDeallocPtr, // tp_dealloc + 0, // tp_print + 0, // tp_getattr + 0, // tp_setattr + 0, // tp_compare + 0, // tp_repr + 0, // tp_as_number + 0, // tp_as_sequence + 0, // tp_as_mapping + 0, // tp_hash + 0, // tp_call + 0, // tp_str + 0, // tp_getattro + 0, // tp_setattro + 0, // tp_as_buffer + (Py_TPFLAGS_DEFAULT | // tp_flags + Py_TPFLAGS_BASETYPE), + packagemanager2_doc, // tp_doc + 0, // tp_traverse + 0, // tp_clear + 0, // tp_richcompare + 0, // tp_weaklistoffset + 0, // tp_iter + 0, // tp_iternext + PkgManager2Methods, // tp_methods + 0, // tp_members + 0, // tp_getset + &PyPackageManager_Type, // tp_base + 0, // tp_dict + 0, // tp_descr_get + 0, // tp_descr_set + 0, // tp_dictoffset + 0, // tp_init + 0, // tp_alloc + PkgManagerNew, // tp_new +}; /*}}}*/ -- cgit v1.2.3 From 6802fbae9a4eac163fc71dc7ed58bc710ee5386d Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Fri, 29 Apr 2011 13:57:46 +0200 Subject: Release 0.8.0~exp4 to experimental --- debian/changelog | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/debian/changelog b/debian/changelog index b6f3da51..2a4e9e29 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,11 +1,11 @@ -python-apt (0.8.0~exp4) UNRELEASED; urgency=low +python-apt (0.8.0~exp4) experimental; urgency=low * apt_pkg: Add OrderList, wanted for mancoosi (Closes: #623485) * apt_pkg: Add subclassing fun to PackageManager, for #623485 as well * apt.cache: Emit change signals in ProblemResolver * apt.Cache: Add a _changes_count member for later use - -- Julian Andres Klode Wed, 27 Apr 2011 12:55:59 +0200 + -- Julian Andres Klode Fri, 29 Apr 2011 13:57:30 +0200 python-apt (0.8.0~exp3) experimental; urgency=low -- cgit v1.2.3 From f1aeb42d32402dbb6f1b7f5ec1d776092ee99177 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Thu, 26 May 2011 18:05:07 +0200 Subject: Increase Breaks for update-notifier to 0.99.3debian9 --- debian/changelog | 6 ++++++ debian/control | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/debian/changelog b/debian/changelog index 2a4e9e29..e985d45f 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +python-apt (0.8.0~exp5) UNRELEASED; urgency=low + + * Increase Breaks for update-notifier to 0.99.3debian9 + + -- Julian Andres Klode Thu, 26 May 2011 18:01:57 +0200 + python-apt (0.8.0~exp4) experimental; urgency=low * apt_pkg: Add OrderList, wanted for mancoosi (Closes: #623485) diff --git a/debian/control b/debian/control index 0997ab3a..4b90c457 100644 --- a/debian/control +++ b/debian/control @@ -50,7 +50,7 @@ Breaks: packagekit-backend-apt (<= 0.4.8-0ubuntu4), ubuntu-dev-tools (<< 0.93debian1), unattended-upgrades (<< 0.42debian2), update-manager (<< 0.200.2-1), - update-notifier (<< 0.99.3debian1), + update-notifier (<< 0.99.3debian9), wajig (<< 2.0.46) Provides: ${python:Provides} Suggests: python-apt-dbg, python-gtk2, python-vte, python-apt-doc -- cgit v1.2.3 From 49b6e5854b816712cfb7422c3506cbc044b2060d Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Fri, 27 May 2011 15:36:08 +0200 Subject: utils/get_debian_mirrors.py: Adjust for new Alioth SCM urls --- debian/changelog | 1 + utils/get_debian_mirrors.py | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/debian/changelog b/debian/changelog index e985d45f..b9a39e83 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,6 +1,7 @@ python-apt (0.8.0~exp5) UNRELEASED; urgency=low * Increase Breaks for update-notifier to 0.99.3debian9 + * utils/get_debian_mirrors.py: Adjust for new Alioth SCM urls -- Julian Andres Klode Thu, 26 May 2011 18:01:57 +0200 diff --git a/utils/get_debian_mirrors.py b/utils/get_debian_mirrors.py index 9fb4dd37..c81f8276 100755 --- a/utils/get_debian_mirrors.py +++ b/utils/get_debian_mirrors.py @@ -1,7 +1,7 @@ #!/usr/bin/python # get_debian_mirrors.py - Parse Mirrors.masterlist and create a mirror list. # -# Copyright (c) 2010 Julian Andres Klode +# Copyright (c) 2010-2011 Julian Andres Klode # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as @@ -22,7 +22,8 @@ import urllib2 from debian_bundle import deb822 mirrors = collections.defaultdict(set) -masterlist = urllib2.urlopen("http://cvs.debian.org/webwml/webwml/english/" +masterlist = urllib2.urlopen("http://anonscm.debian.org/viewvc/" + "webml/webwml/english/" "mirror/Mirrors.masterlist?revision=HEAD") for mirror in deb822.Deb822.iter_paragraphs(masterlist): -- cgit v1.2.3 From 7dd9234e4fc352c8d36fb343afba116e9c774c68 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Fri, 27 May 2011 15:39:18 +0200 Subject: utils/get_debian_mirrors.py: webml must be webwml --- utils/get_debian_mirrors.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/get_debian_mirrors.py b/utils/get_debian_mirrors.py index c81f8276..c1ec3be8 100755 --- a/utils/get_debian_mirrors.py +++ b/utils/get_debian_mirrors.py @@ -23,7 +23,7 @@ from debian_bundle import deb822 mirrors = collections.defaultdict(set) masterlist = urllib2.urlopen("http://anonscm.debian.org/viewvc/" - "webml/webwml/english/" + "webwml/webwml/english/" "mirror/Mirrors.masterlist?revision=HEAD") for mirror in deb822.Deb822.iter_paragraphs(masterlist): -- cgit v1.2.3 From 3a731524efecb28ffaf1550c02d6175a67c2a644 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Fri, 27 May 2011 15:42:39 +0200 Subject: debian/control: Standards-Version 3.9.2 --- debian/changelog | 1 + debian/control | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/debian/changelog b/debian/changelog index b9a39e83..f4038caa 100644 --- a/debian/changelog +++ b/debian/changelog @@ -2,6 +2,7 @@ python-apt (0.8.0~exp5) UNRELEASED; urgency=low * Increase Breaks for update-notifier to 0.99.3debian9 * utils/get_debian_mirrors.py: Adjust for new Alioth SCM urls + * debian/control: Standards-Version 3.9.2 -- Julian Andres Klode Thu, 26 May 2011 18:01:57 +0200 diff --git a/debian/control b/debian/control index 4b90c457..98506aec 100644 --- a/debian/control +++ b/debian/control @@ -3,7 +3,7 @@ Section: python Priority: standard Maintainer: APT Development Team Uploaders: Michael Vogt , Julian Andres Klode -Standards-Version: 3.9.1 +Standards-Version: 3.9.2 XS-Python-Version: >= 2.6 X-Python3-Version: >= 3.1 Build-Depends: apt-utils, -- cgit v1.2.3 From 48d0403a804e8185c5ca6e77660a80725404e7d8 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Fri, 27 May 2011 15:44:45 +0200 Subject: Fix get_changelog in Python 3 (Closes: #626532) --- apt/package.py | 2 +- debian/changelog | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/apt/package.py b/apt/package.py index 14e80594..00470ced 100644 --- a/apt/package.py +++ b/apt/package.py @@ -1142,7 +1142,7 @@ class Package(object): return u"" # Read changelog line by line line_raw = changelog_file.readline() - if line_raw == "": + if not line_raw: break # The changelog is encoded in utf-8, but since there isn't # any http header, urllib2 seems to treat it as ascii diff --git a/debian/changelog b/debian/changelog index f4038caa..f27bb797 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,9 +1,13 @@ python-apt (0.8.0~exp5) UNRELEASED; urgency=low + [ Julian Andres Klode ] * Increase Breaks for update-notifier to 0.99.3debian9 * utils/get_debian_mirrors.py: Adjust for new Alioth SCM urls * debian/control: Standards-Version 3.9.2 + [ Tshepang Lekhonkhobe ] + * Fix get_changelog in Python 3 (Closes: #626532) + -- Julian Andres Klode Thu, 26 May 2011 18:01:57 +0200 python-apt (0.8.0~exp4) experimental; urgency=low -- cgit v1.2.3 From ba4ba3e73303860b032ae1a1ae5c27c98e629cd6 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Fri, 27 May 2011 15:46:49 +0200 Subject: apt/package.py: fix a few typos [formated->formatted] (Closes: #597054) --- apt/package.py | 8 ++++---- debian/changelog | 1 + 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/apt/package.py b/apt/package.py index 00470ced..9223ed22 100644 --- a/apt/package.py +++ b/apt/package.py @@ -343,7 +343,7 @@ class Version(object): def description(self): """Return the formatted long description. - Return the formated long description according to the Debian policy + Return the formatted long description according to the Debian policy (Chapter 5.6.13). See http://www.debian.org/doc/debian-policy/ch-controlfields.html for more information. @@ -892,7 +892,7 @@ class Package(object): def description(self): """Return the formatted long description. - Return the formated long description according to the Debian policy + Return the formatted long description according to the Debian policy (Chapter 5.6.13). See http://www.debian.org/doc/debian-policy/ch-controlfields.html for more information. @@ -1360,8 +1360,8 @@ def _test(): print "SourcePkg: %s " % pkg.candidate.source_name print "Section: %s " % pkg.section print "Summary: %s" % pkg.candidate.summary - print "Description (formated) :\n%s" % pkg.candidate.description - print "Description (unformated):\n%s" % pkg.candidate.raw_description + print "Description (formatted) :\n%s" % pkg.candidate.description + print "Description (unformatted):\n%s" % pkg.candidate.raw_description print "InstalledSize: %s " % pkg.candidate.installed_size print "PackageSize: %s " % pkg.candidate.size print "Dependencies: %s" % pkg.installed.dependencies diff --git a/debian/changelog b/debian/changelog index f27bb797..6a906324 100644 --- a/debian/changelog +++ b/debian/changelog @@ -7,6 +7,7 @@ python-apt (0.8.0~exp5) UNRELEASED; urgency=low [ Tshepang Lekhonkhobe ] * Fix get_changelog in Python 3 (Closes: #626532) + * apt/package.py: fix a few typos [formated->formatted] (Closes: #597054) -- Julian Andres Klode Thu, 26 May 2011 18:01:57 +0200 -- cgit v1.2.3 From b08e19a9ce1dfae6c632831f44916cd4916d672e Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Fri, 27 May 2011 15:53:24 +0200 Subject: * doc/source/tutorials/contributing.rst: minor improvements (Closes: #625225) - one typo [2to => 2to3], one broken link [pep8.py link] --- debian/changelog | 2 ++ doc/source/tutorials/contributing.rst | 6 +++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/debian/changelog b/debian/changelog index 6a906324..bcdaecdc 100644 --- a/debian/changelog +++ b/debian/changelog @@ -8,6 +8,8 @@ python-apt (0.8.0~exp5) UNRELEASED; urgency=low [ Tshepang Lekhonkhobe ] * Fix get_changelog in Python 3 (Closes: #626532) * apt/package.py: fix a few typos [formated->formatted] (Closes: #597054) + * doc/source/tutorials/contributing.rst: minor improvements (Closes: #625225) + - one typo [2to => 2to3], one broken link [pep8.py link] -- Julian Andres Klode Thu, 26 May 2011 18:01:57 +0200 diff --git a/doc/source/tutorials/contributing.rst b/doc/source/tutorials/contributing.rst index 0735982b..aae7f382 100644 --- a/doc/source/tutorials/contributing.rst +++ b/doc/source/tutorials/contributing.rst @@ -232,12 +232,12 @@ 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, and functions provided for 0.7 compatibility purposes. -When writing code, use tools like pylint, pyflakes, pychecker and pep8.py from -http://svn.browsershots.org/trunk/devtools/pep8/ to verify that your code is +When writing code, use tools like pylint, pyflakes, pychecker and pep8.py +(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. -In order to make the automatic generation of Python 3 code using 2to possible, +In order to make the automatic generation of Python 3 code using 2to3 possible, code written in Python may not utilize any functionality unsupported by 2to3 or deprecated as of Python 2.6. -- cgit v1.2.3 From 8b00d8568eac3433d644d7ca4655750f3480cb17 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Fri, 27 May 2011 15:56:58 +0200 Subject: Esperanto (Closes: #626430) --- debian/changelog | 3 + po/eo.po | 485 +++++++++++++++++++++++++++++++++---------------------- 2 files changed, 298 insertions(+), 190 deletions(-) diff --git a/debian/changelog b/debian/changelog index bcdaecdc..9876b407 100644 --- a/debian/changelog +++ b/debian/changelog @@ -11,6 +11,9 @@ python-apt (0.8.0~exp5) UNRELEASED; urgency=low * doc/source/tutorials/contributing.rst: minor improvements (Closes: #625225) - one typo [2to => 2to3], one broken link [pep8.py link] + [ Translation updates ] + * Esperanto (Closes: #626430) + -- Julian Andres Klode Thu, 26 May 2011 18:01:57 +0200 python-apt (0.8.0~exp4) experimental; urgency=low diff --git a/po/eo.po b/po/eo.po index f411a28c..dcac3593 100644 --- a/po/eo.po +++ b/po/eo.po @@ -1,272 +1,329 @@ # Esperanto translation for update-manager -# Copyright (c) (c) 2006 Canonical Ltd, and Rosetta Contributors 2006 +# Copyright (c) 2006 Canonical Ltd, and Rosetta Contributors 2006 # This file is distributed under the same license as the update-manager package. -# FIRST AUTHOR , 2006. +# Ed GLEZ , 2006. +# Aisano < >, 2010. +# Patrick (Petriko) OUDEJANS < >, 2010. +# Roĉjo HUURMAN < >, 2010. +# Michael MORONI < >, 2009, 2011. +# Kristjan SCHMIDT , 2011. # -#, fuzzy msgid "" msgstr "" "Project-Id-Version: update-manager\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2009-07-19 15:59+0200\n" -"PO-Revision-Date: 2006-10-16 04:05+0000\n" -"Last-Translator: Ed Glez \n" -"Language-Team: Esperanto \n" +"POT-Creation-Date: 2011-05-27 15:56+0200\n" +"PO-Revision-Date: 2011-05-09 16:09+0200\n" +"Last-Translator: Kristjan SCHMIDT \n" +"Language-Team: Esperanto \n" +"Language: eo\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=n != 1\n" +"X-Launchpad-Export-Date: 2011-05-09 14:00+0000\n" +"X-Generator: Launchpad (build 12981)\n" +"Plural-Forms: nplurals=2; plural=(n != 1)\n" #. ChangelogURI #: ../data/templates/Ubuntu.info.in.h:4 #, no-c-format msgid "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" -msgstr "" +msgstr "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" #. Description #: ../data/templates/Ubuntu.info.in:13 -msgid "Ubuntu 9.10 'Karmic Koala'" -msgstr "" +msgid "Ubuntu 10.10 'Maverick Meerkat'" +msgstr "Ubuntu 10.10 'Maverick Meerkat'" #. Description #: ../data/templates/Ubuntu.info.in:31 +msgid "Cdrom with Ubuntu 10.10 'Maverick Meerkat'" +msgstr "KD kun Ubuntu 10.10 'Maverick Meerkat'" + +#. Description +#: ../data/templates/Ubuntu.info.in:43 +msgid "Canonical Partners" +msgstr "Partneroj de Canonical" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:45 +msgid "Software packaged by Canonical for their partners" +msgstr "Programaro pakita de Canonical por iliaj partneroj" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:46 +msgid "This software is not part of Ubuntu." +msgstr "Tiuj ĉi programoj ne estas parto de Ubuntu." + +#. Description +#: ../data/templates/Ubuntu.info.in:53 +msgid "Independent" +msgstr "Sendepende" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:55 +msgid "Provided by third-party software developers" +msgstr "Ofertitaj de aliaj programistoj kaj firmaoj" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:56 +msgid "Software offered by third party developers." +msgstr "Programoj ofertitaj de aliaj programistoj kaj firmaoj" + +#. Description +#: ../data/templates/Ubuntu.info.in:94 +msgid "Ubuntu 10.04 'Lucid Lynx'" +msgstr "Ubuntu 10.04 'Lucid Lynx'" + +#. Description +#: ../data/templates/Ubuntu.info.in:112 +msgid "Cdrom with Ubuntu 10.04 'Lucid Lynx'" +msgstr "KD kun Ubuntu 10.04 'Lucid Lynx'" + +#. Description +#: ../data/templates/Ubuntu.info.in:155 +msgid "Ubuntu 9.10 'Karmic Koala'" +msgstr "Ubuntu 9.10 'Karmic Koala'" + +#. Description +#: ../data/templates/Ubuntu.info.in:173 msgid "Cdrom with Ubuntu 9.10 'Karmic Koala'" -msgstr "" +msgstr "KD kun Ubuntu 9.10 'Karmic Koala'" #. Description -#: ../data/templates/Ubuntu.info.in:74 +#: ../data/templates/Ubuntu.info.in:216 msgid "Ubuntu 9.04 'Jaunty Jackalope'" -msgstr "" +msgstr "Ubuntu 9.04 'Jaunty Jackalope'" #. Description -#: ../data/templates/Ubuntu.info.in:92 +#: ../data/templates/Ubuntu.info.in:234 msgid "Cdrom with Ubuntu 9.04 'Jaunty Jackalope'" -msgstr "" +msgstr "KD kun Ubuntu 9.04 'Jaunty Jackalope'" #. Description -#: ../data/templates/Ubuntu.info.in:135 +#: ../data/templates/Ubuntu.info.in:277 msgid "Ubuntu 8.10 'Intrepid Ibex'" -msgstr "" +msgstr "Ubuntu 8.10 'Intrepid Ibex'" #. Description -#: ../data/templates/Ubuntu.info.in:153 +#: ../data/templates/Ubuntu.info.in:295 msgid "Cdrom with Ubuntu 8.10 'Intrepid Ibex'" -msgstr "" +msgstr "KD kun Ubuntu 8.10 'Intrepid Ibex'" #. Description -#: ../data/templates/Ubuntu.info.in:197 +#: ../data/templates/Ubuntu.info.in:339 msgid "Ubuntu 8.04 'Hardy Heron'" -msgstr "" +msgstr "Ubuntu 8.04 'Hardy Heron'" #. Description -#: ../data/templates/Ubuntu.info.in:215 +#: ../data/templates/Ubuntu.info.in:357 msgid "Cdrom with Ubuntu 8.04 'Hardy Heron'" -msgstr "" +msgstr "KD kun Ubuntu 8.04 'Hardy Heron'" #. Description -#: ../data/templates/Ubuntu.info.in:252 +#: ../data/templates/Ubuntu.info.in:402 msgid "Ubuntu 7.10 'Gutsy Gibbon'" -msgstr "" +msgstr "Ubuntu 7.10 'Gutsy Gibbon'" #. Description -#: ../data/templates/Ubuntu.info.in:270 +#: ../data/templates/Ubuntu.info.in:420 msgid "Cdrom with Ubuntu 7.10 'Gutsy Gibbon'" -msgstr "" +msgstr "KD kun Ubuntu 7.10 'Gutsy Gibbon'" #. Description -#: ../data/templates/Ubuntu.info.in:305 +#: ../data/templates/Ubuntu.info.in:465 msgid "Ubuntu 7.04 'Feisty Fawn'" -msgstr "" +msgstr "Ubuntu 7.04 'Feisty Fawn'" #. Description -#: ../data/templates/Ubuntu.info.in:323 +#: ../data/templates/Ubuntu.info.in:483 msgid "Cdrom with Ubuntu 7.04 'Feisty Fawn'" -msgstr "" +msgstr "KD kun Ubuntu 7.04 'Feisty Fawn'" #. Description -#: ../data/templates/Ubuntu.info.in:357 +#: ../data/templates/Ubuntu.info.in:525 msgid "Ubuntu 6.10 'Edgy Eft'" -msgstr "" +msgstr "Ubuntu 6.10 'Edgy Eft'" #. CompDescription -#: ../data/templates/Ubuntu.info.in:362 +#: ../data/templates/Ubuntu.info.in:530 msgid "Community-maintained" -msgstr "" +msgstr "Komunume prizorgata" #. CompDescription -#: ../data/templates/Ubuntu.info.in:368 +#: ../data/templates/Ubuntu.info.in:536 msgid "Restricted software" -msgstr "" +msgstr "Limigita programaro" #. Description -#: ../data/templates/Ubuntu.info.in:375 +#: ../data/templates/Ubuntu.info.in:543 msgid "Cdrom with Ubuntu 6.10 'Edgy Eft'" -msgstr "" +msgstr "KD kun Ubuntu 6.10 'Edgy Eft'" #. Description -#: ../data/templates/Ubuntu.info.in:409 +#: ../data/templates/Ubuntu.info.in:585 msgid "Ubuntu 6.06 LTS 'Dapper Drake'" -msgstr "" +msgstr "Ubuntu 6.06 LTS 'Dapper Drake'" #. CompDescriptionLong -#: ../data/templates/Ubuntu.info.in:412 +#: ../data/templates/Ubuntu.info.in:588 msgid "Canonical-supported Open Source software" -msgstr "" +msgstr "Malfermitkoda programaro subtenata de Canonical" #. CompDescription -#: ../data/templates/Ubuntu.info.in:414 +#: ../data/templates/Ubuntu.info.in:590 msgid "Community-maintained (universe)" -msgstr "" +msgstr "Komunume prizorgata (universo)" #. CompDescriptionLong -#: ../data/templates/Ubuntu.info.in:415 +#: ../data/templates/Ubuntu.info.in:591 msgid "Community-maintained Open Source software" -msgstr "" +msgstr "Komunume prizorgata malfermitkoda programaro" #. CompDescription -#: ../data/templates/Ubuntu.info.in:417 +#: ../data/templates/Ubuntu.info.in:593 msgid "Non-free drivers" -msgstr "" +msgstr "Neliberaj peliloj" #. CompDescriptionLong -#: ../data/templates/Ubuntu.info.in:418 +#: ../data/templates/Ubuntu.info.in:594 msgid "Proprietary drivers for devices" -msgstr "" +msgstr "Fermitkoda peliloj por aparatoj" #. CompDescription -#: ../data/templates/Ubuntu.info.in:420 +#: ../data/templates/Ubuntu.info.in:596 msgid "Restricted software (Multiverse)" -msgstr "" +msgstr "Limigita programaro (multiverso)" #. CompDescriptionLong -#: ../data/templates/Ubuntu.info.in:421 +#: ../data/templates/Ubuntu.info.in:597 msgid "Software restricted by copyright or legal issues" -msgstr "" +msgstr "Programaro limigita per kopirajto aŭ leĝaj temoj" #. Description -#: ../data/templates/Ubuntu.info.in:427 +#: ../data/templates/Ubuntu.info.in:603 msgid "Cdrom with Ubuntu 6.06 LTS 'Dapper Drake'" -msgstr "" +msgstr "KD kun Ubuntu 6.06 LTS 'Dapper Drake'" #. Description -#: ../data/templates/Ubuntu.info.in:439 +#: ../data/templates/Ubuntu.info.in:619 msgid "Important security updates" -msgstr "" +msgstr "Gravaj sekurecaj ĝisdatigoj" #. Description -#: ../data/templates/Ubuntu.info.in:444 +#: ../data/templates/Ubuntu.info.in:624 msgid "Recommended updates" -msgstr "" +msgstr "Rekomenditaj ĝisdatigoj" #. Description -#: ../data/templates/Ubuntu.info.in:449 +#: ../data/templates/Ubuntu.info.in:629 msgid "Pre-released updates" -msgstr "" +msgstr "Antaŭ-eldonataj ĝisdatigoj" #. Description -#: ../data/templates/Ubuntu.info.in:454 +#: ../data/templates/Ubuntu.info.in:634 msgid "Unsupported updates" -msgstr "" +msgstr "Nesubtenataj ĝisdatigoj" #. Description -#: ../data/templates/Ubuntu.info.in:461 +#: ../data/templates/Ubuntu.info.in:645 msgid "Ubuntu 5.10 'Breezy Badger'" -msgstr "" +msgstr "Ubuntu 5.10 'Breezy Badger'" #. Description -#: ../data/templates/Ubuntu.info.in:475 +#: ../data/templates/Ubuntu.info.in:659 msgid "Cdrom with Ubuntu 5.10 'Breezy Badger'" -msgstr "" +msgstr "KD kun Ubuntu 5.10 'Breezy Badger'" #. Description -#: ../data/templates/Ubuntu.info.in:487 +#: ../data/templates/Ubuntu.info.in:675 msgid "Ubuntu 5.10 Security Updates" -msgstr "" +msgstr "Ubuntu 5.10 Sekurecaj ĝisdatigoj" #. Description -#: ../data/templates/Ubuntu.info.in:492 +#: ../data/templates/Ubuntu.info.in:680 msgid "Ubuntu 5.10 Updates" -msgstr "" +msgstr "Ubuntu 5.10 Ĝisdatigoj" #. Description -#: ../data/templates/Ubuntu.info.in:497 +#: ../data/templates/Ubuntu.info.in:685 msgid "Ubuntu 5.10 Backports" -msgstr "" +msgstr "Ubuntu 5.10 Retroportoj" #. Description -#: ../data/templates/Ubuntu.info.in:504 +#: ../data/templates/Ubuntu.info.in:696 msgid "Ubuntu 5.04 'Hoary Hedgehog'" -msgstr "" +msgstr "Ubuntu 5.04 'Hoary Hedgehog'" #. Description -#: ../data/templates/Ubuntu.info.in:518 +#: ../data/templates/Ubuntu.info.in:710 msgid "Cdrom with Ubuntu 5.04 'Hoary Hedgehog'" -msgstr "" +msgstr "KD kun Ubuntu 5.04 'Hoary Hedgehog'" #. CompDescription -#: ../data/templates/Ubuntu.info.in:521 ../data/templates/Debian.info.in:148 +#: ../data/templates/Ubuntu.info.in:713 ../data/templates/Debian.info.in:149 msgid "Officially supported" msgstr "Oficiale subtenata" #. Description -#: ../data/templates/Ubuntu.info.in:530 +#: ../data/templates/Ubuntu.info.in:726 msgid "Ubuntu 5.04 Security Updates" -msgstr "" +msgstr "Ubuntu 5.04 Sekurecaj ĝisdatigoj" #. Description -#: ../data/templates/Ubuntu.info.in:535 +#: ../data/templates/Ubuntu.info.in:731 msgid "Ubuntu 5.04 Updates" -msgstr "" +msgstr "Ubuntu 5.04 Ĝisdatigoj" #. Description -#: ../data/templates/Ubuntu.info.in:540 +#: ../data/templates/Ubuntu.info.in:736 msgid "Ubuntu 5.04 Backports" -msgstr "" +msgstr "Ubuntu 5.04 Retroportoj" #. Description -#: ../data/templates/Ubuntu.info.in:546 +#: ../data/templates/Ubuntu.info.in:742 msgid "Ubuntu 4.10 'Warty Warthog'" -msgstr "" +msgstr "Ubuntu 4.10 'Warty Warthog'" #. CompDescription -#: ../data/templates/Ubuntu.info.in:552 +#: ../data/templates/Ubuntu.info.in:748 msgid "Community-maintained (Universe)" -msgstr "" +msgstr "Komunume flegata (univreso)" #. CompDescription -#: ../data/templates/Ubuntu.info.in:554 +#: ../data/templates/Ubuntu.info.in:750 msgid "Non-free (Multiverse)" -msgstr "" +msgstr "Mallibere (Multiverse)" #. Description -#: ../data/templates/Ubuntu.info.in:560 +#: ../data/templates/Ubuntu.info.in:756 msgid "Cdrom with Ubuntu 4.10 'Warty Warthog'" -msgstr "" +msgstr "KD kun Ubuntu 4.10 'Warty Warthog'" #. CompDescription -#: ../data/templates/Ubuntu.info.in:563 +#: ../data/templates/Ubuntu.info.in:759 msgid "No longer officially supported" -msgstr "" +msgstr "Ne plu oficiale subtenata" #. CompDescription -#: ../data/templates/Ubuntu.info.in:565 +#: ../data/templates/Ubuntu.info.in:761 msgid "Restricted copyright" -msgstr "" +msgstr "Limigita kopirajto" #. Description -#: ../data/templates/Ubuntu.info.in:572 +#: ../data/templates/Ubuntu.info.in:768 msgid "Ubuntu 4.10 Security Updates" -msgstr "" +msgstr "Ubuntu 4.10 Sekurecaj ĝisdatigoj" #. Description -#: ../data/templates/Ubuntu.info.in:577 +#: ../data/templates/Ubuntu.info.in:773 msgid "Ubuntu 4.10 Updates" -msgstr "" +msgstr "Ubuntu 4.10 Ĝisdatigoj" #. Description -#: ../data/templates/Ubuntu.info.in:582 +#: ../data/templates/Ubuntu.info.in:778 msgid "Ubuntu 4.10 Backports" -msgstr "" +msgstr "Ubuntu 4.10 Retroportoj" #. ChangelogURI #: ../data/templates/Debian.info.in.h:4 @@ -276,114 +333,110 @@ msgstr "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" #. Description #: ../data/templates/Debian.info.in:8 -#, fuzzy msgid "Debian 6.0 'Squeeze' " -msgstr "Debian 3.1 \"Sarge\"" +msgstr "Debiano 6.0 'Squeeze' " #. Description #: ../data/templates/Debian.info.in:33 -#, fuzzy msgid "Debian 5.0 'Lenny' " -msgstr "Debian 3.1 \"Sarge\"" +msgstr "Debiano 5.0 'Lenny' " #. Description #: ../data/templates/Debian.info.in:58 -#, fuzzy msgid "Debian 4.0 'Etch'" -msgstr "Debian 3.1 \"Sarge\"" +msgstr "Debiano 4.0 'Etch'" #. Description #: ../data/templates/Debian.info.in:83 -#, fuzzy msgid "Debian 3.1 'Sarge'" -msgstr "Debian 3.1 \"Sarge\"" +msgstr "Debiano 3.1 'Sarge'" #. Description #: ../data/templates/Debian.info.in:94 msgid "Proposed updates" -msgstr "" +msgstr "Proponitaj ĝisdatigoj" #. Description #: ../data/templates/Debian.info.in:101 msgid "Security updates" -msgstr "" +msgstr "Sekurecaj ĝisdatigoj" #. Description #: ../data/templates/Debian.info.in:108 msgid "Debian current stable release" -msgstr "" +msgstr "Debiana aktuala stabila eldono" #. Description #: ../data/templates/Debian.info.in:121 msgid "Debian testing" -msgstr "" +msgstr "Debiana testado" #. Description -#: ../data/templates/Debian.info.in:146 +#: ../data/templates/Debian.info.in:147 msgid "Debian 'Sid' (unstable)" -msgstr "" +msgstr "Debiano 'Sid' (nestabile)" #. CompDescription -#: ../data/templates/Debian.info.in:150 +#: ../data/templates/Debian.info.in:151 msgid "DFSG-compatible Software with Non-Free Dependencies" -msgstr "" +msgstr "DFSG-kongrua programaro kun malliberaj dependecoj" #. CompDescription -#: ../data/templates/Debian.info.in:152 +#: ../data/templates/Debian.info.in:153 msgid "Non-DFSG-compatible Software" -msgstr "" +msgstr "Ne-DFSG-kongruaj programaroj" #. TRANSLATORS: %s is a country -#: ../aptsources/distro.py:208 ../aptsources/distro.py:423 +#: ../aptsources/distro.py:209 ../aptsources/distro.py:427 #, python-format msgid "Server for %s" -msgstr "" +msgstr "Servilo por %s" #. More than one server is used. Since we don't handle this case #. in the user interface we set "custom servers" to true and #. append a list of all used servers -#: ../aptsources/distro.py:226 ../aptsources/distro.py:232 -#: ../aptsources/distro.py:248 +#: ../aptsources/distro.py:227 ../aptsources/distro.py:233 +#: ../aptsources/distro.py:249 msgid "Main server" -msgstr "" +msgstr "Ĉefa servilo" -#: ../aptsources/distro.py:252 +#: ../aptsources/distro.py:253 msgid "Custom servers" -msgstr "" +msgstr "Propraj serviloj" -#: ../apt/progress/gtk2.py:259 +#: ../apt/progress/gtk2.py:260 ../apt/progress/gtk2.py:316 #, python-format msgid "Downloading file %(current)li of %(total)li with %(speed)s/s" -msgstr "" +msgstr "Elŝutante dosieron %(current)li sur %(total)li per %(speed)s/s" -#: ../apt/progress/gtk2.py:265 +#: ../apt/progress/gtk2.py:266 ../apt/progress/gtk2.py:322 #, python-format msgid "Downloading file %(current)li of %(total)li" -msgstr "" +msgstr "Elŝutante dosieron %(current)li sur %(total)li" #. Setup some child widgets -#: ../apt/progress/gtk2.py:285 +#: ../apt/progress/gtk2.py:342 msgid "Details" msgstr "Detaloj" -#: ../apt/progress/gtk2.py:367 +#: ../apt/progress/gtk2.py:430 msgid "Starting..." -msgstr "" +msgstr "Komencante..." -#: ../apt/progress/gtk2.py:373 +#: ../apt/progress/gtk2.py:436 msgid "Complete" -msgstr "" +msgstr "Komplete" -#: ../apt/package.py:301 +#: ../apt/package.py:358 #, python-format msgid "Invalid unicode in description for '%s' (%s). Please report." -msgstr "" +msgstr "Nevalida unikodaĵo en priskribo por '%s' (%s). Bonvolu raporti." -#: ../apt/package.py:937 ../apt/package.py:1043 +#: ../apt/package.py:1065 ../apt/package.py:1171 msgid "The list of changes is not available" -msgstr "" +msgstr "La listo de ŝanĝoj ne haveblas" -#: ../apt/package.py:1047 +#: ../apt/package.py:1177 #, python-format msgid "" "The list of changes is not available yet.\n" @@ -391,109 +444,161 @@ msgid "" "Please use http://launchpad.net/ubuntu/+source/%s/%s/+changelog\n" "until the changes become available or try again later." msgstr "" +"La listo de ŝanĝoj ankoraŭ ne haveblas.\n" +"\n" +"Bonvolu uzi http://launchpad.net/ubuntu/+source/%s/%s/+changelog\n" +"ĝis kiam la ŝanĝoj havebliĝos aŭ poste reklopodi." -#: ../apt/package.py:1053 -#, fuzzy +#: ../apt/package.py:1184 msgid "" "Failed to download the list of changes. \n" "Please check your Internet connection." -msgstr "Bonvolu kontroli vian interretan konekton." +msgstr "" +"Malsukcesis elŝuti la liston de ŝanĝoj. \n" +"Bonvolu kontroli vian interretan konekton." -#: ../apt/debfile.py:56 +#: ../apt/debfile.py:82 #, python-format -msgid "This is not a valid DEB archive, missing '%s' member" -msgstr "" +msgid "List of files for '%s' could not be read" +msgstr "Listo de dosieroj de '%s' ne legeblis" + +#: ../apt/debfile.py:167 +#, python-format +msgid "Dependency is not satisfiable: %s\n" +msgstr "Dependeco ne plenumita: %s\n" -#: ../apt/debfile.py:81 +#: ../apt/debfile.py:188 #, python-format -msgid "List of files for '%s'could not be read" +msgid "Conflicts with the installed package '%s'" +msgstr "Konfliktas kun la instalita pakaĵo '%s'" + +#. TRANSLATORS: the first '%s' is the package that breaks, the second the dependency that makes it break, the third the relation (e.g. >=) and the latest the version for the releation +#: ../apt/debfile.py:327 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' dependency %(depname)s " +"(%(deprelation)s %(depversion)s)" msgstr "" +"Malfunkciigas la ekzistantan pakaĵon '%(pkgname)s' dependaĵo %(depname)s " +"(%(deprelation)s %(depversion)s)" -#: ../apt/debfile.py:149 +#. TRANSLATORS: the first '%s' is the package that conflicts, the second the packagename that it conflicts with (so the name of the deb the user tries to install), the third is the relation (e.g. >=) and the last is the version for the relation +#: ../apt/debfile.py:343 #, python-format -msgid "Dependency is not satisfiable: %s\n" +msgid "" +"Breaks existing package '%(pkgname)s' conflict: %(targetpkg)s (%(comptype)s " +"%(targetver)s)" msgstr "" +"Malfunkciigas la ekzistantan pakaĵon '%(pkgname)s' konflikto: %(targetpkg)s " +"(%(comptype)s %(targetver)s)" -#: ../apt/debfile.py:173 +#: ../apt/debfile.py:353 #, python-format -msgid "Conflicts with the installed package '%s'" +msgid "" +"Breaks existing package '%(pkgname)s' that conflict: '%(targetpkg)s'. But " +"the '%(debfile)s' provides it via: '%(provides)s'" msgstr "" +"Malfunkciigas la ekzistantan pakaĵon '%(pkgname)s' kiu konfliktas kun: " +"'%(targetpkg)s'. Sed la '%(debfile)s' ofertas ĝin per: '%(provides)s'" + +#: ../apt/debfile.py:399 +msgid "No Architecture field in the package" +msgstr "Neniu arĥitekturo-kampo en la pakaĵo" -#: ../apt/debfile.py:319 +#: ../apt/debfile.py:404 #, python-format msgid "Wrong architecture '%s'" -msgstr "" +msgstr "Malkorekta arĥitekturo: '%s'" #. the deb is older than the installed -#: ../apt/debfile.py:325 +#: ../apt/debfile.py:411 msgid "A later version is already installed" -msgstr "" +msgstr "Pli nova versio estas jam instalita" -#: ../apt/debfile.py:345 +#: ../apt/debfile.py:436 msgid "Failed to satisfy all dependencies (broken cache)" -msgstr "" +msgstr "Fiaskis plenumi ĉiujn dependecojn (difektita kaŝmemoro)" -#: ../apt/debfile.py:376 -#, fuzzy, python-format +#: ../apt/debfile.py:466 +#, python-format msgid "Cannot install '%s'" -msgstr "Ne eblis instalo de '%s'" +msgstr "Ne instaleblas '%s'" -#: ../apt/debfile.py:484 +#: ../apt/debfile.py:508 +msgid "Python-debian module not available" +msgstr "Modulo Python-debian ne haveblas" + +#: ../apt/debfile.py:542 +msgid "" +"Automatically decompressed:\n" +"\n" +msgstr "" +"Aŭtomate malpakita:\n" +"\n" + +#: ../apt/debfile.py:548 +msgid "Automatically converted to printable ascii:\n" +msgstr "Aŭtomate konvertita al presebla 'ascii':\n" + +#: ../apt/debfile.py:638 #, python-format msgid "Install Build-Dependencies for source package '%s' that builds %s\n" -msgstr "" +msgstr "Instali kunmet-dependecojn por fontpakaĵo '%s', kiu kunmetas %s\n" -#: ../apt/debfile.py:494 +#: ../apt/debfile.py:648 msgid "An essential package would be removed" -msgstr "" +msgstr "Esenca pakaĵo estus forigita" -#: ../apt/progress/text.py:81 +#: ../apt/progress/text.py:82 #, python-format msgid "%c%s... Done" -msgstr "" +msgstr "%c%s... Farite" -#: ../apt/progress/text.py:118 +#: ../apt/progress/text.py:122 msgid "Hit " -msgstr "" +msgstr "Trafo " -#: ../apt/progress/text.py:126 +#: ../apt/progress/text.py:131 msgid "Ign " -msgstr "" +msgstr "Ign " -#: ../apt/progress/text.py:128 +#: ../apt/progress/text.py:133 msgid "Err " -msgstr "" +msgstr "Era " -#: ../apt/progress/text.py:138 +#: ../apt/progress/text.py:144 msgid "Get:" -msgstr "" +msgstr "Akiri:" -#: ../apt/progress/text.py:198 +#: ../apt/progress/text.py:203 msgid " [Working]" -msgstr "" +msgstr " [laborante]" -#: ../apt/progress/text.py:208 +#: ../apt/progress/text.py:214 #, python-format msgid "" "Media change: please insert the disc labeled\n" " '%s'\n" "in the drive '%s' and press enter\n" msgstr "" +"Ŝanĝo de datenportilo: bonvolu enmeti la diskon nomitan\n" +" '%s'\n" +"en la diskingon '%s' kaj puŝi la enigan klavon\n" #. Trick for getting a translation from apt -#: ../apt/progress/text.py:216 +#: ../apt/progress/text.py:223 #, python-format msgid "Fetched %sB in %s (%sB/s)\n" -msgstr "" +msgstr "Prenis %sB en %s (%sB/s)\n" -#: ../apt/progress/text.py:229 +#: ../apt/progress/text.py:239 msgid "Please provide a name for this Disc, such as 'Debian 2.1r1 Disk 1'" -msgstr "" +msgstr "Bonvolu doni nomon al tiu ĉi disko, ekzemple 'Disko 1 de Debian 2.1r1'" -#: ../apt/progress/text.py:241 +#: ../apt/progress/text.py:255 msgid "Please insert a Disc in the drive and press enter" -msgstr "" +msgstr "Bonvolu enmeti diskon en la diskingon kaj puŝi la enigan klavon" -#: ../apt/cache.py:96 +#: ../apt/cache.py:149 msgid "Building data structures" -msgstr "" +msgstr "Konstruado de datenaj strukturoj" -- cgit v1.2.3 From 1a1d96e49901a834d6208d3561877d8f16d5b758 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Fri, 27 May 2011 16:04:24 +0200 Subject: Fix Lintian overrides --- debian/changelog | 1 + debian/python-apt-common.lintian-overrides | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/debian/changelog b/debian/changelog index 9876b407..85cd3166 100644 --- a/debian/changelog +++ b/debian/changelog @@ -4,6 +4,7 @@ python-apt (0.8.0~exp5) UNRELEASED; urgency=low * Increase Breaks for update-notifier to 0.99.3debian9 * utils/get_debian_mirrors.py: Adjust for new Alioth SCM urls * debian/control: Standards-Version 3.9.2 + * Fix Lintian overrides [ Tshepang Lekhonkhobe ] * Fix get_changelog in Python 3 (Closes: #626532) diff --git a/debian/python-apt-common.lintian-overrides b/debian/python-apt-common.lintian-overrides index 3ae30560..f0eddf6b 100644 --- a/debian/python-apt-common.lintian-overrides +++ b/debian/python-apt-common.lintian-overrides @@ -1,2 +1,2 @@ # package depends on python | python3 -python-script-but-no-python-dep ./usr/share/python-apt/migrate-0.8.py +python-script-but-no-python-dep usr/share/python-apt/migrate-0.8.py -- cgit v1.2.3 From ab08c42c90e9aab009b6d5f1b4bdce0c68300fa5 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Fri, 27 May 2011 16:06:22 +0200 Subject: Fix spelling errors reported by Lintian (sep[a->e]rated, overrid[d]en) --- debian/changelog | 1 + doc/source/library/apt.progress.base.rst | 6 +++--- doc/source/library/apt_pkg.rst | 2 +- python/cdrom.cc | 2 +- python/pkgmanager.cc | 12 ++++++------ 5 files changed, 12 insertions(+), 11 deletions(-) diff --git a/debian/changelog b/debian/changelog index 85cd3166..53830d98 100644 --- a/debian/changelog +++ b/debian/changelog @@ -5,6 +5,7 @@ python-apt (0.8.0~exp5) UNRELEASED; urgency=low * utils/get_debian_mirrors.py: Adjust for new Alioth SCM urls * debian/control: Standards-Version 3.9.2 * Fix Lintian overrides + * Fix spelling errors reported by Lintian (sep[a->e]rated, overrid[d]en) [ Tshepang Lekhonkhobe ] * Fix get_changelog in Python 3 (Closes: #626532) diff --git a/doc/source/library/apt.progress.base.rst b/doc/source/library/apt.progress.base.rst index 3fd2a7a0..22006f77 100644 --- a/doc/source/library/apt.progress.base.rst +++ b/doc/source/library/apt.progress.base.rst @@ -233,7 +233,7 @@ InstallProgress (Abstract) Called when a error is detected during the install. - The following method should be overriden to implement progress reporting + 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) @@ -252,7 +252,7 @@ InstallProgress file (:file:`/var/lib/dpkg/status`) and documented in :manpage:`dpkg(1)`. - The following methods should be overriden to implement progress reporting + The following methods should be overridden to implement progress reporting for :meth:`run` calls with an :class:`apt_pkg.PackageManager` object as their parameter: @@ -274,7 +274,7 @@ InstallProgress This method is called when all changes have been applied. There are also several methods which are fully implemented and should not - be overriden by subclasses unless the subclass has very special needs: + be overridden by subclasses unless the subclass has very special needs: .. method:: fork() -> int diff --git a/doc/source/library/apt_pkg.rst b/doc/source/library/apt_pkg.rst index 81f2d408..ffef9c50 100644 --- a/doc/source/library/apt_pkg.rst +++ b/doc/source/library/apt_pkg.rst @@ -45,7 +45,7 @@ Working with the cache .. note:: - The cache supports colon-seperated name:architecture pairs. For + The cache supports colon-separated 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 diff --git a/python/cdrom.cc b/python/cdrom.cc index 7f89e9d3..6ac16d59 100644 --- a/python/cdrom.cc +++ b/python/cdrom.cc @@ -52,7 +52,7 @@ static PyObject *cdrom_add(PyObject *Self,PyObject *Args) static char *cdrom_ident_doc = "ident(progress: apt_pkg.CdromProgress) -> str\n\n" "Try to identify the CD-ROM and if successful return the hexadecimal\n" - "CDROM-ID (and a integer version suffix seperated by -) as a\n" + "CDROM-ID (and a integer version suffix separated by -) as a\n" "string. Otherwise, return None or raise an error.\n\n" "The ID is created by hashing all file and directory names on the\n" "CD-ROM and appending the version."; diff --git a/python/pkgmanager.cc b/python/pkgmanager.cc index b7bed658..f51dbbbc 100644 --- a/python/pkgmanager.cc +++ b/python/pkgmanager.cc @@ -295,24 +295,24 @@ static PyMethodDef PkgManager2Methods[] = { {"install",PkgManagerInstall,METH_VARARGS, "install(pkg: Package, filename: str) -> bool \n\n" - "Add a install action. Can be overriden in subclasses.\n\n" + "Add a install action. Can be overridden in subclasses.\n\n" "New in version 0.8.0."}, {"configure",PkgManagerConfigure,METH_VARARGS, "configure(pkg: Package) -> bool \n\n" - "Add a configure action. Can be overriden in subclasses.\n\n" + "Add a configure action. Can be overridden in subclasses.\n\n" "New in version 0.8.0."}, {"remove",PkgManagerRemove,METH_VARARGS, "remove(pkg: Package, purge: bool) -> bool \n\n" - "Add a removal action. Can be overriden in subclasses.\n\n" + "Add a removal action. Can be overridden in subclasses.\n\n" "New in version 0.8.0."}, {"go",PkgManagerGo,METH_VARARGS, "go(status_fd: int) -> bool \n\n" - "Start dpkg. Can be overriden in subclasses.\n\n" + "Start dpkg. Can be overridden in subclasses.\n\n" "New in version 0.8.0."}, {"reset",PkgManagerReset,METH_VARARGS, "reset()\n\n" "Reset the package manager for a new round.\n" - "Can be overriden in subclasses.\n\n" + "Can be overridden in subclasses.\n\n" "New in version 0.8.0."}, {} }; @@ -323,7 +323,7 @@ static const char *packagemanager2_doc = "installation and the installation of those packages. The parameter\n" "'depcache' specifies an apt_pkg.DepCache object where information\n" "about the package selections is retrieved from.\n\n" - "Methods in this class can be overriden in sub classes\n" + "Methods in this class can be overridden in sub classes\n" "to implement behavior different from APT's dpkg implementation."; PyTypeObject PyPackageManager2_Type = { -- cgit v1.2.3 From f4a23b4533c0495095045c7bded57427dedd3b3c Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Fri, 27 May 2011 16:09:14 +0200 Subject: po/urd.po: Remove, ur.po is the correct file --- debian/changelog | 1 + po/urd.po | 495 ------------------------------------------------------- 2 files changed, 1 insertion(+), 495 deletions(-) delete mode 100644 po/urd.po diff --git a/debian/changelog b/debian/changelog index 53830d98..e0f1dd72 100644 --- a/debian/changelog +++ b/debian/changelog @@ -6,6 +6,7 @@ python-apt (0.8.0~exp5) UNRELEASED; urgency=low * debian/control: Standards-Version 3.9.2 * Fix Lintian overrides * Fix spelling errors reported by Lintian (sep[a->e]rated, overrid[d]en) + * po/urd.po: Remove, ur.po is the correct file [ Tshepang Lekhonkhobe ] * Fix get_changelog in Python 3 (Closes: #626532) diff --git a/po/urd.po b/po/urd.po deleted file mode 100644 index fc492682..00000000 --- a/po/urd.po +++ /dev/null @@ -1,495 +0,0 @@ -# Urdu translation for update-manager -# Copyright (c) (c) 2006 Canonical Ltd, and Rosetta Contributors 2006 -# This file is distributed under the same license as the update-manager package. -# FIRST AUTHOR , 2006. -# -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: update-manager\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2009-07-19 15:59+0200\n" -"PO-Revision-Date: 2006-05-07 01:53+0000\n" -"Last-Translator: Hameed محمد حمید \n" -"Language-Team: Urdu \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=n != 1\n" - -#. ChangelogURI -#: ../data/templates/Ubuntu.info.in.h:4 -#, no-c-format -msgid "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" -msgstr "" - -#. Description -#: ../data/templates/Ubuntu.info.in:13 -msgid "Ubuntu 9.10 'Karmic Koala'" -msgstr "" - -#. Description -#: ../data/templates/Ubuntu.info.in:31 -msgid "Cdrom with Ubuntu 9.10 'Karmic Koala'" -msgstr "" - -#. Description -#: ../data/templates/Ubuntu.info.in:74 -msgid "Ubuntu 9.04 'Jaunty Jackalope'" -msgstr "" - -#. Description -#: ../data/templates/Ubuntu.info.in:92 -msgid "Cdrom with Ubuntu 9.04 'Jaunty Jackalope'" -msgstr "" - -#. Description -#: ../data/templates/Ubuntu.info.in:135 -msgid "Ubuntu 8.10 'Intrepid Ibex'" -msgstr "" - -#. Description -#: ../data/templates/Ubuntu.info.in:153 -msgid "Cdrom with Ubuntu 8.10 'Intrepid Ibex'" -msgstr "" - -#. Description -#: ../data/templates/Ubuntu.info.in:197 -msgid "Ubuntu 8.04 'Hardy Heron'" -msgstr "" - -#. Description -#: ../data/templates/Ubuntu.info.in:215 -msgid "Cdrom with Ubuntu 8.04 'Hardy Heron'" -msgstr "" - -#. Description -#: ../data/templates/Ubuntu.info.in:252 -msgid "Ubuntu 7.10 'Gutsy Gibbon'" -msgstr "" - -#. Description -#: ../data/templates/Ubuntu.info.in:270 -msgid "Cdrom with Ubuntu 7.10 'Gutsy Gibbon'" -msgstr "" - -#. Description -#: ../data/templates/Ubuntu.info.in:305 -msgid "Ubuntu 7.04 'Feisty Fawn'" -msgstr "" - -#. Description -#: ../data/templates/Ubuntu.info.in:323 -msgid "Cdrom with Ubuntu 7.04 'Feisty Fawn'" -msgstr "" - -#. Description -#: ../data/templates/Ubuntu.info.in:357 -msgid "Ubuntu 6.10 'Edgy Eft'" -msgstr "" - -#. CompDescription -#: ../data/templates/Ubuntu.info.in:362 -msgid "Community-maintained" -msgstr "" - -#. CompDescription -#: ../data/templates/Ubuntu.info.in:368 -msgid "Restricted software" -msgstr "" - -#. Description -#: ../data/templates/Ubuntu.info.in:375 -msgid "Cdrom with Ubuntu 6.10 'Edgy Eft'" -msgstr "" - -#. Description -#: ../data/templates/Ubuntu.info.in:409 -msgid "Ubuntu 6.06 LTS 'Dapper Drake'" -msgstr "" - -#. CompDescriptionLong -#: ../data/templates/Ubuntu.info.in:412 -msgid "Canonical-supported Open Source software" -msgstr "" - -#. CompDescription -#: ../data/templates/Ubuntu.info.in:414 -msgid "Community-maintained (universe)" -msgstr "" - -#. CompDescriptionLong -#: ../data/templates/Ubuntu.info.in:415 -msgid "Community-maintained Open Source software" -msgstr "" - -#. CompDescription -#: ../data/templates/Ubuntu.info.in:417 -msgid "Non-free drivers" -msgstr "" - -#. CompDescriptionLong -#: ../data/templates/Ubuntu.info.in:418 -msgid "Proprietary drivers for devices" -msgstr "" - -#. CompDescription -#: ../data/templates/Ubuntu.info.in:420 -msgid "Restricted software (Multiverse)" -msgstr "" - -#. CompDescriptionLong -#: ../data/templates/Ubuntu.info.in:421 -msgid "Software restricted by copyright or legal issues" -msgstr "" - -#. Description -#: ../data/templates/Ubuntu.info.in:427 -msgid "Cdrom with Ubuntu 6.06 LTS 'Dapper Drake'" -msgstr "" - -#. Description -#: ../data/templates/Ubuntu.info.in:439 -msgid "Important security updates" -msgstr "" - -#. Description -#: ../data/templates/Ubuntu.info.in:444 -msgid "Recommended updates" -msgstr "" - -#. Description -#: ../data/templates/Ubuntu.info.in:449 -msgid "Pre-released updates" -msgstr "" - -#. Description -#: ../data/templates/Ubuntu.info.in:454 -msgid "Unsupported updates" -msgstr "" - -#. Description -#: ../data/templates/Ubuntu.info.in:461 -msgid "Ubuntu 5.10 'Breezy Badger'" -msgstr "" - -#. Description -#: ../data/templates/Ubuntu.info.in:475 -msgid "Cdrom with Ubuntu 5.10 'Breezy Badger'" -msgstr "" - -#. Description -#: ../data/templates/Ubuntu.info.in:487 -msgid "Ubuntu 5.10 Security Updates" -msgstr "" - -#. Description -#: ../data/templates/Ubuntu.info.in:492 -msgid "Ubuntu 5.10 Updates" -msgstr "" - -#. Description -#: ../data/templates/Ubuntu.info.in:497 -msgid "Ubuntu 5.10 Backports" -msgstr "" - -#. Description -#: ../data/templates/Ubuntu.info.in:504 -msgid "Ubuntu 5.04 'Hoary Hedgehog'" -msgstr "" - -#. Description -#: ../data/templates/Ubuntu.info.in:518 -msgid "Cdrom with Ubuntu 5.04 'Hoary Hedgehog'" -msgstr "" - -#. CompDescription -#: ../data/templates/Ubuntu.info.in:521 ../data/templates/Debian.info.in:148 -msgid "Officially supported" -msgstr "" - -#. Description -#: ../data/templates/Ubuntu.info.in:530 -msgid "Ubuntu 5.04 Security Updates" -msgstr "" - -#. Description -#: ../data/templates/Ubuntu.info.in:535 -msgid "Ubuntu 5.04 Updates" -msgstr "" - -#. Description -#: ../data/templates/Ubuntu.info.in:540 -msgid "Ubuntu 5.04 Backports" -msgstr "" - -#. Description -#: ../data/templates/Ubuntu.info.in:546 -msgid "Ubuntu 4.10 'Warty Warthog'" -msgstr "" - -#. CompDescription -#: ../data/templates/Ubuntu.info.in:552 -msgid "Community-maintained (Universe)" -msgstr "" - -#. CompDescription -#: ../data/templates/Ubuntu.info.in:554 -msgid "Non-free (Multiverse)" -msgstr "" - -#. Description -#: ../data/templates/Ubuntu.info.in:560 -msgid "Cdrom with Ubuntu 4.10 'Warty Warthog'" -msgstr "" - -#. CompDescription -#: ../data/templates/Ubuntu.info.in:563 -msgid "No longer officially supported" -msgstr "" - -#. CompDescription -#: ../data/templates/Ubuntu.info.in:565 -msgid "Restricted copyright" -msgstr "" - -#. Description -#: ../data/templates/Ubuntu.info.in:572 -msgid "Ubuntu 4.10 Security Updates" -msgstr "" - -#. Description -#: ../data/templates/Ubuntu.info.in:577 -msgid "Ubuntu 4.10 Updates" -msgstr "" - -#. Description -#: ../data/templates/Ubuntu.info.in:582 -msgid "Ubuntu 4.10 Backports" -msgstr "" - -#. ChangelogURI -#: ../data/templates/Debian.info.in.h:4 -#, no-c-format -msgid "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" -msgstr "" - -#. Description -#: ../data/templates/Debian.info.in:8 -msgid "Debian 6.0 'Squeeze' " -msgstr "" - -#. Description -#: ../data/templates/Debian.info.in:33 -msgid "Debian 5.0 'Lenny' " -msgstr "" - -#. Description -#: ../data/templates/Debian.info.in:58 -msgid "Debian 4.0 'Etch'" -msgstr "" - -#. Description -#: ../data/templates/Debian.info.in:83 -msgid "Debian 3.1 'Sarge'" -msgstr "" - -#. Description -#: ../data/templates/Debian.info.in:94 -msgid "Proposed updates" -msgstr "" - -#. Description -#: ../data/templates/Debian.info.in:101 -msgid "Security updates" -msgstr "" - -#. Description -#: ../data/templates/Debian.info.in:108 -msgid "Debian current stable release" -msgstr "" - -#. Description -#: ../data/templates/Debian.info.in:121 -msgid "Debian testing" -msgstr "" - -#. Description -#: ../data/templates/Debian.info.in:146 -msgid "Debian 'Sid' (unstable)" -msgstr "" - -#. CompDescription -#: ../data/templates/Debian.info.in:150 -msgid "DFSG-compatible Software with Non-Free Dependencies" -msgstr "" - -#. CompDescription -#: ../data/templates/Debian.info.in:152 -msgid "Non-DFSG-compatible Software" -msgstr "" - -#. TRANSLATORS: %s is a country -#: ../aptsources/distro.py:208 ../aptsources/distro.py:423 -#, python-format -msgid "Server for %s" -msgstr "" - -#. More than one server is used. Since we don't handle this case -#. in the user interface we set "custom servers" to true and -#. append a list of all used servers -#: ../aptsources/distro.py:226 ../aptsources/distro.py:232 -#: ../aptsources/distro.py:248 -msgid "Main server" -msgstr "" - -#: ../aptsources/distro.py:252 -msgid "Custom servers" -msgstr "" - -#: ../apt/progress/gtk2.py:259 -#, python-format -msgid "Downloading file %(current)li of %(total)li with %(speed)s/s" -msgstr "" - -#: ../apt/progress/gtk2.py:265 -#, python-format -msgid "Downloading file %(current)li of %(total)li" -msgstr "" - -#. Setup some child widgets -#: ../apt/progress/gtk2.py:285 -#, fuzzy -msgid "Details" -msgstr "روز" - -#: ../apt/progress/gtk2.py:367 -msgid "Starting..." -msgstr "" - -#: ../apt/progress/gtk2.py:373 -msgid "Complete" -msgstr "" - -#: ../apt/package.py:301 -#, python-format -msgid "Invalid unicode in description for '%s' (%s). Please report." -msgstr "" - -#: ../apt/package.py:937 ../apt/package.py:1043 -msgid "The list of changes is not available" -msgstr "" - -#: ../apt/package.py:1047 -#, python-format -msgid "" -"The list of changes is not available yet.\n" -"\n" -"Please use http://launchpad.net/ubuntu/+source/%s/%s/+changelog\n" -"until the changes become available or try again later." -msgstr "" - -#: ../apt/package.py:1053 -msgid "" -"Failed to download the list of changes. \n" -"Please check your Internet connection." -msgstr "" - -#: ../apt/debfile.py:56 -#, python-format -msgid "This is not a valid DEB archive, missing '%s' member" -msgstr "" - -#: ../apt/debfile.py:81 -#, python-format -msgid "List of files for '%s'could not be read" -msgstr "" - -#: ../apt/debfile.py:149 -#, python-format -msgid "Dependency is not satisfiable: %s\n" -msgstr "" - -#: ../apt/debfile.py:173 -#, python-format -msgid "Conflicts with the installed package '%s'" -msgstr "" - -#: ../apt/debfile.py:319 -#, python-format -msgid "Wrong architecture '%s'" -msgstr "" - -#. the deb is older than the installed -#: ../apt/debfile.py:325 -msgid "A later version is already installed" -msgstr "" - -#: ../apt/debfile.py:345 -msgid "Failed to satisfy all dependencies (broken cache)" -msgstr "" - -#: ../apt/debfile.py:376 -#, python-format -msgid "Cannot install '%s'" -msgstr "" - -#: ../apt/debfile.py:484 -#, python-format -msgid "Install Build-Dependencies for source package '%s' that builds %s\n" -msgstr "" - -#: ../apt/debfile.py:494 -msgid "An essential package would be removed" -msgstr "" - -#: ../apt/progress/text.py:81 -#, python-format -msgid "%c%s... Done" -msgstr "" - -#: ../apt/progress/text.py:118 -msgid "Hit " -msgstr "" - -#: ../apt/progress/text.py:126 -msgid "Ign " -msgstr "" - -#: ../apt/progress/text.py:128 -msgid "Err " -msgstr "" - -#: ../apt/progress/text.py:138 -msgid "Get:" -msgstr "" - -#: ../apt/progress/text.py:198 -msgid " [Working]" -msgstr "" - -#: ../apt/progress/text.py:208 -#, python-format -msgid "" -"Media change: please insert the disc labeled\n" -" '%s'\n" -"in the drive '%s' and press enter\n" -msgstr "" - -#. Trick for getting a translation from apt -#: ../apt/progress/text.py:216 -#, python-format -msgid "Fetched %sB in %s (%sB/s)\n" -msgstr "" - -#: ../apt/progress/text.py:229 -msgid "Please provide a name for this Disc, such as 'Debian 2.1r1 Disk 1'" -msgstr "" - -#: ../apt/progress/text.py:241 -msgid "Please insert a Disc in the drive and press enter" -msgstr "" - -#: ../apt/cache.py:96 -msgid "Building data structures" -msgstr "" -- cgit v1.2.3 From fcfcf06060f9043369d346ce1781b2c9a6dfa93c Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Fri, 27 May 2011 16:10:32 +0200 Subject: debian/source/format: Add, set it to "3.0 (native)" --- debian/changelog | 1 + debian/source/format | 1 + 2 files changed, 2 insertions(+) create mode 100644 debian/source/format diff --git a/debian/changelog b/debian/changelog index e0f1dd72..1dfc3300 100644 --- a/debian/changelog +++ b/debian/changelog @@ -7,6 +7,7 @@ python-apt (0.8.0~exp5) UNRELEASED; urgency=low * Fix Lintian overrides * Fix spelling errors reported by Lintian (sep[a->e]rated, overrid[d]en) * po/urd.po: Remove, ur.po is the correct file + * debian/source/format: Add, set it to "3.0 (native)" [ Tshepang Lekhonkhobe ] * Fix get_changelog in Python 3 (Closes: #626532) diff --git a/debian/source/format b/debian/source/format new file mode 100644 index 00000000..89ae9db8 --- /dev/null +++ b/debian/source/format @@ -0,0 +1 @@ +3.0 (native) -- cgit v1.2.3 From c736d5c9290a2ffdb8802a4ac62e521cf1218b54 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Fri, 27 May 2011 16:13:03 +0200 Subject: Upload to unstable --- debian/changelog | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/debian/changelog b/debian/changelog index 1dfc3300..2270c43a 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,4 +1,6 @@ -python-apt (0.8.0~exp5) UNRELEASED; urgency=low +python-apt (0.8.0) unstable; urgency=low + + * Upload to unstable [ Julian Andres Klode ] * Increase Breaks for update-notifier to 0.99.3debian9 @@ -18,7 +20,7 @@ python-apt (0.8.0~exp5) UNRELEASED; urgency=low [ Translation updates ] * Esperanto (Closes: #626430) - -- Julian Andres Klode Thu, 26 May 2011 18:01:57 +0200 + -- Julian Andres Klode Fri, 27 May 2011 16:12:46 +0200 python-apt (0.8.0~exp4) experimental; urgency=low -- cgit v1.2.3 From 20cc87295aef3b04db0cb060d65c21cfce650d19 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Tue, 7 Jun 2011 14:04:19 +0200 Subject: Breaks: debsecan (<< 0.4.15) [not only << 0.4.14] (Closes: #629512) --- debian/changelog | 6 ++++++ debian/control | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/debian/changelog b/debian/changelog index 2270c43a..6cd9a042 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +python-apt (0.8.1) UNRELEASED; urgency=low + + * Breaks: debsecan (<< 0.4.15) [not only << 0.4.14] (Closes: #629512) + + -- Julian Andres Klode Tue, 07 Jun 2011 14:00:22 +0200 + python-apt (0.8.0) unstable; urgency=low * Upload to unstable diff --git a/debian/control b/debian/control index 98506aec..01e8884e 100644 --- a/debian/control +++ b/debian/control @@ -38,7 +38,7 @@ Breaks: packagekit-backend-apt (<= 0.4.8-0ubuntu4), bcfg2 (<< 1.0.1), bzr-builddeb (<< 2.4), debpartial-mirror (<< 0.2.98), - debsecan (<< 0.4.14), + debsecan (<< 0.4.15), gdebi (<< 0.6.1), germinate (<< 1.21), gnome-codec-install (<< 0.4.5), -- cgit v1.2.3 From dad23d3d0cf1b15302c8fe1845a93f3d6de54ed7 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Wed, 13 Jul 2011 14:14:43 +0200 Subject: * python/arfile.cc: - use APT::Configuration::getCompressionTypes() instead of duplicating the supported methods here * tests/test_debfile.py: - add test for raise on unknown data.tar.xxx --- debian/changelog | 8 +++++ python/arfile.cc | 52 +++++++++++++++++++------------ tests/data/test_debs/data-tar-broken.deb | Bin 0 -> 626 bytes tests/test_debfile.py | 6 ++++ 4 files changed, 46 insertions(+), 20 deletions(-) create mode 100644 tests/data/test_debs/data-tar-broken.deb diff --git a/debian/changelog b/debian/changelog index 6cd9a042..a25167d5 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,6 +1,14 @@ python-apt (0.8.1) UNRELEASED; urgency=low + [ Julian Andres Klode ] * Breaks: debsecan (<< 0.4.15) [not only << 0.4.14] (Closes: #629512) + + [ Michael Vogt ] + * python/arfile.cc: + - use APT::Configuration::getCompressionTypes() instead of duplicating + the supported methods here + * tests/test_debfile.py: + - add test for raise on unknown data.tar.xxx -- Julian Andres Klode Tue, 07 Jun 2011 14:00:22 +0200 diff --git a/python/arfile.cc b/python/arfile.cc index c3aa74d1..c31ea35e 100644 --- a/python/arfile.cc +++ b/python/arfile.cc @@ -25,6 +25,8 @@ #include #include #include +#include +#include #include #include @@ -477,8 +479,8 @@ PyTypeObject PyArArchive_Type = { * Representation of a Debian package. * * This does not resemble debDebFile in apt-inst, but instead is a subclass - * of ArFile which adds properties for the control.tar.{xz,lzma,bz2,gz} and - * data.tar.{xz,lzma,bz2,gz} members which return TarFile objects. It also adds + * of ArFile which adds properties for the control.tar.$compression and + * data.tar.$compression members which return TarFile objects. It also adds * a descriptor 'version' which returns the content of 'debian-binary'. * * We are using it this way as it seems more natural to represent this special @@ -532,21 +534,28 @@ static PyObject *debfile_new(PyTypeObject *type, PyObject *args, PyObject *kwds) return PyErr_Format(PyExc_SystemError, "No debian archive, missing %s", "control.tar.gz"); - self->data = _gettar(self, self->Object->FindMember("data.tar.gz"), - "gzip"); - if (!self->data) - self->data = _gettar(self, self->Object->FindMember("data.tar.bz2"), - "bzip2"); - if (!self->data) - self->data = _gettar(self, self->Object->FindMember("data.tar.lzma"), - "lzma"); - if (!self->data) - self->data = _gettar(self, self->Object->FindMember("data.tar.xz"), - "xz"); - if (!self->data) - return PyErr_Format(PyExc_SystemError, "No debian archive, missing %s", - "data.tar.gz or data.tar.bz2 or data.tar.lzma " - "or data.tar.xz"); + // try all compression types + std::vector types = APT::Configuration::getCompressionTypes(); + for (std::vector::const_iterator t = types.begin(); + t != types.end(); ++t) + { + string member = string("data.tar.").append(*t); + string comp = _config->Find(string("Acquire::CompressionTypes::").append(*t)); + self->data = _gettar(self, self->Object->FindMember(member.c_str()), + comp.c_str()); + if (self->data) + break; + } + // no data found, we need to + if (!self->data) { + string error; + for (std::vector::const_iterator t = types.begin(); + t != types.end(); ++t) + error.append(*t + ","); + return PyErr_Format(PyExc_SystemError, + "No debian archive, missing data.tar.{%s}", + error.c_str()); + } const ARArchive::Member *member = self->Object->FindMember("debian-binary"); @@ -590,7 +599,9 @@ static PyGetSetDef debfile_getset[] = { {"control",(getter)debfile_get_control,0, "The TarFile object associated with the control.tar.gz member."}, {"data",(getter)debfile_get_data,0, - "The TarFile object associated with the data.tar.{gz,bz2,lzma,xz}) member."}, + "The TarFile object associated with the data.tar.$compression member. " + "All apt compression methods are supported. " + }, {"debian_binary",(getter)debfile_get_debian_binary,0, "The package version, as contained in debian-binary."}, {NULL} @@ -604,8 +615,9 @@ static const char *debfile_doc = "specifying a file descriptor (returned by e.g. os.open()).\n" "The recommended way of using it is to pass in the path to the file.\n\n" "It differs from ArArchive by providing the members 'control', 'data'\n" - "and 'version' for accessing the control.tar.gz, data.tar.{gz,bz2,lzma,xz},\n" - "and debian-binary members in the archive."; + "and 'version' for accessing the control.tar.gz, data.tar.$compression \n" + "(all apt compression methods are supported), and debian-binary members \n" + "in the archive."; PyTypeObject PyDebFile_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) diff --git a/tests/data/test_debs/data-tar-broken.deb b/tests/data/test_debs/data-tar-broken.deb new file mode 100644 index 00000000..4fd42e0f Binary files /dev/null and b/tests/data/test_debs/data-tar-broken.deb differ diff --git a/tests/test_debfile.py b/tests/test_debfile.py index 5f6d1aa2..86a51cb9 100644 --- a/tests/test_debfile.py +++ b/tests/test_debfile.py @@ -119,6 +119,12 @@ Description: testpackage for gdebi - contains usr/bin/binary for file reading deb = apt.debfile.DebPackage("./data/test_debs/data-tar-xz.deb") self.assertEqual(deb.filelist, ["./", "usr/", "usr/bin/"]) + def test_no_supported_data_tar(self): + # ensure that a unknown data.tar.xxx raises a exception + with self.assertRaises(SystemError): + deb = apt.debfile.DebPackage("./data/test_debs/data-tar-broken.deb") + + if __name__ == "__main__": #logging.basicConfig(level=logging.DEBUG) -- cgit v1.2.3 From c8bd732d5cb8be16ae48f8a72a4ed8a266b4ce36 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Fri, 29 Jul 2011 19:17:06 +0200 Subject: * tests/test_aptsources_ports.py, tests/test_aptsources.py: - use tmpdir during the tests to fix test failure with apt from experimental --- debian/changelog | 3 +++ tests/test_aptsources.py | 3 ++- tests/test_aptsources_ports.py | 4 ++-- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/debian/changelog b/debian/changelog index a25167d5..193f4c58 100644 --- a/debian/changelog +++ b/debian/changelog @@ -9,6 +9,9 @@ python-apt (0.8.1) UNRELEASED; urgency=low the supported methods here * tests/test_debfile.py: - add test for raise on unknown data.tar.xxx + * tests/test_aptsources_ports.py, tests/test_aptsources.py: + - use tmpdir during the tests to fix test failure with apt from + experimental -- Julian Andres Klode Tue, 07 Jun 2011 14:00:22 +0200 diff --git a/tests/test_aptsources.py b/tests/test_aptsources.py index 1597674e..193d3806 100644 --- a/tests/test_aptsources.py +++ b/tests/test_aptsources.py @@ -3,6 +3,7 @@ import unittest import os import copy +import tempfile import apt_pkg import aptsources.sourceslist @@ -17,7 +18,7 @@ class TestAptSources(unittest.TestCase): if apt_pkg.config["APT::Architecture"] not in ('i386', 'amd64'): apt_pkg.config.set("APT::Architecture", "i386") apt_pkg.config.set("Dir::Etc", os.getcwd()) - apt_pkg.config.set("Dir::Etc::sourceparts", "/xxx") + apt_pkg.config.set("Dir::Etc::sourceparts", tempfile.mkdtemp()) if os.path.exists("./build/data/templates"): self.templates = os.path.abspath("./build/data/templates") elif os.path.exists("../build/data/templates"): diff --git a/tests/test_aptsources_ports.py b/tests/test_aptsources_ports.py index 991b532a..67c21b9c 100644 --- a/tests/test_aptsources_ports.py +++ b/tests/test_aptsources_ports.py @@ -1,7 +1,7 @@ #!/usr/bin/env python import os import unittest - +import tempfile import apt_pkg import aptsources.sourceslist @@ -17,7 +17,7 @@ class TestAptSourcesPorts(unittest.TestCase): apt_pkg.config.set("APT::Architecture", "powerpc") apt_pkg.config.set("Dir::Etc", os.path.abspath("data/aptsources_ports")) - apt_pkg.config.set("Dir::Etc::sourceparts", "/xxx") + apt_pkg.config.set("Dir::Etc::sourceparts", tempfile.mkdtemp()) if os.path.exists("../build/data/templates"): self.templates = os.path.abspath("../build/data/templates") else: -- cgit v1.2.3