movoid-debug 1.2.2__tar.gz → 1.3.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,18 @@
1
+ Metadata-Version: 2.1
2
+ Name: movoid_debug
3
+ Version: 1.3.0
4
+ Home-page:
5
+ Author: movoid
6
+ Author-email: bobrobotsun@163.com
7
+ Description-Content-Type: text/markdown
8
+ Requires-Dist: movoid_function
9
+
10
+ 这个是一系列函数、类的装饰器,在运行时,如果报错,那么将会进入调试状态
11
+ 默认情况下:
12
+ 1、将所有Exception raise 出去,不做任何处理
13
+ 2、将Exception保存下来,可以在任意的地方调用某个方法抛出
14
+
15
+ debug状态下:
16
+ 0、直接进入debug模式,弹出窗口,并进行操作
17
+ 1、将所有Exception raise 出去,不做任何处理
18
+ 2、将Exception保存下来,可以在任意的地方调用某个方法抛出
@@ -0,0 +1,9 @@
1
+ 这个是一系列函数、类的装饰器,在运行时,如果报错,那么将会进入调试状态
2
+ 默认情况下:
3
+ 1、将所有Exception raise 出去,不做任何处理
4
+ 2、将Exception保存下来,可以在任意的地方调用某个方法抛出
5
+
6
+ debug状态下:
7
+ 0、直接进入debug模式,弹出窗口,并进行操作
8
+ 1、将所有Exception raise 出去,不做任何处理
9
+ 2、将Exception保存下来,可以在任意的地方调用某个方法抛出
@@ -9,7 +9,7 @@
9
9
  import sys
10
10
  import traceback
11
11
 
12
- from movoid_function import Function, wraps, analyse_args_value_from_function
12
+ from movoid_function import Function, wraps, analyse_args_value_from_function, wraps_ori
13
13
 
14
14
  from ..simple_ui import MainApp, MainWindow
15
15
 
@@ -20,16 +20,26 @@ class Flow:
20
20
  self.current_function = self.main
21
21
  self.test = False
22
22
  self.raise_error = 0
23
- self.error_type = 0
24
- self.check_error_type()
23
+ self.debug_type = 0
24
+ self.debug_flag = 0
25
+ self.init_debug_param()
25
26
  self.app = None
27
+ self.continue_error_list = []
26
28
 
27
- def check_error_type(self):
29
+ def init_debug_param(self):
28
30
  for i in sys.argv:
29
31
  if i.startswith('__debug='):
30
- temp = i[8:]
31
- if temp == '1':
32
- self.error_type = 1
32
+ if i[8:] in ('1', 'debug'):
33
+ self.debug_type = 1
34
+ else:
35
+ self.debug_type = 0
36
+ elif i.startswith('__debug_flag='):
37
+ if i[13:] in ('0', 'debug'):
38
+ self.debug_flag = 0
39
+ elif i[13:] in ('2',):
40
+ self.debug_flag = 2
41
+ else:
42
+ self.debug_flag = 1
33
43
 
34
44
  @property
35
45
  def text(self):
@@ -45,37 +55,63 @@ class Flow:
45
55
  else:
46
56
  self.current_function = self.current_function.parent
47
57
 
48
- def when_error(self):
58
+ def when_error(self, *debug_flag, err=None, traceback_str=None):
59
+ """
60
+ 这是供FlowFunction反调的函数,保证当前的处理模式是预选模式
61
+ :param debug_flag: 这是个传入的参数,就是把自己的参数传进去
62
+ :param err: 把故障传上来
63
+ :param traceback_str: 把traceback信息传上来
64
+ :return: 如果return 1 则是需要continue。如果return 2 则是需要 raise Error
65
+ """
49
66
  self.test = True
50
- if self.error_type == -1:
51
- self.when_error_cmd()
52
- elif self.error_type == 1:
53
- self.when_error_debug()
67
+ flag = self.analyse_target_debug_flag(*debug_flag)
68
+ if flag == 0:
69
+ re_value = self.when_error_debug()
70
+ else:
71
+ re_value = flag
72
+ if flag == 2:
73
+ self.continue_error_list.append([err, traceback_str])
54
74
  self.test = False
75
+ return re_value
55
76
 
56
77
  def when_error_debug(self):
78
+ """
79
+ 调出一个debug窗口来进行debug,编辑请前往main_window.py进行
80
+ """
57
81
  if self.app is None:
58
82
  self.app = MainApp()
59
83
  self.app.main = MainWindow(self)
60
84
  self.app.exec()
85
+ return 2 if self.raise_error == 0 else 1
61
86
 
62
- def when_error_cmd(self):
63
- print('错误发生:')
64
- while True:
65
- print('以下是当前流程')
66
- print(self.text)
67
- input_str = input('请问如何处理?1、重新测试;2、弹出错误到上一级;3、弹出错误直至退出;其他、以当前的返回值返回:')
68
- if input_str == '1':
69
- self.current_function(*self.args, **self.kwargs)
70
- elif input_str == '2':
71
- self.raise_error = 1
72
- break
73
- elif input_str == '3':
74
- self.raise_error = -1
75
- break
76
- else:
77
- self.raise_error = False
78
- break
87
+ def analyse_target_debug_flag(self, default_flag=None, *debug_flag):
88
+ """
89
+ 解析当前的函数对应的debug flag是多少
90
+ 优先看是否设置,没有设置就按照debug_type==0时的设置,如果也没有设置,那就继承flow的设置
91
+ 当debug_type为0时,flag 0会被强制转换为1
92
+ :param default_flag: 保证在无设置时,可以继承flow的设置
93
+ :param debug_flag: 其他debug_type时的设置
94
+ :return: 返回具体的flag
95
+ """
96
+ debug_flag = [default_flag, *debug_flag]
97
+ ind = self.debug_type
98
+ tar_ind_flag = debug_flag[ind] if len(debug_flag) > ind else None
99
+ tar_flag = debug_flag[0] if tar_ind_flag is None else tar_ind_flag
100
+ flag = self.debug_flag if tar_flag is None else tar_flag
101
+ flag = max(0, min(2, flag))
102
+ if self.debug_type == 0:
103
+ flag = max(1, flag)
104
+ return flag
105
+
106
+ def release_all_pass_error(self, raise_it=True):
107
+ """
108
+ 如果之前曾经continue掉一部分error,那么可以通过调用这个函数,来将所有的error释放出来。
109
+ :param raise_it: 是否把这些Error统一在一起raise 一个Error出来
110
+ """
111
+ if raise_it and self.continue_error_list:
112
+ temp = self.continue_error_list
113
+ self.continue_error_list = []
114
+ raise DebugError(*temp)
79
115
 
80
116
 
81
117
  class BasicFunction:
@@ -156,13 +192,13 @@ class MainFunction(BasicFunction):
156
192
  class FlowFunction(BasicFunction):
157
193
  func_type = 'function'
158
194
 
159
- def __init__(self, func, flow, include=None, exclude=None, error_function=None, error_args=None, error_kwargs=None):
195
+ def __init__(self, func, flow, include=None, exclude=None, teardown_function=None):
160
196
  """
161
197
 
162
198
  """
163
199
  super().__init__()
164
200
  self.func = func
165
- self.error_func = Function(error_function, error_args, error_kwargs)
201
+ self.teardown_function = Function() if teardown_function is None else FlowFunction(Function(teardown_function), flow, include=include, exclude=exclude, teardown_function=None)
166
202
  if include is None:
167
203
  self.include_error = Exception
168
204
  if exclude is None:
@@ -188,6 +224,8 @@ class FlowFunction(BasicFunction):
188
224
  test = TestFunction(self.func, self.flow, self)
189
225
  test(*args, **kwargs)
190
226
  else:
227
+ debug_default = kwargs.pop('__debug_default', None)
228
+ debug_debug = kwargs.pop('__debug_debug', None)
191
229
  try:
192
230
  self.args = args
193
231
  self.kwargs = kwargs
@@ -202,18 +240,9 @@ class FlowFunction(BasicFunction):
202
240
  raise err
203
241
  self.error = err
204
242
  self.traceback = traceback.format_exc()
205
- if self.debug_mode.get(self.flow.error_type, False):
206
- if self.flow.error_type in (-1, 1):
207
- self.flow.when_error()
208
- if self.flow.raise_error != 0:
209
- self.flow.raise_error -= 1
210
- raise err
211
- else:
212
- self.has_return = True
213
- return self.re_value
214
- else:
215
- self.error_func()
216
- else:
243
+ error_flag = self.flow.when_error(debug_default, debug_debug, err=self.error, traceback_str=self.traceback)
244
+ if error_flag == 1:
245
+ self.flow.raise_error -= 1
217
246
  raise err
218
247
  except Exception as err:
219
248
  raise err
@@ -222,6 +251,7 @@ class FlowFunction(BasicFunction):
222
251
  self.re_value = re_value
223
252
  return self.re_value
224
253
  finally:
254
+ self.teardown_function(args=self.args, kwargs=self.kwargs, re_value=self.re_value, error=self.error, traceback_str=self.traceback)
225
255
  self.end = True
226
256
  self.flow.current_function_end()
227
257
 
@@ -297,13 +327,24 @@ class TestError(Exception):
297
327
  FLOW = Flow()
298
328
 
299
329
 
300
- def debug_function(func):
301
- @wraps(func)
302
- def wrapper(*args, **kwargs):
303
- temp = FlowFunction(func, FLOW)
304
- temp(*args, **kwargs)
330
+ def debug_function(debug_default=None, debug_debug=None):
331
+ if callable(debug_default):
332
+ return debug_function()(debug_default)
305
333
 
306
- return wrapper
334
+ def dec(func):
335
+ if getattr(func, '__debug', False):
336
+ return func
337
+ else:
338
+ @wraps(func)
339
+ def wrapper(*args, __debug_default=debug_default, __debug_debug=debug_debug, **kwargs):
340
+ temp = FlowFunction(func, FLOW)
341
+ re_value = temp(*args, __debug_default=debug_default, __debug_debug=debug_debug, **kwargs)
342
+ return re_value
343
+
344
+ setattr(wrapper, '__debug', True)
345
+ return wrapper
346
+
347
+ return dec
307
348
 
308
349
 
309
350
  def debug_class_include(name_list):
@@ -339,3 +380,34 @@ def debug_class_exclude(name_list=None):
339
380
  return cls
340
381
 
341
382
  return dec
383
+
384
+
385
+ class DebugError(Exception):
386
+ def __init__(self, *args):
387
+ self.args = args
388
+
389
+ def __str__(self):
390
+ re_str = ''
391
+ for err, trace in self.args:
392
+ re_str += f'{type(err).__name__}\n'
393
+ re_str.strip('\n')
394
+ return re_str
395
+
396
+ def traceback(self):
397
+ re_str = ''
398
+ for err, trace in self.args:
399
+ re_str += f'{trace}\n'
400
+ re_str.strip('\n')
401
+ return re_str
402
+
403
+
404
+ def teardown(func):
405
+ """
406
+ 这个函数可以规范teardown函数,保证无论怎么写,都不会因为参数的传递而报错
407
+ """
408
+
409
+ @wraps_ori(func)
410
+ def wrapper(args=None, kwargs=None, re_value=None, error=None, traceback_str=None):
411
+ pass
412
+
413
+ return wrapper
@@ -7,7 +7,8 @@
7
7
  # Description :
8
8
  """
9
9
  from PySide6.QtWidgets import QMainWindow, QApplication, QWidget, QGridLayout, QTreeWidget, QTextEdit, QHBoxLayout, QVBoxLayout, QPushButton, QTreeWidgetItem
10
- from .value_set_window import ValueSetWindow
10
+
11
+ from .value_set_window import ValueSetWindow, tree_item_can_expand, expand_tree_item_to_show_dir
11
12
 
12
13
 
13
14
  class MainWindow(QMainWindow):
@@ -56,7 +57,7 @@ class MainWindow(QMainWindow):
56
57
  global_tree.setObjectName('global_tree')
57
58
  main_gird.addWidget(global_tree, 1, 2, 2, 1)
58
59
  global_tree.setHeaderLabels(['key', 'type', 'value'])
59
- global_tree.itemExpanded.connect(self.expand_global_tree_to_show_dir)
60
+ global_tree.itemExpanded.connect(self.expand_tree_item_to_show_dir)
60
61
 
61
62
  run_widget = QWidget(main_table)
62
63
  end_widget = QWidget(main_table)
@@ -79,11 +80,16 @@ class MainWindow(QMainWindow):
79
80
  run_continue_button.clicked.connect(self.run_continue)
80
81
  run_grid.addStretch(1)
81
82
 
82
- run_raise_button = QPushButton('忽略错误并raise error', main_table)
83
+ run_raise_button = QPushButton('raise错误', main_table)
83
84
  run_raise_button.setObjectName('run_raise_button')
84
85
  run_grid.addWidget(run_raise_button)
85
86
  run_raise_button.clicked.connect(self.run_raise)
86
87
 
88
+ run_raise_one_button = QPushButton('raise错误至上一层', main_table)
89
+ run_raise_one_button.setObjectName('run_raise_one_button')
90
+ run_grid.addWidget(run_raise_one_button)
91
+ run_raise_one_button.clicked.connect(self.run_raise_one)
92
+
87
93
  run_grid.addStretch(10)
88
94
 
89
95
  def refresh_ui(self):
@@ -174,14 +180,15 @@ class MainWindow(QMainWindow):
174
180
  def refresh_global_tree(self):
175
181
  global_value = globals()
176
182
  global_tree: QTreeWidget = self.findChild(QTreeWidget, 'global_tree')
183
+ global_tree.clear()
177
184
  for k, v in global_value.items():
178
185
  if not k.startswith('__'):
179
186
  temp = QTreeWidgetItem(global_tree)
180
187
  temp.setText(0, k)
181
188
  temp.setText(1, type(v).__name__)
182
189
  temp.setText(2, str(v))
183
- setattr(temp, '__value', v)
184
- self.empty_tree_item_child(temp)
190
+ setattr(temp, '__tree_object', v)
191
+ tree_item_can_expand(temp)
185
192
 
186
193
  def run_test(self, q):
187
194
  arg_tree: QTreeWidget = self.findChild(QTreeWidget, 'arg_tree')
@@ -205,6 +212,10 @@ class MainWindow(QMainWindow):
205
212
  self.flow.raise_error = -1
206
213
  self.close()
207
214
 
215
+ def run_raise_one(self, q):
216
+ self.flow.raise_error = 1
217
+ self.close()
218
+
208
219
  def change_arg_tree_value(self):
209
220
  arg_tree: QTreeWidget = self.findChild(QTreeWidget, 'arg_tree')
210
221
  flow = getattr(arg_tree, 'flow')
@@ -219,28 +230,10 @@ class MainWindow(QMainWindow):
219
230
  temp[current_value[-2]] = new_value
220
231
  self.refresh_arg_tree(flow, kwarg_value)
221
232
 
222
- def empty_tree_item_child(self, item):
223
- value = getattr(item, '__value')
224
- if type(value) in (int, float, bool, str, list, dict) or value is None:
225
- setattr(item, '__expand', False)
226
- else:
227
- temp = QTreeWidgetItem(item)
228
- setattr(temp, '__delete', True)
229
-
230
- def expand_global_tree_to_show_dir(self, item: QTreeWidgetItem):
231
- if getattr(item, '__expand', True):
232
- for i in range(item.childCount() - 1, -1, -1):
233
- tar_item = item.child(i)
234
- if getattr(tar_item, '__delete', False):
235
- item.removeChild(tar_item)
236
- value = getattr(item, '__value')
237
- for k in dir(value):
238
- if not k.startswith('__'):
239
- v = getattr(value, k)
240
- if not callable(v):
241
- temp = QTreeWidgetItem(item)
242
- temp.setText(0, k)
243
- temp.setText(1, type(v).__name__)
244
- temp.setText(2, str(v))
245
- setattr(temp, '__value', v)
246
- self.empty_tree_item_child(temp)
233
+ @staticmethod
234
+ def expand_tree_item_to_show_dir(item: QTreeWidgetItem):
235
+ expand_tree_item_to_show_dir(item, {
236
+ 0: lambda k, v: str(k),
237
+ 1: lambda k, v: type(v).__name__,
238
+ 2: lambda k, v: str(v),
239
+ })
@@ -6,10 +6,9 @@
6
6
  # Time : 2024/6/9 23:13
7
7
  # Description :
8
8
  """
9
- import inspect
10
9
  import traceback
11
10
 
12
- from PySide6.QtWidgets import QWidget, QGridLayout, QApplication, QRadioButton, QErrorMessage, QVBoxLayout, QTextEdit, QTreeWidget, QHBoxLayout, QPushButton, QMessageBox, QDialog, QTreeWidgetItem
11
+ from PySide6.QtWidgets import QWidget, QGridLayout, QApplication, QRadioButton, QVBoxLayout, QTextEdit, QTreeWidget, QHBoxLayout, QPushButton, QMessageBox, QDialog, QTreeWidgetItem
13
12
 
14
13
 
15
14
  class ValueSetWindow(QDialog):
@@ -44,7 +43,7 @@ class ValueSetWindow(QDialog):
44
43
  arg_tree.setObjectName('arg_tree')
45
44
  arg_tree.setHeaderLabels(['from', 'name', 'type', 'value'])
46
45
  input_grid.addWidget(arg_tree, 0, 1)
47
- arg_tree.itemExpanded.connect(self.expand_object_to_show_dir)
46
+ arg_tree.itemExpanded.connect(self.expand_tree_item_to_show_dir)
48
47
 
49
48
  type_widget = QWidget(self)
50
49
  main_grid.addWidget(type_widget, 0, 0)
@@ -195,17 +194,17 @@ class ValueSetWindow(QDialog):
195
194
  temp.setText(0, 'ori')
196
195
  temp.setText(2, type(i).__name__)
197
196
  temp.setText(3, str(i))
198
- setattr(temp, '__value', i)
197
+ setattr(temp, '__tree_object', i)
199
198
  arg_tree.setCurrentItem(temp)
200
- self.empty_tree_item_child(temp)
199
+ tree_item_can_expand(temp)
201
200
  for k, v in global_value.items():
202
201
  if not k.startswith('__'):
203
202
  temp = QTreeWidgetItem(arg_tree)
204
203
  temp.setText(1, str(k))
205
204
  temp.setText(2, type(v).__name__)
206
205
  temp.setText(3, str(v))
207
- setattr(temp, '__value', v)
208
- self.empty_tree_item_child(temp)
206
+ setattr(temp, '__tree_object', v)
207
+ tree_item_can_expand(temp)
209
208
 
210
209
  def end_ok(self):
211
210
  try:
@@ -250,7 +249,7 @@ class ValueSetWindow(QDialog):
250
249
  def _get_object(self):
251
250
  arg_tree: QTreeWidget = self.findChild(QTreeWidget, 'arg_tree')
252
251
  tar_arg = arg_tree.currentItem()
253
- return getattr(tar_arg, '__value')
252
+ return getattr(tar_arg, '__tree_object')
254
253
 
255
254
  def get_re_value(self):
256
255
  print('func', self, self.re_value)
@@ -263,30 +262,37 @@ class ValueSetWindow(QDialog):
263
262
  temp.exec()
264
263
  return temp.re_value
265
264
 
266
- def empty_tree_item_child(self, item):
267
- value = getattr(item, '__value')
268
- if type(value) in (int, float, bool, str, list, dict) or value is None:
269
- setattr(item, '__expand', False)
270
- else:
271
- temp = QTreeWidgetItem(item)
272
- setattr(temp, '__delete', True)
273
- temp = QTreeWidgetItem(item)
274
- setattr(temp, '__delete', True)
275
-
276
- def expand_object_to_show_dir(self, item: QTreeWidgetItem):
277
- if getattr(item, '__expand', True):
278
- for i in range(item.childCount() - 1, -1, -1):
279
- tar_item = item.child(i)
280
- if getattr(tar_item, '__delete'):
281
- item.removeChild(tar_item)
282
- value = getattr(item, '__value')
283
- for k in dir(value):
284
- if not k.startswith('__'):
285
- v = getattr(value, k)
286
- if not callable(v):
287
- temp = QTreeWidgetItem(item)
288
- temp.setText(1, k)
289
- temp.setText(2, type(v).__name__)
290
- temp.setText(3, str(v))
291
- setattr(temp, '__value', v)
292
- self.empty_tree_item_child(temp)
265
+ @staticmethod
266
+ def expand_tree_item_to_show_dir(item):
267
+ expand_tree_item_to_show_dir(item, {
268
+ 1: lambda k, v: str(k),
269
+ 2: lambda k, v: type(v).__name__,
270
+ 3: lambda k, v: str(v),
271
+ })
272
+
273
+
274
+ def tree_item_can_expand(item):
275
+ value = getattr(item, '__tree_object')
276
+ if type(value) in (int, float, bool, str, list, dict) or value is None:
277
+ setattr(item, '__expand', False)
278
+ else:
279
+ temp = QTreeWidgetItem(item)
280
+ setattr(temp, '__delete', True)
281
+
282
+
283
+ def expand_tree_item_to_show_dir(item: QTreeWidgetItem, show_dict: dict):
284
+ if getattr(item, '__expand', True):
285
+ for i in range(item.childCount() - 1, -1, -1):
286
+ tar_item = item.child(i)
287
+ if getattr(tar_item, '__delete'):
288
+ item.removeChild(tar_item)
289
+ value = getattr(item, '__tree_object')
290
+ for k in dir(value):
291
+ if not k.startswith('__'):
292
+ v = getattr(value, k)
293
+ if not callable(v):
294
+ temp = QTreeWidgetItem(item)
295
+ for k2, v2 in show_dict.items():
296
+ temp.setText(int(k2), v2(k, v))
297
+ setattr(temp, '__tree_object', v)
298
+ tree_item_can_expand(temp)
@@ -0,0 +1,18 @@
1
+ Metadata-Version: 2.1
2
+ Name: movoid_debug
3
+ Version: 1.3.0
4
+ Home-page:
5
+ Author: movoid
6
+ Author-email: bobrobotsun@163.com
7
+ Description-Content-Type: text/markdown
8
+ Requires-Dist: movoid_function
9
+
10
+ 这个是一系列函数、类的装饰器,在运行时,如果报错,那么将会进入调试状态
11
+ 默认情况下:
12
+ 1、将所有Exception raise 出去,不做任何处理
13
+ 2、将Exception保存下来,可以在任意的地方调用某个方法抛出
14
+
15
+ debug状态下:
16
+ 0、直接进入debug模式,弹出窗口,并进行操作
17
+ 1、将所有Exception raise 出去,不做任何处理
18
+ 2、将Exception保存下来,可以在任意的地方调用某个方法抛出
@@ -5,7 +5,7 @@ with open("README.md", "r", encoding='utf-8') as fh:
5
5
 
6
6
  setup(
7
7
  name='movoid_debug',
8
- version='1.2.2',
8
+ version='1.3.0',
9
9
  packages=find_packages(),
10
10
  url='',
11
11
  license='',
@@ -1,10 +0,0 @@
1
- Metadata-Version: 2.1
2
- Name: movoid_debug
3
- Version: 1.2.2
4
- Home-page:
5
- Author: movoid
6
- Author-email: bobrobotsun@163.com
7
- Description-Content-Type: text/markdown
8
- Requires-Dist: movoid_function
9
-
10
- This is a simple program for developer to
@@ -1 +0,0 @@
1
- This is a simple program for developer to
@@ -1,10 +0,0 @@
1
- Metadata-Version: 2.1
2
- Name: movoid_debug
3
- Version: 1.2.2
4
- Home-page:
5
- Author: movoid
6
- Author-email: bobrobotsun@163.com
7
- Description-Content-Type: text/markdown
8
- Requires-Dist: movoid_function
9
-
10
- This is a simple program for developer to
File without changes
File without changes