12
12
__all__ = ['view' , 'edit' , 'debug' , 'compare' , 'REOPEN_LAST_FILE' , 'run_editor_on_exception' ]
13
13
14
14
15
- def get_app_and_window (app_name ):
15
+ def _show_dialog (app_name , create_dialog_func , * args , ** kwargs ):
16
+ """Show dialog created by `create_dialog_func`
17
+
18
+ Use either the existing QApplication if any, otherwise a new QApplication.
19
+
20
+ Parameters
21
+ ----------
22
+ app_name : str
23
+ Application name when creating a new one.
24
+ create_dialog_func : function
25
+ The function which creates the dialog.
26
+ """
16
27
qt_app = QApplication .instance ()
17
- if qt_app is None :
28
+ new_app = qt_app is None
29
+ if new_app :
18
30
qt_app = QApplication (sys .argv )
19
31
qt_app .setOrganizationName ("LArray" )
20
32
qt_app .setApplicationName (app_name )
21
33
parent = None
22
34
else :
23
35
parent = qt_app .activeWindow ()
24
- return qt_app , parent
25
36
37
+ if 'depth' in kwargs :
38
+ kwargs ['depth' ] += 1
39
+
40
+ dlg = create_dialog_func (parent , * args , ** kwargs )
41
+ if dlg is None :
42
+ raise RuntimeError ('Could not create dialog' )
43
+
44
+ dlg .show ()
45
+ if new_app :
46
+ # We do not use install_except_hook/restore_except_hook so that we can restore the hook actually used when
47
+ # this function is called instead of the one which was used when the module was loaded.
48
+
49
+ # Note there is no point in changing the except hook when we have an existing QApplication given that
50
+ # in that case the function does not block
51
+ orig_except_hook = sys .excepthook
52
+ sys .excepthook = _qt_except_hook
53
+
54
+ qt_app .exec_ ()
26
55
27
- def find_names (obj , depth = 0 ):
56
+ sys .excepthook = orig_except_hook
57
+
58
+
59
+ def _find_names (obj , depth = 0 ):
28
60
"""Return all names an object is bound to.
29
61
30
62
Parameters
@@ -49,7 +81,7 @@ def find_names(obj, depth=0):
49
81
return sorted (names )
50
82
51
83
52
- def get_title (obj , depth = 0 , maxnames = 3 ):
84
+ def _get_title (obj , depth = 0 , maxnames = 3 ):
53
85
"""Return a title for an object (a combination of the names it is bound to).
54
86
55
87
Parameters
@@ -65,14 +97,49 @@ def get_title(obj, depth=0, maxnames=3):
65
97
str
66
98
title for obj. This can be '' if we computed an array just to view it.
67
99
"""
68
- names = find_names (obj , depth = depth + 1 )
100
+ names = _find_names (obj , depth = depth + 1 )
69
101
# names can be == []
70
102
# eg. view(arr['M'])
71
103
if len (names ) > maxnames :
72
104
names = names [:maxnames ] + ['...' ]
73
105
return ', ' .join (names )
74
106
75
107
108
+ def _edit_dialog (parent , obj = None , title = '' , minvalue = None , maxvalue = None , readonly = False , depth = 0 ,
109
+ display_caller_info = True , add_larray_functions = None ):
110
+ caller_frame = sys ._getframe (depth + 1 )
111
+ caller_info = getframeinfo (caller_frame ) if display_caller_info else None
112
+ if add_larray_functions is None :
113
+ add_larray_functions = obj is not None
114
+
115
+ if obj is None :
116
+ global_vars = caller_frame .f_globals
117
+ local_vars = caller_frame .f_locals
118
+ obj = {k : global_vars [k ] for k in sorted (global_vars .keys ())}
119
+ if local_vars is not global_vars :
120
+ obj .update ({k : local_vars [k ] for k in sorted (local_vars .keys ())})
121
+
122
+ if not isinstance (obj , (la .Session , la .Array )) and hasattr (obj , 'keys' ):
123
+ obj = la .Session (obj )
124
+
125
+ if not title and obj is not REOPEN_LAST_FILE :
126
+ title = _get_title (obj , depth = depth + 1 )
127
+
128
+ if obj is REOPEN_LAST_FILE or isinstance (obj , (str , la .Session )):
129
+ dlg = MappingEditor (parent )
130
+ assert minvalue is None and maxvalue is None
131
+ setup_ok = dlg .setup_and_check (obj , title = title , readonly = readonly , caller_info = caller_info ,
132
+ add_larray_functions = add_larray_functions )
133
+ else :
134
+ dlg = ArrayEditor (parent )
135
+ setup_ok = dlg .setup_and_check (obj , title = title , readonly = readonly , caller_info = caller_info ,
136
+ minvalue = minvalue , maxvalue = maxvalue )
137
+ if setup_ok :
138
+ return dlg
139
+ else :
140
+ return None
141
+
142
+
76
143
def edit (obj = None , title = '' , minvalue = None , maxvalue = None , readonly = False , depth = 0 , display_caller_info = True ,
77
144
add_larray_functions = None ):
78
145
"""
@@ -113,46 +180,8 @@ def edit(obj=None, title='', minvalue=None, maxvalue=None, readonly=False, depth
113
180
>>> # will open an editor for a1 only
114
181
>>> edit(a1) # doctest: +SKIP
115
182
"""
116
- # we don't use install_except_hook/restore_except_hook so that we can restore the hook actually used when
117
- # this function is called instead of the one which was used when the module was loaded.
118
- orig_except_hook = sys .excepthook
119
- sys .excepthook = _qt_except_hook
120
-
121
- qt_app , parent = get_app_and_window ("Viewer" )
122
-
123
- caller_frame = sys ._getframe (depth + 1 )
124
- caller_info = getframeinfo (caller_frame ) if display_caller_info else None
125
- if add_larray_functions is None :
126
- add_larray_functions = obj is not None
127
-
128
- if obj is None :
129
- global_vars = caller_frame .f_globals
130
- local_vars = caller_frame .f_locals
131
- obj = {k : global_vars [k ] for k in sorted (global_vars .keys ())}
132
- if local_vars is not global_vars :
133
- obj .update ({k : local_vars [k ] for k in sorted (local_vars .keys ())})
134
-
135
- if not isinstance (obj , (la .Session , la .Array )) and hasattr (obj , 'keys' ):
136
- obj = la .Session (obj )
137
-
138
- if not title and obj is not REOPEN_LAST_FILE :
139
- title = get_title (obj , depth = depth + 1 )
140
-
141
- if obj is REOPEN_LAST_FILE or isinstance (obj , (str , la .Session )):
142
- dlg = MappingEditor (parent )
143
- assert minvalue is None and maxvalue is None
144
- setup_ok = dlg .setup_and_check (obj , title = title , readonly = readonly , caller_info = caller_info ,
145
- add_larray_functions = add_larray_functions )
146
- else :
147
- dlg = ArrayEditor (parent )
148
- setup_ok = dlg .setup_and_check (obj , title = title , readonly = readonly , minvalue = minvalue , maxvalue = maxvalue ,
149
- caller_info = caller_info )
150
-
151
- if setup_ok :
152
- dlg .show ()
153
- qt_app .exec_ ()
154
-
155
- sys .excepthook = orig_except_hook
183
+ _show_dialog ("Viewer" , _edit_dialog , obj = obj , title = title , minvalue = minvalue , maxvalue = maxvalue , readonly = readonly ,
184
+ depth = depth + 2 , display_caller_info = display_caller_info , add_larray_functions = add_larray_functions )
156
185
157
186
158
187
def view (obj = None , title = '' , depth = 0 , display_caller_info = True , add_larray_functions = None ):
@@ -187,26 +216,17 @@ def view(obj=None, title='', depth=0, display_caller_info=True, add_larray_funct
187
216
>>> # will open a viewer showing only a1
188
217
>>> view(a1) # doctest: +SKIP
189
218
"""
190
- edit ( obj , title = title , readonly = True , depth = depth + 1 , display_caller_info = display_caller_info ,
191
- add_larray_functions = add_larray_functions )
219
+ _show_dialog ( "Viewer" , _edit_dialog , obj = obj , title = title , readonly = True ,
220
+ depth = depth + 2 , display_caller_info = display_caller_info , add_larray_functions = add_larray_functions )
192
221
193
222
194
- def _debug (stack_summary , stack_pos = None ):
195
- # we don't use install_except_hook/restore_except_hook so that we can restore the hook actually used when
196
- # this function is called instead of the one which was used when the module was loaded.
197
- orig_except_hook = sys .excepthook
198
- sys .excepthook = _qt_except_hook
199
-
200
- qt_app , parent = get_app_and_window ("Debugger" )
201
-
223
+ def _debug_dialog (parent , stack_summary , stack_pos = None ):
202
224
assert isinstance (stack_summary , StackSummary )
203
225
dlg = MappingEditor (parent )
204
- setup_ok = dlg .setup_and_check (stack_summary , stack_pos = stack_pos )
205
- if setup_ok :
206
- dlg .show ()
207
- qt_app .exec_ ()
208
-
209
- sys .excepthook = orig_except_hook
226
+ if dlg .setup_and_check (stack_summary , stack_pos = stack_pos ):
227
+ return dlg
228
+ else :
229
+ return None
210
230
211
231
212
232
def debug (depth = 0 ):
@@ -220,7 +240,44 @@ def debug(depth=0):
220
240
"""
221
241
caller_frame = sys ._getframe (depth + 1 )
222
242
stack_summary = extract_stack (caller_frame )
223
- _debug (stack_summary )
243
+ _show_dialog ("Debugger" , _debug_dialog , stack_summary )
244
+
245
+
246
+ def _compare_dialog (parent , * args , ** kwargs ):
247
+ title = kwargs .pop ('title' , '' )
248
+ names = kwargs .pop ('names' , None )
249
+ depth = kwargs .pop ('depth' , 0 )
250
+ display_caller_info = kwargs .pop ('display_caller_info' , True )
251
+
252
+ caller_frame = sys ._getframe (depth + 1 )
253
+ if display_caller_info :
254
+ caller_info = getframeinfo (caller_frame )
255
+ else :
256
+ caller_info = None
257
+
258
+ if any (isinstance (a , la .Session ) for a in args ):
259
+ from larray_editor .comparator import SessionComparator
260
+ dlg = SessionComparator (parent )
261
+ default_name = 'session'
262
+ else :
263
+ from larray_editor .comparator import ArrayComparator
264
+ dlg = ArrayComparator (parent )
265
+ default_name = 'array'
266
+
267
+ if names is None :
268
+ def get_name (i , obj , depth = 0 ):
269
+ obj_names = _find_names (obj , depth = depth + 1 )
270
+ return obj_names [0 ] if obj_names else f'{ default_name } { i :d} '
271
+
272
+ # depth + 2 because of the list comprehension
273
+ names = [get_name (i , a , depth = depth + 2 ) for i , a in enumerate (args )]
274
+ else :
275
+ assert isinstance (names , list ) and len (names ) == len (args )
276
+
277
+ if dlg .setup_and_check (args , names = names , title = title , caller_info = caller_info , ** kwargs ):
278
+ return dlg
279
+ else :
280
+ return None
224
281
225
282
226
283
def compare (* args , ** kwargs ):
@@ -264,48 +321,7 @@ def compare(*args, **kwargs):
264
321
>>> compare(a1, a2, title='first comparison') # doctest: +SKIP
265
322
>>> compare(a1 + 1, a2, title='second comparison', names=['a1+1', 'a2']) # doctest: +SKIP
266
323
"""
267
- # we don't use install_except_hook/restore_except_hook so that we can restore the hook actually used when
268
- # this function is called instead of the one which was used when the module was loaded.
269
- orig_except_hook = sys .excepthook
270
- sys .excepthook = _qt_except_hook
271
-
272
- title = kwargs .pop ('title' , '' )
273
- names = kwargs .pop ('names' , None )
274
- depth = kwargs .pop ('depth' , 0 )
275
- display_caller_info = kwargs .pop ('display_caller_info' , True )
276
-
277
- qt_app , parent = get_app_and_window ("Viewer" )
278
-
279
- caller_frame = sys ._getframe (depth + 1 )
280
- if display_caller_info :
281
- caller_info = getframeinfo (caller_frame )
282
- else :
283
- caller_info = None
284
-
285
- if any (isinstance (a , la .Session ) for a in args ):
286
10000
code>
- from larray_editor .comparator import SessionComparator
287
- dlg = SessionComparator (parent )
288
- default_name = 'session'
289
- else :
290
- from larray_editor .comparator import ArrayComparator
291
- dlg = ArrayComparator (parent )
292
- default_name = 'array'
293
-
294
- if names is None :
295
- def get_name (i , obj , depth = 0 ):
296
- obj_names = find_names (obj , depth = depth + 1 )
297
- return obj_names [0 ] if obj_names else f'{ default_name } { i :d} '
298
-
299
- # depth + 2 because of the list comprehension
300
- names = [get_name (i , a , depth = depth + 2 ) for i , a in enumerate (args )]
301
- else :
302
- assert isinstance (names , list ) and len (names ) == len (args )
303
-
304
- if dlg .setup_and_check (args , names = names , title = title , caller_info = caller_info , ** kwargs ):
305
- dlg .show ()
306
- qt_app .exec_ ()
307
-
308
- sys .excepthook = orig_except_hook
324
+ _show_dialog ("Comparator" , _compare_dialog , * args , ** kwargs )
309
325
310
326
311
327
_orig_except_hook = sys .excepthook
@@ -391,7 +407,7 @@ def excepthook(type, value, tback):
391
407
stack = extract_tb (main_tb , limit = tb_limit )
392
408
stack_pos = user_tb_length - 1 if user_tb_length is not None and usercode_frame else None
393
409
print ("\n launching larray editor to debug..." , file = sys .stderr )
394
- _debug ( stack , stack_pos = stack_pos )
410
+ _show_dialog ( "Debugger" , _debug_dialog , stack , stack_pos = stack_pos )
395
411
396
412
return excepthook
397
413
0 commit comments