From 3b4330920da718d2dbb2a4a94577c07eaa58a8c5 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Thu, 10 Jun 2010 11:55:18 +0200 Subject: * apt/utils.py: - fix end date calculation for releases in june --- apt/utils.py | 5 +++++ debian/changelog | 7 +++++++ tests/test_utils.py | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 68 insertions(+) create mode 100644 tests/test_utils.py diff --git a/apt/utils.py b/apt/utils.py index 80ba6d65..8fc69215 100644 --- a/apt/utils.py +++ b/apt/utils.py @@ -28,11 +28,16 @@ def get_maintenance_end_date(release_date, m_months): ends. Needs the data of the release and the number of months that its is supported as input """ + # calc end date years = m_months / 12 months = m_months % 12 support_end_year = (release_date.year + years + (release_date.month + months)/12) support_end_month = (release_date.month + months) % 12 + # special case: this happens when e.g. doing 2010-06 + 18 months + if support_end_month == 0: + support_end_month = 12 + support_end_year -= 1 return (support_end_year, support_end_month) diff --git a/debian/changelog b/debian/changelog index dde80a4f..9fe79188 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,10 @@ +python-apt (0.7.95ubuntu2) maverick; urgency=low + + * apt/utils.py: + - fix end date calculation for releases in june + + -- Michael Vogt Thu, 10 Jun 2010 11:50:21 +0200 + python-apt (0.7.95ubuntu1) maverick; urgency=low * merge from debian bzr, remaining changes: diff --git a/tests/test_utils.py b/tests/test_utils.py new file mode 100644 index 00000000..19dd977d --- /dev/null +++ b/tests/test_utils.py @@ -0,0 +1,56 @@ +#!/usr/bin/python +# +# Copyright (C) 2010 Michael Vogt +# +# 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. + +import sys +sys.path.insert(0, "..") +import apt_pkg +import apt.utils +import datetime +import unittest + +class TestUtils(unittest.TestCase): + + + def test_maintenance_time(self): + from apt.utils import get_maintenance_end_date + months_of_support = 18 + # test historic releases, jaunty + release_date = datetime.datetime(2009, 04, 23) + (end_year, end_month) = get_maintenance_end_date(release_date, months_of_support) + self.assertEqual(end_year, 2010) + self.assertEqual(end_month, 10) + # test historic releases, karmic + release_date = datetime.datetime(2009, 10, 29) + (end_year, end_month) = get_maintenance_end_date(release_date, months_of_support) + self.assertEqual(end_year, 2011) + self.assertEqual(end_month, 04) + # test maverick + release_date = datetime.datetime(2010, 10, 10) + (end_year, end_month) = get_maintenance_end_date(release_date, months_of_support) + self.assertEqual(end_year, 2012) + self.assertEqual(end_month, 04) + + # test with modulo zero + release_date = datetime.datetime(2010, 06, 10) + (end_year, end_month) = get_maintenance_end_date(release_date, months_of_support) + self.assertEqual(end_year, 2011) + self.assertEqual(end_month, 12) + + # test dapper + months_of_support = 60 + release_date = datetime.datetime(2008, 04, 24) + (end_year, end_month) = get_maintenance_end_date(release_date, months_of_support) + self.assertEqual(end_year, 2013) + self.assertEqual(end_month, 04) + + # what datetime says + #d = datetime.timedelta(18*30) + #print "end date: ", release_date + d + +if __name__ == "__main__": + unittest.main() -- cgit v1.2.3 From 18e3642b04ca7b6c1400a699606727a511bfbec3 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Fri, 30 Jul 2010 12:47:07 +0200 Subject: rebuild against lastest libapt --- debian/changelog | 6 ++++++ debian/control | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/debian/changelog b/debian/changelog index 3083d377..08922d2d 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +python-apt (0.7.96.1ubuntu3) maverick; urgency=low + + * rebuild against lastest libapt + + -- Michael Vogt Thu, 29 Jul 2010 12:23:27 +0200 + python-apt (0.7.96.1ubuntu2) maverick; urgency=low [ Michael Vogt ] diff --git a/debian/control b/debian/control index 65f72367..77a87bad 100644 --- a/debian/control +++ b/debian/control @@ -8,7 +8,7 @@ Standards-Version: 3.8.4 XS-Python-Version: all Build-Depends: apt-utils, debhelper (>= 7.3.5), - libapt-pkg-dev (>= 0.7.22~), + libapt-pkg-dev (>= 0.7.26~exp11), python-all-dev, python-all-dbg, python-central (>= 0.5), -- cgit v1.2.3 From 28ad58115b7a113da5797f42d8ec154f105777a5 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Thu, 5 Aug 2010 23:39:50 +0200 Subject: releasing version 0.7.96.1ubuntu4 --- debian/changelog | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/debian/changelog b/debian/changelog index de4e8259..6f3d2326 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,9 +1,9 @@ -python-apt (0.7.96.1ubuntu4) UNRELEASED; urgency=low +python-apt (0.7.96.1ubuntu4) maverick; urgency=low * apt/debfile.py: - fix crash in DscFile handling and add regression test - -- Michael Vogt Thu, 05 Aug 2010 13:28:58 +0200 + -- Michael Vogt Thu, 05 Aug 2010 23:36:53 +0200 python-apt (0.7.96.1ubuntu3) maverick; urgency=low -- cgit v1.2.3 From d16f52e874378f1ebf1fe0b2491585b46bfe2e55 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Fri, 27 Aug 2010 11:18:44 +0200 Subject: * apt/debfile.py: - add missing init for _installed_conflicts (LP: #618597) --- apt/debfile.py | 1 + debian/changelog | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/apt/debfile.py b/apt/debfile.py index 33f0f04d..9bf27da3 100644 --- a/apt/debfile.py +++ b/apt/debfile.py @@ -598,6 +598,7 @@ class DscSrcPackage(DebPackage): self.filename = filename self._depends = [] self._conflicts = [] + self._installed_conflicts = set() self.pkgname = "" self.binaries = [] if self.filename is not None: diff --git a/debian/changelog b/debian/changelog index af215801..1fb41d07 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,10 @@ +python-apt (0.7.96.1ubuntu6) maverick; urgency=low + + * apt/debfile.py: + - add missing init for _installed_conflicts (LP: #618597) + + -- Michael Vogt Fri, 27 Aug 2010 11:18:13 +0200 + python-apt (0.7.96.1ubuntu5) maverick; urgency=low * python/acquire.cc: -- cgit v1.2.3 From 4b91eac101b839c188835aa0e8d5284e32c6bdc1 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Tue, 31 Aug 2010 15:31:26 +0200 Subject: * cherry pick debfile fix from lp:~mvo/python-apt/mvo (402..405): * apt/debfile.py: - fix error when reading binary content and add regresion test --- apt/debfile.py | 4 ++-- debian/changelog | 8 ++++++++ tests/data/test_debs/gdebi-test11.deb | Bin 0 -> 634 bytes tests/data/test_debs/gdebi-test12.deb | Bin 0 -> 966 bytes tests/test_debfile.py | 13 +++++++++++++ 5 files changed, 23 insertions(+), 2 deletions(-) create mode 100644 tests/data/test_debs/gdebi-test11.deb create mode 100644 tests/data/test_debs/gdebi-test12.deb diff --git a/apt/debfile.py b/apt/debfile.py index 9bf27da3..f4a31379 100644 --- a/apt/debfile.py +++ b/apt/debfile.py @@ -512,7 +512,7 @@ class DebPackage(object): return sorted(content) @staticmethod - def to_hex(self, in_data): + def to_hex(in_data): hex = "" for (i, c) in enumerate(in_data): if i%80 == 0: @@ -521,7 +521,7 @@ class DebPackage(object): return hex @staticmethod - def to_strish(self, in_data): + def to_strish(in_data): s = "" for c in in_data: if ord(c) < 10 or ord(c) > 127: diff --git a/debian/changelog b/debian/changelog index 1fb41d07..e926c124 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,11 @@ +python-apt (0.7.96.1ubuntu7) UNRELEASED; urgency=low + + * cherry pick debfile fix from lp:~mvo/python-apt/mvo (402..405): + * apt/debfile.py: + - fix error when reading binary content and add regresion test + + -- Michael Vogt Tue, 31 Aug 2010 15:21:08 +0200 + python-apt (0.7.96.1ubuntu6) maverick; urgency=low * apt/debfile.py: diff --git a/tests/data/test_debs/gdebi-test11.deb b/tests/data/test_debs/gdebi-test11.deb new file mode 100644 index 00000000..af9b441f Binary files /dev/null and b/tests/data/test_debs/gdebi-test11.deb differ diff --git a/tests/data/test_debs/gdebi-test12.deb b/tests/data/test_debs/gdebi-test12.deb new file mode 100644 index 00000000..36544cc7 Binary files /dev/null and b/tests/data/test_debs/gdebi-test12.deb differ diff --git a/tests/test_debfile.py b/tests/test_debfile.py index 5874dfc4..42cda6f6 100644 --- a/tests/test_debfile.py +++ b/tests/test_debfile.py @@ -77,6 +77,19 @@ class TestDebfilee(unittest.TestCase): "Unexpected result for package '%s' (got %s wanted %s)\n%s" % ( filename, res, expected_res, deb._failure_string)) + def testContent(self): + # normal + deb = apt.debfile.DebPackage(cache=self.cache) + deb.open(os.path.join("data", "test_debs", "gdebi-test11.deb")) + self.assertEqual('#!/bin/sh\necho "test"\n', + deb.data_content("usr/bin/test")) + # binary + deb = apt.debfile.DebPackage(cache=self.cache) + deb.open(os.path.join("data", "test_debs", "gdebi-test12.deb")) + content = deb.data_content("usr/bin/binary") + self.assertTrue(content.startswith("Automatically converted to printable ascii:\n\x7fELF ")) + + if __name__ == "__main__": #logging.basicConfig(level=logging.DEBUG) unittest.main() -- cgit v1.2.3 From a4053adcbc23d909d09e060f29acd39e7ec1e03f Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Thu, 2 Sep 2010 10:56:04 +0200 Subject: releasing version 0.7.96.1ubuntu7 --- debian/changelog | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/debian/changelog b/debian/changelog index e926c124..6edf0a61 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,10 +1,10 @@ -python-apt (0.7.96.1ubuntu7) UNRELEASED; urgency=low +python-apt (0.7.96.1ubuntu7) maverick; urgency=low * cherry pick debfile fix from lp:~mvo/python-apt/mvo (402..405): * apt/debfile.py: - fix error when reading binary content and add regresion test - -- Michael Vogt Tue, 31 Aug 2010 15:21:08 +0200 + -- Michael Vogt Thu, 02 Sep 2010 10:53:46 +0200 python-apt (0.7.96.1ubuntu6) maverick; urgency=low -- cgit v1.2.3 From 92246a6af0ef54b3cb49a7448ad972e4f1b2186c Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Fri, 3 Sep 2010 18:34:09 +0200 Subject: * debian/control: - add missing build-depends on python-debian (needed to run the tests for apt.debfile.DebPackage() --- debian/changelog | 8 ++++++++ debian/control | 3 ++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/debian/changelog b/debian/changelog index 6edf0a61..dcd87b64 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,11 @@ +python-apt (0.7.96.1ubuntu8) maverick; urgency=low + + * debian/control: + - add missing build-depends on python-debian (needed to run the + tests for apt.debfile.DebPackage() + + -- Michael Vogt Fri, 03 Sep 2010 18:33:50 +0200 + python-apt (0.7.96.1ubuntu7) maverick; urgency=low * cherry pick debfile fix from lp:~mvo/python-apt/mvo (402..405): diff --git a/debian/control b/debian/control index 77a87bad..5015022c 100644 --- a/debian/control +++ b/debian/control @@ -13,7 +13,8 @@ Build-Depends: apt-utils, python-all-dbg, python-central (>= 0.5), python-distutils-extra (>= 2.0), - python-sphinx (>= 0.5) + python-sphinx (>= 0.5), + python-debian Vcs-Bzr: http://bzr.debian.org/apt/python-apt/debian-sid Vcs-Browser: http://bzr.debian.org/loggerhead/apt/python-apt/debian-sid/changes -- cgit v1.2.3 From bc301a8f07e50c7a14973b10fa4cb95f7a2beff2 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Tue, 7 Sep 2010 11:56:17 +0200 Subject: * apt/debfile: - don't fail if we conflict with the pkgs we are reinstalling --- apt/debfile.py | 3 ++- debian/changelog | 8 ++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/apt/debfile.py b/apt/debfile.py index f4a31379..d8159546 100644 --- a/apt/debfile.py +++ b/apt/debfile.py @@ -347,7 +347,8 @@ class DebPackage(object): 'targetver' : c_or.target_ver } self._cache.op_progress.done() return False - if c_or.target_pkg.name in provides: + if (c_or.target_pkg.name in provides and + self.pkgname != pkg.name): self._dbg(2, "would break (conflicts) %s" % provides) self._failure_string += _("Breaks existing package '%(pkgname)s' that conflict: '%(targetpkg)s'. But the '%(debfile)s' provides it via: '%(provides)s'") % { 'provides' : ",".join(provides), diff --git a/debian/changelog b/debian/changelog index dcd87b64..44be9f23 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,11 @@ +python-apt (0.7.97.2) UNRELEASED; urgency=low + + [ Kiwinote ] + * apt/debfile: + - don't fail if we conflict with the pkgs we are reinstalling + + -- Michael Vogt Fri, 27 Aug 2010 11:22:23 +0200 + python-apt (0.7.96.1ubuntu8) maverick; urgency=low * debian/control: -- cgit v1.2.3 From a8e7d5e6931e56fbe67f5dd33c5da0705468fe0b Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Tue, 7 Sep 2010 18:23:36 +0200 Subject: releasing version 0.7.96.1ubuntu9 --- debian/changelog | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/debian/changelog b/debian/changelog index afd31ff5..4eb436ff 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,4 +1,4 @@ -python-apt (0.7.96ubuntu9) UNRELEASED; urgency=low +python-apt (0.7.96.1ubuntu9) maverick; urgency=low [ Kiwinote ] * apt/debfile: @@ -17,7 +17,7 @@ python-apt (0.7.96ubuntu9) UNRELEASED; urgency=low - add missing build-depends on python-debian (needed to run the tests for apt.debfile.DebPackage() - -- Michael Vogt Tue, 07 Sep 2010 13:36:18 +0200 + -- Michael Vogt Tue, 07 Sep 2010 13:47:03 +0200 python-apt (0.7.96.1ubuntu8) maverick; urgency=low -- cgit v1.2.3 From d806cac23d66b55f4fc2e5e9e58ab0859301b595 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Mon, 13 Sep 2010 11:32:44 +0200 Subject: releasing version 0.7.96.1ubuntu10 --- debian/changelog | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/debian/changelog b/debian/changelog index d10d5534..b56f1534 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,4 +1,4 @@ -python-apt (0.7.96.1ubuntu10) UNRELEASED; urgency=low +python-apt (0.7.96.1ubuntu10) maverick; urgency=low * data/templates/Ubuntu.info.in: - add extras.ubuntu.com and archvie.canonical.com to the @@ -8,7 +8,7 @@ python-apt (0.7.96.1ubuntu10) UNRELEASED; urgency=low * python/tag.cc: - accept "byte" type as well in TacSecNew (for py3) - -- Michael Vogt Mon, 13 Sep 2010 11:09:27 +0200 + -- Michael Vogt Mon, 13 Sep 2010 11:28:24 +0200 python-apt (0.7.96.1ubuntu9) maverick; urgency=low -- cgit v1.2.3 From ba81885de8c079e096d19e301c972426fc3e7366 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Mon, 20 Sep 2010 10:46:04 +0200 Subject: releasing version 0.7.96.1ubuntu11 --- debian/changelog | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/debian/changelog b/debian/changelog index 37b5cbc4..f847f345 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,9 +1,9 @@ -python-apt (0.7.96.1ubuntu11) unstable; urgency=low +python-apt (0.7.96.1ubuntu11) maverick; urgency=low - * fix return type of DebSize() and UsrSize(), thanks to - Sebastian Heinlein, LP: #642936 + * Fix return type of DebSize() and UsrSize(), its long long, + not float. Thanks to Sebastian Heinlein, LP: #642936 - -- Michael Vogt Mon, 20 Sep 2010 10:34:33 +0200 + -- Michael Vogt Mon, 20 Sep 2010 10:43:47 +0200 python-apt (0.7.96.1ubuntu10) maverick; urgency=low -- cgit v1.2.3 From 8fa5dba770ce8f77b266720e64f57d911e557f17 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Tue, 28 Sep 2010 16:27:57 +0200 Subject: releasing version 0.7.96.1ubuntu12 --- debian/changelog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/changelog b/debian/changelog index 010c30c1..beb93dd2 100644 --- a/debian/changelog +++ b/debian/changelog @@ -9,7 +9,7 @@ python-apt (0.7.96.1ubuntu12) maverick; urgency=low because PyString_FromFormat() does not support %llu in python versions below 2.7 - -- Michael Vogt Fri, 24 Sep 2010 21:22:38 +0200 + -- Michael Vogt Tue, 28 Sep 2010 16:01:21 +0200 python-apt (0.7.96.1ubuntu11) maverick; urgency=low -- cgit v1.2.3 From d9deeabe21f828ae4301c4aab5073f775f954e25 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Mon, 18 Oct 2010 10:43:22 +0200 Subject: * data/templates/Ubuntu.info.in: - add natty, LP:661578 --- data/templates/Ubuntu.info.in | 81 +++++++++++++++++++++++++++++++++++++++++++ debian/changelog | 7 +++- 2 files changed, 87 insertions(+), 1 deletion(-) diff --git a/data/templates/Ubuntu.info.in b/data/templates/Ubuntu.info.in index a9b539af..ca041c26 100644 --- a/data/templates/Ubuntu.info.in +++ b/data/templates/Ubuntu.info.in @@ -1,5 +1,86 @@ _ChangelogURI: http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog +Suite: natty +RepositoryType: deb +BaseURI: http://ports.ubuntu.com/ubuntu-ports/ +MatchURI: ports.ubuntu.com/ubuntu-ports +BaseURI-amd64: http://archive.ubuntu.com/ubuntu +MatchURI-amd64: archive.ubuntu.com/ubuntu +BaseURI-i386: http://archive.ubuntu.com/ubuntu +MatchURI-i386: archive.ubuntu.com/ubuntu +MirrorsFile-amd64: Ubuntu.mirrors +MirrorsFile-i386: Ubuntu.mirrors +_Description: Ubuntu 11.04 'Natty Narwhal' +Component: main +_CompDescription: Officially supported +_CompDescriptionLong: Canonical-supported Open Source software +Component: universe +_CompDescription: Community-maintained +_CompDescriptionLong: Community-maintained Open Source software +Component: restricted +_CompDescription: Non-free drivers +_CompDescriptionLong: Proprietary drivers for devices +Component: multiverse +_CompDescription: Restricted software +_CompDescriptionLong: Software restricted by copyright or legal issues + +Suite: natty +MatchName: .* +BaseURI: cdrom:\[Ubuntu.*11.04 +MatchURI: cdrom:\[Ubuntu.*11.04 +_Description: Cdrom with Ubuntu 11.04 'Natty Narwhal' +Available: False +Component: main +_CompDescription: Officially supported +Component: restricted +_CompDescription: Restricted copyright + +Suite: natty +Official: false +RepositoryType: deb +BaseURI: http://archive.canonical.com +MatchURI: archive.canonical.com +_Description: Canonical Partners +Component: partner +_CompDescription: Software packaged by Canonical for their partners +_CompDescriptionLong: This software is not part of Ubuntu. + +Suite: natty +Official: false +RepositoryType: deb +BaseURI: http://extras.ubuntu.com +MatchURI: extras.ubuntu.com +_Description: Independent +Component: main +_CompDescription: Provided by third-party software developers +_CompDescriptionLong: Software offered by third party developers. + +Suite: natty-security +ParentSuite: natty +RepositoryType: deb +BaseURI: http://ports.ubuntu.com/ubuntu-ports/ +MatchURI: ports.ubuntu.com/ubuntu-ports +BaseURI-amd64: http://security.ubuntu.com/ubuntu/ +MatchURI-amd64: archive.ubuntu.com/ubuntu|security.ubuntu.com +BaseURI-i386: http://security.ubuntu.com/ubuntu/ +MatchURI-i386: archive.ubuntu.com/ubuntu|security.ubuntu.com +_Description: Important security updates + +Suite: natty-updates +ParentSuite: natty +RepositoryType: deb +_Description: Recommended updates + +Suite: natty-proposed +ParentSuite: natty +RepositoryType: deb +_Description: Pre-released updates + +Suite: natty-backports +ParentSuite: natty +RepositoryType: deb +_Description: Unsupported updates + Suite: maverick RepositoryType: deb BaseURI: http://ports.ubuntu.com/ubuntu-ports/ diff --git a/debian/changelog b/debian/changelog index 40d61b9d..817d34bd 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,8 +1,13 @@ -python-apt (0.7.98.1ubuntu1) maverick; urgency=low +python-apt (0.7.98.1ubuntu1) UNRELEASEDmaverick; urgency=low + [ Michael Vogt ] * merged from debian/sid, remaining changes: - updated mirror list + [ Jeremy Bicha ] + * data/templates/Ubuntu.info.in: + - add natty, LP:661578 + -- Michael Vogt Fri, 15 Oct 2010 10:30:58 +0200 python-apt (0.7.98.1) unstable; urgency=low -- cgit v1.2.3 From 3bf6b76611bf0b148d495e2e4aae08546e54fa94 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Mon, 18 Oct 2010 11:51:44 +0200 Subject: fix compat issues with python3 --- apt/utils.py | 4 ++-- aptsources/distinfo.py | 28 ++++++++++++++-------------- aptsources/distro.py | 5 +++-- aptsources/sourceslist.py | 15 ++++++++------- debian/changelog | 5 +++-- tests/test_utils.py | 12 ++++++------ 6 files changed, 36 insertions(+), 33 deletions(-) diff --git a/apt/utils.py b/apt/utils.py index 8fc69215..49e8bed5 100644 --- a/apt/utils.py +++ b/apt/utils.py @@ -29,10 +29,10 @@ def get_maintenance_end_date(release_date, m_months): its is supported as input """ # calc end date - years = m_months / 12 + years = m_months // 12 months = m_months % 12 support_end_year = (release_date.year + years + - (release_date.month + months)/12) + (release_date.month + months)//12) support_end_month = (release_date.month + months) % 12 # special case: this happens when e.g. doing 2010-06 + 18 months if support_end_month == 0: diff --git a/aptsources/distinfo.py b/aptsources/distinfo.py index 6374f185..a69f944a 100644 --- a/aptsources/distinfo.py +++ b/aptsources/distinfo.py @@ -22,11 +22,11 @@ # USA import errno +import logging import os import gettext from os import getenv from subprocess import Popen, PIPE -import ConfigParser import re import apt_pkg @@ -166,9 +166,9 @@ class DistInfo(object): try: dist = Popen(["lsb_release", "-i", "-s"], stdout=PIPE).communicate()[0].strip() - except OSError, exc: + except OSError as exc: if exc.errno != errno.ENOENT: - print 'WARNING: lsb_release failed, using defaults:', exc + logging.warn('lsb_release failed, using defaults:' % exc) dist = "Debian" self.dist = dist @@ -232,7 +232,7 @@ class DistInfo(object): mirror_data = filter(match_mirror_line.match, [x.strip() for x in open(value)]) except Exception: - print "WARNING: Failed to read mirror file" + logging.warn("Failed to read mirror file") mirror_data = [] for line in mirror_data: if line.startswith("#LOC:"): @@ -286,17 +286,17 @@ class DistInfo(object): if __name__ == "__main__": d = DistInfo("Ubuntu", "/usr/share/python-apt/templates") - print d.changelogs_uri + logging.info(d.changelogs_uri) for template in d.templates: - print "\nSuite: %s" % template.name - print "Desc: %s" % template.description - print "BaseURI: %s" % template.base_uri - print "MatchURI: %s" % template.match_uri + logging.info("\nSuite: %s" % template.name) + logging.info("Desc: %s" % template.description) + logging.info("BaseURI: %s" % template.base_uri) + logging.info("MatchURI: %s" % template.match_uri) if template.mirror_set != {}: - print "Mirrors: %s" % template.mirror_set.keys() + logging.info("Mirrors: %s" % template.mirror_set.keys()) for comp in template.components: - print " %s -%s -%s" % (comp.name, - comp.description, - comp.description_long) + logging.info(" %s -%s -%s" % (comp.name, + comp.description, + comp.description_long)) for child in template.children: - print " %s" % child.description + logging.info(" %s" % child.description) diff --git a/aptsources/distro.py b/aptsources/distro.py index 23192f50..d4b65645 100644 --- a/aptsources/distro.py +++ b/aptsources/distro.py @@ -22,6 +22,7 @@ # USA import gettext +import logging import re import os import sys @@ -451,9 +452,9 @@ def _lsb_release(): # Convert to unicode string, needed for Python 3.1 out = out.decode("utf-8") result.update(l.split(":\t") for l in out.split("\n") if ':\t' in l) - except OSError, exc: + except OSError as exc: if exc.errno != errno.ENOENT: - print 'WARNING: lsb_release failed, using defaults:', exc + logging.warn('lsb_release failed, using defaults:' % exc) return result diff --git a/aptsources/sourceslist.py b/aptsources/sourceslist.py index 76bea43a..0c4335ec 100644 --- a/aptsources/sourceslist.py +++ b/aptsources/sourceslist.py @@ -25,6 +25,7 @@ import gettext import glob +import logging import os.path import re import shutil @@ -346,7 +347,7 @@ class SourcesList(object): source = SourceEntry(line, file) self.list.append(source) except: - print "could not open file '%s'" % file + logging.error("could not open file '%s'" % file) else: f.close() @@ -437,14 +438,14 @@ if __name__ == "__main__": sources = SourcesList() for entry in sources: - print entry.str() + logging.info("entry %s" % entry.str()) #print entry.uri mirror = is_mirror("http://archive.ubuntu.com/ubuntu/", "http://de.archive.ubuntu.com/ubuntu/") - print "is_mirror(): %s" % mirror + logging.info("is_mirror(): %s" % mirror) - print is_mirror("http://archive.ubuntu.com/ubuntu", - "http://de.archive.ubuntu.com/ubuntu/") - print is_mirror("http://archive.ubuntu.com/ubuntu/", - "http://de.archive.ubuntu.com/ubuntu") + logging.info(is_mirror("http://archive.ubuntu.com/ubuntu", + "http://de.archive.ubuntu.com/ubuntu/")) + logging.info(is_mirror("http://archive.ubuntu.com/ubuntu/", + "http://de.archive.ubuntu.com/ubuntu")) diff --git a/debian/changelog b/debian/changelog index 817d34bd..3bf12153 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,14 +1,15 @@ -python-apt (0.7.98.1ubuntu1) UNRELEASEDmaverick; urgency=low +python-apt (0.7.98.1ubuntu1) natty; urgency=low [ Michael Vogt ] * merged from debian/sid, remaining changes: - updated mirror list + - compat fixes for 3.x (pending upstream inclusion) [ Jeremy Bicha ] * data/templates/Ubuntu.info.in: - add natty, LP:661578 - -- Michael Vogt Fri, 15 Oct 2010 10:30:58 +0200 + -- Michael Vogt Mon, 18 Oct 2010 10:55:00 +0200 python-apt (0.7.98.1) unstable; urgency=low diff --git a/tests/test_utils.py b/tests/test_utils.py index 19dd977d..23511f32 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -20,7 +20,7 @@ class TestUtils(unittest.TestCase): from apt.utils import get_maintenance_end_date months_of_support = 18 # test historic releases, jaunty - release_date = datetime.datetime(2009, 04, 23) + release_date = datetime.datetime(2009, 4, 23) (end_year, end_month) = get_maintenance_end_date(release_date, months_of_support) self.assertEqual(end_year, 2010) self.assertEqual(end_month, 10) @@ -28,25 +28,25 @@ class TestUtils(unittest.TestCase): release_date = datetime.datetime(2009, 10, 29) (end_year, end_month) = get_maintenance_end_date(release_date, months_of_support) self.assertEqual(end_year, 2011) - self.assertEqual(end_month, 04) + self.assertEqual(end_month, 4) # test maverick release_date = datetime.datetime(2010, 10, 10) (end_year, end_month) = get_maintenance_end_date(release_date, months_of_support) self.assertEqual(end_year, 2012) - self.assertEqual(end_month, 04) + self.assertEqual(end_month, 4) # test with modulo zero - release_date = datetime.datetime(2010, 06, 10) + release_date = datetime.datetime(2010, 6, 10) (end_year, end_month) = get_maintenance_end_date(release_date, months_of_support) self.assertEqual(end_year, 2011) self.assertEqual(end_month, 12) # test dapper months_of_support = 60 - release_date = datetime.datetime(2008, 04, 24) + release_date = datetime.datetime(2008, 4, 24) (end_year, end_month) = get_maintenance_end_date(release_date, months_of_support) self.assertEqual(end_year, 2013) - self.assertEqual(end_month, 04) + self.assertEqual(end_month, 4) # what datetime says #d = datetime.timedelta(18*30) -- cgit v1.2.3 From 85665b9162f8b9c087e6f7fb4eade14bf2b236c2 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Wed, 10 Nov 2010 18:17:40 +0100 Subject: releasing version 0.7.98.1ubuntu2 --- debian/changelog | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/debian/changelog b/debian/changelog index 3bf12153..9f860c2d 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +python-apt (0.7.98.1ubuntu2) natty; urgency=low + + * rebuild for python2.7 + + -- Michael Vogt Wed, 10 Nov 2010 17:49:45 +0100 + python-apt (0.7.98.1ubuntu1) natty; urgency=low [ Michael Vogt ] -- cgit v1.2.3 From 871ae7011578cd84269e0ddfe20609261cfb88a1 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Wed, 24 Nov 2010 11:00:09 +0100 Subject: releasing version 0.7.100ubuntu1 --- debian/changelog | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/debian/changelog b/debian/changelog index fc90e997..4c320ba0 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,10 +1,10 @@ -python-apt (0.7.100ubuntu1) UNRELEASED; urgency=low +python-apt (0.7.100ubuntu1) natty; urgency=low * re-merged from debian/sid * tests/test_apt_cache.py: - fix tests to work if apt compressed indexes are enabled - -- Michael Vogt Wed, 24 Nov 2010 10:18:13 +0100 + -- Michael Vogt Wed, 24 Nov 2010 10:58:05 +0100 python-apt (0.7.100) unstable; urgency=low -- cgit v1.2.3 From 2a0259649b0656b9c262fea304ee8feb0c27ab1e Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Tue, 7 Dec 2010 14:52:09 +0100 Subject: releasing version 0.7.100ubuntu2 --- debian/changelog | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/debian/changelog b/debian/changelog index f55369d7..17c6abc3 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,4 +1,4 @@ -python-apt (0.7.100ubuntu2) UNRELEASED; urgency=low +python-apt (0.7.100ubuntu2) natty; urgency=low * python/generic.h: - set Object to NULL in CppDeallocPtr @@ -6,7 +6,7 @@ python-apt (0.7.100ubuntu2) UNRELEASED; urgency=low - don't run "actiongroup.release()" if the object was already deallocated - -- Michael Vogt Tue, 07 Dec 2010 13:41:07 +0100 + -- Michael Vogt Tue, 07 Dec 2010 14:49:42 +0100 python-apt (0.7.100ubuntu1) natty; urgency=low -- cgit v1.2.3 From 06720135e8a408369cbb74e7d1fa7e554dd36067 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Tue, 21 Dec 2010 18:23:37 +0100 Subject: releasing version 0.7.100.1ubuntu1 --- debian/changelog | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/debian/changelog b/debian/changelog index f36571f9..c1ab2f0e 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,6 +1,7 @@ -python-apt (0.7.100.1ubuntu1) UNRELEASEDnatty; urgency=low +python-apt (0.7.100.1ubuntu1) natty; urgency=low * merged from debian + * dropped python2.6 recommends * apt/progress/text.py: - only run ioctl for termios.TIOCGWINSZ if the fd is a tty * apt/debfile.py, tests/test_debfile.py: -- cgit v1.2.3 From e1d214484bdb2c6fed6a3bfeaff6229a31190fdd Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Wed, 22 Dec 2010 11:02:50 +0100 Subject: * debian/control: - really dropped python2.6 recommends --- debian/changelog | 4 +++- debian/control | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/debian/changelog b/debian/changelog index f6956175..f155d1c7 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,9 +1,11 @@ -python-apt (0.7.100.1ubuntu2) natty; urgency=low +python-apt (0.7.100.1ubuntu2) UNRELEASEDnatty; urgency=low * python/depcache.cc: - when using the actiongroup as a contextmanager incref/decref on enter and leave. this should fix the instablity issues that aptdaemon runs into (LP: #691134) + * debian/control: + - really dropped python2.6 recommends -- Michael Vogt Wed, 22 Dec 2010 10:52:50 +0100 diff --git a/debian/control b/debian/control index 4b1b2d92..a5d2236a 100644 --- a/debian/control +++ b/debian/control @@ -23,7 +23,7 @@ Vcs-Browser: http://bzr.debian.org/loggerhead/apt/python-apt/debian-sid/changes Package: python-apt Architecture: any Depends: ${python:Depends}, ${shlibs:Depends}, ${misc:Depends}, python-apt-common -Recommends: lsb-release, iso-codes, python2.6 +Recommends: lsb-release, iso-codes Breaks: debdelta (<< 0.28~), packagekit-backend-apt (<= 0.4.8-0ubuntu4), ${python:Breaks} Provides: ${python:Provides} Suggests: python-apt-dbg, python-gtk2, python-vte, python-apt-doc -- cgit v1.2.3 From b0c7c1ab8c33d8f4c7dae341ac9c74bb7bc1c699 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Wed, 22 Dec 2010 11:05:09 +0100 Subject: releasing version 0.7.100.1ubuntu2 --- debian/changelog | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/debian/changelog b/debian/changelog index f155d1c7..0422b262 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,4 +1,4 @@ -python-apt (0.7.100.1ubuntu2) UNRELEASEDnatty; urgency=low +python-apt (0.7.100.1ubuntu2) natty; urgency=low * python/depcache.cc: - when using the actiongroup as a contextmanager incref/decref @@ -7,7 +7,7 @@ python-apt (0.7.100.1ubuntu2) UNRELEASEDnatty; urgency=low * debian/control: - really dropped python2.6 recommends - -- Michael Vogt Wed, 22 Dec 2010 10:52:50 +0100 + -- Michael Vogt Wed, 22 Dec 2010 11:03:07 +0100 python-apt (0.7.100.1ubuntu1) natty; urgency=low -- cgit v1.2.3 From 1764db1ac8ea738f18a98d010ad36613c32651c4 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Thu, 13 Jan 2011 22:08:27 +0100 Subject: update changelog to match current archive --- debian/changelog | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/debian/changelog b/debian/changelog index cd43e56b..03e9b64b 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,16 +1,19 @@ -python-apt (0.7.100.2) UNRELEASED; urgency=low - - [ Michael Vogt ] - * python/depcache.cc: - - remove unneeded DECREF +python-apt (0.7.100.1ubunt4) UNRELEASED; urgency=low [ Michael Bienia ] * Use the new "except Exception as e" syntax from Python 2.6 (and later) to allow building with Python 3.2. * Bump XS-Python-Version to >= 2.6 therefor. - + -- Michael Vogt Tue, 07 Dec 2010 13:41:07 +0100 +python-apt (0.7.100.1ubuntu3) natty; urgency=low + + * python/depcache.cc: + - fix another refcount problem + + -- Michael Vogt Wed, 22 Dec 2010 16:39:49 +0100 + python-apt (0.7.100.1ubuntu2) natty; urgency=low * python/depcache.cc: -- cgit v1.2.3 From 4c0f43da5e3fc902193be578ad3aaa1e7c6457a7 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Thu, 13 Jan 2011 22:12:18 +0100 Subject: releasing version 0.7.100.1ubunt4 --- debian/changelog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/changelog b/debian/changelog index 4ac372b8..5162dd04 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,4 +1,4 @@ -python-apt (0.7.100.1ubunt4) UNRELEASED; urgency=low +python-apt (0.7.100.1ubunt4) natty; urgency=low [ Michael Bienia ] * Use the new "except Exception as e" syntax from Python 2.6 (and later) to -- cgit v1.2.3 From 28b6f80373ad00704615e1cb0aa9ef65a794771c Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Thu, 13 Jan 2011 23:24:10 +0100 Subject: releasing version 0.7.100.1ubuntu4 --- debian/changelog | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/debian/changelog b/debian/changelog index 5162dd04..7f935923 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,4 +1,4 @@ -python-apt (0.7.100.1ubunt4) natty; urgency=low +python-apt (0.7.100.1ubuntu4) natty; urgency=low [ Michael Bienia ] * Use the new "except Exception as e" syntax from Python 2.6 (and later) to @@ -10,7 +10,7 @@ python-apt (0.7.100.1ubunt4) natty; urgency=low - fix py3 extension module install location (thanks to Barry) - -- Michael Vogt Thu, 13 Jan 2011 22:09:39 +0100 + -- Michael Vogt Thu, 13 Jan 2011 22:58:43 +0100 python-apt (0.7.100.1ubuntu3) natty; urgency=low -- cgit v1.2.3 From 50cd25232b87fcf0be1a87bf2757f76a369ee175 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Fri, 18 Feb 2011 17:28:48 +0100 Subject: releasing version 0.7.100.1ubuntu5 --- debian/changelog | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/debian/changelog b/debian/changelog index 00207cbe..37062230 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,11 +1,11 @@ -python-apt (0.7.100.1ubuntu5) UNRELEASEDnatty; urgency=low +python-apt (0.7.100.1ubuntu5) natty; urgency=low * python/depcache.cc: - provide bindings for new libapt SetCandidateRelease() * debian/control: - require new libapt-pkg-dev SetCandidateRelease() - -- Michael Vogt Fri, 18 Feb 2011 17:16:01 +0100 + -- Michael Vogt Fri, 18 Feb 2011 17:26:47 +0100 python-apt (0.7.100.1ubuntu4) natty; urgency=low -- cgit v1.2.3 From 2820cf928b411a0227c07780dd2e74b9b0ebbd98 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Mon, 21 Mar 2011 15:24:56 +0100 Subject: releasing version 0.7.100.2ubuntu1 --- debian/changelog | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/debian/changelog b/debian/changelog index a606a1c9..c45f483d 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,9 +1,9 @@ -python-apt (0.7.100.2ubuntu1) UNRELEASEDnatty; urgency=low +python-apt (0.7.100.2ubuntu1) natty; urgency=low * merged fix for parse_depends() in a multiarch environment from debian/sid branch - -- Michael Vogt Mon, 21 Mar 2011 15:14:38 +0100 + -- Michael Vogt Mon, 21 Mar 2011 15:23:59 +0100 python-apt (0.7.100.2) unstable; urgency=low -- cgit v1.2.3 From f88db9b5fab274879fe1aeae1309dc7a23257040 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Tue, 29 Mar 2011 09:16:26 +0200 Subject: PyFetchProgress::Pulse(): When ignoring a false return value from PyArg_Parse() after running the simple callback pulse(), there can be an exception on the stack, which must be cleared. (LP: #711225) --- debian/changelog | 9 +++++++++ python/progress.cc | 4 +++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/debian/changelog b/debian/changelog index c45f483d..6f337b91 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,12 @@ +python-apt (0.7.100.2ubuntu2) UNRELEASED; urgency=low + + [ Barry Warsaw ] + * PyFetchProgress::Pulse(): When ignoring a false return value from + PyArg_Parse() after running the simple callback pulse(), there can be + an exception on the stack, which must be cleared. (LP: #711225) + + -- Michael Vogt Mon, 21 Mar 2011 15:46:50 +0100 + python-apt (0.7.100.2ubuntu1) natty; urgency=low * merged fix for parse_depends() in a multiarch environment diff --git a/python/progress.cc b/python/progress.cc index 437309cf..5700a1b6 100644 --- a/python/progress.cc +++ b/python/progress.cc @@ -399,7 +399,9 @@ bool PyFetchProgress::Pulse(pkgAcquire * Owner) { // most of the time the user who subclasses the pulse() // method forgot to add a return {True,False} so we just - // assume he wants a True + // assume he wants a True. There may be a Python exception on the stack + // that must be cleared. + PyErr_Clear(); PyCbObj_BEGIN_ALLOW_THREADS return true; } -- cgit v1.2.3 From 33b79b4717953064130e5be3b3371613e2b7a210 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Tue, 29 Mar 2011 09:20:55 +0200 Subject: releasing version 0.7.100.2ubuntu2 --- debian/changelog | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/debian/changelog b/debian/changelog index 6f337b91..89395ab4 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,11 +1,11 @@ -python-apt (0.7.100.2ubuntu2) UNRELEASED; urgency=low +python-apt (0.7.100.2ubuntu2) natty; urgency=low [ Barry Warsaw ] * PyFetchProgress::Pulse(): When ignoring a false return value from PyArg_Parse() after running the simple callback pulse(), there can be an exception on the stack, which must be cleared. (LP: #711225) - -- Michael Vogt Mon, 21 Mar 2011 15:46:50 +0100 + -- Barry Warsaw Mon, 28 Mar 2011 18:17:11 -0400 python-apt (0.7.100.2ubuntu1) natty; urgency=low -- cgit v1.2.3 From d108dcccc57a37f987459a1346f23fb6e8c79b57 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Wed, 30 Mar 2011 17:53:06 +0200 Subject: releasing version 0.7.100.2ubuntu3 --- debian/changelog | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/debian/changelog b/debian/changelog index 346a42a2..b3c00782 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,4 +1,4 @@ -python-apt (0.7.100.2ubuntu3) UNRELEASED; urgency=low +python-apt (0.7.100.2ubuntu3) natty; urgency=low [ Michael Vogt ] * python/arfile.cc, apt/debfile.py: @@ -7,7 +7,7 @@ python-apt (0.7.100.2ubuntu3) UNRELEASED; urgency=low - add test for xz compression * update priority of python3-apt to match the archive - -- Michael Vogt Mon, 21 Mar 2011 15:46:50 +0100 + -- Michael Vogt Wed, 30 Mar 2011 17:16:00 +0200 python-apt (0.7.100.2ubuntu2) natty; urgency=low -- cgit v1.2.3 From bf950bc2b0a1f247714aee3e3096ed6872166d91 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Wed, 6 Apr 2011 17:20:16 +0200 Subject: merged upload from loic --- debian/changelog | 10 +++++++++- debian/control | 4 ++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/debian/changelog b/debian/changelog index 6f22ad9f..6086ef61 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,4 +1,4 @@ -python-apt (0.7.100.3ubuntu2) UNRELEASED; urgency=low +python-apt (0.7.100.3ubuntu3) UNRELEASED; urgency=low [ Michael Vogt ] * cherry pick multiarch support for aptsources from debian @@ -9,6 +9,14 @@ python-apt (0.7.100.3ubuntu2) UNRELEASED; urgency=low -- Michael Vogt Wed, 06 Apr 2011 16:59:07 +0200 +python-apt (0.7.100.3ubuntu2) natty; urgency=low + + * Rename Vcs-* to XS-Debian-Vcs-*. + * No other changes upload to build against latest apt and hopefully fix + LP #733741. + + -- Loïc Minier Tue, 05 Apr 2011 18:11:40 +0200 + python-apt (0.7.100.3ubuntu1) natty; urgency=low * merge fixes from debian-sid, most notably the fixes diff --git a/debian/control b/debian/control index 7b052bfc..8969af63 100644 --- a/debian/control +++ b/debian/control @@ -17,8 +17,8 @@ Build-Depends: apt-utils, python-distutils-extra (>= 2.0), python-sphinx (>= 0.5), python-debian -Vcs-Bzr: http://bzr.debian.org/apt/python-apt/debian-sid -Vcs-Browser: http://bzr.debian.org/loggerhead/apt/python-apt/debian-sid/changes +XS-Debian-Vcs-Bzr: http://bzr.debian.org/apt/python-apt/debian-sid +XS-Debian-Vcs-Browser: http://bzr.debian.org/loggerhead/apt/python-apt/debian-sid/changes Package: python-apt Architecture: any -- cgit v1.2.3 From a416a97ffcaef3bff627fa7c38d448cbf126a99d Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Wed, 6 Apr 2011 17:31:21 +0200 Subject: releasing version 0.7.100.3ubuntu3 --- debian/changelog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/changelog b/debian/changelog index 6086ef61..70fc2c12 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,4 +1,4 @@ -python-apt (0.7.100.3ubuntu3) UNRELEASED; urgency=low +python-apt (0.7.100.3ubuntu3) natty; urgency=low [ Michael Vogt ] * cherry pick multiarch support for aptsources from debian -- cgit v1.2.3 From 67130f4b702a750f777042e4ad557bef9364f997 Mon Sep 17 00:00:00 2001 From: Stéphane Graber Date: Tue, 12 Apr 2011 10:49:58 -0400 Subject: releasing version 0.7.100.3ubuntu4 --- aptsources/distro.py | 3 +++ debian/changelog | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/aptsources/distro.py b/aptsources/distro.py index d4b65645..41c86981 100644 --- a/aptsources/distro.py +++ b/aptsources/distro.py @@ -337,6 +337,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 70fc2c12..695d59a4 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +python-apt (0.7.100.3ubuntu4) natty; urgency=low + + * Update enable_component to also apply to -src entries (LP: #758732) + + -- Stéphane Graber Tue, 12 Apr 2011 10:49:34 -0400 + python-apt (0.7.100.3ubuntu3) natty; urgency=low [ Michael Vogt ] -- cgit v1.2.3 From 3db02c5215d36bb1cd2c912ad69e5ed2796380c0 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Wed, 20 Apr 2011 18:13:47 +0200 Subject: releasing version 0.7.100.3ubuntu5 --- aptsources/sourceslist.py | 5 ++++- data/templates/Ubuntu.info.in | 48 +++++++++++++++++++++++++++++++++++++++++++ debian/changelog | 8 ++++++++ 3 files changed, 60 insertions(+), 1 deletion(-) diff --git a/aptsources/sourceslist.py b/aptsources/sourceslist.py index 83d2c8b9..04f6a5a7 100644 --- a/aptsources/sourceslist.py +++ b/aptsources/sourceslist.py @@ -449,7 +449,10 @@ class SourceEntryMatcher(object): found = False for template in self.templates: if (re.search(template.match_uri, source.uri) and - re.match(template.match_name, source.dist)): + re.match(template.match_name, source.dist) and + # deb is a valid fallback for deb-src (if that is not + # definied, see #760035 + (source.type == template.type or template.type == "deb")): found = True source.template = template break diff --git a/data/templates/Ubuntu.info.in b/data/templates/Ubuntu.info.in index ca041c26..99bd5422 100644 --- a/data/templates/Ubuntu.info.in +++ b/data/templates/Ubuntu.info.in @@ -25,6 +25,13 @@ _CompDescription: Restricted software _CompDescriptionLong: Software restricted by copyright or legal issues Suite: natty +ParentSuite: natty +RepositoryType: deb-src +BaseURI: http://archive.ubuntu.com/ubuntu/ +MatchURI: archive.ubuntu.com/ubuntu|ports.ubuntu.com/ubuntu-ports + +Suite: natty +RepositoryType: deb MatchName: .* BaseURI: cdrom:\[Ubuntu.*11.04 MatchURI: cdrom:\[Ubuntu.*11.04 @@ -66,21 +73,49 @@ BaseURI-i386: http://security.ubuntu.com/ubuntu/ MatchURI-i386: archive.ubuntu.com/ubuntu|security.ubuntu.com _Description: Important security updates +Suite: natty-security +ParentSuite: natty +RepositoryType: deb-src +BaseURI: http://archive.ubuntu.com/ubuntu/ +MatchURI: archive.ubuntu.com/ubuntu|ports.ubuntu.com/ubuntu-ports|security.ubuntu.com +_Description: Important security updates + Suite: natty-updates ParentSuite: natty RepositoryType: deb _Description: Recommended updates +Suite: natty-updates +ParentSuite: natty +RepositoryType: deb-src +BaseURI: http://archive.ubuntu.com/ubuntu/ +MatchURI: archive.ubuntu.com/ubuntu|ports.ubuntu.com/ubuntu-ports +_Description: Recommended updates + Suite: natty-proposed ParentSuite: natty RepositoryType: deb _Description: Pre-released updates +Suite: natty-proposed +ParentSuite: natty +RepositoryType: deb-src +BaseURI: http://archive.ubuntu.com/ubuntu/ +MatchURI: archive.ubuntu.com/ubuntu|ports.ubuntu.com/ubuntu-ports +_Description: Pre-released updates + Suite: natty-backports ParentSuite: natty RepositoryType: deb _Description: Unsupported updates +Suite: natty-backports +ParentSuite: natty +RepositoryType: deb-src +BaseURI: http://archive.ubuntu.com/ubuntu/ +MatchURI: archive.ubuntu.com/ubuntu|ports.ubuntu.com/ubuntu-ports +_Description: Unsupported updates + Suite: maverick RepositoryType: deb BaseURI: http://ports.ubuntu.com/ubuntu-ports/ @@ -106,6 +141,7 @@ _CompDescription: Restricted software _CompDescriptionLong: Software restricted by copyright or legal issues Suite: maverick +RepositoryType: deb MatchName: .* BaseURI: cdrom:\[Ubuntu.*10.10 MatchURI: cdrom:\[Ubuntu.*10.10 @@ -187,6 +223,7 @@ _CompDescription: Restricted software _CompDescriptionLong: Software restricted by copyright or legal issues Suite: lucid +RepositoryType: deb MatchName: .* BaseURI: cdrom:\[Ubuntu.*10.04 MatchURI: cdrom:\[Ubuntu.*10.04 @@ -248,6 +285,7 @@ _CompDescription: Restricted software _CompDescriptionLong: Software restricted by copyright or legal issues Suite: karmic +RepositoryType: deb MatchName: .* BaseURI: cdrom:\[Ubuntu.*9.10 MatchURI: cdrom:\[Ubuntu.*9.10 @@ -309,6 +347,7 @@ _CompDescription: Restricted software _CompDescriptionLong: Software restricted by copyright or legal issues Suite: jaunty +RepositoryType: deb MatchName: .* BaseURI: cdrom:\[Ubuntu.*9.04 MatchURI: cdrom:\[Ubuntu.*9.04 @@ -370,6 +409,7 @@ _CompDescription: Restricted software _CompDescriptionLong: Software restricted by copyright or legal issues Suite: intrepid +RepositoryType: deb MatchName: .* BaseURI: cdrom:\[Ubuntu.*8.10 MatchURI: cdrom:\[Ubuntu.*8.10 @@ -432,6 +472,7 @@ _CompDescription: Restricted software _CompDescriptionLong: Software restricted by copyright or legal issues Suite: hardy +RepositoryType: deb MatchName: .* BaseURI: cdrom:\[Ubuntu.*8.04 MatchURI: cdrom:\[Ubuntu.*8.04 @@ -495,6 +536,7 @@ _CompDescription: Restricted software _CompDescriptionLong: Software restricted by copyright or legal issues Suite: gutsy +RepositoryType: deb MatchName: .* BaseURI: cdrom:\[Ubuntu.*7.10 MatchURI: cdrom:\[Ubuntu.*7.10 @@ -558,6 +600,7 @@ _CompDescription: Restricted software _CompDescriptionLong: Software restricted by copyright or legal issues Suite: feisty +RepositoryType: deb MatchName: .* BaseURI: cdrom:\[Ubuntu.*7.04 MatchURI: cdrom:\[Ubuntu.*7.04 @@ -618,6 +661,7 @@ _CompDescription: Restricted software _CompDescriptionLong: Software restricted by copyright or legal issues Suite: edgy +RepositoryType: deb MatchName: .* BaseURI: cdrom:\[Ubuntu.*6.10 MatchURI: cdrom:\[Ubuntu.*6.10 @@ -678,6 +722,7 @@ _CompDescription: Restricted software (Multiverse) _CompDescriptionLong: Software restricted by copyright or legal issues Suite: dapper +RepositoryType: deb MatchName: .* BaseURI: cdrom:\[Ubuntu.*6.06 MatchURI: cdrom:\[Ubuntu.*6.06 @@ -734,6 +779,7 @@ Component: multiverse _CompDescription: Non-free (Multiverse) Suite: breezy +RepositoryType: deb MatchName: .* BaseURI: cdrom:\[Ubuntu.*5.10 MatchURI: cdrom:\[Ubuntu.*5.10 @@ -785,6 +831,7 @@ Component: multiverse _CompDescription: Non-free (Multiverse) Suite: hoary +RepositoryType: deb MatchName: .* BaseURI: cdrom:\[Ubuntu.*5.04 MatchURI: cdrom:\[Ubuntu.*5.04 @@ -831,6 +878,7 @@ Component: multiverse _CompDescription: Non-free (Multiverse) Suite: warty +RepositoryType: deb MatchName: .* BaseURI: cdrom:\[Ubuntu.*4.10 MatchURI: cdrom:\[Ubuntu.*4.10 diff --git a/debian/changelog b/debian/changelog index 695d59a4..6624e8c5 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,11 @@ +python-apt (0.7.100.3ubuntu5) natty; urgency=low + + [ Stéphane Graber ] + * fix enable_components for deb-src entries on ports.ubuntu.com + (LP: #760035) + + -- Michael Vogt Wed, 20 Apr 2011 18:05:51 +0200 + python-apt (0.7.100.3ubuntu4) natty; urgency=low * Update enable_component to also apply to -src entries (LP: #758732) -- cgit v1.2.3 From 35e1f9341f30acc3e059234945108a7e976a2eb8 Mon Sep 17 00:00:00 2001 From: Stéphane Graber Date: Sun, 24 Apr 2011 13:26:22 -0400 Subject: releasing version 0.7.100.3ubuntu6 --- data/templates/Ubuntu.info.in | 1 + debian/changelog | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/data/templates/Ubuntu.info.in b/data/templates/Ubuntu.info.in index 99bd5422..b49312e8 100644 --- a/data/templates/Ubuntu.info.in +++ b/data/templates/Ubuntu.info.in @@ -29,6 +29,7 @@ ParentSuite: natty RepositoryType: deb-src BaseURI: http://archive.ubuntu.com/ubuntu/ MatchURI: archive.ubuntu.com/ubuntu|ports.ubuntu.com/ubuntu-ports +_Description: Ubuntu 11.04 'Natty Narwhal' Suite: natty RepositoryType: deb diff --git a/debian/changelog b/debian/changelog index 6624e8c5..adf51acc 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,10 @@ +python-apt (0.7.100.3ubuntu6) natty; urgency=low + + * Add missing _Description entry to Ubuntu.info for new deb-src entries. + (LP: #768363) + + -- Stéphane Graber Sun, 24 Apr 2011 13:24:53 -0400 + python-apt (0.7.100.3ubuntu5) natty; urgency=low [ Stéphane Graber ] -- cgit v1.2.3 From 8c291baf30b7fe903461823100004bc994707086 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Thu, 28 Apr 2011 12:27:20 +0200 Subject: * data/templates/Ubuntu.info.in: - add oneiric templates --- data/templates/Ubuntu.info.in | 118 ++++++++++++++++++++++++++++++++++++++++++ debian/changelog | 7 +++ 2 files changed, 125 insertions(+) diff --git a/data/templates/Ubuntu.info.in b/data/templates/Ubuntu.info.in index b49312e8..39d9256e 100644 --- a/data/templates/Ubuntu.info.in +++ b/data/templates/Ubuntu.info.in @@ -1,5 +1,123 @@ _ChangelogURI: http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog +Suite: oneiric +RepositoryType: deb +BaseURI: http://ports.ubuntu.com/ubuntu-ports/ +MatchURI: ports.ubuntu.com/ubuntu-ports +BaseURI-amd64: http://archive.ubuntu.com/ubuntu +MatchURI-amd64: archive.ubuntu.com/ubuntu +BaseURI-i386: http://archive.ubuntu.com/ubuntu +MatchURI-i386: archive.ubuntu.com/ubuntu +MirrorsFile-amd64: Ubuntu.mirrors +MirrorsFile-i386: Ubuntu.mirrors +_Description: Ubuntu 11.10 'Oneiric Ocelot' +Component: main +_CompDescription: Officially supported +_CompDescriptionLong: Canonical-supported Open Source software +Component: universe +_CompDescription: Community-maintained +_CompDescriptionLong: Community-maintained Open Source software +Component: restricted +_CompDescription: Non-free drivers +_CompDescriptionLong: Proprietary drivers for devices +Component: multiverse +_CompDescription: Restricted software +_CompDescriptionLong: Software restricted by copyright or legal issues + +Suite: oneiric +ParentSuite: oneiric +RepositoryType: deb-src +BaseURI: http://archive.ubuntu.com/ubuntu/ +MatchURI: archive.ubuntu.com/ubuntu|ports.ubuntu.com/ubuntu-ports +_Description: Ubuntu 11.10 'Oneiric Ocelot' + +Suite: oneiric +RepositoryType: deb +MatchName: .* +BaseURI: cdrom:\[Ubuntu.*11.10 +MatchURI: cdrom:\[Ubuntu.*11.10 +_Description: Cdrom with Ubuntu 11.10 'Oneiric Ocelot' +Available: False +Component: main +_CompDescription: Officially supported +Component: restricted +_CompDescription: Restricted copyright + +Suite: oneiric +Official: false +RepositoryType: deb +BaseURI: http://archive.canonical.com +MatchURI: archive.canonical.com +_Description: Canonical Partners +Component: partner +_CompDescription: Software packaged by Canonical for their partners +_CompDescriptionLong: This software is not part of Ubuntu. + +Suite: oneiric +Official: false +RepositoryType: deb +BaseURI: http://extras.ubuntu.com +MatchURI: extras.ubuntu.com +_Description: Independent +Component: main +_CompDescription: Provided by third-party software developers +_CompDescriptionLong: Software offered by third party developers. + +Suite: oneiric-security +ParentSuite: oneiric +RepositoryType: deb +BaseURI: http://ports.ubuntu.com/ubuntu-ports/ +MatchURI: ports.ubuntu.com/ubuntu-ports +BaseURI-amd64: http://security.ubuntu.com/ubuntu/ +MatchURI-amd64: archive.ubuntu.com/ubuntu|security.ubuntu.com +BaseURI-i386: http://security.ubuntu.com/ubuntu/ +MatchURI-i386: archive.ubuntu.com/ubuntu|security.ubuntu.com +_Description: Important security updates + +Suite: oneiric-security +ParentSuite: oneiric +RepositoryType: deb-src +BaseURI: http://archive.ubuntu.com/ubuntu/ +MatchURI: archive.ubuntu.com/ubuntu|ports.ubuntu.com/ubuntu-ports|security.ubuntu.com +_Description: Important security updates + +Suite: oneiric-updates +ParentSuite: oneiric +RepositoryType: deb +_Description: Recommended updates + +Suite: oneiric-updates +ParentSuite: oneiric +RepositoryType: deb-src +BaseURI: http://archive.ubuntu.com/ubuntu/ +MatchURI: archive.ubuntu.com/ubuntu|ports.ubuntu.com/ubuntu-ports +_Description: Recommended updates + +Suite: oneiric-proposed +ParentSuite: oneiric +RepositoryType: deb +_Description: Pre-released updates + +Suite: oneiric-proposed +ParentSuite: oneiric +RepositoryType: deb-src +BaseURI: http://archive.ubuntu.com/ubuntu/ +MatchURI: archive.ubuntu.com/ubuntu|ports.ubuntu.com/ubuntu-ports +_Description: Pre-released updates + +Suite: oneiric-backports +ParentSuite: oneiric +RepositoryType: deb +_Description: Unsupported updates + +Suite: oneiric-backports +ParentSuite: oneiric +RepositoryType: deb-src +BaseURI: http://archive.ubuntu.com/ubuntu/ +MatchURI: archive.ubuntu.com/ubuntu|ports.ubuntu.com/ubuntu-ports +_Description: Unsupported updates + + Suite: natty RepositoryType: deb BaseURI: http://ports.ubuntu.com/ubuntu-ports/ diff --git a/debian/changelog b/debian/changelog index adf51acc..983a480a 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,10 @@ +python-apt (0.7.100.3ubuntu7) UNRELEASEDoneiric; urgency=low + + * data/templates/Ubuntu.info.in: + - add oneiric templates + + -- Michael Vogt Thu, 28 Apr 2011 11:49:32 +0200 + python-apt (0.7.100.3ubuntu6) natty; urgency=low * Add missing _Description entry to Ubuntu.info for new deb-src entries. -- cgit v1.2.3 From e0b2560ab0fab5716187b7a1f93052373f5cbd23 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Fri, 29 Apr 2011 17:32:34 +0200 Subject: releasing version 0.7.100.3ubuntu7 --- debian/changelog | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/debian/changelog b/debian/changelog index 983a480a..11e8819d 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,9 +1,9 @@ -python-apt (0.7.100.3ubuntu7) UNRELEASEDoneiric; urgency=low +python-apt (0.7.100.3ubuntu7) oneiric; urgency=low * data/templates/Ubuntu.info.in: - add oneiric templates - -- Michael Vogt Thu, 28 Apr 2011 11:49:32 +0200 + -- Michael Vogt Fri, 29 Apr 2011 17:30:29 +0200 python-apt (0.7.100.3ubuntu6) natty; urgency=low -- cgit v1.2.3 From 19e2e0f210da3fb4cb87cfe1ddd4bbc6c61d8cd1 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Thu, 26 May 2011 18:01:26 +0200 Subject: merge from debian, omit disable of the 0.7 API --- apt/cache.py | 44 ++++- apt/cdrom.py | 7 +- apt/debfile.py | 2 +- apt/package.py | 50 ++++-- apt/progress/old.py | 5 +- apt/progress/text.py | 5 +- aptsources/distinfo.py | 167 +++++++++---------- aptsources/sourceslist.py | 87 +++++----- debian/changelog | 63 ++++++++ debian/rules | 8 +- doc/examples/architecture.py | 12 ++ doc/source/c++/api.rst | 60 +++++++ doc/source/library/apt.package.rst | 31 +++- doc/source/library/apt_pkg.rst | 306 ++++++++++++++++++++++++++++++++++- doc/source/tutorials/apt-cdrom.rst | 2 +- doc/source/whatsnew/0.8.0.rst | 38 +++++ pre-build.sh | 4 +- python/acquire-item.cc | 10 +- python/acquire.cc | 14 +- python/apt_pkgmodule.cc | 106 +++++++++---- python/apt_pkgmodule.h | 8 + python/arfile.cc | 12 +- python/cache.cc | 265 +++++++++++++++++++++++-------- python/cachegroup.cc | 188 ++++++++++++++++++++++ python/configuration.cc | 6 +- python/depcache.cc | 12 +- python/generic.h | 16 ++ python/indexfile.cc | 2 +- python/indexrecords.cc | 2 +- python/orderlist.cc | 317 +++++++++++++++++++++++++++++++++++++ python/pkgmanager.cc | 279 +++++++++++++++++++++++++++----- python/pkgsrcrecords.cc | 10 +- python/policy.cc | 2 +- python/progress.cc | 60 +++---- python/python-apt-helpers.cc | 2 + python/python-apt.h | 16 ++ python/string.cc | 14 +- python/tag.cc | 5 +- python/tarfile.cc | 14 +- setup.py | 3 +- tests/test_apt_cache.py | 31 ++-- tests/test_cache_invocation.py | 4 +- tests/test_configuration.py | 30 ++++ tests/test_group.py | 32 ++++ tests/test_hashes.py | 7 +- tests/test_progress.py | 3 +- 46 files changed, 1964 insertions(+), 397 deletions(-) create mode 100644 doc/examples/architecture.py create mode 100644 doc/source/whatsnew/0.8.0.rst create mode 100644 python/cachegroup.cc create mode 100644 python/orderlist.cc create mode 100644 tests/test_configuration.py create mode 100644 tests/test_group.py diff --git a/apt/cache.py b/apt/cache.py index bfa41edc..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): """ @@ -107,7 +116,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 """ @@ -288,6 +297,30 @@ 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. + + .. versionadded:: 0.8.0 + """ + 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: @@ -339,6 +372,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() . @@ -548,6 +585,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.""" @@ -567,11 +605,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/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..14e80594 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): @@ -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. @@ -994,11 +1024,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 +1131,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/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/aptsources/distinfo.py b/aptsources/distinfo.py index a69f944a..249985e7 100644 --- a/aptsources/distinfo.py +++ b/aptsources/distinfo.py @@ -176,89 +176,90 @@ 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: - logging.warn("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 04f6a5a7..b85e6947 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 @@ -276,6 +276,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. @@ -287,39 +293,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) @@ -370,15 +369,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: - logging.error("could not open file '%s'" % file) - else: - f.close() + print "could not open file '%s'" % file def save(self): """ save the current sources """ @@ -390,14 +386,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 11e8819d..edd0081f 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,66 @@ +python-apt (0.8.0~exp4ubuntu1) oneiric; urgency=low + + * Merged from debian/experimental, remaining changes: + - updated mirror list + - do not disable 0.7 compat API yet + + -- Michael Vogt Tue, 24 May 2011 10:08:56 +0200 + +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 Fri, 29 Apr 2011 13:57:30 +0200 + +python-apt (0.8.0~exp3) experimental; 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 Thu, 21 Apr 2011 15:33:38 +0200 + +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 + * 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) + * 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) + * 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) + * 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 Tue, 12 Apr 2011 15:25:38 +0200 + +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 + * 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. + * 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 16:21:45 +0200 + python-apt (0.7.100.3ubuntu7) oneiric; urgency=low * data/templates/Ubuntu.info.in: diff --git a/debian/rules b/debian/rules index 5428375d..a85d1eb2 100755 --- a/debian/rules +++ b/debian/rules @@ -2,8 +2,8 @@ # 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 -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 $@ @@ -28,14 +28,14 @@ override_dh_installdocs: override_dh_strip: dh_strip -p python-apt --dbg-package=python-apt-dbg dh_strip -p python3-apt --dbg-package=python3-apt-dbg - + override_dh_compress: dh_compress -X.js -X_static/* -X _sources/* -X_sources/*/* -X.inv # 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 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() diff --git a/doc/source/c++/api.rst b/doc/source/c++/api.rst index 97ab24d1..63ed1599 100644 --- a/doc/source/c++/api.rst +++ b/doc/source/c++/api.rst @@ -389,6 +389,38 @@ Description (pkgCache::DescIterator) Return the :ctype:`pkgCache::DescIterator` reference contained in the Python object *object*. + +Group (pkgCache::GrpIterator) +---------------------------------- +.. versionadded:: 0.8.0 + +.. 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 @@ -590,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.package.rst b/doc/source/library/apt.package.rst index 4b143b8a..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 @@ -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 diff --git a/doc/source/library/apt_pkg.rst b/doc/source/library/apt_pkg.rst index 426cb97e..81f2d408 100644 --- a/doc/source/library/apt_pkg.rst +++ b/doc/source/library/apt_pkg.rst @@ -40,17 +40,43 @@ 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. + + .. 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. + + .. versionadded: 0.8.0 .. 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. + + .. versionadded: 0.8.0 .. method:: update(progress, sources [, pulse_interval]) -> bool @@ -73,6 +99,44 @@ 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. + + .. versionadded: 0.8.0 + + .. attribute:: groups + + A sequence of :class:`Group` objects, implemented as a + :class:`GroupList` object. + + .. versionadded: 0.8.0 + + .. class:: GroupList + + A simple sequence-like object which only provides a length and + an implementation of ``__getitem__`` for accessing groups at + a certain index. Apart from being iterable, it can be used in + the following ways: + + .. versionadded: 0.8.0 + + .. describe:: list[index] + + Get the :class:`Group` object for the group at the position + given by *index* in the GroupList *list*. + + .. describe:: len(list) + + Return the length of the GroupList object *list*. + + + .. attribute:: is_multi_arch + + An attribute determining whether the cache supports multi-arch. + + .. versionadded: 0.8.0 + .. attribute:: package_count The total number of packages available in the cache. This value is @@ -358,6 +422,158 @@ 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` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. 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` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -432,6 +648,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 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -653,6 +910,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/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 diff --git a/doc/source/whatsnew/0.8.0.rst b/doc/source/whatsnew/0.8.0.rst new file mode 100644 index 00000000..2eeb135e --- /dev/null +++ b/doc/source/whatsnew/0.8.0.rst @@ -0,0 +1,38 @@ +What's New In python-apt 0.8 +============================ +Python-apt 0.8 is a new major release of the python bindings for the APT +package management libraries. + + +Removal of old API +------------------ +The old API that was deprecated in 0.7.100 is no longer available. Applications +that have not yet updated to the new API should do so. + +Multi-arch support +------------------ +This version of python-apt introduces multi-arch support: + + * A new class, :class:`apt_pkg.Group` has been added. + * :class:`apt_pkg.Cache` can now be indexed by ``(name, architecture)`` + tuples + +Features for mancoosi +---------------------- +Several new features related to ordering have been added on request +of the mancoosi project: + + * A new class :class:`apt_pkg.OrderList` has been added + * The :class:`apt_pkg.PackageManager` class now provides new methods + for registering install/remove/configure actions which can be + subclassed to check ordering. + +Other changes +------------- +This release of python-apt also features several other, smaller changes: + + * apt_pkg.Cache() now takes None for the progress parameter, preventing + progress reporting. + +There have been various other changes, see the changelog for a complete list +of changes. diff --git a/pre-build.sh b/pre-build.sh index 026a491e..a150272d 100755 --- a/pre-build.sh +++ b/pre-build.sh @@ -7,5 +7,5 @@ if [ -n "$https_proxy" ]; then fi utils/get_ubuntu_mirrors_from_lp.py > data/templates/Ubuntu.mirrors -echo "updating Debian mirror list" -utils/get_debian_mirrors.py > data/templates/Debian.mirrors +#echo "updating Debian mirror list" +#utils/get_debian_mirrors.py > data/templates/Debian.mirrors 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 d1ac33e0..e8490b4e 100644 --- a/python/apt_pkgmodule.cc +++ b/python/apt_pkgmodule.cc @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -83,7 +84,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 +460,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 = @@ -732,6 +733,12 @@ 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 + &PyOrderList_Type, // orderlist_type + &PyOrderList_FromCpp, // orderlist_fromcpp + &PyOrderList_ToCpp // orderlist_tocpp }; @@ -811,6 +818,8 @@ 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); + ADDTYPE(Module,"GroupList", &PyGroupList_Type); /* ============================ cdrom.cc ============================ */ ADDTYPE(Module,"Cdrom",&PyCdrom_Type); /* ========================= configuration.cc ========================= */ @@ -824,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 ========================= */ @@ -838,6 +848,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)); @@ -845,86 +856,110 @@ 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 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 + 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", - 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 @@ -964,6 +999,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 da647c3f..b3534a30 100644 --- a/python/apt_pkgmodule.h +++ b/python/apt_pkgmodule.h @@ -70,6 +70,8 @@ extern PyTypeObject PyCache_Type; 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; @@ -100,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); @@ -132,6 +135,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. @@ -149,6 +153,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 @@ -156,6 +161,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 @@ -186,7 +192,9 @@ 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* 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/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 190d4f27..b263d320 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 MkPyNumber(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()); @@ -182,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*) { @@ -222,11 +276,21 @@ 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."}, + {"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, "The number of apt_pkg.Package objects stored in the cache."}, {"package_file_count",PkgCacheGetPackageFileCount,0, @@ -242,24 +306,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(); + } + + return cache->FindPkg(name, architecture); +} - // Search for the package - pkgCache::PkgIterator Pkg = Cache->FindPkg(Name); +// 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; } @@ -269,11 +346,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) @@ -292,7 +367,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, @@ -342,9 +421,11 @@ 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)."; + "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 = @@ -418,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) @@ -429,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); } @@ -501,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*) \ { \ @@ -514,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)) @@ -714,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); } @@ -869,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); } @@ -896,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()); @@ -924,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) @@ -999,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, @@ -1118,7 +1249,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*) @@ -1135,7 +1266,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) @@ -1344,13 +1475,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/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/configuration.cc b/python/configuration.cc index 93e92efa..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 = @@ -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/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/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/pkgmanager.cc b/python/pkgmanager.cc index 95e8c27e..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); @@ -79,7 +53,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) @@ -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 +}; /*}}}*/ 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/python-apt-helpers.cc b/python/python-apt-helpers.cc index 7a0f20c4..079b93cf 100644 --- a/python/python-apt-helpers.cc +++ b/python/python-apt-helpers.cc @@ -52,7 +52,9 @@ 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(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 b9fc9212..6f2a02df 100644 --- a/python/python-apt.h +++ b/python/python-apt.h @@ -167,6 +167,13 @@ 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); + + PyTypeObject *orderlist_type; + PyObject* (*orderlist_fromcpp)(pkgOrderList* const &obj, bool Delete, PyObject *Owner); + pkgOrderList*& (*orderlist_tocpp)(PyObject *self); }; // Checking macros. @@ -184,6 +191,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,12 +225,14 @@ 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) # 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) @@ -260,6 +270,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) @@ -267,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) @@ -292,6 +304,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 @@ -299,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 @@ -324,6 +338,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 @@ -331,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/python/string.cc b/python/string.cc index 6a1ce4e2..7abe2d17 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 /*{{{*/ @@ -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) diff --git a/setup.py b/setup.py index 9c6eda60..eff78379 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', 'orderlist.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_apt_cache.py b/tests/test_apt_cache.py index cccfc9c8..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() @@ -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) @@ -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_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_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() diff --git a/tests/test_group.py b/tests/test_group.py new file mode 100644 index 00000000..3c3a5b7a --- /dev/null +++ b/tests/test_group.py @@ -0,0 +1,32 @@ +import unittest + +import apt_pkg + + +class TestGroup(unittest.TestCase): + + def setUp(self): + apt_pkg.init() + self.cache = apt_pkg.Cache(progress=None) + + 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) + + + 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() 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 73050c16039e2adc3cb09b522a0ef36de450737e Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Wed, 13 Jul 2011 11:52:05 +0200 Subject: * add missing bits for the xz compression support for the 0.7 API, thanks to Colin Watson for the fix! (LP: #805389) * backport xz compression support the debian-sid bzr branch (LP: #805389) * apt/utils.py: - fix end date calculation for releases in june (LP: #602469) * apt/package.py: - Fix the changelog downloading if there are several source package versions available which provide the binary (LP: #377535). See http://bugs.debian.org/581831 for further details * debian/control: - update Vcs-Bzr location --- debian/changelog | 35 +++++++++++++++++++++++++++++++++++ doc/source/library/apt_inst.rst | 6 +++--- python/tar.cc | 2 ++ 3 files changed, 40 insertions(+), 3 deletions(-) diff --git a/debian/changelog b/debian/changelog index edd0081f..48ef958d 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,10 @@ +python-apt (0.8.0~exp4ubuntu2) UNRELEASED; urgency=low + + * add missing bits for the xz compression support for the + 0.7 API, thanks to Colin Watson for the fix! (LP: #805389) + + -- Michael Vogt Wed, 13 Jul 2011 11:51:47 +0200 + python-apt (0.8.0~exp4ubuntu1) oneiric; urgency=low * Merged from debian/experimental, remaining changes: @@ -682,6 +689,34 @@ python-apt (0.7.94.2ubuntu7) maverick; urgency=low -- Colin Watson Sun, 09 May 2010 13:17:03 +0200 +python-apt (0.7.94.2ubuntu6.3) lucid-proposed; urgency=low + + * backport xz compression support the debian-sid bzr branch + (LP: #805389) + + -- Michael Vogt Thu, 07 Jul 2011 10:59:49 +0200 + +python-apt (0.7.94.2ubuntu6.2) lucid-proposed; urgency=low + + * apt/utils.py: + - fix end date calculation for releases in june (LP: #602469) + + -- Jean-Baptiste Lallement Tue, 06 Jul 2010 23:46:49 +0200 + +python-apt (0.7.94.2ubuntu6.1) lucid-proposed; urgency=low + + [ Sebastian Heinlein ] + * apt/package.py: + - Fix the changelog downloading if there are several source package + versions available which provide the binary (LP: #377535). + See http://bugs.debian.org/581831 for further details + + [ Michael Vogt ] + * debian/control: + - update Vcs-Bzr location + + -- Michael Vogt Mon, 17 May 2010 15:37:44 +0200 + python-apt (0.7.94.2ubuntu6) lucid; urgency=low Cherry pick fix from the debian branch: diff --git a/doc/source/library/apt_inst.rst b/doc/source/library/apt_inst.rst index d9403a9e..9e6772f5 100644 --- a/doc/source/library/apt_inst.rst +++ b/doc/source/library/apt_inst.rst @@ -134,8 +134,8 @@ Debian Packages .. attribute:: data - The :class:`TarFile` object associated with the data.tar.{gz,bz2,lzma} - member. + The :class:`TarFile` object associated with the + data.tar.{gz,bz2,lzma,xz} member. .. attribute:: debian_binary @@ -307,7 +307,7 @@ function can be replaced. Call the function *func* for each member of the tar file *file*. The parameter *comp* is a string determining the compressor used. Possible - options are "lzma", "bzip2" and "gzip". The parameter *file* may be + options are "xz", "lzma", "bzip2" and "gzip". The parameter *file* may be a :class:`file()` object, a file descriptor, or anything implementing a :meth:`fileno` method. diff --git a/python/tar.cc b/python/tar.cc index b994d4e7..e42a9c50 100644 --- a/python/tar.cc +++ b/python/tar.cc @@ -182,6 +182,8 @@ PyObject *debExtract(PyObject *Self,PyObject *Args) Comp = "bzip2"; else if(strcmp(".lzma", &Chunk[strlen(Chunk)-5]) == 0) Comp = "lzma"; + else if(strcmp(".xz", &Chunk[strlen(Chunk)-3]) == 0) + Comp = "xz"; ExtractTar Tar(Deb.GetFile(),Member->Size,Comp); ProcessTar Proc(Function); if (Tar.Go(Proc) == false) -- cgit v1.2.3 From 4e2ee0c6dd09706f379b980796625439d16cc598 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Mon, 1 Aug 2011 09:49:51 +0200 Subject: merged from debian-sid --- po/python-apt.pot | 188 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 99 insertions(+), 89 deletions(-) diff --git a/po/python-apt.pot b/po/python-apt.pot index ec222e09..78f1fd11 100644 --- a/po/python-apt.pot +++ b/po/python-apt.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2011-03-21 15:14+0100\n" +"POT-Creation-Date: 2011-08-01 09:30+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -24,307 +24,317 @@ msgid "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" msgstr "" #. Description -#: ../data/templates/Ubuntu.info.in:13 +#: ../data/templates/Ubuntu.info.in:32 +msgid "Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:39 +msgid "Cdrom with Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:150 msgid "Ubuntu 11.04 'Natty Narwhal'" msgstr "" #. Description -#: ../data/templates/Ubuntu.info.in:31 +#: ../data/templates/Ubuntu.info.in:157 msgid "Cdrom with Ubuntu 11.04 'Natty Narwhal'" msgstr "" #. Description -#: ../data/templates/Ubuntu.info.in:94 +#: ../data/templates/Ubuntu.info.in:248 msgid "Ubuntu 10.10 'Maverick Meerkat'" msgstr "" #. Description -#: ../data/templates/Ubuntu.info.in:112 +#: ../data/templates/Ubuntu.info.in:267 msgid "Cdrom with Ubuntu 10.10 'Maverick Meerkat'" msgstr "" #. Description -#: ../data/templates/Ubuntu.info.in:124 +#: ../data/templates/Ubuntu.info.in:279 msgid "Canonical Partners" msgstr "" #. CompDescription -#: ../data/templates/Ubuntu.info.in:126 +#: ../data/templates/Ubuntu.info.in:281 msgid "Software packaged by Canonical for their partners" msgstr "" #. CompDescriptionLong -#: ../data/templates/Ubuntu.info.in:127 +#: ../data/templates/Ubuntu.info.in:282 msgid "This software is not part of Ubuntu." msgstr "" #. Description -#: ../data/templates/Ubuntu.info.in:134 +#: ../data/templates/Ubuntu.info.in:289 msgid "Independent" msgstr "" #. CompDescription -#: ../data/templates/Ubuntu.info.in:136 +#: ../data/templates/Ubuntu.info.in:291 msgid "Provided by third-party software developers" msgstr "" #. CompDescriptionLong -#: ../data/templates/Ubuntu.info.in:137 +#: ../data/templates/Ubuntu.info.in:292 msgid "Software offered by third party developers." msgstr "" #. Description -#: ../data/templates/Ubuntu.info.in:175 +#: ../data/templates/Ubuntu.info.in:330 msgid "Ubuntu 10.04 'Lucid Lynx'" msgstr "" #. Description -#: ../data/templates/Ubuntu.info.in:193 +#: ../data/templates/Ubuntu.info.in:349 msgid "Cdrom with Ubuntu 10.04 'Lucid Lynx'" msgstr "" #. Description -#: ../data/templates/Ubuntu.info.in:236 +#: ../data/templates/Ubuntu.info.in:392 msgid "Ubuntu 9.10 'Karmic Koala'" msgstr "" #. Description -#: ../data/templates/Ubuntu.info.in:254 +#: ../data/templates/Ubuntu.info.in:411 msgid "Cdrom with Ubuntu 9.10 'Karmic Koala'" msgstr "" #. Description -#: ../data/templates/Ubuntu.info.in:297 +#: ../data/templates/Ubuntu.info.in:454 msgid "Ubuntu 9.04 'Jaunty Jackalope'" msgstr "" #. Description -#: ../data/templates/Ubuntu.info.in:315 +#: ../data/templates/Ubuntu.info.in:473 msgid "Cdrom with Ubuntu 9.04 'Jaunty Jackalope'" msgstr "" #. Description -#: ../data/templates/Ubuntu.info.in:358 +#: ../data/templates/Ubuntu.info.in:516 msgid "Ubuntu 8.10 'Intrepid Ibex'" msgstr "" #. Description -#: ../data/templates/Ubuntu.info.in:376 +#: ../data/templates/Ubuntu.info.in:535 msgid "Cdrom with Ubuntu 8.10 'Intrepid Ibex'" msgstr "" #. Description -#: ../data/templates/Ubuntu.info.in:420 +#: ../data/templates/Ubuntu.info.in:579 msgid "Ubuntu 8.04 'Hardy Heron'" msgstr "" #. Description -#: ../data/templates/Ubuntu.info.in:438 +#: ../data/templates/Ubuntu.info.in:598 msgid "Cdrom with Ubuntu 8.04 'Hardy Heron'" msgstr "" #. Description -#: ../data/templates/Ubuntu.info.in:483 +#: ../data/templates/Ubuntu.info.in:643 msgid "Ubuntu 7.10 'Gutsy Gibbon'" msgstr "" #. Description -#: ../data/templates/Ubuntu.info.in:501 +#: ../data/templates/Ubuntu.info.in:662 msgid "Cdrom with Ubuntu 7.10 'Gutsy Gibbon'" msgstr "" #. Description -#: ../data/templates/Ubuntu.info.in:546 +#: ../data/templates/Ubuntu.info.in:707 msgid "Ubuntu 7.04 'Feisty Fawn'" msgstr "" #. Description -#: ../data/templates/Ubuntu.info.in:564 +#: ../data/templates/Ubuntu.info.in:726 msgid "Cdrom with Ubuntu 7.04 'Feisty Fawn'" msgstr "" #. Description -#: ../data/templates/Ubuntu.info.in:606 +#: ../data/templates/Ubuntu.info.in:768 msgid "Ubuntu 6.10 'Edgy Eft'" msgstr "" #. CompDescription -#: ../data/templates/Ubuntu.info.in:611 +#: ../data/templates/Ubuntu.info.in:773 msgid "Community-maintained" msgstr "" #. CompDescription -#: ../data/templates/Ubuntu.info.in:617 +#: ../data/templates/Ubuntu.info.in:779 msgid "Restricted software" msgstr "" #. Description -#: ../data/templates/Ubuntu.info.in:624 +#: ../data/templates/Ubuntu.info.in:787 msgid "Cdrom with Ubuntu 6.10 'Edgy Eft'" msgstr "" #. Description -#: ../data/templates/Ubuntu.info.in:666 +#: ../data/templates/Ubuntu.info.in:829 msgid "Ubuntu 6.06 LTS 'Dapper Drake'" msgstr "" #. CompDescriptionLong -#: ../data/templates/Ubuntu.info.in:669 +#: ../data/templates/Ubuntu.info.in:832 msgid "Canonical-supported Open Source software" msgstr "" #. CompDescription -#: ../data/templates/Ubuntu.info.in:671 +#: ../data/templates/Ubuntu.info.in:834 msgid "Community-maintained (universe)" msgstr "" #. CompDescriptionLong -#: ../data/templates/Ubuntu.info.in:672 +#: ../data/templates/Ubuntu.info.in:835 msgid "Community-maintained Open Source software" msgstr "" #. CompDescription -#: ../data/templates/Ubuntu.info.in:674 +#: ../data/templates/Ubuntu.info.in:837 msgid "Non-free drivers" msgstr "" #. CompDescriptionLong -#: ../data/templates/Ubuntu.info.in:675 +#: ../data/templates/Ubuntu.info.in:838 msgid "Proprietary drivers for devices" msgstr "" #. CompDescription -#: ../data/templates/Ubuntu.info.in:677 +#: ../data/templates/Ubuntu.info.in:840 msgid "Restricted software (Multiverse)" msgstr "" #. CompDescriptionLong -#: ../data/templates/Ubuntu.info.in:678 +#: ../data/templates/Ubuntu.info.in:841 msgid "Software restricted by copyright or legal issues" msgstr "" #. Description -#: ../data/templates/Ubuntu.info.in:684 +#: ../data/templates/Ubuntu.info.in:848 msgid "Cdrom with Ubuntu 6.06 LTS 'Dapper Drake'" msgstr "" #. Description -#: ../data/templates/Ubuntu.info.in:700 +#: ../data/templates/Ubuntu.info.in:864 msgid "Important security updates" msgstr "" #. Description -#: ../data/templates/Ubuntu.info.in:705 +#: ../data/templates/Ubuntu.info.in:869 msgid "Recommended updates" msgstr "" #. Description -#: ../data/templates/Ubuntu.info.in:710 +#: ../data/templates/Ubuntu.info.in:874 msgid "Pre-released updates" msgstr "" #. Description -#: ../data/templates/Ubuntu.info.in:715 +#: ../data/templates/Ubuntu.info.in:879 msgid "Unsupported updates" msgstr "" #. Description -#: ../data/templates/Ubuntu.info.in:726 +#: ../data/templates/Ubuntu.info.in:890 msgid "Ubuntu 5.10 'Breezy Badger'" msgstr "" #. Description -#: ../data/templates/Ubuntu.info.in:740 +#: ../data/templates/Ubuntu.info.in:905 msgid "Cdrom with Ubuntu 5.10 'Breezy Badger'" msgstr "" #. Description -#: ../data/templates/Ubuntu.info.in:756 +#: ../data/templates/Ubuntu.info.in:921 msgid "Ubuntu 5.10 Security Updates" msgstr "" #. Description -#: ../data/templates/Ubuntu.info.in:761 +#: ../data/templates/Ubuntu.info.in:926 msgid "Ubuntu 5.10 Updates" msgstr "" #. Description -#: ../data/templates/Ubuntu.info.in:766 +#: ../data/templates/Ubuntu.info.in:931 msgid "Ubuntu 5.10 Backports" msgstr "" #. Description -#: ../data/templates/Ubuntu.info.in:777 +#: ../data/templates/Ubuntu.info.in:942 msgid "Ubuntu 5.04 'Hoary Hedgehog'" msgstr "" #. Description -#: ../data/templates/Ubuntu.info.in:791 +#: ../data/templates/Ubuntu.info.in:957 msgid "Cdrom with Ubuntu 5.04 'Hoary Hedgehog'" msgstr "" #. CompDescription -#: ../data/templates/Ubuntu.info.in:794 ../data/templates/Debian.info.in:149 +#: ../data/templates/Ubuntu.info.in:960 ../data/templates/Debian.info.in:149 msgid "Officially supported" msgstr "" #. Description -#: ../data/templates/Ubuntu.info.in:807 +#: ../data/templates/Ubuntu.info.in:973 msgid "Ubuntu 5.04 Security Updates" msgstr "" #. Description -#: ../data/templates/Ubuntu.info.in:812 +#: ../data/templates/Ubuntu.info.in:978 msgid "Ubuntu 5.04 Updates" msgstr "" #. Description -#: ../data/templates/Ubuntu.info.in:817 +#: ../data/templates/Ubuntu.info.in:983 msgid "Ubuntu 5.04 Backports" msgstr "" #. Description -#: ../data/templates/Ubuntu.info.in:823 +#: ../data/templates/Ubuntu.info.in:989 msgid "Ubuntu 4.10 'Warty Warthog'" msgstr "" #. CompDescription -#: ../data/templates/Ubuntu.info.in:829 +#: ../data/templates/Ubuntu.info.in:995 msgid "Community-maintained (Universe)" msgstr "" #. CompDescription -#: ../data/templates/Ubuntu.info.in:831 +#: ../data/templates/Ubuntu.info.in:997 msgid "Non-free (Multiverse)" msgstr "" #. Description -#: ../data/templates/Ubuntu.info.in:837 +#: ../data/templates/Ubuntu.info.in:1004 msgid "Cdrom with Ubuntu 4.10 'Warty Warthog'" msgstr "" #. CompDescription -#: ../data/templates/Ubuntu.info.in:840 +#: ../data/templates/Ubuntu.info.in:1007 msgid "No longer officially supported" msgstr "" #. CompDescription -#: ../data/templates/Ubuntu.info.in:842 +#: ../data/templates/Ubuntu.info.in:1009 msgid "Restricted copyright" msgstr "" #. Description -#: ../data/templates/Ubuntu.info.in:849 +#: ../data/templates/Ubuntu.info.in:1016 msgid "Ubuntu 4.10 Security Updates" msgstr "" #. Description -#: ../data/templates/Ubuntu.info.in:854 +#: ../data/templates/Ubuntu.info.in:1021 msgid "Ubuntu 4.10 Updates" msgstr "" #. Description -#: ../data/templates/Ubuntu.info.in:859 +#: ../data/templates/Ubuntu.info.in:1026 msgid "Ubuntu 4.10 Backports" msgstr "" @@ -390,7 +400,7 @@ msgid "Non-DFSG-compatible Software" msgstr "" #. TRANSLATORS: %s is a country -#: ../aptsources/distro.py:210 ../aptsources/distro.py:425 +#: ../aptsources/distro.py:210 ../aptsources/distro.py:428 #, python-format msgid "Server for %s" msgstr "" @@ -430,16 +440,16 @@ msgstr "" msgid "Complete" msgstr "" -#: ../apt/package.py:342 +#: ../apt/package.py:358 #, python-format msgid "Invalid unicode in description for '%s' (%s). Please report." msgstr "" -#: ../apt/package.py:1012 ../apt/package.py:1117 +#: ../apt/package.py:1065 ../apt/package.py:1171 msgid "The list of changes is not available" msgstr "" -#: ../apt/package.py:1123 +#: ../apt/package.py:1177 #, python-format msgid "" "The list of changes is not available yet.\n" @@ -448,29 +458,29 @@ msgid "" "until the changes become available or try again later." msgstr "" -#: ../apt/package.py:1130 +#: ../apt/package.py:1184 msgid "" "Failed to download the list of changes. \n" "Please check your Internet connection." msgstr "" -#: ../apt/debfile.py:81 +#: ../apt/debfile.py:82 #, python-format msgid "List of files for '%s' could not be read" msgstr "" -#: ../apt/debfile.py:166 +#: ../apt/debfile.py:167 #, python-format msgid "Dependency is not satisfiable: %s\n" msgstr "" -#: ../apt/debfile.py:187 +#: ../apt/debfile.py:188 #, python-format msgid "Conflicts with the installed package '%s'" msgstr "" #. 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:326 +#: ../apt/debfile.py:327 #, python-format msgid "" "Breaks existing package '%(pkgname)s' dependency %(depname)s " @@ -478,63 +488,63 @@ msgid "" msgstr "" #. 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:342 +#: ../apt/debfile.py:343 #, python-format msgid "" "Breaks existing package '%(pkgname)s' conflict: %(targetpkg)s (%(comptype)s " "%(targetver)s)" msgstr "" -#: ../apt/debfile.py:352 +#: ../apt/debfile.py:353 #, python-format msgid "" "Breaks existing package '%(pkgname)s' that conflict: '%(targetpkg)s'. But " "the '%(debfile)s' provides it via: '%(provides)s'" msgstr "" -#: ../apt/debfile.py:398 +#: ../apt/debfile.py:399 msgid "No Architecture field in the package" msgstr "" -#: ../apt/debfile.py:403 +#: ../apt/debfile.py:404 #, python-format msgid "Wrong architecture '%s'" msgstr "" #. the deb is older than the installed -#: ../apt/debfile.py:410 +#: ../apt/debfile.py:411 msgid "A later version is already installed" msgstr "" -#: ../apt/debfile.py:435 +#: ../apt/debfile.py:436 msgid "Failed to satisfy all dependencies (broken cache)" msgstr "" -#: ../apt/debfile.py:465 +#: ../apt/debfile.py:466 #, python-format msgid "Cannot install '%s'" msgstr "" -#: ../apt/debfile.py:507 +#: ../apt/debfile.py:508 msgid "Python-debian module not available" msgstr "" -#: ../apt/debfile.py:541 +#: ../apt/debfile.py:542 msgid "" "Automatically decompressed:\n" "\n" msgstr "" -#: ../apt/debfile.py:547 +#: ../apt/debfile.py:548 msgid "Automatically converted to printable ascii:\n" msgstr "" -#: ../apt/debfile.py:637 +#: ../apt/debfile.py:638 #, python-format msgid "Install Build-Dependencies for source package '%s' that builds %s\n" msgstr "" -#: ../apt/debfile.py:647 +#: ../apt/debfile.py:648 msgid "An essential package would be removed" msgstr "" @@ -559,11 +569,11 @@ msgstr "" msgid "Get:" msgstr "" -#: ../apt/progress/text.py:204 +#: ../apt/progress/text.py:203 msgid " [Working]" msgstr "" -#: ../apt/progress/text.py:215 +#: ../apt/progress/text.py:214 #, python-format msgid "" "Media change: please insert the disc labeled\n" @@ -572,19 +582,19 @@ msgid "" msgstr "" #. Trick for getting a translation from apt -#: ../apt/progress/text.py:224 +#: ../apt/progress/text.py:223 #, python-format msgid "Fetched %sB in %s (%sB/s)\n" msgstr "" -#: ../apt/progress/text.py:240 +#: ../apt/progress/text.py:239 msgid "Please provide a name for this Disc, such as 'Debian 2.1r1 Disk 1'" msgstr "" -#: ../apt/progress/text.py:256 +#: ../apt/progress/text.py:255 msgid "Please insert a Disc in the drive and press enter" msgstr "" -#: ../apt/cache.py:135 +#: ../apt/cache.py:149 msgid "Building data structures" msgstr "" -- cgit v1.2.3 From 4ac62e28a844ff17c40c50eb16625baeb116a1c1 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Mon, 8 Aug 2011 15:24:10 +0200 Subject: releasing version 0.8.0ubuntu1 --- debian/changelog | 24 +++--------------------- debian/control | 2 +- 2 files changed, 4 insertions(+), 22 deletions(-) diff --git a/debian/changelog b/debian/changelog index 8ec9c660..72cb6289 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,4 +1,4 @@ -python-apt (0.8.1) UNRELEASED; urgency=low +python-apt (0.8.0ubuntu1) oneiric; urgency=low [ Julian Andres Klode ] * Breaks: debsecan (<< 0.4.15) [not only << 0.4.14] (Closes: #629512) @@ -16,27 +16,9 @@ python-apt (0.8.1) UNRELEASED; urgency=low - fix test by providing proper fixture data - fix test if sources.list is not readable (as is the case on some PPA buildds) + * build against the latest libapt - -- Julian Andres Klode Tue, 07 Jun 2011 14:00:22 +0200 - -python-apt (0.8.0ubuntu1) UNRELEASED; urgency=low - - [ Julian Andres Klode ] - * Breaks: debsecan (<< 0.4.15) [not only << 0.4.14] (Closes: #629512) - - [ Michael Vogt ] - * merged from the debian-sid bzr branch - - * 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 - * 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 + -- Michael Vogt Mon, 08 Aug 2011 14:24:29 +0200 python-apt (0.8.0) unstable; urgency=low diff --git a/debian/control b/debian/control index 2945e1b3..e91a5e09 100644 --- a/debian/control +++ b/debian/control @@ -9,7 +9,7 @@ XS-Python-Version: >= 2.6 X-Python3-Version: >= 3.1 Build-Depends: apt-utils, debhelper (>= 7.3.5), - libapt-pkg-dev (>= 0.8.11), + libapt-pkg-dev (>= 0.8.16~exp5), python-all-dev (>= 2.6.6-3~), python-all-dbg, python3-all-dev (>= 3.1.2-10~), -- cgit v1.2.3 From cf6cbda23e3b78beb6ce2ef84c5445200b1dfc08 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Mon, 8 Aug 2011 18:55:44 +0200 Subject: disable tests if /etc/apt/sources.list is not readable --- debian/changelog | 6 ++++++ tests/test_all.py | 4 ++++ 2 files changed, 10 insertions(+) diff --git a/debian/changelog b/debian/changelog index 72cb6289..681ce97d 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +python-apt (0.8.0ubuntu2) oneiric; urgency=low + + * disable tests if /etc/apt/sources.list is not readable + + -- Michael Vogt Mon, 08 Aug 2011 18:51:50 +0200 + python-apt (0.8.0ubuntu1) oneiric; urgency=low [ Julian Andres Klode ] diff --git a/tests/test_all.py b/tests/test_all.py index 091581f8..f7b9dc8c 100644 --- a/tests/test_all.py +++ b/tests/test_all.py @@ -34,6 +34,10 @@ def get_library_dir(): return os.path.abspath(library_dir) if __name__ == '__main__': + if not os.access("/etc/apt/sources.list", os.R_OK): + sys.stderr.write("[tests] Skipping because sources.list is not readable\n") + sys.exit(0) + sys.stderr.write("[tests] Running on %s\n" % sys.version.replace("\n", "")) dirname = os.path.dirname(__file__) if dirname: -- cgit v1.2.3 From 7d66a39c6a3a8ca30dc507c531d7894435476eec Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Tue, 9 Aug 2011 16:03:15 +0200 Subject: * aptsources/sourceslist.py: - fix py3.2 compat issue that causes FTBFS on amd64 tests --- aptsources/sourceslist.py | 2 +- debian/changelog | 9 ++++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/aptsources/sourceslist.py b/aptsources/sourceslist.py index b85e6947..62442cc3 100644 --- a/aptsources/sourceslist.py +++ b/aptsources/sourceslist.py @@ -374,7 +374,7 @@ class SourcesList(object): source = SourceEntry(line, file) self.list.append(source) except: - print "could not open file '%s'" % file + sys.stderr.write("could not open file '%s'\n" % file) def save(self): """ save the current sources """ diff --git a/debian/changelog b/debian/changelog index 62721860..c03e304c 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,10 +1,17 @@ -python-apt (0.8.0ubuntu3) oneiric; urgency=low +python-apt (0.8.0ubuntu4) oneiric; urgency=low * apt/package.py: - fix py3 compatbility with print -- Michael Vogt Tue, 09 Aug 2011 09:19:42 +0200 +python-apt (0.8.0ubuntu3) oneiric; urgency=low + + * aptsources/sourceslist.py: + - fix py3.2 compat issue that causes FTBFS on amd64 tests + + -- Michael Vogt Mon, 08 Aug 2011 22:48:43 +0200 + python-apt (0.8.0ubuntu2) oneiric; urgency=low * disable tests if /etc/apt/sources.list is not readable -- cgit v1.2.3 From abe2144d5969694c1143c8fa6dc87800275b81be Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Tue, 9 Aug 2011 16:05:59 +0200 Subject: releasing version 0.8.0ubuntu5 --- debian/changelog | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/debian/changelog b/debian/changelog index c03e304c..86c0bb06 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,9 +1,16 @@ +python-apt (0.8.0ubuntu5) oneiric; urgency=low + + * setup.py: + - enable extra builds too + + -- Michael Vogt Tue, 09 Aug 2011 16:05:09 +0200 + python-apt (0.8.0ubuntu4) oneiric; urgency=low * apt/package.py: - fix py3 compatbility with print - -- Michael Vogt Tue, 09 Aug 2011 09:19:42 +0200 + -- Michael Vogt Tue, 09 Aug 2011 16:04:04 +0200 python-apt (0.8.0ubuntu3) oneiric; urgency=low -- cgit v1.2.3 From 3650bfc5b6dd1267c5489a8a1f619ab218a03f69 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Tue, 9 Aug 2011 16:39:37 +0200 Subject: * debian/control: - remove recommends of python2.6 --- debian/changelog | 7 +++++++ debian/control | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/debian/changelog b/debian/changelog index 86c0bb06..5a541b40 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,10 @@ +python-apt (0.8.0ubuntu6) UNRELEASED; urgency=low + + * debian/control: + - remove recommends of python2.6 + + -- Michael Vogt Tue, 09 Aug 2011 16:39:06 +0200 + python-apt (0.8.0ubuntu5) oneiric; urgency=low * setup.py: diff --git a/debian/control b/debian/control index e91a5e09..b34007cd 100644 --- a/debian/control +++ b/debian/control @@ -23,7 +23,7 @@ XS-Debian-Vcs-Browser: http://bzr.debian.org/loggerhead/apt/python-apt/debian-si Package: python-apt Architecture: any Depends: ${python:Depends}, ${shlibs:Depends}, ${misc:Depends}, python-apt-common -Recommends: lsb-release, iso-codes, python2.6 +Recommends: lsb-release, iso-codes Breaks: packagekit-backend-apt (<= 0.4.8-0ubuntu4), computer-janitor (<< 1.14.1-1+), debdelta (<< 0.41+), -- cgit v1.2.3 From cf9edec2eb91a4d087ba50c0bc90606bc3121ed4 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Thu, 11 Aug 2011 15:38:04 +0200 Subject: * utils/get_ubuntu_mirrors_from_lp.py: - add "mirror://mirrors.ubuntu.com/mirrors.txt" to the default mirror list --- debian/changelog | 3 +++ utils/get_ubuntu_mirrors_from_lp.py | 1 + 2 files changed, 4 insertions(+) diff --git a/debian/changelog b/debian/changelog index 354c13d6..de846946 100644 --- a/debian/changelog +++ b/debian/changelog @@ -2,6 +2,9 @@ python-apt (0.8.0ubuntu7) UNRELEASED; urgency=low * aptsources/distinfo.py: - make mirror a valid protocol name + * utils/get_ubuntu_mirrors_from_lp.py: + - add "mirror://mirrors.ubuntu.com/mirrors.txt" to the + default mirror list -- Michael Vogt Thu, 11 Aug 2011 15:31:55 +0200 diff --git a/utils/get_ubuntu_mirrors_from_lp.py b/utils/get_ubuntu_mirrors_from_lp.py index 341dba8a..ed0ee936 100755 --- a/utils/get_ubuntu_mirrors_from_lp.py +++ b/utils/get_ubuntu_mirrors_from_lp.py @@ -42,6 +42,7 @@ for entry in d.entries: keys = countries.keys() keys.sort() +print "mirror://mirrors.ubuntu.com/mirrors.txt" for country in keys: print "#LOC:%s" % country print "\n".join(sorted(countries[country])) -- cgit v1.2.3 From bb4108a5aee372c75e1743892e2b43b268efb562 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Thu, 11 Aug 2011 15:38:58 +0200 Subject: releasing version 0.8.0ubuntu7 --- debian/changelog | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/debian/changelog b/debian/changelog index de846946..3d998dd4 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,4 +1,4 @@ -python-apt (0.8.0ubuntu7) UNRELEASED; urgency=low +python-apt (0.8.0ubuntu7) oneiric; urgency=low * aptsources/distinfo.py: - make mirror a valid protocol name @@ -6,7 +6,7 @@ python-apt (0.8.0ubuntu7) UNRELEASED; urgency=low - add "mirror://mirrors.ubuntu.com/mirrors.txt" to the default mirror list - -- Michael Vogt Thu, 11 Aug 2011 15:31:55 +0200 + -- Michael Vogt Thu, 11 Aug 2011 15:38:06 +0200 python-apt (0.8.0ubuntu6) oneiric; urgency=low -- cgit v1.2.3 From bbe36232eb04a191d8fefee5bc65710e4347c0dd Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Wed, 28 Sep 2011 16:25:09 +0200 Subject: add concept of "ParentComponent" for e.g. ubuntu/multiverse that needs universe enabled as well (plus add test) LP: #829284 --- aptsources/distinfo.py | 11 ++++++++++- aptsources/distro.py | 14 ++++++++++++-- data/templates/Ubuntu.info.in | 4 ++++ debian/changelog | 8 ++++++++ tests/test_aptsources.py | 23 +++++++++++++++++++++++ 5 files changed, 57 insertions(+), 3 deletions(-) diff --git a/aptsources/distinfo.py b/aptsources/distinfo.py index dbd28939..c8ec5c46 100644 --- a/aptsources/distinfo.py +++ b/aptsources/distinfo.py @@ -69,10 +69,17 @@ class Template(object): class Component(object): - def __init__(self, name, desc=None, long_desc=None): + def __init__(self, name, desc=None, long_desc=None, parent_component=None): self.name = name self.description = desc self.description_long = long_desc + self.parent_component = parent_component + + def get_parent_component(self): + return self.parent_component + + def set_parent_component(self, parent): + self.parent_component = parent def get_description(self): if self.description_long is not None: @@ -257,6 +264,8 @@ class DistInfo(object): component.set_description(_(value)) elif field == 'CompDescriptionLong': component.set_description_long(_(value)) + elif field == 'ParentComponent': + component.set_parent_component(value) self.finish_template(template, component) template=None component=None diff --git a/aptsources/distro.py b/aptsources/distro.py index 41c86981..f777a4ea 100644 --- a/aptsources/distro.py +++ b/aptsources/distro.py @@ -291,6 +291,16 @@ class Distribution(object): comp: the component that should be enabled """ + comps = set([comp]) + # look for parent components that we may have to add + for source in self.main_sources: + for c in source.template.components: + if c.name == comp and c.parent_component: + comps.add(c.parent_component) + for c in comps: + self._enable_component(c) + + def _enable_component(self, comp): def add_component_only_once(source, comps_per_dist): """ @@ -298,12 +308,12 @@ class Distribution(object): a repository could be splitted into different apt lines. If not add the component """ - # if we don't that distro, just reutnr (can happen for e.g. + # if we don't have that distro, just return (can happen for e.g. # dapper-update only in deb-src if source.dist not in comps_per_dist: return # if we have seen this component already for this distro, - # return (nothing to do + # return (nothing to do) if comp in comps_per_dist[source.dist]: return # add it diff --git a/data/templates/Ubuntu.info.in b/data/templates/Ubuntu.info.in index 39d9256e..e8afe443 100644 --- a/data/templates/Ubuntu.info.in +++ b/data/templates/Ubuntu.info.in @@ -21,6 +21,7 @@ Component: restricted _CompDescription: Non-free drivers _CompDescriptionLong: Proprietary drivers for devices Component: multiverse +ParentComponent: universe _CompDescription: Restricted software _CompDescriptionLong: Software restricted by copyright or legal issues @@ -139,6 +140,7 @@ Component: restricted _CompDescription: Non-free drivers _CompDescriptionLong: Proprietary drivers for devices Component: multiverse +ParentComponent: universe _CompDescription: Restricted software _CompDescriptionLong: Software restricted by copyright or legal issues @@ -256,6 +258,7 @@ Component: restricted _CompDescription: Non-free drivers _CompDescriptionLong: Proprietary drivers for devices Component: multiverse +ParentComponent: universe _CompDescription: Restricted software _CompDescriptionLong: Software restricted by copyright or legal issues @@ -338,6 +341,7 @@ Component: restricted _CompDescription: Non-free drivers _CompDescriptionLong: Proprietary drivers for devices Component: multiverse +ParentComponent: universe _CompDescription: Restricted software _CompDescriptionLong: Software restricted by copyright or legal issues diff --git a/debian/changelog b/debian/changelog index 3d998dd4..47ff5efd 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,11 @@ +python-apt (0.8.0ubuntu8) UNRELEASEDoneiric; urgency=low + + * add concept of "ParentComponent" for e.g. ubuntu/multiverse + that needs universe enabled as well (plus add test) + LP: #829284 + + -- Michael Vogt Wed, 28 Sep 2011 15:48:23 +0200 + python-apt (0.8.0ubuntu7) oneiric; urgency=low * aptsources/distinfo.py: diff --git a/tests/test_aptsources.py b/tests/test_aptsources.py index 193d3806..dcfb0682 100644 --- a/tests/test_aptsources.py +++ b/tests/test_aptsources.py @@ -160,6 +160,29 @@ class TestAptSources(unittest.TestCase): assert sources.list[8].comps == ["main"] assert sources.list[8].line.strip() == str(sources.list[8]) + def test_enable_component(self): + from subprocess import Popen, PIPE + target = "./data/aptsources/sources.list.enable_comps" + line = "deb http://archive.ubuntu.com/ubuntu lucid main\n" + open(target, "w").write(line) + apt_pkg.config.set("Dir::Etc::sourcelist", target) + sources = aptsources.sourceslist.SourcesList(True, self.templates) + distro = aptsources.distro.get_distro(id="Ubuntu") + # make sure we are using the right distro + distro.codename = "lucid" + distro.id = "Ubuntu" + distro.release = "10.04" + # and get the sources + distro.get_sources(sources) + # test enable_component + comp = "multiverse" + distro.enable_component(comp) + comps = set() + for entry in sources: + comps = comps.union(set(entry.comps)) + self.assertTrue("multiverse" in comps) + self.assertTrue("universe" in comps) + def testDistribution(self): """aptsources: Test distribution detection.""" apt_pkg.config.set("Dir::Etc::sourcelist", "data/aptsources/" -- cgit v1.2.3 From b00b27a414421e8965f95af421ce5675133c1884 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Wed, 28 Sep 2011 16:40:42 +0200 Subject: releasing version 0.8.0ubuntu8 --- debian/changelog | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/debian/changelog b/debian/changelog index 47ff5efd..906f86df 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,10 +1,10 @@ -python-apt (0.8.0ubuntu8) UNRELEASEDoneiric; urgency=low +python-apt (0.8.0ubuntu8) oneiric; urgency=low * add concept of "ParentComponent" for e.g. ubuntu/multiverse that needs universe enabled as well (plus add test) LP: #829284 - -- Michael Vogt Wed, 28 Sep 2011 15:48:23 +0200 + -- Michael Vogt Wed, 28 Sep 2011 16:27:20 +0200 python-apt (0.8.0ubuntu7) oneiric; urgency=low -- cgit v1.2.3 From 53aea1b695035db409775f9f1fbfadabbbf4d593 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Tue, 4 Oct 2011 16:36:48 +0200 Subject: * apt/progress/gtk2.py: - update to the latest vte API for child-exited (LP: #865388) --- apt/progress/gtk2.py | 9 +++++---- debian/changelog | 7 +++++++ 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/apt/progress/gtk2.py b/apt/progress/gtk2.py index 9137ef76..b5794e92 100644 --- a/apt/progress/gtk2.py +++ b/apt/progress/gtk2.py @@ -34,6 +34,7 @@ except ImportError: import gobject as glib import gobject import pango +import time import vte import apt_pkg @@ -127,16 +128,15 @@ class GInstallProgress(gobject.GObject, base.InstallProgress): self.apt_status = -1 self.time_last_update = time.time() self.term = term - reaper = vte.reaper_get() - reaper.connect("child-exited", self.child_exited) + self.term.connect("child-exited", self.child_exited) self.env = ["VTE_PTY_KEEP_FD=%s" % self.writefd, "DEBIAN_FRONTEND=gnome", "APT_LISTCHANGES_FRONTEND=gtk"] self._context = glib.main_context_default() - def child_exited(self, term, pid, status): + def child_exited(self, term): """Called when a child process exits""" - self.apt_status = os.WEXITSTATUS(status) + self.apt_status = term.get_child_exit_status() self.finished = True def error(self, pkg, errormsg): @@ -204,6 +204,7 @@ class GInstallProgress(gobject.GObject, base.InstallProgress): """Wait for the child process to exit.""" while not self.finished: self.update_interface() + time.sleep(0.02) return self.apt_status if apt_pkg._COMPAT_0_7: diff --git a/debian/changelog b/debian/changelog index 906f86df..d7a4d46f 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,10 @@ +python-apt (0.8.0ubuntu9) oneiric; urgency=low + + * apt/progress/gtk2.py: + - update to the latest vte API for child-exited (LP: #865388) + + -- Michael Vogt Tue, 04 Oct 2011 16:35:52 +0200 + python-apt (0.8.0ubuntu8) oneiric; urgency=low * add concept of "ParentComponent" for e.g. ubuntu/multiverse -- cgit v1.2.3 From 71a4595542ccb37fa6a781826984af77d294646c Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Mon, 10 Oct 2011 11:19:46 +0200 Subject: * aptsources/sourceslist.py: - import distinfo from the same dir (LP: #871007) --- aptsources/sourceslist.py | 2 +- debian/changelog | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/aptsources/sourceslist.py b/aptsources/sourceslist.py index 62442cc3..208b0175 100644 --- a/aptsources/sourceslist.py +++ b/aptsources/sourceslist.py @@ -33,7 +33,7 @@ import sys import time import apt_pkg -from aptsources.distinfo import DistInfo +from distinfo import DistInfo from apt.deprecation import function_deprecated_by diff --git a/debian/changelog b/debian/changelog index d7a4d46f..246391b9 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,10 @@ +python-apt (0.8.0ubuntu10) UNRELEASEDoneiric-updates; urgency=low + + * aptsources/sourceslist.py: + - import distinfo from the same dir (LP: #871007) + + -- Michael Vogt Mon, 10 Oct 2011 11:13:20 +0200 + python-apt (0.8.0ubuntu9) oneiric; urgency=low * apt/progress/gtk2.py: -- cgit v1.2.3 From 8c24ad05afb705f7842cb2bc7e08450acbe49653 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Wed, 19 Oct 2011 17:38:57 +0200 Subject: * data/templates/Ubuntu.info.in: - add precise --- data/templates/Ubuntu.info.in | 121 ++++++++++++++++++++++++++++++++++++++++++ debian/changelog | 2 + 2 files changed, 123 insertions(+) diff --git a/data/templates/Ubuntu.info.in b/data/templates/Ubuntu.info.in index e8afe443..9e62c0fa 100644 --- a/data/templates/Ubuntu.info.in +++ b/data/templates/Ubuntu.info.in @@ -1,5 +1,123 @@ _ChangelogURI: http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog +Suite: precise +RepositoryType: deb +BaseURI: http://ports.ubuntu.com/ubuntu-ports/ +MatchURI: ports.ubuntu.com/ubuntu-ports +BaseURI-amd64: http://archive.ubuntu.com/ubuntu +MatchURI-amd64: archive.ubuntu.com/ubuntu +BaseURI-i386: http://archive.ubuntu.com/ubuntu +MatchURI-i386: archive.ubuntu.com/ubuntu +MirrorsFile-amd64: Ubuntu.mirrors +MirrorsFile-i386: Ubuntu.mirrors +_Description: Ubuntu 12.04 'Precise Pangolin' +Component: main +_CompDescription: Officially supported +_CompDescriptionLong: Canonical-supported Open Source software +Component: universe +_CompDescription: Community-maintained +_CompDescriptionLong: Community-maintained Open Source software +Component: restricted +_CompDescription: Non-free drivers +_CompDescriptionLong: Proprietary drivers for devices +Component: multiverse +ParentComponent: universe +_CompDescription: Restricted software +_CompDescriptionLong: Software restricted by copyright or legal issues + +Suite: precise +ParentSuite: precise +RepositoryType: deb-src +BaseURI: http://archive.ubuntu.com/ubuntu/ +MatchURI: archive.ubuntu.com/ubuntu|ports.ubuntu.com/ubuntu-ports +_Description: Ubuntu 12.04 'Precise Pangolin' + +Suite: precise +RepositoryType: deb +MatchName: .* +BaseURI: cdrom:\[Ubuntu.*12.04 +MatchURI: cdrom:\[Ubuntu.*12.04 +_Description: Cdrom with Ubuntu 12.04 'Precise Pangolin' +Available: False +Component: main +_CompDescription: Officially supported +Component: restricted +_CompDescription: Restricted copyright + +Suite: precise +Official: false +RepositoryType: deb +BaseURI: http://archive.canonical.com +MatchURI: archive.canonical.com +_Description: Canonical Partners +Component: partner +_CompDescription: Software packaged by Canonical for their partners +_CompDescriptionLong: This software is not part of Ubuntu. + +Suite: precise +Official: false +RepositoryType: deb +BaseURI: http://extras.ubuntu.com +MatchURI: extras.ubuntu.com +_Description: Independent +Component: main +_CompDescription: Provided by third-party software developers +_CompDescriptionLong: Software offered by third party developers. + +Suite: precise-security +ParentSuite: precise +RepositoryType: deb +BaseURI: http://ports.ubuntu.com/ubuntu-ports/ +MatchURI: ports.ubuntu.com/ubuntu-ports +BaseURI-amd64: http://security.ubuntu.com/ubuntu/ +MatchURI-amd64: archive.ubuntu.com/ubuntu|security.ubuntu.com +BaseURI-i386: http://security.ubuntu.com/ubuntu/ +MatchURI-i386: archive.ubuntu.com/ubuntu|security.ubuntu.com +_Description: Important security updates + +Suite: precise-security +ParentSuite: precise +RepositoryType: deb-src +BaseURI: http://archive.ubuntu.com/ubuntu/ +MatchURI: archive.ubuntu.com/ubuntu|ports.ubuntu.com/ubuntu-ports|security.ubuntu.com +_Description: Important security updates + +Suite: precise-updates +ParentSuite: precise +RepositoryType: deb +_Description: Recommended updates + +Suite: precise-updates +ParentSuite: precise +RepositoryType: deb-src +BaseURI: http://archive.ubuntu.com/ubuntu/ +MatchURI: archive.ubuntu.com/ubuntu|ports.ubuntu.com/ubuntu-ports +_Description: Recommended updates + +Suite: precise-proposed +ParentSuite: precise +RepositoryType: deb +_Description: Pre-released updates + +Suite: precise-proposed +ParentSuite: precise +RepositoryType: deb-src +BaseURI: http://archive.ubuntu.com/ubuntu/ +MatchURI: archive.ubuntu.com/ubuntu|ports.ubuntu.com/ubuntu-ports +_Description: Pre-released updates + +Suite: precise-backports +ParentSuite: precise +RepositoryType: deb +_Description: Unsupported updates + +Suite: precise-backports +ParentSuite: precise +RepositoryType: deb-src +BaseURI: http://archive.ubuntu.com/ubuntu/ +MatchURI: archive.ubuntu.com/ubuntu|ports.ubuntu.com/ubuntu-ports +_Description: Unsupported updates + Suite: oneiric RepositoryType: deb BaseURI: http://ports.ubuntu.com/ubuntu-ports/ @@ -404,6 +522,7 @@ Component: restricted _CompDescription: Non-free drivers _CompDescriptionLong: Proprietary drivers for devices Component: multiverse +ParentComponent: universe _CompDescription: Restricted software _CompDescriptionLong: Software restricted by copyright or legal issues @@ -528,6 +647,7 @@ Component: restricted _CompDescription: Non-free drivers _CompDescriptionLong: Proprietary drivers for devices Component: multiverse +ParentComponent: universe _CompDescription: Restricted software _CompDescriptionLong: Software restricted by copyright or legal issues @@ -591,6 +711,7 @@ Component: restricted _CompDescription: Non-free drivers _CompDescriptionLong: Proprietary drivers for devices Component: multiverse +ParentComponent: universe _CompDescription: Restricted software _CompDescriptionLong: Software restricted by copyright or legal issues diff --git a/debian/changelog b/debian/changelog index 246391b9..7c76edb1 100644 --- a/debian/changelog +++ b/debian/changelog @@ -2,6 +2,8 @@ python-apt (0.8.0ubuntu10) UNRELEASEDoneiric-updates; urgency=low * aptsources/sourceslist.py: - import distinfo from the same dir (LP: #871007) + * data/templates/Ubuntu.info.in: + - add precise -- Michael Vogt Mon, 10 Oct 2011 11:13:20 +0200 -- cgit v1.2.3 From b0995cca556668a4eced03e40e3edbc7362c2a10 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Wed, 19 Oct 2011 17:52:31 +0200 Subject: releasing version 0.8.1ubuntu1 --- debian/changelog | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/debian/changelog b/debian/changelog index c6a29ed1..f5a2beae 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,11 +1,11 @@ -python-apt (0.8.1ubuntu1) UNRELEASEDprecise; urgency=low +python-apt (0.8.1ubuntu1) precise; urgency=low * aptsources/sourceslist.py: - import distinfo from the same dir (LP: #871007) * data/templates/Ubuntu.info.in: - add precise - -- Michael Vogt Mon, 10 Oct 2011 11:13:20 +0200 + -- Michael Vogt Wed, 19 Oct 2011 17:46:18 +0200 python-apt (0.8.1) unstable; urgency=low -- cgit v1.2.3