Merge lp:~jameinel/qbzr/bug_430232_early_qapp into lp:qbzr/0.14

Proposed by John A Meinel
Status: Merged
Approved by: Ian Clatworthy
Approved revision: 951
Merged at revision: not available
Proposed branch: lp:~jameinel/qbzr/bug_430232_early_qapp
Merge into: lp:qbzr/0.14
Diff against target: None lines
To merge this branch: bzr merge lp:~jameinel/qbzr/bug_430232_early_qapp
Reviewer Review Type Date Requested Status
Ian Clatworthy (community) Approve
Review via email: mp+11831@code.launchpad.net
To post a comment you must log in.
Revision history for this message
John A Meinel (jameinel) wrote :

This is a fix for bug #430232

It isn't the smallest fix I could come up with, but I noticed that the bug exists in both qcommit and qmerge, and I think a few others (qsend also creates the qapp after opening a branch).

I don't know if there was a legitimate use case for creating the QApplication late, but I *can* say that it is dangerous to install QUIFactory before creating QApplication. Once in an installer, it causes segfaults if the QUIFactory is actually used.

As such, I could change this to continue instantiating the app late, but then also install the QUIFactory late.

This seemed the most reasonable route.

Note that I'm currently doing on-site training and the segfault is a major problem as they want to have their standard workflow use checkouts from their server. As such, I'll probably roll a 0.14.1-win32-1 with this fix if it is going to be controversial.

Revision history for this message
Ian Clatworthy (ian-clatworthy) wrote :

This looks good to me. I like moving it to where you did.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'NEWS.txt'
2--- NEWS.txt 2009-09-10 20:31:33 +0000
3+++ NEWS.txt 2009-09-15 22:51:30 +0000
4@@ -1,6 +1,14 @@
5 0.14.2 - in development
6 -----------------------
7
8+ * qmerge, qcommit, ...:
9+ * Fixed a bug where we create the QApp after opening a Branch, but we had
10+ already installed the QUIFactory(). A branch can be a lightweight checkout
11+ of a remote location which requires a password. Which wants to open a UI
12+ dialog, which causes a crash because QApp has not been created yet.
13+ (#430232, John Arbash Meinel)
14+
15+
16 0.14.1 - 2009-09-10
17 -------------------
18 Maintenance release:
19
20=== modified file 'lib/commands.py'
21--- lib/commands.py 2009-08-28 21:27:09 +0000
22+++ lib/commands.py 2009-09-15 22:51:30 +0000
23@@ -148,6 +148,11 @@
24 @install_gettext
25 @report_missing_pyqt
26 def run(self, *args, **kwargs):
27+ # We must create the QApplication before we install the QUIFactory.
28+ # This is because once the factory is installed, it is possible that
29+ # opening a branch, etc will go to the ui_factory to request a
30+ # password, and the app must exist before the dialog can be created.
31+ self._application = QtGui.QApplication(sys.argv)
32 ui.ui_factory = QUIFactory()
33
34 # Set up global exception handling.
35@@ -256,14 +261,13 @@
36
37 def _qbzr_run(self, filename=None, revision=None, encoding=None,
38 ui_mode=False, no_graph=False):
39- app = QtGui.QApplication(sys.argv)
40 win = AnnotateWindow(None, None, None, None,
41 encoding=encoding, ui_mode=ui_mode,
42 loader=self._load_branch,
43 loader_args=(filename, revision),
44 no_graph=no_graph)
45 win.show()
46- app.exec_()
47+ self._application.exec_()
48
49
50 class cmd_qadd(QBzrCommand):
51@@ -275,10 +279,9 @@
52 tree, selected_list = builtins.tree_files(selected_list)
53 if selected_list == ['']:
54 selected_list = []
55- application = QtGui.QApplication(sys.argv)
56 self.main_window = AddWindow(tree, selected_list, dialog=False, ui_mode=ui_mode)
57 self.main_window.show()
58- application.exec_()
59+ self._application.exec_()
60
61
62 class cmd_qrevert(QBzrCommand):
63@@ -290,12 +293,11 @@
64 tree, selected_list = builtins.tree_files(selected_list)
65 if selected_list == ['']:
66 selected_list = []
67- application = QtGui.QApplication(sys.argv)
68 self.main_window = RevertWindow(tree, selected_list, dialog=False,
69 ui_mode=ui_mode,
70 backup=not no_backup)
71 self.main_window.show()
72- application.exec_()
73+ self._application.exec_()
74
75
76 class cmd_qconflicts(QBzrCommand):
77@@ -306,10 +308,9 @@
78
79 def _qbzr_run(self):
80 from bzrlib.plugins.qbzr.lib.conflicts import ConflictsWindow
81- application = QtGui.QApplication(sys.argv)
82 self.main_window = ConflictsWindow(u'.')
83 self.main_window.show()
84- application.exec_()
85+ self._application.exec_()
86
87
88 class cmd_qbrowse(QBzrCommand):
89@@ -319,13 +320,12 @@
90 aliases = ['qbw']
91
92 def _qbzr_run(self, revision=None, location=None):
93- app = QtGui.QApplication(sys.argv)
94 if revision is None:
95 win = BrowseWindow(location = location)
96 else:
97 win = BrowseWindow(location = location, revision = revision[0])
98 win.show()
99- app.exec_()
100+ self._application.exec_()
101
102
103 class cmd_qcommit(QBzrCommand):
104@@ -342,11 +342,10 @@
105 tree, selected_list = builtins.tree_files(selected_list)
106 if selected_list == ['']:
107 selected_list = []
108- application = QtGui.QApplication(sys.argv)
109 self.main_window = CommitWindow(tree, selected_list, dialog=False,
110 message=message, local=local, ui_mode=ui_mode)
111 self.main_window.show()
112- application.exec_()
113+ self._application.exec_()
114
115
116 class cmd_qdiff(QBzrCommand, DiffArgProvider):
117@@ -437,14 +436,13 @@
118 self.old = old
119 self.new = new
120
121- app = QtGui.QApplication(sys.argv)
122 window = DiffWindow(self,
123 complete=complete,
124 encoding=encoding,
125 filter_options=filter_options,
126 ui_mode=ui_mode)
127 window.show()
128- app.exec_()
129+ self._application.exec_()
130
131
132 class cmd_qlog(QBzrCommand):
133@@ -474,11 +472,10 @@
134 ]
135
136 def _qbzr_run(self, locations_list, ui_mode=False, no_graph=False):
137- app = QtGui.QApplication(sys.argv)
138 window = LogWindow(locations_list, None, None, ui_mode=ui_mode,
139 no_graph=no_graph)
140 window.show()
141- app.exec_()
142+ self._application.exec_()
143
144
145 class cmd_qconfig(QBzrCommand):
146@@ -489,10 +486,9 @@
147 aliases = ['qconfigure']
148
149 def _qbzr_run(self):
150- app = QtGui.QApplication(sys.argv)
151 window = QBzrConfigWindow()
152 window.show()
153- app.exec_()
154+ self._application.exec_()
155
156
157 class cmd_qcat(QBzrCommand):
158@@ -526,11 +522,10 @@
159 return int(not result)
160
161
162- app = QtGui.QApplication(sys.argv)
163 window = QBzrCatWindow(filename = filename, revision = revision,
164 encoding = encoding)
165 window.show()
166- app.exec_()
167+ self._application.exec_()
168
169
170 class cmd_qpull(QBzrCommand):
171@@ -554,14 +549,13 @@
172 except errors.NoWorkingTree:
173 tree_to = None
174 branch_to = Branch.open_containing(directory)[0]
175- app = QtGui.QApplication(sys.argv)
176 self.main_window = QBzrPullWindow(branch_to, tree_to, location,
177 remember=remember,
178 overwrite=overwrite,
179 revision=revision,
180 ui_mode=ui_mode)
181 self.main_window.show()
182- app.exec_()
183+ self._application.exec_()
184
185
186 class cmd_qmerge(QBzrCommand):
187@@ -585,12 +579,11 @@
188 except errors.NoWorkingTree:
189 tree_to = None
190 branch_to = Branch.open_containing(directory)[0]
191- app = QtGui.QApplication(sys.argv)
192 self.main_window = QBzrMergeWindow(branch_to, tree_to, location,
193 revision=revision, remember=remember, force=force,
194 uncommitted=uncommitted, ui_mode=ui_mode)
195 self.main_window.show()
196- app.exec_()
197+ self._application.exec_()
198
199
200 class cmd_qpush(QBzrCommand):
201@@ -617,7 +610,6 @@
202 except errors.NoWorkingTree:
203 tree_to = None
204 branch_to = Branch.open_containing(directory)[0]
205- app = QtGui.QApplication(sys.argv)
206 self.main_window = QBzrPushWindow(branch_to, tree_to,
207 location=location,
208 create_prefix=create_prefix,
209@@ -626,7 +618,7 @@
210 overwrite=overwrite,
211 ui_mode=ui_mode)
212 self.main_window.show()
213- app.exec_()
214+ self._application.exec_()
215
216
217 class cmd_qbranch(QBzrCommand):
218@@ -638,11 +630,10 @@
219
220 def _qbzr_run(self, from_location=None, to_location=None,
221 revision=None, ui_mode=False):
222- app = QtGui.QApplication(sys.argv)
223 self.main_window = QBzrBranchWindow(from_location, to_location,
224 revision=revision, ui_mode=ui_mode)
225 self.main_window.show()
226- app.exec_()
227+ self._application.exec_()
228
229
230 class cmd_qinfo(QBzrCommand):
231@@ -652,10 +643,9 @@
232 takes_args = ['location?']
233
234 def _qbzr_run(self, location=u'.'):
235- app = QtGui.QApplication(sys.argv)
236 window = QBzrInfoWindow(location)
237 window.show()
238- app.exec_()
239+ self._application.exec_()
240
241
242 class cmd_qinit(QBzrCommand):
243@@ -665,10 +655,9 @@
244 takes_args = ['location?']
245
246 def _qbzr_run(self, location=u'.', ui_mode=False):
247- app = QtGui.QApplication(sys.argv)
248 self.main_window = QBzrInitWindow(location, ui_mode=ui_mode)
249 self.main_window.show()
250- app.exec_()
251+ self._application.exec_()
252
253
254 class cmd_merge(bzrlib.builtins.cmd_merge, DiffArgProvider):
255@@ -707,10 +696,9 @@
256
257 self.merger = merger
258 try:
259- application = QtGui.QApplication(sys.argv)
260 window = DiffWindow(self, encoding=self._encoding)
261 window.show()
262- application.exec_()
263+ self._application.exec_()
264 finally:
265 if self.tt:
266 self.tt.finalize()
267@@ -743,11 +731,10 @@
268 BzrDirFormat.unregister_control_format(SvnWorkingTreeDirFormat)
269 format_registry.remove('subversion-wc')
270 # Start QBzr
271- app = QtGui.QApplication(sys.argv)
272 window = QBzrMainWindow()
273 window.setDirectory(osutils.realpath(u'.'))
274 window.show()
275- app.exec_()
276+ self._application.exec_()
277
278
279 class cmd_qsubprocess(Command):
280@@ -800,14 +787,13 @@
281
282 def _qbzr_run(self, location=u".", ui_mode=False):
283 branch, relpath = Branch.open_containing(location)
284- app = QtGui.QApplication(sys.argv)
285 if branch.get_bound_location():
286 window = UpdateCheckoutWindow(branch, ui_mode=ui_mode)
287 else:
288 window = UpdateBranchWindow(branch, ui_mode=ui_mode)
289 self.main_window = window
290 self.main_window.show()
291- app.exec_()
292+ self._application.exec_()
293
294
295 class cmd_qgetnew(QBzrCommand):
296@@ -819,10 +805,9 @@
297
298 def _qbzr_run(self, location=u".", ui_mode=False):
299 from bzrlib.plugins.qbzr.lib.getnew import GetNewWorkingTreeWindow
300- app = QtGui.QApplication(sys.argv)
301 self.main_window = GetNewWorkingTreeWindow(location, ui_mode=ui_mode)
302 self.main_window.show()
303- app.exec_()
304+ self._application.exec_()
305
306
307 class cmd_qhelp(QBzrCommand):
308@@ -834,9 +819,8 @@
309 hidden = True
310
311 def _qbzr_run(self, topic):
312- app = QtGui.QApplication(sys.argv)
313 window = show_help(topic)
314- app.exec_()
315+ self._application.exec_()
316
317
318 class cmd_qtag(QBzrCommand):
319@@ -856,11 +840,10 @@
320 branch = Branch.open_containing(directory)[0]
321 # determine action based on given options
322 action = TagWindow.action_from_options(force=force, delete=delete)
323- app = QtGui.QApplication(sys.argv)
324 self.main_window = TagWindow(branch, tag_name=tag_name, action=action,
325 revision=revision, ui_mode=ui_mode)
326 self.main_window.show()
327- app.exec_()
328+ self._application.exec_()
329
330
331 class cmd_quncommit(QBzrCommand):
332@@ -872,10 +855,9 @@
333 takes_args = ["location?"]
334
335 def _qbzr_run(self, location=u'.', ui_mode=False):
336- app = QtGui.QApplication(sys.argv)
337 window = QBzrUncommitWindow(location, ui_mode=ui_mode)
338 window.show()
339- app.exec_()
340+ self._application.exec_()
341
342
343 class cmd_qviewer(QBzrCommand):
344@@ -889,10 +871,9 @@
345 _see_also = ['qcat']
346
347 def _qbzr_run(self, filename, encoding=None):
348- app = QtGui.QApplication(sys.argv)
349 window = QBzrViewWindow(filename=filename, encoding=encoding)
350 window.show()
351- app.exec_()
352+ self._application.exec_()
353
354
355 class cmd_qversion(QBzrCommand):
356@@ -903,10 +884,9 @@
357
358 def _qbzr_run(self):
359 from bzrlib.plugins.qbzr.lib.sysinfo import QBzrSysInfoWindow
360- application = QtGui.QApplication(sys.argv)
361 window = QBzrSysInfoWindow()
362 window.show()
363- application.exec_()
364+ self._application.exec_()
365
366
367 class cmd_qplugins(QBzrCommand):
368@@ -918,10 +898,9 @@
369
370 def _qbzr_run(self):
371 from bzrlib.plugins.qbzr.lib.plugins import QBzrPluginsWindow
372- app = QtGui.QApplication(sys.argv)
373 window = QBzrPluginsWindow()
374 window.show()
375- app.exec_()
376+ self._application.exec_()
377
378
379 class cmd_qupdate(QBzrCommand):
380@@ -932,13 +911,12 @@
381
382 def _qbzr_run(self, directory=None, ui_mode=False):
383 from bzrlib.plugins.qbzr.lib.update import QBzrUpdateWindow
384- application = QtGui.QApplication(sys.argv)
385 tree = open_tree(directory, ui_mode)
386 if tree is None:
387 return
388 self.main_window = QBzrUpdateWindow(tree, ui_mode)
389 self.main_window.show()
390- application.exec_()
391+ self._application.exec_()
392
393
394 class cmd_qsend(QBzrCommand):
395@@ -949,10 +927,9 @@
396
397 def _qbzr_run(self, submit_branch=".", public_branch=None, ui_mode=False):
398 branch = Branch.open_containing(submit_branch)[0]
399- app = QtGui.QApplication(sys.argv)
400 window = SendWindow(branch, ui_mode)
401 window.show()
402- app.exec_()
403+ self._application.exec_()
404
405
406 class cmd_qswitch(QBzrCommand):
407@@ -964,12 +941,11 @@
408 def _qbzr_run(self, location=None, ui_mode=False):
409 from bzrlib.plugins.qbzr.lib.switch import QBzrSwitchWindow
410
411- application = QtGui.QApplication(sys.argv)
412 branch = Branch.open_containing(".")[0]
413 bzrdir = BzrDir.open_containing(".")[0]
414 self.main_window = QBzrSwitchWindow(branch, bzrdir, location, ui_mode)
415 self.main_window.show()
416- application.exec_()
417+ self._application.exec_()
418
419
420 class cmd_qunbind(QBzrCommand):
421@@ -979,14 +955,13 @@
422 def _qbzr_run(self, ui_mode=False):
423 from bzrlib.plugins.qbzr.lib.unbind import QBzrUnbindDialog
424
425- application = QtGui.QApplication(sys.argv)
426 branch = Branch.open_containing(".")[0]
427 if branch.get_bound_location() == None:
428 raise errors.BzrCommandError("This branch is not bound.")
429
430 self.main_window = QBzrUnbindDialog(branch, ui_mode)
431 self.main_window.show()
432- application.exec_()
433+ self._application.exec_()
434
435
436 class cmd_qexport(QBzrCommand):
437@@ -1003,7 +978,6 @@
438 def _qbzr_run(self, dest=None, branch_or_subdir=None, ui_mode=False):
439 from bzrlib.plugins.qbzr.lib.export import QBzrExportDialog
440
441- application = QtGui.QApplication(sys.argv)
442 if branch_or_subdir == None:
443 branch = Branch.open_containing(".")[0]
444 else:
445@@ -1011,7 +985,7 @@
446
447 window = QBzrExportDialog(dest, branch, ui_mode)
448 window.show()
449- application.exec_()
450+ self._application.exec_()
451
452
453 class cmd_qbind(QBzrCommand):
454@@ -1026,10 +1000,8 @@
455 def _qbzr_run(self, location=None, ui_mode=False):
456 from bzrlib.plugins.qbzr.lib.bind import QBzrBindDialog
457
458- application = QtGui.QApplication(sys.argv)
459-
460 branch = Branch.open_containing(".")[0]
461
462 self.main_window = QBzrBindDialog(branch, location, ui_mode)
463 self.main_window.show()
464- application.exec_()
465+ self._application.exec_()

Subscribers

People subscribed via source and target branches