@@ -268,14 +268,15 @@ def analyse_args(analyser: Analyser, argv: Argv, args: _Args) -> dict[str, Any]:
268
268
return result
269
269
270
270
271
- def handle_option (analyser : Analyser , argv : Argv , opt : Option , name_validated : bool ) -> tuple [Any , dict [ str , Any ]] :
271
+ def analyse_option (analyser : Analyser , opt : Option , argv : Argv , path : tuple [str , ...], name_validated : bool ) :
272
272
"""
273
- 处理 `Option` 部分
273
+ 分析 `Option` 部分
274
274
275
275
Args:
276
- analyser (Analyser): 当前解析器
277
- argv (Argv): 命令行参数
276
+ analyser (SubAnalyser): 当前解析器
278
277
opt (Option): 目标 `Option`
278
+ argv (Argv): 命令行参数
279
+ path (tuple[str, ...]): 路径
279
280
name_validated (bool): 是否已经验证过名称
280
281
"""
281
282
_cnt = 0
@@ -303,53 +304,36 @@ def handle_option(analyser: Analyser, argv: Argv, opt: Option, name_validated: b
303
304
if levenshtein (name , al ) >= argv .fuzzy_threshold :
304
305
raise FuzzyMatchSuccess (lang .require ("fuzzy" , "matched" ).format (source = al , target = name ))
305
306
raise InvalidParam (lang .require ("option" , "name_error" ).format (source = opt .dest , target = name ), opt )
306
- if opt .nargs :
307
- return ..., analyse_args (analyser , argv , opt .args )
308
- return _cnt or opt .action .value , {}
309
-
310
-
311
- def analyse_option (analyser : Analyser , opt : Option , argv : Argv , path : tuple [str , ...], name_validated : bool ):
312
- """
313
- 分析 `Option` 部分
314
-
315
- Args:
316
- analyser (SubAnalyser): 当前解析器
317
- opt (Option): 目标 `Option`
318
- argv (Argv): 命令行参数
319
- path (tuple[str, ...]): 路径
320
- name_validated (bool): 是否已经验证过名称
321
- """
322
- value , args = handle_option (analyser , argv , opt , name_validated )
307
+ args = analyse_args (analyser , argv , opt .args ) if opt .nargs else {}
323
308
if path not in analyser .value_result :
324
- if opt .action .type == 1 :
325
- if args :
326
- analyser .value_result [path ] = value
327
- analyser .args_result [path ] = {key : [value ] for key , value in args .items ()}
328
- else :
329
- analyser .value_result [path ] = value [:]
330
- else :
331
- analyser .value_result [path ] = value
332
- analyser .args_result [path ] = args
333
- return
309
+ analyser .args_result [path ] = args
310
+ if opt .action .type == 1 and args :
311
+ analyser .args_result [path ] = {key : [value ] for key , value in args .items ()}
312
+ analyser .value_result [path ] = _cnt or opt .action .value
313
+ return True
334
314
if opt .action .type == 0 : # cover the old value
335
- analyser .value_result [path ] = value
315
+ analyser .value_result [path ] = _cnt or opt . action . value
336
316
analyser .args_result [path ] = args
337
- elif opt .action .type == 2 :
338
- if not opt .nargs :
339
- analyser .value_result [path ] += value
340
- else :
341
- analyser .value_result [path ] = value
342
- elif not opt .nargs : # opt.action.type == 1
343
- analyser .value_result [path ].extend (value )
317
+ return True
318
+ if opt .action .type == 2 :
319
+ analyser .value_result [path ] += _cnt or opt .action .value
320
+ return True
321
+ if not opt .nargs : # opt.action.type == 1
322
+ source = analyser .value_result [path ][:]
323
+ source .extend (opt .action .value )
324
+ analyser .value_result [path ] = source
344
325
else :
345
326
for key , value in args .items ():
346
327
if key in analyser .args_result [path ]:
347
328
analyser .args_result [path ][key ].append (args [key ])
348
329
else :
349
330
analyser .args_result [path ][key ] = [value ]
331
+ return True
350
332
351
333
352
334
def analyse_subcommand (analyser : Analyser , sub : Subcommand , argv : Argv , path : tuple [str , ...], name_validated : bool = True ):
335
+ if path in analyser .value_result :
336
+ return False
353
337
if not name_validated :
354
338
name , _ = argv .next (sub .separators )
355
339
if name not in sub .aliases :
@@ -365,7 +349,7 @@ def analyse_subcommand(analyser: Analyser, sub: Subcommand, argv: Argv, path: tu
365
349
while analyse_param (analyser , sub , argv , path , sub .separators ) and argv .current_index != argv .ndata :
366
350
pass
367
351
if path not in analyser .args_optional or path in analyser .args_result :
368
- return
352
+ return True
369
353
if not analyser .args_optional [path ]:
370
354
raise ArgumentMissing (
371
355
sub .args .data [0 ].field .get_missing_tips (
@@ -374,7 +358,7 @@ def analyse_subcommand(analyser: Analyser, sub: Subcommand, argv: Argv, path: tu
374
358
sub
375
359
)
376
360
analyser .args_result [path ] = analyse_args (analyser , argv , sub .args )
377
- return
361
+ return True
378
362
379
363
380
364
def analyse_compact_params (analyser : Analyser , argv : Argv , prefixes : tuple [str , ...]):
@@ -426,25 +410,18 @@ def analyse_param(analyser: Analyser, current: Subcommand, argv: Argv, prefixes:
426
410
# analyser.compile_params 有命中,说明在当前子命令内有对应的选项/子命令
427
411
if _str and _text and (_param := current ._lookup_map .get (_text )):
428
412
path = prefixes + (_param .dest ,)
429
- if _param .__class__ is Subcommand :
430
- # 禁止子命令重复解析
431
- if path not in analyser .value_result :
432
- try :
433
- analyse_subcommand (analyser , _param , argv , path , True ) # type: ignore
434
- except (FuzzyMatchSuccess , PauseTriggered ):
435
- raise
436
- except AnalyseException as e :
437
- if not analyser ._error :
438
- analyser ._error = e
439
- return True
440
- else :
441
- try :
442
- analyse_option (analyser , _param , argv , path , True ) # type: ignore
443
- except (FuzzyMatchSuccess , PauseTriggered ):
444
- raise
445
- except AnalyseException as e :
446
- if not analyser ._error :
447
- analyser ._error = e
413
+ apply = True
414
+ try :
415
+ if _param .__class__ is Subcommand :
416
+ apply = analyse_subcommand (analyser , _param , argv , path , True ) # type: ignore
417
+ else :
418
+ apply = analyse_option (analyser , _param , argv , path , True ) # type: ignore
419
+ except (FuzzyMatchSuccess , PauseTriggered ):
420
+ raise
421
+ except AnalyseException as e :
422
+ if not analyser ._error :
423
+ analyser ._error = e
424
+ if apply :
448
425
return True
449
426
# 如果没有命中,则说明当前参数可能存在自定义分隔符,或者属于子命令的主参数,那么需要重新解析
450
427
argv .rollback (_text )
@@ -473,18 +450,17 @@ def analyse_param(analyser: Analyser, current: Subcommand, argv: Argv, prefixes:
473
450
474
451
475
452
def analyse_header (header : "Header" , argv : Argv ):
476
- content = header .content
477
453
head_text , _str = argv .next ()
478
454
if _str :
479
- if head_text in content :
455
+ if head_text in header . content :
480
456
return HeadResult (head_text , head_text , True )
481
457
if header .compact and (mat := header .compact_pattern .match (head_text )):
482
458
argv .rollback (head_text [len (mat [0 ]):], replace = True )
483
459
return HeadResult (mat [0 ], mat [0 ], True )
484
460
may_cmd , _m_str = argv .next ()
485
461
if _m_str :
486
462
cmd = f"{ head_text } { argv .separators [0 ]} { may_cmd } "
487
- if cmd in content :
463
+ if cmd in header . content :
488
464
return HeadResult (cmd , cmd , True )
489
465
if header .compact and (mat := header .compact_pattern .match (cmd )):
490
466
argv .rollback (cmd [len (mat [0 ]):], replace = True )
0 commit comments