pytest-dsl 0.4.0__py3-none-any.whl → 0.6.0__py3-none-any.whl
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.
- pytest_dsl/cli.py +28 -33
- pytest_dsl/core/auto_decorator.py +72 -53
- pytest_dsl/core/auto_directory.py +8 -5
- pytest_dsl/core/dsl_executor.py +211 -53
- pytest_dsl/core/http_request.py +272 -221
- pytest_dsl/core/lexer.py +14 -13
- pytest_dsl/core/parser.py +27 -8
- pytest_dsl/core/parsetab.py +71 -66
- pytest_dsl/core/plugin_discovery.py +1 -8
- pytest_dsl/core/yaml_loader.py +96 -19
- pytest_dsl/examples/assert/assertion_example.auto +1 -1
- pytest_dsl/examples/assert/boolean_test.auto +2 -2
- pytest_dsl/examples/assert/expression_test.auto +1 -1
- pytest_dsl/examples/custom/test_advanced_keywords.auto +2 -2
- pytest_dsl/examples/custom/test_custom_keywords.auto +2 -2
- pytest_dsl/examples/custom/test_default_values.auto +2 -2
- pytest_dsl/examples/http/file_reference_test.auto +1 -1
- pytest_dsl/examples/http/http_advanced.auto +1 -1
- pytest_dsl/examples/http/http_example.auto +1 -1
- pytest_dsl/examples/http/http_length_test.auto +1 -1
- pytest_dsl/examples/http/http_retry_assertions.auto +1 -1
- pytest_dsl/examples/http/http_retry_assertions_enhanced.auto +2 -2
- pytest_dsl/examples/http/http_with_yaml.auto +1 -1
- pytest_dsl/examples/quickstart/api_basics.auto +1 -1
- pytest_dsl/examples/quickstart/assertions.auto +1 -1
- pytest_dsl/examples/quickstart/loops.auto +2 -2
- pytest_dsl/keywords/assertion_keywords.py +76 -62
- pytest_dsl/keywords/global_keywords.py +43 -4
- pytest_dsl/keywords/http_keywords.py +141 -139
- {pytest_dsl-0.4.0.dist-info → pytest_dsl-0.6.0.dist-info}/METADATA +266 -15
- pytest_dsl-0.6.0.dist-info/RECORD +68 -0
- {pytest_dsl-0.4.0.dist-info → pytest_dsl-0.6.0.dist-info}/WHEEL +1 -1
- {pytest_dsl-0.4.0.dist-info → pytest_dsl-0.6.0.dist-info}/entry_points.txt +1 -0
- pytest_dsl-0.4.0.dist-info/RECORD +0 -68
- {pytest_dsl-0.4.0.dist-info → pytest_dsl-0.6.0.dist-info}/licenses/LICENSE +0 -0
- {pytest_dsl-0.4.0.dist-info → pytest_dsl-0.6.0.dist-info}/top_level.txt +0 -0
@@ -14,24 +14,24 @@ from pytest_dsl.core.keyword_manager import keyword_manager
|
|
14
14
|
|
15
15
|
def _extract_jsonpath(json_data: Union[Dict, List], path: str) -> Any:
|
16
16
|
"""使用JSONPath从JSON数据中提取值
|
17
|
-
|
17
|
+
|
18
18
|
Args:
|
19
19
|
json_data: 要提取数据的JSON对象或数组
|
20
20
|
path: JSONPath表达式
|
21
|
-
|
21
|
+
|
22
22
|
Returns:
|
23
23
|
提取的值或值列表
|
24
|
-
|
24
|
+
|
25
25
|
Raises:
|
26
26
|
ValueError: 如果JSONPath表达式无效或找不到匹配项
|
27
27
|
"""
|
28
28
|
try:
|
29
29
|
if isinstance(json_data, str):
|
30
30
|
json_data = json.loads(json_data)
|
31
|
-
|
31
|
+
|
32
32
|
jsonpath_expr = jsonpath.parse(path)
|
33
33
|
matches = [match.value for match in jsonpath_expr.find(json_data)]
|
34
|
-
|
34
|
+
|
35
35
|
if not matches:
|
36
36
|
return None
|
37
37
|
elif len(matches) == 1:
|
@@ -44,12 +44,12 @@ def _extract_jsonpath(json_data: Union[Dict, List], path: str) -> Any:
|
|
44
44
|
|
45
45
|
def _compare_values(actual: Any, expected: Any, operator: str = "==") -> bool:
|
46
46
|
"""比较两个值
|
47
|
-
|
47
|
+
|
48
48
|
Args:
|
49
49
|
actual: 实际值
|
50
50
|
expected: 预期值
|
51
51
|
operator: 比较运算符 (==, !=, >, <, >=, <=, contains, not_contains, matches, and, or, not)
|
52
|
-
|
52
|
+
|
53
53
|
Returns:
|
54
54
|
比较结果 (True/False)
|
55
55
|
"""
|
@@ -101,32 +101,32 @@ def _compare_values(actual: Any, expected: Any, operator: str = "==") -> bool:
|
|
101
101
|
])
|
102
102
|
def assert_condition(**kwargs):
|
103
103
|
"""执行表达式断言
|
104
|
-
|
104
|
+
|
105
105
|
Args:
|
106
106
|
condition: 断言条件表达式
|
107
107
|
message: 断言失败时的错误消息
|
108
|
-
|
108
|
+
|
109
109
|
Returns:
|
110
110
|
断言结果 (True/False)
|
111
|
-
|
111
|
+
|
112
112
|
Raises:
|
113
113
|
AssertionError: 如果断言失败
|
114
114
|
"""
|
115
115
|
condition = kwargs.get('condition')
|
116
116
|
message = kwargs.get('message', '断言失败')
|
117
117
|
context = kwargs.get('context')
|
118
|
-
|
118
|
+
|
119
119
|
# 简单解析表达式,支持 ==, !=, >, <, >=, <=, contains, not_contains, matches, in, and, or, not
|
120
120
|
# 格式: "left_value operator right_value" 或 "boolean_expression"
|
121
121
|
operators = ["==", "!=", ">", "<", ">=", "<=", "contains", "not_contains", "matches", "in", "and", "or", "not"]
|
122
|
-
|
122
|
+
|
123
123
|
# 先检查是否包含这些操作符
|
124
124
|
operator_used = None
|
125
125
|
for op in operators:
|
126
126
|
if f" {op} " in condition:
|
127
127
|
operator_used = op
|
128
128
|
break
|
129
|
-
|
129
|
+
|
130
130
|
if not operator_used:
|
131
131
|
# 如果没有找到操作符,尝试作为布尔表达式直接求值
|
132
132
|
try:
|
@@ -142,36 +142,36 @@ def assert_condition(**kwargs):
|
|
142
142
|
return True
|
143
143
|
except Exception as e:
|
144
144
|
raise AssertionError(f"{message}. 无法解析条件表达式: {condition}. 错误: {str(e)}")
|
145
|
-
|
145
|
+
|
146
146
|
# 解析左值和右值
|
147
147
|
left_value, right_value = condition.split(f" {operator_used} ", 1)
|
148
148
|
left_value = left_value.strip()
|
149
149
|
right_value = right_value.strip()
|
150
|
-
|
150
|
+
|
151
151
|
# 移除引号(如果有)
|
152
152
|
if left_value.startswith('"') and left_value.endswith('"'):
|
153
153
|
left_value = left_value[1:-1]
|
154
154
|
elif left_value.startswith("'") and left_value.endswith("'"):
|
155
155
|
left_value = left_value[1:-1]
|
156
|
-
|
156
|
+
|
157
157
|
if right_value.startswith('"') and right_value.endswith('"'):
|
158
158
|
right_value = right_value[1:-1]
|
159
159
|
elif right_value.startswith("'") and right_value.endswith("'"):
|
160
160
|
right_value = right_value[1:-1]
|
161
|
-
|
161
|
+
|
162
162
|
# 记录原始值(用于调试)
|
163
163
|
allure.attach(
|
164
164
|
f"原始左值: {left_value}\n原始右值: {right_value}\n操作符: {operator_used}",
|
165
165
|
name="表达式解析",
|
166
166
|
attachment_type=allure.attachment_type.TEXT
|
167
167
|
)
|
168
|
-
|
168
|
+
|
169
169
|
# 对左值进行变量替换和表达式计算
|
170
170
|
try:
|
171
171
|
# 如果左值包含变量引用,先进行变量替换
|
172
172
|
if '${' in left_value:
|
173
173
|
left_value = context.executor.variable_replacer.replace_in_string(left_value)
|
174
|
-
|
174
|
+
|
175
175
|
# 检查是否需要计算表达式
|
176
176
|
if any(op in str(left_value) for op in ['+', '-', '*', '/', '%', '(', ')']):
|
177
177
|
try:
|
@@ -187,7 +187,7 @@ def assert_condition(**kwargs):
|
|
187
187
|
attachment_type=allure.attachment_type.TEXT
|
188
188
|
)
|
189
189
|
raise ValueError(f"表达式计算错误: {str(e)}")
|
190
|
-
|
190
|
+
|
191
191
|
# 处理布尔值字符串和数字字符串
|
192
192
|
if isinstance(left_value, str):
|
193
193
|
if left_value.lower() in ('true', 'false'):
|
@@ -210,13 +210,13 @@ def assert_condition(**kwargs):
|
|
210
210
|
attachment_type=allure.attachment_type.TEXT
|
211
211
|
)
|
212
212
|
raise
|
213
|
-
|
213
|
+
|
214
214
|
# 对右值进行变量替换和表达式计算
|
215
215
|
try:
|
216
216
|
# 如果右值包含变量引用,先进行变量替换
|
217
217
|
if '${' in right_value:
|
218
218
|
right_value = context.executor.variable_replacer.replace_in_string(right_value)
|
219
|
-
|
219
|
+
|
220
220
|
# 检查是否需要计算表达式
|
221
221
|
if any(op in str(right_value) for op in ['+', '-', '*', '/', '%', '(', ')']):
|
222
222
|
try:
|
@@ -232,7 +232,7 @@ def assert_condition(**kwargs):
|
|
232
232
|
attachment_type=allure.attachment_type.TEXT
|
233
233
|
)
|
234
234
|
raise ValueError(f"表达式计算错误: {str(e)}")
|
235
|
-
|
235
|
+
|
236
236
|
# 处理布尔值字符串
|
237
237
|
if isinstance(right_value, str):
|
238
238
|
if right_value.lower() in ('true', 'false'):
|
@@ -246,7 +246,7 @@ def assert_condition(**kwargs):
|
|
246
246
|
attachment_type=allure.attachment_type.TEXT
|
247
247
|
)
|
248
248
|
raise
|
249
|
-
|
249
|
+
|
250
250
|
# 类型转换和特殊处理
|
251
251
|
if operator_used == "contains":
|
252
252
|
# 特殊处理字符串包含操作
|
@@ -285,7 +285,7 @@ def assert_condition(**kwargs):
|
|
285
285
|
# 尝试将右值解析为列表或字典
|
286
286
|
if isinstance(right_value, str):
|
287
287
|
right_value = eval(right_value)
|
288
|
-
|
288
|
+
|
289
289
|
# 如果是字典,检查键
|
290
290
|
if isinstance(right_value, dict):
|
291
291
|
result = left_value in right_value.keys()
|
@@ -310,17 +310,17 @@ def assert_condition(**kwargs):
|
|
310
310
|
right_value = float(right_value)
|
311
311
|
except:
|
312
312
|
pass
|
313
|
-
|
313
|
+
|
314
314
|
# 记录类型转换后的值(用于调试)
|
315
315
|
allure.attach(
|
316
316
|
f"类型转换后左值: {left_value} ({type(left_value).__name__})\n类型转换后右值: {right_value} ({type(right_value).__name__})",
|
317
317
|
name="类型转换",
|
318
318
|
attachment_type=allure.attachment_type.TEXT
|
319
319
|
)
|
320
|
-
|
320
|
+
|
321
321
|
# 执行比较
|
322
322
|
result = _compare_values(left_value, right_value, operator_used)
|
323
|
-
|
323
|
+
|
324
324
|
# 记录和处理断言结果
|
325
325
|
if not result:
|
326
326
|
error_details = f"""
|
@@ -337,7 +337,7 @@ def assert_condition(**kwargs):
|
|
337
337
|
attachment_type=allure.attachment_type.TEXT
|
338
338
|
)
|
339
339
|
raise AssertionError(error_details)
|
340
|
-
|
340
|
+
|
341
341
|
# 记录成功的断言
|
342
342
|
allure.attach(
|
343
343
|
f"实际值: {left_value}\n预期值: {right_value}\n操作符: {operator_used}",
|
@@ -356,17 +356,17 @@ def assert_condition(**kwargs):
|
|
356
356
|
])
|
357
357
|
def assert_json(**kwargs):
|
358
358
|
"""执行JSON断言
|
359
|
-
|
359
|
+
|
360
360
|
Args:
|
361
361
|
json_data: JSON数据(字符串或对象)
|
362
362
|
jsonpath: JSONPath表达式
|
363
363
|
expected_value: 预期的值
|
364
364
|
operator: 比较操作符,默认为"=="
|
365
365
|
message: 断言失败时的错误消息
|
366
|
-
|
366
|
+
|
367
367
|
Returns:
|
368
368
|
断言结果 (True/False)
|
369
|
-
|
369
|
+
|
370
370
|
Raises:
|
371
371
|
AssertionError: 如果断言失败
|
372
372
|
ValueError: 如果JSONPath无效或找不到匹配项
|
@@ -376,27 +376,27 @@ def assert_json(**kwargs):
|
|
376
376
|
expected_value = kwargs.get('expected_value')
|
377
377
|
operator = kwargs.get('operator', '==')
|
378
378
|
message = kwargs.get('message', 'JSON断言失败')
|
379
|
-
|
379
|
+
|
380
380
|
# 解析JSON(如果需要)
|
381
381
|
if isinstance(json_data, str):
|
382
382
|
try:
|
383
383
|
json_data = json.loads(json_data)
|
384
384
|
except json.JSONDecodeError as e:
|
385
385
|
raise ValueError(f"无效的JSON数据: {str(e)}")
|
386
|
-
|
386
|
+
|
387
387
|
# 使用JSONPath提取值
|
388
388
|
actual_value = _extract_jsonpath(json_data, path)
|
389
|
-
|
389
|
+
|
390
390
|
# 记录提取的值
|
391
391
|
allure.attach(
|
392
392
|
f"JSONPath: {path}\n提取值: {actual_value}",
|
393
393
|
name="JSONPath提取结果",
|
394
394
|
attachment_type=allure.attachment_type.TEXT
|
395
395
|
)
|
396
|
-
|
396
|
+
|
397
397
|
# 比较值
|
398
398
|
result = _compare_values(actual_value, expected_value, operator)
|
399
|
-
|
399
|
+
|
400
400
|
# 记录和处理断言结果
|
401
401
|
if not result:
|
402
402
|
allure.attach(
|
@@ -405,7 +405,7 @@ def assert_json(**kwargs):
|
|
405
405
|
attachment_type=allure.attachment_type.TEXT
|
406
406
|
)
|
407
407
|
raise AssertionError(message)
|
408
|
-
|
408
|
+
|
409
409
|
# 记录成功的断言
|
410
410
|
allure.attach(
|
411
411
|
f"实际值: {actual_value}\n预期值: {expected_value}\n操作符: {operator}",
|
@@ -422,21 +422,23 @@ def assert_json(**kwargs):
|
|
422
422
|
])
|
423
423
|
def extract_json(**kwargs):
|
424
424
|
"""从JSON数据中提取值并保存到变量
|
425
|
-
|
425
|
+
|
426
426
|
Args:
|
427
427
|
json_data: JSON数据(字符串或对象)
|
428
428
|
jsonpath: JSONPath表达式
|
429
429
|
variable: 存储提取值的变量名
|
430
|
-
|
430
|
+
context: 测试上下文
|
431
|
+
|
431
432
|
Returns:
|
432
|
-
|
433
|
-
|
433
|
+
提取的值或包含提取值的字典(远程模式)
|
434
|
+
|
434
435
|
Raises:
|
435
436
|
ValueError: 如果JSONPath无效或找不到匹配项
|
436
437
|
"""
|
437
438
|
json_data = kwargs.get('json_data')
|
438
439
|
path = kwargs.get('jsonpath')
|
439
440
|
variable = kwargs.get('variable')
|
441
|
+
context = kwargs.get('context')
|
440
442
|
|
441
443
|
# 解析JSON(如果需要)
|
442
444
|
if isinstance(json_data, str):
|
@@ -444,19 +446,31 @@ def extract_json(**kwargs):
|
|
444
446
|
json_data = json.loads(json_data)
|
445
447
|
except json.JSONDecodeError as e:
|
446
448
|
raise ValueError(f"无效的JSON数据: {str(e)}")
|
447
|
-
|
449
|
+
|
448
450
|
# 使用JSONPath提取值
|
449
451
|
value = _extract_jsonpath(json_data, path)
|
450
|
-
|
452
|
+
|
453
|
+
# 将提取的值设置到上下文中(本地模式)
|
454
|
+
if context and variable:
|
455
|
+
context.set(variable, value)
|
456
|
+
|
451
457
|
# 记录提取的值
|
452
458
|
allure.attach(
|
453
459
|
f"JSONPath: {path}\n提取值: {value}\n保存到变量: {variable}",
|
454
460
|
name="JSON数据提取",
|
455
461
|
attachment_type=allure.attachment_type.TEXT
|
456
462
|
)
|
457
|
-
|
458
|
-
#
|
459
|
-
return
|
463
|
+
|
464
|
+
# 统一返回格式 - 支持远程关键字模式
|
465
|
+
return {
|
466
|
+
"result": value, # 主要返回值保持兼容
|
467
|
+
"captures": {variable: value} if variable else {}, # 明确的捕获变量
|
468
|
+
"session_state": {},
|
469
|
+
"metadata": {
|
470
|
+
"jsonpath": path,
|
471
|
+
"variable_name": variable
|
472
|
+
}
|
473
|
+
}
|
460
474
|
|
461
475
|
|
462
476
|
@keyword_manager.register('类型断言', [
|
@@ -466,22 +480,22 @@ def extract_json(**kwargs):
|
|
466
480
|
])
|
467
481
|
def assert_type(**kwargs):
|
468
482
|
"""断言值的类型
|
469
|
-
|
483
|
+
|
470
484
|
Args:
|
471
485
|
value: 要检查的值
|
472
486
|
type: 预期的类型 (string, number, boolean, list, object, null)
|
473
487
|
message: 断言失败时的错误消息
|
474
|
-
|
488
|
+
|
475
489
|
Returns:
|
476
490
|
断言结果 (True/False)
|
477
|
-
|
491
|
+
|
478
492
|
Raises:
|
479
493
|
AssertionError: 如果断言失败
|
480
494
|
"""
|
481
495
|
value = kwargs.get('value')
|
482
496
|
expected_type = kwargs.get('type')
|
483
497
|
message = kwargs.get('message', '类型断言失败')
|
484
|
-
|
498
|
+
|
485
499
|
# 检查类型
|
486
500
|
if expected_type == 'string':
|
487
501
|
result = isinstance(value, str)
|
@@ -508,7 +522,7 @@ def assert_type(**kwargs):
|
|
508
522
|
result = value is None
|
509
523
|
else:
|
510
524
|
raise ValueError(f"不支持的类型: {expected_type}")
|
511
|
-
|
525
|
+
|
512
526
|
# 记录和处理断言结果
|
513
527
|
if not result:
|
514
528
|
actual_type = type(value).__name__
|
@@ -518,7 +532,7 @@ def assert_type(**kwargs):
|
|
518
532
|
attachment_type=allure.attachment_type.TEXT
|
519
533
|
)
|
520
534
|
raise AssertionError(message)
|
521
|
-
|
535
|
+
|
522
536
|
# 记录成功的断言
|
523
537
|
allure.attach(
|
524
538
|
f"值: {value}\n类型: {expected_type}",
|
@@ -536,16 +550,16 @@ def assert_type(**kwargs):
|
|
536
550
|
])
|
537
551
|
def compare_values(**kwargs):
|
538
552
|
"""比较两个值
|
539
|
-
|
553
|
+
|
540
554
|
Args:
|
541
555
|
actual: 实际值
|
542
556
|
expected: 预期值
|
543
557
|
operator: 比较操作符,默认为"=="
|
544
558
|
message: 断言失败时的错误消息
|
545
|
-
|
559
|
+
|
546
560
|
Returns:
|
547
561
|
比较结果 (True/False)
|
548
|
-
|
562
|
+
|
549
563
|
Raises:
|
550
564
|
AssertionError: 如果比较失败
|
551
565
|
"""
|
@@ -553,7 +567,7 @@ def compare_values(**kwargs):
|
|
553
567
|
expected = kwargs.get('expected')
|
554
568
|
operator = kwargs.get('operator', '==')
|
555
569
|
message = kwargs.get('message', '数据比较失败')
|
556
|
-
|
570
|
+
|
557
571
|
# 处理布尔值字符串和表达式
|
558
572
|
if isinstance(actual, str):
|
559
573
|
# 检查是否需要计算表达式
|
@@ -571,7 +585,7 @@ def compare_values(**kwargs):
|
|
571
585
|
actual = actual.lower() == 'true'
|
572
586
|
elif actual.lower() in ('yes', 'no', '1', '0', 't', 'f', 'y', 'n'):
|
573
587
|
actual = actual.lower() in ('yes', '1', 't', 'y')
|
574
|
-
|
588
|
+
|
575
589
|
if isinstance(expected, str):
|
576
590
|
# 检查是否需要计算表达式
|
577
591
|
if any(op in expected for op in ['+', '-', '*', '/', '%', '(', ')']):
|
@@ -588,10 +602,10 @@ def compare_values(**kwargs):
|
|
588
602
|
expected = expected.lower() == 'true'
|
589
603
|
elif expected.lower() in ('yes', 'no', '1', '0', 't', 'f', 'y', 'n'):
|
590
604
|
expected = expected.lower() in ('yes', '1', 't', 'y')
|
591
|
-
|
605
|
+
|
592
606
|
# 比较值
|
593
607
|
result = _compare_values(actual, expected, operator)
|
594
|
-
|
608
|
+
|
595
609
|
# 记录和处理比较结果
|
596
610
|
if not result:
|
597
611
|
allure.attach(
|
@@ -600,11 +614,11 @@ def compare_values(**kwargs):
|
|
600
614
|
attachment_type=allure.attachment_type.TEXT
|
601
615
|
)
|
602
616
|
raise AssertionError(message)
|
603
|
-
|
617
|
+
|
604
618
|
# 记录成功的比较
|
605
619
|
allure.attach(
|
606
620
|
f"实际值: {actual}\n预期值: {expected}\n操作符: {operator}",
|
607
621
|
name="数据比较成功",
|
608
622
|
attachment_type=allure.attachment_type.TEXT
|
609
623
|
)
|
610
|
-
return result
|
624
|
+
return result
|
@@ -12,7 +12,17 @@ from pytest_dsl.core.global_context import global_context
|
|
12
12
|
def set_global_variable(name, value, context):
|
13
13
|
"""设置全局变量"""
|
14
14
|
global_context.set_variable(name, value)
|
15
|
-
|
15
|
+
|
16
|
+
# 统一返回格式 - 支持远程关键字模式
|
17
|
+
return {
|
18
|
+
"result": value, # 主要返回值保持兼容
|
19
|
+
"captures": {},
|
20
|
+
"session_state": {},
|
21
|
+
"metadata": {
|
22
|
+
"variable_name": name,
|
23
|
+
"operation": "set_global_variable"
|
24
|
+
}
|
25
|
+
}
|
16
26
|
|
17
27
|
|
18
28
|
@keyword_manager.register(
|
@@ -26,7 +36,17 @@ def get_global_variable(name, context):
|
|
26
36
|
value = global_context.get_variable(name)
|
27
37
|
if value is None:
|
28
38
|
raise Exception(f"全局变量未定义: {name}")
|
29
|
-
|
39
|
+
|
40
|
+
# 统一返回格式 - 支持远程关键字模式
|
41
|
+
return {
|
42
|
+
"result": value, # 主要返回值保持兼容
|
43
|
+
"captures": {},
|
44
|
+
"session_state": {},
|
45
|
+
"metadata": {
|
46
|
+
"variable_name": name,
|
47
|
+
"operation": "get_global_variable"
|
48
|
+
}
|
49
|
+
}
|
30
50
|
|
31
51
|
|
32
52
|
@keyword_manager.register(
|
@@ -38,7 +58,17 @@ def get_global_variable(name, context):
|
|
38
58
|
def delete_global_variable(name, context):
|
39
59
|
"""删除全局变量"""
|
40
60
|
global_context.delete_variable(name)
|
41
|
-
|
61
|
+
|
62
|
+
# 统一返回格式 - 支持远程关键字模式
|
63
|
+
return {
|
64
|
+
"result": True, # 主要返回值保持兼容
|
65
|
+
"captures": {},
|
66
|
+
"session_state": {},
|
67
|
+
"metadata": {
|
68
|
+
"variable_name": name,
|
69
|
+
"operation": "delete_global_variable"
|
70
|
+
}
|
71
|
+
}
|
42
72
|
|
43
73
|
|
44
74
|
@keyword_manager.register(
|
@@ -48,4 +78,13 @@ def delete_global_variable(name, context):
|
|
48
78
|
def clear_all_global_variables(context):
|
49
79
|
"""清除所有全局变量"""
|
50
80
|
global_context.clear_all()
|
51
|
-
|
81
|
+
|
82
|
+
# 统一返回格式 - 支持远程关键字模式
|
83
|
+
return {
|
84
|
+
"result": True, # 主要返回值保持兼容
|
85
|
+
"captures": {},
|
86
|
+
"session_state": {},
|
87
|
+
"metadata": {
|
88
|
+
"operation": "clear_all_global_variables"
|
89
|
+
}
|
90
|
+
}
|