Merge ~albertomilone/ubuntu/+source/software-properties:apt-pkg-transition into ubuntu/+source/software-properties:ubuntu/devel
- Git
- lp:~albertomilone/ubuntu/+source/software-properties
- apt-pkg-transition
- Merge into ubuntu/devel
Status: | Needs review |
---|---|
Proposed branch: | ~albertomilone/ubuntu/+source/software-properties:apt-pkg-transition |
Merge into: | ubuntu/+source/software-properties:ubuntu/devel |
Diff against target: |
406 lines (+121/-80) 3 files modified
softwareproperties/SoftwareProperties.py (+24/-12) softwareproperties/gtk/SoftwarePropertiesGtk.py (+49/-35) softwareproperties/qt/SoftwarePropertiesQt.py (+48/-33) |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Sebastien Bacher (community) | Approve | ||
Julian Andres Klode (community) | Needs Fixing | ||
git-ubuntu import | Pending | ||
Review via email: mp+416950@code.launchpad.net |
Commit message
This makes software-
Description of the change
Julian Andres Klode (juliank) wrote : | # |
I found a couple of spots worth fixing/considering in the diff
- 68577e2... by Alberto Milone
-
softwarepropert
ies/SoftwarePro perties. py: import apt only on demand - 66473bd... by Alberto Milone
-
Do without a couple of tries, and make get_package_id return the installed package when available
Alberto Milone (albertomilone) wrote : | # |
I have just pushed a couple of commits which should fix the problems reported by Julian and Matthew. Thanks
Sebastien Bacher (seb128) wrote : | # |
Thanks, I've merged and uploaded but I can't close that one since it's targetting the wrong Vcs, for reference the git repository is reference in debian/control and https:/
I've also updated the depends on ubuntu-
Alberto Milone (albertomilone) wrote : | # |
I understand. Sorry about that. Thanks
Unmerged commits
- 66473bd... by Alberto Milone
-
Do without a couple of tries, and make get_package_id return the installed package when available
- 68577e2... by Alberto Milone
-
softwarepropert
ies/SoftwarePro perties. py: import apt only on demand - ada2244... by Alberto Milone
-
Use apt_pkg instead of apt, as in ubuntu-
drivers- common Fixes LP: #1964880
Preview Diff
1 | diff --git a/softwareproperties/SoftwareProperties.py b/softwareproperties/SoftwareProperties.py |
2 | index 3e94731..7fc9862 100644 |
3 | --- a/softwareproperties/SoftwareProperties.py |
4 | +++ b/softwareproperties/SoftwareProperties.py |
5 | @@ -26,7 +26,6 @@ |
6 | from __future__ import absolute_import, print_function |
7 | |
8 | import apt_pkg |
9 | -import apt |
10 | import copy |
11 | from hashlib import md5 |
12 | import re |
13 | @@ -828,22 +827,35 @@ class SoftwareProperties(object): |
14 | except: |
15 | return False |
16 | |
17 | - def get_package_id(self, ver): |
18 | + def get_package_id(self, apt_cache, pkg): |
19 | """ Return the PackageKit package id """ |
20 | - assert isinstance(ver, apt.package.Version) |
21 | - return "%s;%s;%s;" % (ver.package.shortname, ver.version, |
22 | - ver.package.architecture()) |
23 | + assert isinstance(pkg, apt_pkg.Package) |
24 | + cur_ver = pkg.current_ver |
25 | + if cur_ver: |
26 | + ver = cur_ver.ver_str |
27 | + arch = cur_ver.arch |
28 | + else: |
29 | + depcache = apt_pkg.DepCache(apt_cache) |
30 | + candidate = depcache.get_candidate_ver(pkg) |
31 | + ver = candidate.ver_str |
32 | + arch = candidate.arch |
33 | + return "%s;%s;%s;" % (pkg.name, ver, arch) |
34 | |
35 | @staticmethod |
36 | - def get_dependencies(apt_cache, package_name, pattern=None): |
37 | + def get_dependencies(apt_cache, package, pattern=None): |
38 | """ Get the package dependencies, which can be filtered out by a pattern """ |
39 | + depcache = apt_pkg.DepCache(apt_cache) |
40 | + candidate = depcache.get_candidate_ver(package) |
41 | + |
42 | dependencies = [] |
43 | - for or_group in apt_cache[package_name].candidate.dependencies: |
44 | - for dep in or_group: |
45 | - if dep.rawtype in ["Depends", "PreDepends"]: |
46 | - dependencies.append(dep.name) |
47 | - if pattern: |
48 | - dependencies = [ x for x in dependencies if x.find(pattern) != -1 ] |
49 | + try: |
50 | + for dep_list in candidate.depends_list_str.get('Depends'): |
51 | + for dep_name, dep_ver, dep_op in dep_list: |
52 | + if dep_name.find(pattern) != -1: |
53 | + dependencies.append(apt_cache[dep_name]) |
54 | + except (KeyError, TypeError): |
55 | + return [] |
56 | + |
57 | return dependencies |
58 | |
59 | |
60 | diff --git a/softwareproperties/gtk/SoftwarePropertiesGtk.py b/softwareproperties/gtk/SoftwarePropertiesGtk.py |
61 | index 9b797ac..01e3d28 100644 |
62 | --- a/softwareproperties/gtk/SoftwarePropertiesGtk.py |
63 | +++ b/softwareproperties/gtk/SoftwarePropertiesGtk.py |
64 | @@ -26,7 +26,6 @@ |
65 | |
66 | from __future__ import absolute_import, print_function |
67 | |
68 | -import apt |
69 | import apt_pkg |
70 | import datetime |
71 | import dbus |
72 | @@ -228,7 +227,9 @@ class SoftwarePropertiesGtk(SoftwareProperties, SimpleGtkbuilderApp): |
73 | # used to store the handlers of callbacks |
74 | self.handlers = {} |
75 | |
76 | - self.apt_cache = {} |
77 | + # Initialise and store the apt cache |
78 | + self.init_apt_cache() |
79 | + |
80 | self.pk_task = None |
81 | |
82 | # Put some life into the user interface: |
83 | @@ -290,6 +291,17 @@ class SoftwarePropertiesGtk(SoftwareProperties, SimpleGtkbuilderApp): |
84 | self.handlers[self.combobox_release_upgrades] = \ |
85 | self.combobox_release_upgrades.connect("changed", |
86 | self.on_combobox_release_upgrades_changed) |
87 | + def init_apt_cache(self): |
88 | + apt_pkg.init_config() |
89 | + apt_pkg.init_system() |
90 | + self.apt_cache = apt_pkg.Cache(None) |
91 | + self.depcache = apt_pkg.DepCache(self.apt_cache) |
92 | + self.records = apt_pkg.PackageRecords(self.apt_cache) |
93 | + |
94 | + def update_apt_cache(self): |
95 | + self.apt_cache = apt_pkg.Cache(None) |
96 | + self.depcache = apt_pkg.DepCache(self.apt_cache) |
97 | + self.records = apt_pkg.PackageRecords(self.apt_cache) |
98 | |
99 | def init_auto_update(self): |
100 | """ Set up the widgets that allow to configure the update automation """ |
101 | @@ -983,7 +995,7 @@ class SoftwarePropertiesGtk(SoftwareProperties, SimpleGtkbuilderApp): |
102 | # dbus events |
103 | def on_config_modified(self): |
104 | """The config was changed and now needs to be saved and reloaded""" |
105 | - apt.apt_pkg.init_config() |
106 | + apt_pkg.init_config() |
107 | self.button_revert.set_sensitive(True) |
108 | |
109 | def on_keys_modified(self): |
110 | @@ -1226,7 +1238,7 @@ class SoftwarePropertiesGtk(SoftwareProperties, SimpleGtkbuilderApp): |
111 | if not installs_pending: |
112 | self.progress_bar.set_visible(False) |
113 | self.clear_changes() |
114 | - self.apt_cache = apt.Cache() |
115 | + self.update_apt_cache() |
116 | self.set_driver_action_status() |
117 | self.update_label_and_icons_from_status() |
118 | self.button_driver_revert.set_visible(True) |
119 | @@ -1239,19 +1251,20 @@ class SoftwarePropertiesGtk(SoftwareProperties, SimpleGtkbuilderApp): |
120 | installs = [] |
121 | removals = [] |
122 | |
123 | + has_nvidia = False |
124 | for pkg in self.driver_changes: |
125 | - if pkg.is_installed: |
126 | - removals.append(self.get_package_id(pkg.installed)) |
127 | + if pkg.current_ver: |
128 | + removals.append(self.get_package_id(self.apt_cache, pkg)) |
129 | # The main NVIDIA package is only a metapackage. |
130 | # We need to collect its dependencies, so that |
131 | # we can uninstall the driver properly. |
132 | - if 'nvidia' in pkg.shortname: |
133 | - for dep in self.get_dependencies(self.apt_cache, pkg.shortname, 'nvidia'): |
134 | - dep_pkg = self.apt_cache[dep] |
135 | - if dep_pkg.is_installed: |
136 | - removals.append(self.get_package_id(dep_pkg.installed)) |
137 | + if 'nvidia' in pkg.name: |
138 | + has_nvidia = True |
139 | + for dep in self.get_dependencies(self.apt_cache, pkg, 'nvidia'): |
140 | + if dep.current_ver: |
141 | + removals.append(self.get_package_id(self.apt_cache, dep)) |
142 | else: |
143 | - installs.append(self.get_package_id(pkg.candidate)) |
144 | + installs.append(self.get_package_id(self.apt_cache, pkg)) |
145 | |
146 | self.cancellable = Gio.Cancellable() |
147 | try: |
148 | @@ -1269,6 +1282,11 @@ class SoftwarePropertiesGtk(SoftwareProperties, SimpleGtkbuilderApp): |
149 | installs_pending # callback data |
150 | ) |
151 | if installs: |
152 | + if has_nvidia: |
153 | + to_install = [] |
154 | + for item in installs: |
155 | + name = item.split(';')[0] |
156 | + to_install.append(name) |
157 | self.pk_task.install_packages_async(installs, |
158 | self.cancellable, # cancellable |
159 | self.on_driver_changes_progress, |
160 | @@ -1376,7 +1394,6 @@ class SoftwarePropertiesGtk(SoftwareProperties, SimpleGtkbuilderApp): |
161 | # WARNING: This is run in a separate thread. |
162 | self.detect_called = True |
163 | try: |
164 | - self.apt_cache = apt.Cache() |
165 | self.devices = detect.system_device_drivers(self.apt_cache) |
166 | except: |
167 | # Catch all exceptions and feed them to apport. |
168 | @@ -1395,22 +1412,16 @@ class SoftwarePropertiesGtk(SoftwareProperties, SimpleGtkbuilderApp): |
169 | return |
170 | |
171 | pkg = None |
172 | - try: |
173 | - if pkg_name: |
174 | - pkg = self.apt_cache[pkg_name] |
175 | - # If the package depends on dkms |
176 | - # we need to install the correct linux metapackage |
177 | - # so that users get the latest headers |
178 | - if 'dkms' in pkg.candidate.record['Depends']: |
179 | - linux_meta = detect.get_linux(self.apt_cache) |
180 | - if (linux_meta and |
181 | - linux_meta not in self.driver_changes): |
182 | - # Install the linux metapackage |
183 | - lmp = self.apt_cache[linux_meta] |
184 | - if not lmp.is_installed: |
185 | - self.driver_changes.append(lmp) |
186 | - except (AttributeError, KeyError): |
187 | - pass |
188 | + if pkg_name: |
189 | + pkg = self.apt_cache[pkg_name] |
190 | + # Add the matching linux modules package when available |
191 | + try: |
192 | + modules_package = detect.get_linux_modules_metapackage(self.apt_cache, pkg_name) |
193 | + modules_package_obj = self.apt_cache[modules_package] |
194 | + if modules_package and not modules_package_obj.current_ver: |
195 | + self.driver_changes.append(modules_package_obj) |
196 | + except KeyError: |
197 | + pass |
198 | |
199 | if button.get_active(): |
200 | if pkg in self.driver_changes: |
201 | @@ -1430,7 +1441,7 @@ class SoftwarePropertiesGtk(SoftwareProperties, SimpleGtkbuilderApp): |
202 | |
203 | if (pkg is not None |
204 | and pkg not in self.driver_changes |
205 | - and pkg.is_installed): |
206 | + and pkg.current_ver): |
207 | self.driver_changes.append(pkg) |
208 | |
209 | self.button_driver_revert.set_sensitive(bool(self.driver_changes)) |
210 | @@ -1492,11 +1503,14 @@ class SoftwarePropertiesGtk(SoftwareProperties, SimpleGtkbuilderApp): |
211 | |
212 | try: |
213 | pkg = self.apt_cache[pkg_driver_name] |
214 | - installed = pkg.is_installed |
215 | - if pkg.candidate is not None: |
216 | - description = _("Using {} from {}").format(pkg.candidate.summary, pkg.shortname) |
217 | + installed = pkg.current_ver |
218 | + candidate = self.depcache.get_candidate_ver(pkg) |
219 | + |
220 | + if candidate is not None: |
221 | + self.records.lookup(candidate.file_list[0]) |
222 | + description = _("Using {} from {}").format(self.records.short_desc, pkg_driver_name) |
223 | else: |
224 | - description = _("Using {}").format(pkg.shortname) |
225 | + description = _("Using {}").format(pkg_driver_name) |
226 | except KeyError: |
227 | print("WARNING: a driver ({}) doesn't have any available package associated: {}".format(pkg_driver_name, current_driver)) |
228 | continue |
229 | @@ -1626,7 +1640,7 @@ class SoftwarePropertiesGtk(SoftwareProperties, SimpleGtkbuilderApp): |
230 | for device in self.devices: |
231 | for pkg_name in self.devices[device]['drivers']: |
232 | pkg = self.apt_cache[pkg_name] |
233 | - if not self.devices[device]['drivers'][pkg_name]['free'] and pkg.is_installed: |
234 | + if not self.devices[device]['drivers'][pkg_name]['free'] and pkg.current_ver: |
235 | self.nonfree_drivers = self.nonfree_drivers + 1 |
236 | |
237 | if self.nonfree_drivers > 0: |
238 | diff --git a/softwareproperties/qt/SoftwarePropertiesQt.py b/softwareproperties/qt/SoftwarePropertiesQt.py |
239 | index 332bf06..e9e5818 100644 |
240 | --- a/softwareproperties/qt/SoftwarePropertiesQt.py |
241 | +++ b/softwareproperties/qt/SoftwarePropertiesQt.py |
242 | @@ -55,7 +55,6 @@ from .CdromProgress import CdromProgress |
243 | |
244 | from UbuntuDrivers import detect |
245 | import sys |
246 | -import apt |
247 | from functools import partial |
248 | import aptsources.distro |
249 | import logging |
250 | @@ -345,6 +344,18 @@ class SoftwarePropertiesQt(SoftwareProperties): |
251 | self.userinterface.combobox_server.addItem(_("Other...")) |
252 | self.other_mirrors_index = self.userinterface.combobox_server.count() - 1 |
253 | |
254 | + def init_apt_cache(self): |
255 | + apt_pkg.init_config() |
256 | + apt_pkg.init_system() |
257 | + self.apt_cache = apt_pkg.Cache(None) |
258 | + self.depcache = apt_pkg.DepCache(self.apt_cache) |
259 | + self.records = apt_pkg.PackageRecords(self.apt_cache) |
260 | + |
261 | + def update_apt_cache(self): |
262 | + self.apt_cache = apt_pkg.Cache(None) |
263 | + self.depcache = apt_pkg.DepCache(self.apt_cache) |
264 | + self.records = apt_pkg.PackageRecords(self.apt_cache) |
265 | + |
266 | def show_distro(self): |
267 | """ |
268 | Represent the distro information in the user interface |
269 | @@ -736,7 +747,7 @@ class SoftwarePropertiesQt(SoftwareProperties): |
270 | |
271 | def on_restore_clicked(self): |
272 | """Restore the original keys""" |
273 | - self.apt_key.update() |
274 | + self.update_apt_cache() |
275 | self.show_keys() |
276 | |
277 | def on_pktask_progress(self, progress, ptype, udata=(None,)): |
278 | @@ -859,7 +870,7 @@ class SoftwarePropertiesQt(SoftwareProperties): |
279 | if not installs_pending: |
280 | self.progress_bar.setVisible(False) |
281 | self.clear_changes() |
282 | - self.apt_cache = apt.Cache() |
283 | + self.update_apt_cache() |
284 | self.set_driver_action_status() |
285 | self.update_label_and_icons_from_status() |
286 | self.button_driver_revert.setVisible(True) |
287 | @@ -885,19 +896,20 @@ class SoftwarePropertiesQt(SoftwareProperties): |
288 | installs = [] |
289 | removals = [] |
290 | |
291 | + has_nvidia = False |
292 | for pkg in self.driver_changes: |
293 | - if pkg.is_installed: |
294 | - removals.append(self.get_package_id(pkg.installed)) |
295 | + if pkg.current_ver: |
296 | + removals.append(self.get_package_id(self.apt_cache, pkg)) |
297 | # The main NVIDIA package is only a metapackage. |
298 | # We need to collect its dependencies, so that |
299 | # we can uninstall the driver properly. |
300 | - if 'nvidia' in pkg.shortname: |
301 | - for dep in self.get_dependencies(self.apt_cache, pkg.shortname, 'nvidia'): |
302 | - dep_pkg = self.apt_cache[dep] |
303 | - if dep_pkg.is_installed: |
304 | - removals.append(self.get_package_id(dep_pkg.installed)) |
305 | + if 'nvidia' in pkg.name: |
306 | + has_nvidia = True |
307 | + for dep in self.get_dependencies(self.apt_cache, pkg, 'nvidia'): |
308 | + if dep.current_ver: |
309 | + removals.append(self.get_package_id(self.apt_cache, dep)) |
310 | else: |
311 | - installs.append(self.get_package_id(pkg.candidate)) |
312 | + installs.append(self.get_package_id(self.apt_cache, pkg)) |
313 | |
314 | self.cancellable = Gio.Cancellable() |
315 | try: |
316 | @@ -915,6 +927,11 @@ class SoftwarePropertiesQt(SoftwareProperties): |
317 | installs_pending # callback data |
318 | ) |
319 | if installs: |
320 | + if has_nvidia: |
321 | + to_install = [] |
322 | + for item in installs: |
323 | + name = item.split(';')[0] |
324 | + to_install.append(name) |
325 | self.pk_task.install_packages_async(installs, |
326 | self.cancellable, # cancellable |
327 | self.on_driver_changes_progress, |
328 | @@ -1019,8 +1036,8 @@ class SoftwarePropertiesQt(SoftwareProperties): |
329 | def detect_drivers(self): |
330 | # WARNING: This is run in a separate thread. |
331 | self.detect_called = True |
332 | + self.init_apt_cache() |
333 | try: |
334 | - self.apt_cache = apt.Cache() |
335 | self.devices = detect.system_device_drivers(self.apt_cache) |
336 | except: |
337 | # Catch all exceptions and feed them to apport. |
338 | @@ -1039,21 +1056,17 @@ class SoftwarePropertiesQt(SoftwareProperties): |
339 | return |
340 | |
341 | pkg = None |
342 | - try: |
343 | - if pkg_name: |
344 | - pkg = self.apt_cache[pkg_name] |
345 | - # If the package depends on dkms |
346 | - # we need to install the correct linux metapackage |
347 | - # so that users get the latest headers |
348 | - if 'dkms' in pkg.candidate.record['Depends']: |
349 | - linux_meta = detect.get_linux(self.apt_cache) |
350 | - if (linux_meta and linux_meta not in self.driver_changes): |
351 | - # Install the linux metapackage |
352 | - lmp = self.apt_cache[linux_meta] |
353 | - if not lmp.is_installed: |
354 | - self.driver_changes.append(lmp) |
355 | - except KeyError: |
356 | - pass |
357 | + |
358 | + if pkg_name: |
359 | + pkg = self.apt_cache[pkg_name] |
360 | + # Add the matching linux modules package when available |
361 | + try: |
362 | + modules_package = detect.get_linux_modules_metapackage(self.apt_cache, pkg_name) |
363 | + modules_package_obj = self.apt_cache[modules_package] |
364 | + if modules_package and not modules_package_obj.current_ver: |
365 | + self.driver_changes.append(modules_package_obj) |
366 | + except KeyError: |
367 | + pass |
368 | |
369 | if button.isChecked(): |
370 | if pkg in self.driver_changes: |
371 | @@ -1069,7 +1082,7 @@ class SoftwarePropertiesQt(SoftwareProperties): |
372 | if modalias not in self.orig_selection: |
373 | self.orig_selection[modalias] = button |
374 | |
375 | - if (pkg is not None and pkg not in self.driver_changes and pkg.is_installed): |
376 | + if (pkg is not None and pkg not in self.driver_changes and pkg.current_ver): |
377 | self.driver_changes.append(pkg) |
378 | |
379 | self.button_driver_revert.setEnabled(bool(self.driver_changes)) |
380 | @@ -1137,11 +1150,13 @@ None if not applicable |
381 | |
382 | try: |
383 | pkg = self.apt_cache[pkg_driver_name] |
384 | - installed = pkg.is_installed |
385 | - if pkg.candidate is not None: |
386 | - description = _("Using {} from {}").format(pkg.candidate.summary, pkg.shortname) |
387 | + installed = pkg.current_ver or False |
388 | + candidate = self.depcache.get_candidate_ver(pkg) |
389 | + if candidate is not None: |
390 | + self.records.lookup(candidate.file_list[0]) |
391 | + description = _("Using {} from {}").format(self.records.short_desc, pkg_driver_name) |
392 | else: |
393 | - description = _("Using {}").format(pkg.shortname) |
394 | + description = _("Using {}").format(pkg_driver_name) |
395 | except KeyError: |
396 | print("WARNING: a driver ({}) doesn't have any available package associated: {}".format(pkg_driver_name, current_driver)) |
397 | continue |
398 | @@ -1277,7 +1292,7 @@ licence=licence) |
399 | for device in self.devices: |
400 | for pkg_name in self.devices[device]['drivers']: |
401 | pkg = self.apt_cache[pkg_name] |
402 | - if not self.devices[device]['drivers'][pkg_name]['free'] and pkg.is_installed: |
403 | + if not self.devices[device]['drivers'][pkg_name]['free'] and pkg.current_ver: |
404 | self.nonfree_drivers = self.nonfree_drivers + 1 |
405 | |
406 | if self.nonfree_drivers > 0: |
Hi Alberto,
I tried to build and test your patch, but it fails on the pyflakes3 test:
$ python3 tests/test_ pyflakes. py Work/lp1964880/ alberto/ software- properties/ softwarepropert ies/SoftwarePro perties. py:29:1 'apt' imported but unused Work/lp1964880/ alberto/ software- properties/ softwarepropert ies/SoftwarePro perties. py:753: 9 redefinition of unused 'apt' from line 29 ======= ======= ======= ======= ======= ======= ======= ======= ======= clean (__main_ _.TestPyflakesC lean) ------- ------- ------- ------- ------- ------- ------- ------- ------- matthew/ Work/lp1964880/ alberto/ software- properties/ tests/test_ pyflakes. py", line 21, in test_pyflakes3_ clean assertEqual( subprocess. check_call( ['pyflakes3' ] + self.paths), 0) python3. 10/subprocess. py", line 369, in check_call ror(retcode, cmd)
/home/matthew/
/home/matthew/
E
=======
ERROR: test_pyflakes3_
-------
Traceback (most recent call last):
File "/home/
self.
File "/usr/lib/
raise CalledProcessEr