Merge lp:~mvo/python-apt/mvo into lp:~mvo/python-apt/debian-sid-mirror

Proposed by Michael Vogt
Status: Needs review
Proposed branch: lp:~mvo/python-apt/mvo
Merge into: lp:~mvo/python-apt/debian-sid-mirror
Diff against target: 293 lines (+117/-9) (has conflicts)
10 files modified
apt/auth.py (+2/-1)
apt/cache.py (+23/-0)
debian/changelog (+16/-0)
debian/control (+1/-0)
debian/tests/control (+2/-0)
debian/tests/run-tests (+8/-0)
python/apt_pkgmodule.cc (+2/-2)
python/cache.cc (+8/-0)
python/generic.h (+4/-0)
tests/test_apt_cache.py (+51/-6)
Text conflict in debian/changelog
To merge this branch: bzr merge lp:~mvo/python-apt/mvo
Reviewer Review Type Date Requested Status
Michael Vogt Pending
Review via email: mp+119519@code.launchpad.net

Description of the change

This adds the "codename" to the PackageFile object.

To post a comment you must log in.
lp:~mvo/python-apt/mvo updated
612. By Michael Vogt

add dep8 style tests

613. By Michael Vogt

debian/tests/control: update depends line

614. By Michael Vogt

merge from the debian-sid branch

615. By Michael Vogt

update changelog

616. By Michael Vogt

merged lp:~jconti/python-apt/closeable-cache

617. By Michael Vogt

add changelog for lp:~jconti/python-apt/closeable-cache and add new test "test_cache_close_download_fails"

618. By Michael Vogt

close cache on (re)open

619. By Michael Vogt

apt/cache.py: add comment

620. By Michael Vogt

tests/test_apt_cache.py: delete test_cache_delete_leasks_fds() as its not reliable

621. By Michael Vogt

build fixes for python3.3

622. By Michael Vogt

fix documentation for version_compare(), thanks to
Ansgar Burchardt, closes: #680891

Unmerged revisions

622. By Michael Vogt

fix documentation for version_compare(), thanks to
Ansgar Burchardt, closes: #680891

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'apt/auth.py'
2--- apt/auth.py 2012-10-10 14:05:28 +0000
3+++ apt/auth.py 2013-03-09 19:55:24 +0000
4@@ -78,7 +78,8 @@
5 stderr=subprocess.PIPE)
6
7 content = kwargs.get("stdin", None)
8- if isinstance(content, unicode):
9+ # py2 needs this encoded, py3.3 will crash if it is
10+ if isinstance(content, unicode) and sys.version_info[:2] < (3, 3):
11 content = content.encode("utf-8")
12
13 output, stderr = proc.communicate(content)
14
15=== modified file 'apt/cache.py'
16--- apt/cache.py 2012-04-17 19:17:10 +0000
17+++ apt/cache.py 2013-03-09 19:55:24 +0000
18@@ -42,6 +42,9 @@
19 class LockFailedException(IOError):
20 """Exception that is thrown when locking fails."""
21
22+class CacheClosedException(Exception):
23+ """Exception that is thrown when the cache is used after close()."""
24+
25
26 class Cache(object):
27 """Dictionary-like package cache.
28@@ -139,6 +142,8 @@
29 """
30 if progress is None:
31 progress = apt.progress.base.OpProgress()
32+ # close old cache on (re)open
33+ self.close()
34 self.op_progress = progress
35 self._run_callbacks("cache_pre_open")
36
37@@ -172,6 +177,20 @@
38 progress.done()
39 self._run_callbacks("cache_post_open")
40
41+ def close(self):
42+ """ Close the package cache """
43+ # explicitely free the FDs that _records has open
44+ del self._records
45+ self._records = None
46+
47+ def __enter__(self):
48+ """ Enter the with statement """
49+ return self
50+
51+ def __exit__(self, exc_type, exc_value, traceback):
52+ """ Exit the with statement """
53+ self.close()
54+
55 def __getitem__(self, key):
56 """ look like a dictionary (get key) """
57 try:
58@@ -238,6 +257,8 @@
59 @property
60 def required_download(self):
61 """Get the size of the packages that are required to download."""
62+ if self._records is None:
63+ raise CacheClosedException("Cache object used after close() called")
64 pm = apt_pkg.PackageManager(self._depcache)
65 fetcher = apt_pkg.Acquire()
66 pm.get_archives(fetcher, self._list, self._records)
67@@ -288,6 +309,8 @@
68
69 def _fetch_archives(self, fetcher, pm):
70 """ fetch the needed archives """
71+ if self._records is None:
72+ raise CacheClosedException("Cache object used after close() called")
73
74 # get lock
75 lockfile = apt_pkg.config.find_dir("Dir::Cache::Archives") + "lock"
76
77=== modified file 'debian/changelog'
78--- debian/changelog 2012-11-15 13:30:14 +0000
79+++ debian/changelog 2013-03-09 19:55:24 +0000
80@@ -1,13 +1,29 @@
81 python-apt (0.8.8.1) unstable; urgency=low
82
83+ [ Michael Vogt ]
84 * python/tag.cc:
85 - make TagSecString_FromStringAndSize, TagSecString_FromString
86 static, thanks to jcristau
87+<<<<<<< TREE
88 * tests/test_lp659438.py:
89 - fix missing architecture to make the tests pass again during
90 build with the latest apt
91
92 -- Michael Vogt <mvo@debian.org> Thu, 15 Nov 2012 09:55:24 +0100
93+=======
94+ * python/cache.cc:
95+ - add "Codename" to PackageFile object
96+ * add dep8 style autopkgtest support
97+ * build fixes for python3.3
98+ * fix documentation for version_compare(), thanks to
99+ Ansgar Burchardt, closes: #680891
100+
101+ [ Jason Conti ]
102+ * lp:~jconti/python-apt/closeable-cache:
103+ - add apt.Cache.close() method
104+
105+ -- Michael Vogt <mvo@debian.org> Mon, 15 Oct 2012 10:03:21 +0200
106+>>>>>>> MERGE-SOURCE
107
108 python-apt (0.8.8) unstable; urgency=low
109
110
111=== modified file 'debian/control'
112--- debian/control 2012-10-12 08:08:21 +0000
113+++ debian/control 2013-03-09 19:55:24 +0000
114@@ -21,6 +21,7 @@
115 python-unittest2
116 Vcs-Bzr: http://bzr.debian.org/apt/python-apt/debian-sid
117 Vcs-Browser: http://bzr.debian.org/loggerhead/apt/python-apt/debian-sid/changes
118+XS-Testsuite: autopkgtest
119
120 Package: python-apt
121 Architecture: any
122
123=== added directory 'debian/tests'
124=== added file 'debian/tests/control'
125--- debian/tests/control 1970-01-01 00:00:00 +0000
126+++ debian/tests/control 2013-03-09 19:55:24 +0000
127@@ -0,0 +1,2 @@
128+Tests: run-tests
129+Depends: @, apt-utils, python-debian, fakeroot, intltool
130
131=== added file 'debian/tests/run-tests'
132--- debian/tests/run-tests 1970-01-01 00:00:00 +0000
133+++ debian/tests/run-tests 2013-03-09 19:55:24 +0000
134@@ -0,0 +1,8 @@
135+#!/bin/sh
136+
137+set -e
138+
139+# from debian/rules
140+for python in $(utils/pyversions -r); do
141+ $python tests/test_all.py -q
142+done
143
144=== modified file 'python/apt_pkgmodule.cc'
145--- python/apt_pkgmodule.cc 2012-03-05 12:05:39 +0000
146+++ python/apt_pkgmodule.cc 2013-03-09 19:55:24 +0000
147@@ -68,8 +68,8 @@
148 // These are kind of legacy..
149 static char *doc_VersionCompare =
150 "version_compare(a: str, b: str) -> int\n\n"
151- "Compare the given versions; return -1 if 'a' is smaller than 'b',\n"
152- "0 if they are equal, and 2 if 'a' is larger than 'b'.";
153+ "Compare the given versions; return <0 if 'a' is smaller than 'b',\n"
154+ "0 if they are equal, and >0 if 'a' is larger than 'b'.";
155 static PyObject *VersionCompare(PyObject *Self,PyObject *Args)
156 {
157 char *A;
158
159=== modified file 'python/cache.cc'
160--- python/cache.cc 2012-10-01 08:10:49 +0000
161+++ python/cache.cc 2013-03-09 19:55:24 +0000
162@@ -1247,6 +1247,12 @@
163 return Safe_FromString(File.Architecture());
164 }
165
166+static PyObject *PackageFile_GetCodename(PyObject *Self,void*)
167+{
168+ pkgCache::PkgFileIterator &File = GetCpp<pkgCache::PkgFileIterator>(Self);
169+ return Safe_FromString(File.Codename());
170+}
171+
172 static PyObject *PackageFile_GetSite(PyObject *Self,void*)
173 {
174 pkgCache::PkgFileIterator &File = GetCpp<pkgCache::PkgFileIterator>(Self);
175@@ -1305,6 +1311,8 @@
176 "The archive of the package file (i.e. 'Suite' in the Release file)."},
177 {"component",PackageFile_GetComponent,0,
178 "The component of this package file (e.g. 'main')."},
179+ {"codename",PackageFile_GetCodename,0,
180+ "The codename of this package file (e.g. squeeze-updates)."},
181 {"filename",PackageFile_GetFileName,0,
182 "The path to the file."},
183 {"id",PackageFile_GetID,0,
184
185=== modified file 'python/generic.h'
186--- python/generic.h 2011-08-01 07:29:25 +0000
187+++ python/generic.h 2013-03-09 19:55:24 +0000
188@@ -80,10 +80,14 @@
189
190 static inline const char *PyUnicode_AsString(PyObject *op) {
191 // Convert to bytes object, using the default encoding.
192+#if PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION >= 3
193+ return PyUnicode_AsUTF8(op);
194+#else
195 // Use Python-internal API, there is no other way to do this
196 // without a memory leak.
197 PyObject *bytes = _PyUnicode_AsDefaultEncodedString(op, 0);
198 return bytes ? PyBytes_AS_STRING(bytes) : 0;
199+#endif
200 }
201
202 // Convert any type of string based object to a const char.
203
204=== modified file 'tests/test_apt_cache.py'
205--- tests/test_apt_cache.py 2011-12-09 08:16:08 +0000
206+++ tests/test_apt_cache.py 2013-03-09 19:55:24 +0000
207@@ -7,19 +7,27 @@
208 # are permitted in any medium without royalty provided the copyright
209 # notice and this notice are preserved.
210 """Unit tests for verifying the correctness of check_dep, etc in apt_pkg."""
211+
212+import glob
213+import logging
214 import os
215+import shutil
216+import sys
217 import tempfile
218 import unittest
219
220+if sys.version_info[0] == 2 and sys.version_info[1] == 6:
221+ from unittest2 import TestCase
222+else:
223+ from unittest import TestCase
224+
225+
226 from test_all import get_library_dir
227-import sys
228 sys.path.insert(0, get_library_dir())
229
230 import apt
231 import apt_pkg
232-import shutil
233-import glob
234-import logging
235+
236
237 def if_sources_list_is_readable(f):
238 def wrapper(*args, **kwargs):
239@@ -29,7 +37,17 @@
240 logging.warn("skipping '%s' because sources.list is not readable" % f)
241 return wrapper
242
243-class TestAptCache(unittest.TestCase):
244+
245+def get_open_file_descriptors():
246+ try:
247+ fds = os.listdir("/proc/self/fd")
248+ except OSError:
249+ logging.warn("failed to list /proc/self/fd")
250+ return set([])
251+ return set(map(int, fds))
252+
253+
254+class TestAptCache(TestCase):
255 """ test the apt cache """
256
257 def setUp(self):
258@@ -68,7 +86,34 @@
259 self.assertEqual(r['Package'], pkg.shortname)
260 self.assertTrue('Version' in r)
261 self.assertTrue(len(r['Description']) > 0)
262- self.assertTrue(str(r).startswith('Package: %s\n' % pkg.shortname))
263+ self.assertTrue(
264+ str(r).startswith('Package: %s\n' % pkg.shortname))
265+
266+ @if_sources_list_is_readable
267+ def test_cache_close_leak_fd(self):
268+ fds_before_open = get_open_file_descriptors()
269+ cache = apt.Cache()
270+ opened_fd = get_open_file_descriptors().difference(fds_before_open)
271+ cache.close()
272+ fds_after_close = get_open_file_descriptors()
273+ unclosed_fd = opened_fd.intersection(fds_after_close)
274+ self.assertEqual(fds_before_open, fds_after_close)
275+ self.assertEqual(unclosed_fd, set())
276+
277+ def test_cache_open_twice_leaks_fds(self):
278+ cache = apt.Cache()
279+ fds_before_open = get_open_file_descriptors()
280+ cache.open()
281+ fds_after_open_twice = get_open_file_descriptors()
282+ self.assertEqual(fds_before_open, fds_after_open_twice)
283+
284+ @if_sources_list_is_readable
285+ def test_cache_close_download_fails(self):
286+ cache = apt.Cache()
287+ self.assertEqual(cache.required_download, 0)
288+ cache.close()
289+ with self.assertRaises(apt.cache.CacheClosedException):
290+ cache.required_download
291
292 def test_get_provided_packages(self):
293 apt.apt_pkg.config.set("Apt::architecture", "i386")

Subscribers

People subscribed via source and target branches

to all changes: