Skip to content

Commit

Permalink
🐛 fix duplicate subcommand
Browse files Browse the repository at this point in the history
  • Loading branch information
RF-Tar-Railt committed Sep 22, 2024
1 parent 3a36d6f commit 2a8d8c3
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 34 deletions.
5 changes: 3 additions & 2 deletions src/arclet/alconna/_internal/_analyser.py
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,8 @@ def analyse(self, argv: Argv[TDC]) -> Self:
ArgumentMissing: 参数缺失
"""
while analyse_param(self, argv, self.command.separators):
pass
self.sentences.clear()
argv.current_node = None
if self.default_main_only and not self.args_result:
self.args_result = analyse_args(argv, self.self_args)
if not self.args_result and self.need_main_args:
Expand Down Expand Up @@ -406,7 +407,7 @@ def process(self, argv: Argv[TDC]) -> Arparma[TDC]:
def analyse(self, argv: Argv[TDC]) -> Arparma[TDC] | None:
try:
while analyse_param(self, argv) and argv.current_index != argv.ndata:
pass
argv.current_node = None
except FuzzyMatchSuccess as e:
output_manager.send(self.command.name, lambda: str(e))
return self.export(argv, True)
Expand Down
68 changes: 37 additions & 31 deletions src/arclet/alconna/_internal/_handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -442,22 +442,20 @@ def analyse_param(analyser: SubAnalyser, argv: Argv, seps: tuple[str, ...] | Non
return True
else:
_param = None
if not _param and analyser.command.nargs and not analyser.args_result:
analyser.args_result = analyse_args(argv, analyser.self_args)
if analyser.args_result:
argv.current_node = None
return True
if _param.__class__ is Sentence:
analyser.sentences.append(argv.next()[0])
return True
if _param.name not in analyser.sentences: # type: ignore
analyser.sentences.append(argv.next()[0])
return True
if _param.__class__ is Option:
oparam: Option = _param # type: ignore
if oparam.requires and analyser.sentences != oparam.requires:
raise InvalidParam(
lang.require("option", "require_error").format(source=oparam.name, target=" ".join(analyser.sentences))
)
analyse_option(analyser, argv, oparam)
elif _param.__class__ is list:
analyser.sentences.clear()
return True
if _param.__class__ is list:
exc: Exception | None = None
lparam: list[Option] = _param # type: ignore
for opt in lparam:
Expand All @@ -479,38 +477,46 @@ def analyse_param(analyser: SubAnalyser, argv: Argv, seps: tuple[str, ...] | Non
argv.data_reset(_data, _index)
if exc:
raise exc # type: ignore # noqa
elif _param is not None:
analyser.sentences.clear()
return True
if _param is not None:
sparam: SubAnalyser = _param # type: ignore
if sparam.command.requires and analyser.sentences != sparam.command.requires:
raise InvalidParam(
lang.require("subcommand", "require_error").format(
source=sparam.command.name, target=" ".join(analyser.sentences)
if sparam.command.dest not in analyser.subcommands_result:
if sparam.command.requires and analyser.sentences != sparam.command.requires:
raise InvalidParam(
lang.require("subcommand", "require_error").format(
source=sparam.command.name, target=" ".join(analyser.sentences)
)
)
)
try:
sparam.process(argv)
except (FuzzyMatchSuccess, PauseTriggered, SpecialOptionTriggered):
sparam.result()
raise
except InvalidParam:
if argv.current_node is sparam.command:
try:
sparam.process(argv)
except (FuzzyMatchSuccess, PauseTriggered, SpecialOptionTriggered):
sparam.result()
raise
except InvalidParam:
if argv.current_node is sparam.command:
sparam.result()
else:
analyser.subcommands_result[sparam.command.dest] = sparam.result()
raise
except AlconnaException:
analyser.subcommands_result[sparam.command.dest] = sparam.result()
raise
else:
analyser.subcommands_result[sparam.command.dest] = sparam.result()
raise
except AlconnaException:
analyser.subcommands_result[sparam.command.dest] = sparam.result()
raise
else:
analyser.subcommands_result[sparam.command.dest] = sparam.result()
elif analyser.extra_allow:
analyser.sentences.clear()
return True
if _param is None and analyser.command.nargs and not analyser.args_result:
analyser.args_result = analyse_args(argv, analyser.self_args)
if analyser.args_result:
argv.current_node = None
return True
if analyser.extra_allow:
analyser.args_result.setdefault("$extra", []).append(_text)
argv.next(seps, move=True)
return True
else:
return False
analyser.sentences.clear()
argv.current_node = None
return True


def _header_handle0(header: "Header[set[str], TPattern]", argv: Argv):
Expand Down
2 changes: 1 addition & 1 deletion tests/core_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -868,7 +868,7 @@ def test_action():
Option("--q", action=count, requires=["foo", "bar"]),
)
res = alc24_2.parse(
"core24_2 -A --a -vvv -x -x --xyzxyz " "-Fabc -Fdef --flag xyz --i 4 --i 5 " "foo bar --q foo bar --qq"
"core24_2 -A --a -vvv -x -x --xyzxyz -Fabc -Fdef --flag xyz --i 4 --i 5 foo bar --q foo bar --qq"
)
assert res.query[int]("i.foo") == 5
assert res.query[List[int]]("a.value") == [1, 1]
Expand Down

0 comments on commit 2a8d8c3

Please sign in to comment.