fix(parser,selection): correct None handling and Path type checks
- Ensure required argument validation treats only `None` as missing instead of falsy values (e.g., 0, False, empty string) - Guard SelectionAction default resolution against `None` results - Replace direct `type == Path` checks with `issubclass(..., Path)` for proper handling of Path subclasses across suggestions logic Improves correctness in argument parsing and selection defaults, aligning with Falyx’s explicit and predictable behavior goals.
This commit is contained in:
@@ -344,7 +344,7 @@ class SelectionAction(BaseAction):
|
|||||||
selection = [
|
selection = [
|
||||||
key
|
key
|
||||||
for key, sel in self.selections.items()
|
for key, sel in self.selections.items()
|
||||||
if sel.value == maybe_result
|
if sel.value == maybe_result and maybe_result is not None
|
||||||
]
|
]
|
||||||
if selection:
|
if selection:
|
||||||
effective_default = selection[0]
|
effective_default = selection[0]
|
||||||
|
|||||||
@@ -1155,7 +1155,7 @@ class CommandArgumentParser:
|
|||||||
for spec in self._arguments:
|
for spec in self._arguments:
|
||||||
if spec.dest == "help" or spec.dest == "tldr":
|
if spec.dest == "help" or spec.dest == "tldr":
|
||||||
continue
|
continue
|
||||||
if spec.required and not result.get(spec.dest):
|
if spec.required and result.get(spec.dest) is None:
|
||||||
help_text = f" help: {spec.help}" if spec.help else ""
|
help_text = f" help: {spec.help}" if spec.help else ""
|
||||||
if (
|
if (
|
||||||
spec.action == ArgumentAction.ACTION
|
spec.action == ArgumentAction.ACTION
|
||||||
@@ -1316,7 +1316,7 @@ class CommandArgumentParser:
|
|||||||
for suggestion in arg.suggestions
|
for suggestion in arg.suggestions
|
||||||
if suggestion_filter(suggestion)
|
if suggestion_filter(suggestion)
|
||||||
]
|
]
|
||||||
if arg.type is Path:
|
if issubclass(arg.type, Path):
|
||||||
return self._suggest_paths(prefix if not cursor_at_end_of_token else ".")
|
return self._suggest_paths(prefix if not cursor_at_end_of_token else ".")
|
||||||
return []
|
return []
|
||||||
|
|
||||||
@@ -1391,7 +1391,7 @@ class CommandArgumentParser:
|
|||||||
):
|
):
|
||||||
return []
|
return []
|
||||||
return sorted(next_non_consumed_positional_arg.suggestions)
|
return sorted(next_non_consumed_positional_arg.suggestions)
|
||||||
if next_non_consumed_positional_arg.type == Path:
|
if issubclass(next_non_consumed_positional_arg.type, Path):
|
||||||
if cursor_at_end_of_token:
|
if cursor_at_end_of_token:
|
||||||
return self._suggest_paths(".")
|
return self._suggest_paths(".")
|
||||||
else:
|
else:
|
||||||
@@ -1536,7 +1536,7 @@ class CommandArgumentParser:
|
|||||||
if suggestion.startswith(last)
|
if suggestion.startswith(last)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
elif arg.type == Path and not cursor_at_end_of_token:
|
elif issubclass(arg.type, Path) and not cursor_at_end_of_token:
|
||||||
suggestions.extend(self._suggest_paths(last))
|
suggestions.extend(self._suggest_paths(last))
|
||||||
elif last_keyword_state_in_args and not last_keyword_state_in_args.consumed:
|
elif last_keyword_state_in_args and not last_keyword_state_in_args.consumed:
|
||||||
suggestions.extend(
|
suggestions.extend(
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
__version__ = "0.1.86"
|
__version__ = "0.1.87"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[tool.poetry]
|
[tool.poetry]
|
||||||
name = "falyx"
|
name = "falyx"
|
||||||
version = "0.1.86"
|
version = "0.1.87"
|
||||||
description = "Reliable and introspectable async CLI action framework."
|
description = "Reliable and introspectable async CLI action framework."
|
||||||
authors = ["Roland Thomas Jr <roland@rtj.dev>"]
|
authors = ["Roland Thomas Jr <roland@rtj.dev>"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
|
|||||||
Reference in New Issue
Block a user