diff options
| author | Michael Vogt <michael.vogt@ubuntu.com> | 2012-10-23 12:49:45 +0200 |
|---|---|---|
| committer | Michael Vogt <michael.vogt@ubuntu.com> | 2012-10-23 12:49:45 +0200 |
| commit | 62ad4f8a9f447d99d539723e9c7ab8f46c7eda56 (patch) | |
| tree | ec0f9736ae2edbd3453bb182f5fa504158e7e322 | |
| parent | 01a05d8689621df4c9983be315b864142bb8077a (diff) | |
| parent | 2675db362167b75b1c006e7a165890e2b67079ec (diff) | |
| download | python-apt-62ad4f8a9f447d99d539723e9c7ab8f46c7eda56.tar.gz | |
merged from debian experimental
| -rw-r--r-- | apt/auth.py | 3 | ||||
| -rw-r--r-- | apt/cache.py | 23 | ||||
| -rw-r--r-- | data/templates/Ubuntu.info.in | 127 | ||||
| -rw-r--r-- | debian/changelog | 25 | ||||
| -rw-r--r-- | debian/control | 3 | ||||
| -rw-r--r-- | python/generic.h | 4 | ||||
| -rw-r--r-- | python/tag.cc | 4 | ||||
| -rw-r--r-- | tests/test_apt_cache.py | 57 |
8 files changed, 224 insertions, 22 deletions
diff --git a/apt/auth.py b/apt/auth.py index eff13b1a..c1b8da2a 100644 --- a/apt/auth.py +++ b/apt/auth.py @@ -78,7 +78,8 @@ def _call_apt_key_script(*args, **kwargs): stderr=subprocess.PIPE) content = kwargs.get("stdin", None) - if isinstance(content, unicode): + # py2 needs this encoded, py3.3 will crash if it is + if isinstance(content, unicode) and sys.version_info[:2] < (3, 3): content = content.encode("utf-8") output, stderr = proc.communicate(content) diff --git a/apt/cache.py b/apt/cache.py index 86a788bb..9842cb2a 100644 --- a/apt/cache.py +++ b/apt/cache.py @@ -42,6 +42,9 @@ class FetchFailedException(IOError): class LockFailedException(IOError): """Exception that is thrown when locking fails.""" +class CacheClosedException(Exception): + """Exception that is thrown when the cache is used after close().""" + class Cache(object): """Dictionary-like package cache. @@ -139,6 +142,8 @@ class Cache(object): """ if progress is None: progress = apt.progress.base.OpProgress() + # close old cache on (re)open + self.close() self.op_progress = progress self._run_callbacks("cache_pre_open") @@ -172,6 +177,20 @@ class Cache(object): progress.done() self._run_callbacks("cache_post_open") + def close(self): + """ Close the package cache """ + # explicitely free the FDs that _records has open + del self._records + self._records = None + + def __enter__(self): + """ Enter the with statement """ + return self + + def __exit__(self, exc_type, exc_value, traceback): + """ Exit the with statement """ + self.close() + def __getitem__(self, key): """ look like a dictionary (get key) """ try: @@ -238,6 +257,8 @@ class Cache(object): @property def required_download(self): """Get the size of the packages that are required to download.""" + if self._records is None: + raise CacheClosedException("Cache object used after close() called") pm = apt_pkg.PackageManager(self._depcache) fetcher = apt_pkg.Acquire() pm.get_archives(fetcher, self._list, self._records) @@ -288,6 +309,8 @@ class Cache(object): def _fetch_archives(self, fetcher, pm): """ fetch the needed archives """ + if self._records is None: + raise CacheClosedException("Cache object used after close() called") # get lock lockfile = apt_pkg.config.find_dir("Dir::Cache::Archives") + "lock" diff --git a/data/templates/Ubuntu.info.in b/data/templates/Ubuntu.info.in index 2aba269e..a3fc1bec 100644 --- a/data/templates/Ubuntu.info.in +++ b/data/templates/Ubuntu.info.in @@ -1,5 +1,124 @@ _ChangelogURI: http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog +Suite: raring +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 13.04 'Raring Ringtail' +Component: main +_CompDescription: Officially supported +_CompDescriptionLong: Canonical-supported free and open-source software +Component: universe +_CompDescription: Community-maintained +_CompDescriptionLong: Community-maintained free and 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: raring +ParentSuite: raring +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: raring +RepositoryType: deb +MatchName: .* +BaseURI: cdrom:\[Ubuntu.*13.04 +MatchURI: cdrom:\[Ubuntu.*13.04 +_Description: Cdrom with Ubuntu 12.04 'Raring Ringtail' +Available: False +Component: main +_CompDescription: Officially supported +Component: restricted +_CompDescription: Restricted copyright + +Suite: raring +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: raring +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: raring-security +ParentSuite: raring +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: raring-security +ParentSuite: raring +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: raring-updates +ParentSuite: raring +RepositoryType: deb +_Description: Recommended updates + +Suite: raring-updates +ParentSuite: raring +RepositoryType: deb-src +BaseURI: http://archive.ubuntu.com/ubuntu/ +MatchURI: archive.ubuntu.com/ubuntu|ports.ubuntu.com/ubuntu-ports +_Description: Recommended updates + +Suite: raring-proposed +ParentSuite: raring +RepositoryType: deb +_Description: Pre-released updates + +Suite: raring-proposed +ParentSuite: raring +RepositoryType: deb-src +BaseURI: http://archive.ubuntu.com/ubuntu/ +MatchURI: archive.ubuntu.com/ubuntu|ports.ubuntu.com/ubuntu-ports +_Description: Pre-released updates + +Suite: raring-backports +ParentSuite: raring +RepositoryType: deb +_Description: Unsupported updates + +Suite: raring-backports +ParentSuite: raring +RepositoryType: deb-src +BaseURI: http://archive.ubuntu.com/ubuntu/ +MatchURI: archive.ubuntu.com/ubuntu|ports.ubuntu.com/ubuntu-ports +_Description: Unsupported updates + + Suite: quantal RepositoryType: deb BaseURI: http://ports.ubuntu.com/ubuntu-ports/ @@ -30,14 +149,14 @@ ParentSuite: quantal 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' +_Description: Ubuntu 12.10 'Quantal Quetzal' Suite: quantal RepositoryType: deb MatchName: .* -BaseURI: cdrom:\[Ubuntu.*12.04 -MatchURI: cdrom:\[Ubuntu.*12.04 -_Description: Cdrom with Ubuntu 12.04 'Precise Pangolin' +BaseURI: cdrom:\[Ubuntu.*12.10 +MatchURI: cdrom:\[Ubuntu.*12.10 +_Description: Cdrom with Ubuntu 12.10 'Quantal Quetzal' Available: False Component: main _CompDescription: Officially supported diff --git a/debian/changelog b/debian/changelog index d76cc746..1da809b5 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,22 +1,31 @@ -python-apt (0.8.8ubuntu1) UNRELEASED; urgency=low - - NOTE: THIS is intended for R, use lp:~ubuntu-core-dev/python-apt/quantal - for quantal (and remove this note on the first R upload ;) +python-apt (0.8.8ubuntu1) UNRELEASEDraring; urgency=low + [ Michael Vogt ] * merged from the debian-sid branch: - do not build-depend on python-unittest2, only needed for python2.6 + * merged from the debian-experimental branch + * python/tag.cc: + - make TagSecString_FromStringAndSize, TagSecString_FromString + static, thanks to jcristau + * python/cache.cc: + - add "Codename" to PackageFile object * add dep8 style autopkgtest support - * add "codename" to the PackageFile object - - -- Michael Vogt <michael.vogt@ubuntu.com> Fri, 12 Oct 2012 11:02:03 +0200 + * build fixes for python3.3 + * data/templates/Ubuntu.info.in: + - add raring + + [ Jason Conti ] + * lp:~jconti/python-apt/closeable-cache: + - add apt.Cache.close() method + -- Michael Vogt <michael.vogt@ubuntu.com> Tue, 23 Oct 2012 12:49:21 +0200 python-apt (0.8.8) unstable; urgency=low [ Program translation updates ] * po/pl.po: Polish (Michał Kułach) (closes: #684308) * po/da.po: Danish (Joe Hansen) (closes: #689827) - + [ Michael Vogt ] * merged lp:~sampo555/python-apt/fix_1042916 reuse existing but disabled sources.list entries instead of duplicating them. diff --git a/debian/control b/debian/control index c186dc23..6d990a08 100644 --- a/debian/control +++ b/debian/control @@ -18,7 +18,8 @@ Build-Depends: apt (>= 0.9.6), python3-all-dbg (>= 3.1.2-6~), python-distutils-extra (>= 2.0), python-sphinx (>= 0.5), - python-debian + python-debian, + python-unittest2 Vcs-Bzr: http://code.launchpad.net/~ubuntu-core-dev/python-apt/ubuntu 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 diff --git a/python/generic.h b/python/generic.h index f9680ca5..914456e2 100644 --- a/python/generic.h +++ b/python/generic.h @@ -80,10 +80,14 @@ typedef int Py_ssize_t; static inline const char *PyUnicode_AsString(PyObject *op) { // Convert to bytes object, using the default encoding. +#if PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION >= 3 + return PyUnicode_AsUTF8(op); +#else // Use Python-internal API, there is no other way to do this // without a memory leak. PyObject *bytes = _PyUnicode_AsDefaultEncodedString(op, 0); return bytes ? PyBytes_AS_STRING(bytes) : 0; +#endif } // Convert any type of string based object to a const char. diff --git a/python/tag.cc b/python/tag.cc index 248d818d..6ae439f5 100644 --- a/python/tag.cc +++ b/python/tag.cc @@ -74,7 +74,7 @@ int TagFileClear(PyObject *self) { PyString_FromStringAndSize((v), (len)) #define TagSecString_FromString(self, v) PyString_FromString(v) #else -PyObject *TagSecString_FromStringAndSize(PyObject *self, const char *v, +static PyObject *TagSecString_FromStringAndSize(PyObject *self, const char *v, Py_ssize_t len) { TagSecData *Self = (TagSecData *)self; if (Self->Bytes) @@ -85,7 +85,7 @@ PyObject *TagSecString_FromStringAndSize(PyObject *self, const char *v, return PyUnicode_FromStringAndSize(v, len); } -PyObject *TagSecString_FromString(PyObject *self, const char *v) { +static PyObject *TagSecString_FromString(PyObject *self, const char *v) { TagSecData *Self = (TagSecData *)self; if (Self->Bytes) return PyBytes_FromString(v); diff --git a/tests/test_apt_cache.py b/tests/test_apt_cache.py index 448aed75..7e2ead2d 100644 --- a/tests/test_apt_cache.py +++ b/tests/test_apt_cache.py @@ -7,19 +7,27 @@ # are permitted in any medium without royalty provided the copyright # notice and this notice are preserved. """Unit tests for verifying the correctness of check_dep, etc in apt_pkg.""" + +import glob +import logging import os +import shutil +import sys import tempfile import unittest +if sys.version_info[0] == 2 and sys.version_info[1] == 6: + from unittest2 import TestCase +else: + from unittest import TestCase + + from test_all import get_library_dir -import sys sys.path.insert(0, get_library_dir()) import apt import apt_pkg -import shutil -import glob -import logging + def if_sources_list_is_readable(f): def wrapper(*args, **kwargs): @@ -29,7 +37,17 @@ def if_sources_list_is_readable(f): logging.warn("skipping '%s' because sources.list is not readable" % f) return wrapper -class TestAptCache(unittest.TestCase): + +def get_open_file_descriptors(): + try: + fds = os.listdir("/proc/self/fd") + except OSError: + logging.warn("failed to list /proc/self/fd") + return set([]) + return set(map(int, fds)) + + +class TestAptCache(TestCase): """ test the apt cache """ def setUp(self): @@ -68,7 +86,34 @@ class TestAptCache(unittest.TestCase): self.assertEqual(r['Package'], pkg.shortname) self.assertTrue('Version' in r) self.assertTrue(len(r['Description']) > 0) - self.assertTrue(str(r).startswith('Package: %s\n' % pkg.shortname)) + self.assertTrue( + str(r).startswith('Package: %s\n' % pkg.shortname)) + + @if_sources_list_is_readable + def test_cache_close_leak_fd(self): + fds_before_open = get_open_file_descriptors() + cache = apt.Cache() + opened_fd = get_open_file_descriptors().difference(fds_before_open) + cache.close() + fds_after_close = get_open_file_descriptors() + unclosed_fd = opened_fd.intersection(fds_after_close) + self.assertEqual(fds_before_open, fds_after_close) + self.assertEqual(unclosed_fd, set()) + + def test_cache_open_twice_leaks_fds(self): + cache = apt.Cache() + fds_before_open = get_open_file_descriptors() + cache.open() + fds_after_open_twice = get_open_file_descriptors() + self.assertEqual(fds_before_open, fds_after_open_twice) + + @if_sources_list_is_readable + def test_cache_close_download_fails(self): + cache = apt.Cache() + self.assertEqual(cache.required_download, 0) + cache.close() + with self.assertRaises(apt.cache.CacheClosedException): + cache.required_download def test_get_provided_packages(self): apt.apt_pkg.config.set("Apt::architecture", "i386") |
