falyx 0.1.37__py3-none-any.whl → 0.1.39__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.
falyx/parsers/argparse.py CHANGED
@@ -10,6 +10,7 @@ from rich.console import Console
10
10
  from rich.markup import escape
11
11
  from rich.text import Text
12
12
 
13
+ from falyx.action.base import BaseAction
13
14
  from falyx.exceptions import CommandArgumentError
14
15
  from falyx.signals import HelpSignal
15
16
 
@@ -17,6 +18,7 @@ from falyx.signals import HelpSignal
17
18
  class ArgumentAction(Enum):
18
19
  """Defines the action to be taken when the argument is encountered."""
19
20
 
21
+ ACTION = "action"
20
22
  STORE = "store"
21
23
  STORE_TRUE = "store_true"
22
24
  STORE_FALSE = "store_false"
@@ -51,6 +53,7 @@ class Argument:
51
53
  help: str = "" # Help text for the argument
52
54
  nargs: int | str | None = None # int, '?', '*', '+', None
53
55
  positional: bool = False # True if no leading - or -- in flags
56
+ resolver: BaseAction | None = None # Action object for the argument
54
57
 
55
58
  def get_positional_text(self) -> str:
56
59
  """Get the positional text for the argument."""
@@ -104,6 +107,8 @@ class Argument:
104
107
  and self.required == other.required
105
108
  and self.nargs == other.nargs
106
109
  and self.positional == other.positional
110
+ and self.default == other.default
111
+ and self.help == other.help
107
112
  )
108
113
 
109
114
  def __hash__(self) -> int:
@@ -117,6 +122,8 @@ class Argument:
117
122
  self.required,
118
123
  self.nargs,
119
124
  self.positional,
125
+ self.default,
126
+ self.help,
120
127
  )
121
128
  )
122
129
 
@@ -159,8 +166,8 @@ class CommandArgumentParser:
159
166
  self.help_epilogue: str = help_epilogue
160
167
  self.aliases: list[str] = aliases or []
161
168
  self._arguments: list[Argument] = []
162
- self._positional: list[Argument] = []
163
- self._keyword: list[Argument] = []
169
+ self._positional: dict[str, Argument] = {}
170
+ self._keyword: dict[str, Argument] = {}
164
171
  self._flag_map: dict[str, Argument] = {}
165
172
  self._dest_set: set[str] = set()
166
173
  self._add_help()
@@ -220,6 +227,12 @@ class CommandArgumentParser:
220
227
  if required:
221
228
  return True
222
229
  if positional:
230
+ assert (
231
+ nargs is None
232
+ or isinstance(nargs, int)
233
+ or isinstance(nargs, str)
234
+ and nargs in ("+", "*", "?")
235
+ ), f"Invalid nargs value: {nargs}"
223
236
  if isinstance(nargs, int):
224
237
  return nargs > 0
225
238
  elif isinstance(nargs, str):
@@ -227,8 +240,8 @@ class CommandArgumentParser:
227
240
  return True
228
241
  elif nargs in ("*", "?"):
229
242
  return False
230
- else:
231
- raise CommandArgumentError(f"Invalid nargs value: {nargs}")
243
+ else:
244
+ return True
232
245
 
233
246
  return required
234
247
 
@@ -247,7 +260,7 @@ class CommandArgumentParser:
247
260
  )
248
261
  return None
249
262
  if nargs is None:
250
- nargs = 1
263
+ return None
251
264
  allowed_nargs = ("?", "*", "+")
252
265
  if isinstance(nargs, int):
253
266
  if nargs <= 0:
@@ -308,6 +321,23 @@ class CommandArgumentParser:
308
321
  f"Default list value {default!r} for '{dest}' cannot be coerced to {expected_type.__name__}"
309
322
  )
310
323
 
324
+ def _validate_resolver(
325
+ self, action: ArgumentAction, resolver: BaseAction | None
326
+ ) -> BaseAction | None:
327
+ """Validate the action object."""
328
+ if action != ArgumentAction.ACTION and resolver is None:
329
+ return None
330
+ elif action == ArgumentAction.ACTION and resolver is None:
331
+ raise CommandArgumentError("resolver must be provided for ACTION action")
332
+ elif action != ArgumentAction.ACTION and resolver is not None:
333
+ raise CommandArgumentError(
334
+ f"resolver should not be provided for action {action}"
335
+ )
336
+
337
+ if not isinstance(resolver, BaseAction):
338
+ raise CommandArgumentError("resolver must be an instance of BaseAction")
339
+ return resolver
340
+
311
341
  def _validate_action(
312
342
  self, action: ArgumentAction | str, positional: bool
313
343
  ) -> ArgumentAction:
@@ -347,6 +377,8 @@ class CommandArgumentParser:
347
377
  return 0
348
378
  elif action in (ArgumentAction.APPEND, ArgumentAction.EXTEND):
349
379
  return []
380
+ elif isinstance(nargs, int):
381
+ return []
350
382
  elif nargs in ("+", "*"):
351
383
  return []
352
384
  else:
@@ -380,8 +412,15 @@ class CommandArgumentParser:
380
412
  required: bool = False,
381
413
  help: str = "",
382
414
  dest: str | None = None,
415
+ resolver: BaseAction | None = None,
383
416
  ) -> None:
384
417
  """Add an argument to the parser.
418
+ For `ArgumentAction.ACTION`, `nargs` and `type` determine how many and what kind
419
+ of inputs are passed to the `resolver`.
420
+
421
+ The return value of the `resolver` is used directly (no type coercion is applied).
422
+ Validation, structure, and post-processing should be handled within the `resolver`.
423
+
385
424
  Args:
386
425
  name or flags: Either a name or prefixed flags (e.g. 'faylx', '-f', '--falyx').
387
426
  action: The action to be taken when the argument is encountered.
@@ -392,6 +431,7 @@ class CommandArgumentParser:
392
431
  required: Whether or not the argument is required.
393
432
  help: A brief description of the argument.
394
433
  dest: The name of the attribute to be added to the object returned by parse_args().
434
+ resolver: A BaseAction called with optional nargs specified parsed arguments.
395
435
  """
396
436
  expected_type = type
397
437
  self._validate_flags(flags)
@@ -403,8 +443,8 @@ class CommandArgumentParser:
403
443
  "Merging multiple arguments into the same dest (e.g. positional + flagged) "
404
444
  "is not supported. Define a unique 'dest' for each argument."
405
445
  )
406
- self._dest_set.add(dest)
407
446
  action = self._validate_action(action, positional)
447
+ resolver = self._validate_resolver(action, resolver)
408
448
  nargs = self._validate_nargs(nargs, action)
409
449
  default = self._resolve_default(default, action, nargs)
410
450
  if (
@@ -432,6 +472,7 @@ class CommandArgumentParser:
432
472
  help=help,
433
473
  nargs=nargs,
434
474
  positional=positional,
475
+ resolver=resolver,
435
476
  )
436
477
  for flag in flags:
437
478
  if flag in self._flag_map:
@@ -439,12 +480,14 @@ class CommandArgumentParser:
439
480
  raise CommandArgumentError(
440
481
  f"Flag '{flag}' is already used by argument '{existing.dest}'"
441
482
  )
483
+ for flag in flags:
442
484
  self._flag_map[flag] = argument
485
+ if not positional:
486
+ self._keyword[flag] = argument
487
+ self._dest_set.add(dest)
443
488
  self._arguments.append(argument)
444
489
  if positional:
445
- self._positional.append(argument)
446
- else:
447
- self._keyword.append(argument)
490
+ self._positional[dest] = argument
448
491
 
449
492
  def get_argument(self, dest: str) -> Argument | None:
450
493
  return next((a for a in self._arguments if a.dest == dest), None)
@@ -462,6 +505,8 @@ class CommandArgumentParser:
462
505
  "required": arg.required,
463
506
  "nargs": arg.nargs,
464
507
  "positional": arg.positional,
508
+ "default": arg.default,
509
+ "help": arg.help,
465
510
  }
466
511
  )
467
512
  return defs
@@ -469,14 +514,17 @@ class CommandArgumentParser:
469
514
  def _consume_nargs(
470
515
  self, args: list[str], start: int, spec: Argument
471
516
  ) -> tuple[list[str], int]:
517
+ assert (
518
+ spec.nargs is None
519
+ or isinstance(spec.nargs, int)
520
+ or isinstance(spec.nargs, str)
521
+ and spec.nargs in ("+", "*", "?")
522
+ ), f"Invalid nargs value: {spec.nargs}"
472
523
  values = []
473
524
  i = start
474
525
  if isinstance(spec.nargs, int):
475
526
  values = args[i : i + spec.nargs]
476
527
  return values, i + spec.nargs
477
- elif spec.nargs is None:
478
- values = [args[i]]
479
- return values, i + 1
480
528
  elif spec.nargs == "+":
481
529
  if i >= len(args):
482
530
  raise CommandArgumentError(
@@ -496,10 +544,13 @@ class CommandArgumentParser:
496
544
  if i < len(args) and not args[i].startswith("-"):
497
545
  return [args[i]], i + 1
498
546
  return [], i
499
- else:
500
- assert False, "Invalid nargs value: shouldn't happen"
547
+ elif spec.nargs is None:
548
+ if i < len(args) and not args[i].startswith("-"):
549
+ return [args[i]], i + 1
550
+ return [], i
551
+ assert False, "Invalid nargs value: shouldn't happen"
501
552
 
502
- def _consume_all_positional_args(
553
+ async def _consume_all_positional_args(
503
554
  self,
504
555
  args: list[str],
505
556
  result: dict[str, Any],
@@ -519,18 +570,22 @@ class CommandArgumentParser:
519
570
  remaining = len(args) - i
520
571
  min_required = 0
521
572
  for next_spec in positional_args[j + 1 :]:
522
- if isinstance(next_spec.nargs, int):
523
- min_required += next_spec.nargs
524
- elif next_spec.nargs is None:
573
+ assert (
574
+ next_spec.nargs is None
575
+ or isinstance(next_spec.nargs, int)
576
+ or isinstance(next_spec.nargs, str)
577
+ and next_spec.nargs in ("+", "*", "?")
578
+ ), f"Invalid nargs value: {spec.nargs}"
579
+ if next_spec.nargs is None:
525
580
  min_required += 1
581
+ elif isinstance(next_spec.nargs, int):
582
+ min_required += next_spec.nargs
526
583
  elif next_spec.nargs == "+":
527
584
  min_required += 1
528
585
  elif next_spec.nargs == "?":
529
586
  min_required += 0
530
587
  elif next_spec.nargs == "*":
531
588
  min_required += 0
532
- else:
533
- assert False, "Invalid nargs value: shouldn't happen"
534
589
 
535
590
  slice_args = args[i:] if is_last else args[i : i + (remaining - min_required)]
536
591
  values, new_i = self._consume_nargs(slice_args, 0, spec)
@@ -542,10 +597,19 @@ class CommandArgumentParser:
542
597
  raise CommandArgumentError(
543
598
  f"Invalid value for '{spec.dest}': expected {spec.type.__name__}"
544
599
  )
545
-
546
- if spec.action == ArgumentAction.APPEND:
600
+ if spec.action == ArgumentAction.ACTION:
601
+ assert isinstance(
602
+ spec.resolver, BaseAction
603
+ ), "resolver should be an instance of BaseAction"
604
+ try:
605
+ result[spec.dest] = await spec.resolver(*typed)
606
+ except Exception as error:
607
+ raise CommandArgumentError(
608
+ f"[{spec.dest}] Action failed: {error}"
609
+ ) from error
610
+ elif spec.action == ArgumentAction.APPEND:
547
611
  assert result.get(spec.dest) is not None, "dest should not be None"
548
- if spec.nargs in (None, 1):
612
+ if spec.nargs is None:
549
613
  result[spec.dest].append(typed[0])
550
614
  else:
551
615
  result[spec.dest].append(typed)
@@ -565,6 +629,23 @@ class CommandArgumentParser:
565
629
 
566
630
  return i
567
631
 
632
+ def _expand_posix_bundling(self, args: list[str]) -> list[str]:
633
+ """Expand POSIX-style bundled arguments into separate arguments."""
634
+ expanded = []
635
+ for token in args:
636
+ if token.startswith("-") and not token.startswith("--") and len(token) > 2:
637
+ # POSIX bundle
638
+ # e.g. -abc -> -a -b -c
639
+ for char in token[1:]:
640
+ flag = f"-{char}"
641
+ arg = self._flag_map.get(flag)
642
+ if not arg:
643
+ raise CommandArgumentError(f"Unrecognized option: {flag}")
644
+ expanded.append(flag)
645
+ else:
646
+ expanded.append(token)
647
+ return expanded
648
+
568
649
  async def parse_args(
569
650
  self, args: list[str] | None = None, from_validate: bool = False
570
651
  ) -> dict[str, Any]:
@@ -572,22 +653,43 @@ class CommandArgumentParser:
572
653
  if args is None:
573
654
  args = []
574
655
 
656
+ args = self._expand_posix_bundling(args)
657
+
575
658
  result = {arg.dest: deepcopy(arg.default) for arg in self._arguments}
576
659
  positional_args = [arg for arg in self._arguments if arg.positional]
577
660
  consumed_positional_indices: set[int] = set()
578
-
579
661
  consumed_indices: set[int] = set()
662
+
580
663
  i = 0
581
664
  while i < len(args):
582
665
  token = args[i]
583
- if token in self._flag_map:
584
- spec = self._flag_map[token]
666
+ if token in self._keyword:
667
+ spec = self._keyword[token]
585
668
  action = spec.action
586
669
 
587
670
  if action == ArgumentAction.HELP:
588
671
  if not from_validate:
589
672
  self.render_help()
590
673
  raise HelpSignal()
674
+ elif action == ArgumentAction.ACTION:
675
+ assert isinstance(
676
+ spec.resolver, BaseAction
677
+ ), "resolver should be an instance of BaseAction"
678
+ values, new_i = self._consume_nargs(args, i + 1, spec)
679
+ try:
680
+ typed_values = [spec.type(value) for value in values]
681
+ except ValueError:
682
+ raise CommandArgumentError(
683
+ f"Invalid value for '{spec.dest}': expected {spec.type.__name__}"
684
+ )
685
+ try:
686
+ result[spec.dest] = await spec.resolver(*typed_values)
687
+ except Exception as error:
688
+ raise CommandArgumentError(
689
+ f"[{spec.dest}] Action failed: {error}"
690
+ ) from error
691
+ consumed_indices.update(range(i, new_i))
692
+ i = new_i
591
693
  elif action == ArgumentAction.STORE_TRUE:
592
694
  result[spec.dest] = True
593
695
  consumed_indices.add(i)
@@ -609,13 +711,8 @@ class CommandArgumentParser:
609
711
  raise CommandArgumentError(
610
712
  f"Invalid value for '{spec.dest}': expected {spec.type.__name__}"
611
713
  )
612
- if spec.nargs in (None, 1):
613
- try:
614
- result[spec.dest].append(spec.type(values[0]))
615
- except ValueError:
616
- raise CommandArgumentError(
617
- f"Invalid value for '{spec.dest}': expected {spec.type.__name__}"
618
- )
714
+ if spec.nargs is None:
715
+ result[spec.dest].append(spec.type(values[0]))
619
716
  else:
620
717
  result[spec.dest].append(typed_values)
621
718
  consumed_indices.update(range(i, new_i))
@@ -640,6 +737,10 @@ class CommandArgumentParser:
640
737
  raise CommandArgumentError(
641
738
  f"Invalid value for '{spec.dest}': expected {spec.type.__name__}"
642
739
  )
740
+ if not typed_values and spec.nargs not in ("*", "?"):
741
+ raise CommandArgumentError(
742
+ f"Expected at least one value for '{spec.dest}'"
743
+ )
643
744
  if (
644
745
  spec.nargs in (None, 1, "?")
645
746
  and spec.action != ArgumentAction.APPEND
@@ -651,6 +752,9 @@ class CommandArgumentParser:
651
752
  result[spec.dest] = typed_values
652
753
  consumed_indices.update(range(i, new_i))
653
754
  i = new_i
755
+ elif token.startswith("-"):
756
+ # Handle unrecognized option
757
+ raise CommandArgumentError(f"Unrecognized flag: {token}")
654
758
  else:
655
759
  # Get the next flagged argument index if it exists
656
760
  next_flagged_index = -1
@@ -660,8 +764,7 @@ class CommandArgumentParser:
660
764
  break
661
765
  if next_flagged_index == -1:
662
766
  next_flagged_index = len(args)
663
-
664
- args_consumed = self._consume_all_positional_args(
767
+ args_consumed = await self._consume_all_positional_args(
665
768
  args[i:next_flagged_index],
666
769
  result,
667
770
  positional_args,
@@ -681,26 +784,22 @@ class CommandArgumentParser:
681
784
  f"Invalid value for {spec.dest}: must be one of {spec.choices}"
682
785
  )
683
786
 
787
+ if spec.action == ArgumentAction.ACTION:
788
+ continue
789
+
684
790
  if isinstance(spec.nargs, int) and spec.nargs > 1:
685
- if not isinstance(result.get(spec.dest), list):
686
- raise CommandArgumentError(
687
- f"Invalid value for {spec.dest}: expected a list"
688
- )
791
+ assert isinstance(
792
+ result.get(spec.dest), list
793
+ ), f"Invalid value for {spec.dest}: expected a list"
794
+ if not result[spec.dest] and not spec.required:
795
+ continue
689
796
  if spec.action == ArgumentAction.APPEND:
690
- if not isinstance(result[spec.dest], list):
691
- raise CommandArgumentError(
692
- f"Invalid value for {spec.dest}: expected a list"
693
- )
694
797
  for group in result[spec.dest]:
695
798
  if len(group) % spec.nargs != 0:
696
799
  raise CommandArgumentError(
697
800
  f"Invalid number of values for {spec.dest}: expected a multiple of {spec.nargs}"
698
801
  )
699
802
  elif spec.action == ArgumentAction.EXTEND:
700
- if not isinstance(result[spec.dest], list):
701
- raise CommandArgumentError(
702
- f"Invalid value for {spec.dest}: expected a list"
703
- )
704
803
  if len(result[spec.dest]) % spec.nargs != 0:
705
804
  raise CommandArgumentError(
706
805
  f"Invalid number of values for {spec.dest}: expected a multiple of {spec.nargs}"
@@ -737,7 +836,7 @@ class CommandArgumentParser:
737
836
  # Options
738
837
  # Add all keyword arguments to the options list
739
838
  options_list = []
740
- for arg in self._keyword:
839
+ for arg in self._keyword.values():
741
840
  choice_text = arg.get_choice_text()
742
841
  if choice_text:
743
842
  options_list.extend([f"[{arg.flags[0]} {choice_text}]"])
@@ -745,7 +844,7 @@ class CommandArgumentParser:
745
844
  options_list.extend([f"[{arg.flags[0]}]"])
746
845
 
747
846
  # Add positional arguments to the options list
748
- for arg in self._positional:
847
+ for arg in self._positional.values():
749
848
  choice_text = arg.get_choice_text()
750
849
  if isinstance(arg.nargs, int):
751
850
  choice_text = " ".join([choice_text] * arg.nargs)
@@ -771,14 +870,14 @@ class CommandArgumentParser:
771
870
  if self._arguments:
772
871
  if self._positional:
773
872
  self.console.print("[bold]positional:[/bold]")
774
- for arg in self._positional:
873
+ for arg in self._positional.values():
775
874
  flags = arg.get_positional_text()
776
875
  arg_line = Text(f" {flags:<30} ")
777
876
  help_text = arg.help or ""
778
877
  arg_line.append(help_text)
779
878
  self.console.print(arg_line)
780
879
  self.console.print("[bold]options:[/bold]")
781
- for arg in self._keyword:
880
+ for arg in self._keyword.values():
782
881
  flags = ", ".join(arg.flags)
783
882
  flags_choice = f"{flags} {arg.get_choice_text()}"
784
883
  arg_line = Text(f" {flags_choice:<30} ")
@@ -807,8 +906,8 @@ class CommandArgumentParser:
807
906
  required = sum(arg.required for arg in self._arguments)
808
907
  return (
809
908
  f"CommandArgumentParser(args={len(self._arguments)}, "
810
- f"flags={len(self._flag_map)}, dests={len(self._dest_set)}, "
811
- f"required={required}, positional={positional})"
909
+ f"flags={len(self._flag_map)}, keywords={len(self._keyword)}, "
910
+ f"positional={positional}, required={required})"
812
911
  )
813
912
 
814
913
  def __repr__(self) -> str:
falyx/parsers/utils.py CHANGED
@@ -1,5 +1,6 @@
1
1
  from typing import Any
2
2
 
3
+ from falyx.action.base import BaseAction
3
4
  from falyx.logger import logger
4
5
  from falyx.parsers.signature import infer_args_from_func
5
6
 
@@ -8,7 +9,6 @@ def same_argument_definitions(
8
9
  actions: list[Any],
9
10
  arg_metadata: dict[str, str | dict[str, Any]] | None = None,
10
11
  ) -> list[dict[str, Any]] | None:
11
- from falyx.action.action import BaseAction
12
12
 
13
13
  arg_sets = []
14
14
  for action in actions:
falyx/protocols.py CHANGED
@@ -4,7 +4,7 @@ from __future__ import annotations
4
4
 
5
5
  from typing import Any, Awaitable, Protocol, runtime_checkable
6
6
 
7
- from falyx.action.action import BaseAction
7
+ from falyx.action.base import BaseAction
8
8
 
9
9
 
10
10
  @runtime_checkable
falyx/retry_utils.py CHANGED
@@ -1,6 +1,7 @@
1
1
  # Falyx CLI Framework — (c) 2025 rtj.dev LLC — MIT Licensed
2
2
  """retry_utils.py"""
3
- from falyx.action.action import Action, BaseAction
3
+ from falyx.action.action import Action
4
+ from falyx.action.base import BaseAction
4
5
  from falyx.hook_manager import HookType
5
6
  from falyx.retry import RetryHandler, RetryPolicy
6
7
 
falyx/utils.py CHANGED
@@ -184,7 +184,7 @@ def setup_logging(
184
184
  console_handler.setLevel(console_log_level)
185
185
  root.addHandler(console_handler)
186
186
 
187
- file_handler = logging.FileHandler(log_filename)
187
+ file_handler = logging.FileHandler(log_filename, "a", "UTF-8")
188
188
  file_handler.setLevel(file_log_level)
189
189
  if json_log_to_file:
190
190
  file_handler.setFormatter(
falyx/version.py CHANGED
@@ -1 +1 @@
1
- __version__ = "0.1.37"
1
+ __version__ = "0.1.39"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: falyx
3
- Version: 0.1.37
3
+ Version: 0.1.39
4
4
  Summary: Reliable and introspectable async CLI action framework.
5
5
  License: MIT
6
6
  Author: Roland Thomas Jr
@@ -75,7 +75,8 @@ poetry install
75
75
  import asyncio
76
76
  import random
77
77
 
78
- from falyx import Falyx, Action, ChainedAction
78
+ from falyx import Falyx
79
+ from falyx.action import Action, ChainedAction
79
80
 
80
81
  # A flaky async step that fails randomly
81
82
  async def flaky_step():
@@ -85,8 +86,8 @@ async def flaky_step():
85
86
  return "ok"
86
87
 
87
88
  # Create the actions
88
- step1 = Action(name="step_1", action=flaky_step, retry=True)
89
- step2 = Action(name="step_2", action=flaky_step, retry=True)
89
+ step1 = Action(name="step_1", action=flaky_step)
90
+ step2 = Action(name="step_2", action=flaky_step)
90
91
 
91
92
  # Chain the actions
92
93
  chain = ChainedAction(name="my_pipeline", actions=[step1, step2])
@@ -97,9 +98,9 @@ falyx.add_command(
97
98
  key="R",
98
99
  description="Run My Pipeline",
99
100
  action=chain,
100
- logging_hooks=True,
101
101
  preview_before_confirm=True,
102
102
  confirm=True,
103
+ retry_all=True,
103
104
  )
104
105
 
105
106
  # Entry point
@@ -0,0 +1,61 @@
1
+ falyx/.pytyped,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ falyx/__init__.py,sha256=Gh88lQ5pbD7xbGWrBgslE2kSTZKY9TkvKSa53rZ3l8U,305
3
+ falyx/__main__.py,sha256=g_LwJieofK3DJzCYtpkAMEeOXhzSLQenb7pRVUqcf-Y,2152
4
+ falyx/action/.pytyped,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
+ falyx/action/__init__.py,sha256=4E3Rb0GgGcmggrPJh0YFiwbVgN_PQjIzL06-Z3qMReo,1247
6
+ falyx/action/action.py,sha256=w6xDbsB1SlMPSvpo2Dh0e11lRGP6a4E3K6AdfjlEqGY,5759
7
+ falyx/action/action_factory.py,sha256=br-P7Oip-4tZkO8qVT_ECwLe6idYjJa_GuBi5QR7vS4,4832
8
+ falyx/action/action_group.py,sha256=dfCEJM0RfdopuLFtfaxpvNzbZT6hVMrUuRBAFz--Uss,6835
9
+ falyx/action/base.py,sha256=W6jAG5qaZA0_6hcMZLCjSxUqIr1eVYw2YFkG20PiWQY,5861
10
+ falyx/action/chained_action.py,sha256=aV_plUdDVdc1o-oU57anbWkw33jgRIh4W29QwEA_1Mw,8501
11
+ falyx/action/fallback_action.py,sha256=0z5l0s_LKnhIwgMdykm8lJqs246DKSpyYs-p7PnsKok,1619
12
+ falyx/action/http_action.py,sha256=DNeSBWh58UTFGlfFyTk2GnhS54hpLAJLC0QNbq2cYic,5799
13
+ falyx/action/io_action.py,sha256=8x9HpvLhqJF7lI8PUo7Hs9F2NdJ1WfGs_wP5Myyoor8,10059
14
+ falyx/action/literal_input_action.py,sha256=7H2VX_L5VaytVdV2uis-VTGi782kQtwKTB8T04c7J1k,1293
15
+ falyx/action/menu_action.py,sha256=YGnfe6fNIi9-um1uiKn0NlcF3mdatvc4FsAS6xqhhmo,5759
16
+ falyx/action/mixins.py,sha256=eni8_PwzMnuwh0ZqOdzCdAyWlOphoiqL7z27xnFsg5s,1117
17
+ falyx/action/process_action.py,sha256=HsDqlKy1PkG3HHC6mHa4O6ayY_oKVY2qj5nDRJuSn24,4571
18
+ falyx/action/process_pool_action.py,sha256=1fFVEKpe-_XiMJxo4xF-j749Yd1noXjf76EOCPeX9xA,5940
19
+ falyx/action/prompt_menu_action.py,sha256=mt_XC4kZij6btGZn1r6nB-ko-FzCV57wBaLGps7cZmk,5163
20
+ falyx/action/select_file_action.py,sha256=umsE238ekkTRdM2pXcN9Q_srX-VDenEYXdh9CkTqqCw,8603
21
+ falyx/action/selection_action.py,sha256=5ZCdnsSvLZi9Gp5lcY61n4ff8bYHJOzw9DYMlgIMTZA,12894
22
+ falyx/action/signal_action.py,sha256=5UMqvzy7fBnLANGwYUWoe1VRhrr7e-yOVeLdOnCBiJo,1350
23
+ falyx/action/types.py,sha256=NfZz1ufZuvCgp-he2JIItbnjX7LjOUadjtKbjpRlSIY,1399
24
+ falyx/action/user_input_action.py,sha256=7kL5G7L0j2LuLvHu-CMwOaHyEisagE7O_2G2EhqWRr8,3483
25
+ falyx/bottom_bar.py,sha256=iWxgOKWgn5YmREeZBuGA50FzqzEfz1-Vnqm0V_fhldc,7383
26
+ falyx/command.py,sha256=QCuhbsTu93PPggGhhPTmL0iiR3AoY7XhFiO7FnRaYP0,14623
27
+ falyx/config.py,sha256=wfxKnhCyfwxHP0pLbYf-i8Tt1lBJlSeB-5DgI8JbnKM,9626
28
+ falyx/context.py,sha256=NfBpxzFzn-dYP6I3wrtGFucqm__UZo4SSBLmM8yYayE,10330
29
+ falyx/debug.py,sha256=IRpYtdH8yeXJEsfP5rASALmBQb2U_EwrTudF2GIDdZY,1545
30
+ falyx/exceptions.py,sha256=kK9k1v7LVNjJSwYztRa9Krhr3ZOI-6Htq2ZjlYICPKg,922
31
+ falyx/execution_registry.py,sha256=rctsz0mrIHPToLZqylblVjDdKWdq1x_JBc8GwMP5sJ8,4710
32
+ falyx/falyx.py,sha256=rz4md-dOMOuFsdZ8lLMeIFz82PKgj8fpeegZRtHOETs,44741
33
+ falyx/hook_manager.py,sha256=TFuHQnAncS_rk6vuw-VSx8bnAppLuHfrZCrzLwqcO9o,2979
34
+ falyx/hooks.py,sha256=xMfQROib0BNsaQF4AXJpmCiGePoE1f1xpcdibgnVZWM,2913
35
+ falyx/init.py,sha256=abcSlPmxVeByLIHdUkNjqtO_tEkO3ApC6f9WbxsSEWg,3393
36
+ falyx/logger.py,sha256=1Mfb_vJFJ1tQwziuyU2p-cSMi2Js8N2byniFEnI6vOQ,132
37
+ falyx/menu.py,sha256=E580qZsx08bnWcqRVjJuD2Fy8Zh_1zIexp5f0lC7L2c,3745
38
+ falyx/options_manager.py,sha256=dFAnQw543tQ6Xupvh1PwBrhiSWlSACHw8K-sHP_lUh4,2842
39
+ falyx/parsers/.pytyped,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
40
+ falyx/parsers/__init__.py,sha256=l0QMf89uJHhTpOqQfiV3tx7aAHvELqDFWAyjCbwEgBQ,370
41
+ falyx/parsers/argparse.py,sha256=P4iH0N5_vqzbw7dS9mU1HJ2TPhZMF6BN7t0RxRadXbM,36076
42
+ falyx/parsers/parsers.py,sha256=yGyAwNIJQz12LU_WF87aW4xbBmJtyEY7RnLRFqXAsio,5763
43
+ falyx/parsers/signature.py,sha256=i4iOiJxv70sxQYivKKXC_YOsShRUYfcI8Cjq8yVZvMo,2262
44
+ falyx/parsers/utils.py,sha256=Z4qLu8NVIprcHK2RDXoISpcDKBUii3n05G9mlgiPDgw,889
45
+ falyx/prompt_utils.py,sha256=qgk0bXs7mwzflqzWyFhEOTpKQ_ZtMIqGhKeg-ocwNnE,1542
46
+ falyx/protocols.py,sha256=-9GbCBUzzsEgw2_KOCYqxxzWJuez0eHmwnZp_ShY0jc,493
47
+ falyx/retry.py,sha256=sGRE9QhdZK98M99G8F15WUsJ_fYLNyLlCgu3UANaSQs,3744
48
+ falyx/retry_utils.py,sha256=vwoZmFVCGVqZ13BX_xi3qZZVsmSxkp-jfaf6kJtBV9c,723
49
+ falyx/selection.py,sha256=PLfiULkJ76cn1yBFwUux9KEMt6NFF00_Nj5oHS2e498,12894
50
+ falyx/signals.py,sha256=Y_neFXpfHs7qY0syw9XcfR9WeAGRcRw1nG_2L1JJqKE,1083
51
+ falyx/tagged_table.py,sha256=4SV-SdXFrAhy1JNToeBCvyxT-iWVf6cWY7XETTys4n8,1067
52
+ falyx/themes/__init__.py,sha256=1CZhEUCin9cUk8IGYBUFkVvdHRNNJBEFXccHwpUKZCA,284
53
+ falyx/themes/colors.py,sha256=4aaeAHJetmeNInI0Zytg4E3YqKfPFelpf04vtjSvsS8,19776
54
+ falyx/utils.py,sha256=U45xnZFUdoFC4xiji_9S1jHS5V7MvxSDtufP8EgB0SM,6732
55
+ falyx/validators.py,sha256=t5iyzVpY8tdC4rfhr4isEfWpD5gNTzjeX_Hbi_Uq6sA,1328
56
+ falyx/version.py,sha256=sfc5YqMhonehojmfXWQszjknUHF_Q-G6tt4E1pfsXOY,23
57
+ falyx-0.1.39.dist-info/LICENSE,sha256=B0yqgaHuSdhN7T3OBmgQSiDTy8HqT5Oe_dLypRe4Ra4,1073
58
+ falyx-0.1.39.dist-info/METADATA,sha256=jZJgj9PMmgsdng7LEe4t0jCTFfHXHuGwpwk6vy55o14,5517
59
+ falyx-0.1.39.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
60
+ falyx-0.1.39.dist-info/entry_points.txt,sha256=j8owOSl2j1Ss8DtGMnKfgehKaolqnIPhVFHaUBLUnMs,45
61
+ falyx-0.1.39.dist-info/RECORD,,
@@ -1,53 +0,0 @@
1
- falyx/.pytyped,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- falyx/__init__.py,sha256=MZzno-7HvIYM6pDjDP4t22aN7OaBTTlQYOb7W3Gw_7g,615
3
- falyx/__main__.py,sha256=g_LwJieofK3DJzCYtpkAMEeOXhzSLQenb7pRVUqcf-Y,2152
4
- falyx/action/.pytyped,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
- falyx/action/__init__.py,sha256=Vd-XNp_MEpyfbHL9PAhSOXQAlwKKsIpZFbO5pskHdOA,1047
6
- falyx/action/action.py,sha256=guC5ztULpozlsryqpH8GPYxOxpH2KDVhlcPkDoQYKZk,33350
7
- falyx/action/action_factory.py,sha256=iJ7jx8WxQ9W2v1-xBoUzFD3X-3IFQjjClfGYCg5io4o,4834
8
- falyx/action/http_action.py,sha256=DNeSBWh58UTFGlfFyTk2GnhS54hpLAJLC0QNbq2cYic,5799
9
- falyx/action/io_action.py,sha256=tQVonWst44ZXR_87H6-aQ62DZf7qfpbBiKE1oTp9qVA,10061
10
- falyx/action/menu_action.py,sha256=B4RBqjo0llYaAlblnO4XlRjVPhU89n7oiPKJLpzjwzc,5761
11
- falyx/action/prompt_menu_action.py,sha256=8Qh8egbqiF9agTdeU45IrlehY6fxGc9rtyhIe0nfKK4,5165
12
- falyx/action/select_file_action.py,sha256=JzKa989xxVOHv2WX6ql9VEBKPoaUolFH62rbIRKL5RU,8605
13
- falyx/action/selection_action.py,sha256=8ts0WM3UF5ziMGLeg8faTVKwvzzOGPKxeZJF2z3o9BY,12918
14
- falyx/action/signal_action.py,sha256=5UMqvzy7fBnLANGwYUWoe1VRhrr7e-yOVeLdOnCBiJo,1350
15
- falyx/action/types.py,sha256=NfZz1ufZuvCgp-he2JIItbnjX7LjOUadjtKbjpRlSIY,1399
16
- falyx/action/user_input_action.py,sha256=TQ7BlH9lQ5h_t28q6UXCH0hbr2b0vJP7syJmM-okwS0,3478
17
- falyx/bottom_bar.py,sha256=iWxgOKWgn5YmREeZBuGA50FzqzEfz1-Vnqm0V_fhldc,7383
18
- falyx/command.py,sha256=1ppsADoWLpMW1hPy1gVvp2OMeQlEkWFUz1yd5rdDvxg,14594
19
- falyx/config.py,sha256=sApU53PHM8h8eV9YIuTDM1qSGp24AbNy_jJ6GAZhjEo,9597
20
- falyx/context.py,sha256=NfBpxzFzn-dYP6I3wrtGFucqm__UZo4SSBLmM8yYayE,10330
21
- falyx/debug.py,sha256=IRpYtdH8yeXJEsfP5rASALmBQb2U_EwrTudF2GIDdZY,1545
22
- falyx/exceptions.py,sha256=kK9k1v7LVNjJSwYztRa9Krhr3ZOI-6Htq2ZjlYICPKg,922
23
- falyx/execution_registry.py,sha256=rctsz0mrIHPToLZqylblVjDdKWdq1x_JBc8GwMP5sJ8,4710
24
- falyx/falyx.py,sha256=_cbjz1OU1ZhuEucbOHWyVv21G9NwfeQAPhsrkJaDG2w,44427
25
- falyx/hook_manager.py,sha256=TFuHQnAncS_rk6vuw-VSx8bnAppLuHfrZCrzLwqcO9o,2979
26
- falyx/hooks.py,sha256=xMfQROib0BNsaQF4AXJpmCiGePoE1f1xpcdibgnVZWM,2913
27
- falyx/init.py,sha256=abcSlPmxVeByLIHdUkNjqtO_tEkO3ApC6f9WbxsSEWg,3393
28
- falyx/logger.py,sha256=1Mfb_vJFJ1tQwziuyU2p-cSMi2Js8N2byniFEnI6vOQ,132
29
- falyx/menu.py,sha256=Dp_afAkRZoLe7s2DmNrePQelL-ZSpOELUFr-7pC_eGo,3740
30
- falyx/options_manager.py,sha256=dFAnQw543tQ6Xupvh1PwBrhiSWlSACHw8K-sHP_lUh4,2842
31
- falyx/parsers/.pytyped,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
32
- falyx/parsers/__init__.py,sha256=l0QMf89uJHhTpOqQfiV3tx7aAHvELqDFWAyjCbwEgBQ,370
33
- falyx/parsers/argparse.py,sha256=k8j0MiTwV53UqesZ-GsYSi7-T7XOOo7o1DB8UnFFZ7Q,31545
34
- falyx/parsers/parsers.py,sha256=yGyAwNIJQz12LU_WF87aW4xbBmJtyEY7RnLRFqXAsio,5763
35
- falyx/parsers/signature.py,sha256=i4iOiJxv70sxQYivKKXC_YOsShRUYfcI8Cjq8yVZvMo,2262
36
- falyx/parsers/utils.py,sha256=MDYXYtbXlRU5t_oNNaB-FKQA4ZgdXcMk9VnU6Iwrgtg,895
37
- falyx/prompt_utils.py,sha256=qgk0bXs7mwzflqzWyFhEOTpKQ_ZtMIqGhKeg-ocwNnE,1542
38
- falyx/protocols.py,sha256=mesdq5CjPF_5Kyu7Evwr6qMT71tUHlw0SjjtmnggTZw,495
39
- falyx/retry.py,sha256=sGRE9QhdZK98M99G8F15WUsJ_fYLNyLlCgu3UANaSQs,3744
40
- falyx/retry_utils.py,sha256=EAzc-ECTu8AxKkmlw28ioOW9y-Y9tLQ0KasvSkBRYgs,694
41
- falyx/selection.py,sha256=PLfiULkJ76cn1yBFwUux9KEMt6NFF00_Nj5oHS2e498,12894
42
- falyx/signals.py,sha256=Y_neFXpfHs7qY0syw9XcfR9WeAGRcRw1nG_2L1JJqKE,1083
43
- falyx/tagged_table.py,sha256=4SV-SdXFrAhy1JNToeBCvyxT-iWVf6cWY7XETTys4n8,1067
44
- falyx/themes/__init__.py,sha256=1CZhEUCin9cUk8IGYBUFkVvdHRNNJBEFXccHwpUKZCA,284
45
- falyx/themes/colors.py,sha256=4aaeAHJetmeNInI0Zytg4E3YqKfPFelpf04vtjSvsS8,19776
46
- falyx/utils.py,sha256=u3puR4Bh-unNBw9a0V9sw7PDTIzRaNLolap0oz5bVIk,6718
47
- falyx/validators.py,sha256=t5iyzVpY8tdC4rfhr4isEfWpD5gNTzjeX_Hbi_Uq6sA,1328
48
- falyx/version.py,sha256=fZtrhA5kKp_n3T2sxpEh-YEt3P1ZAtGrg_Xuu1JX3ZQ,23
49
- falyx-0.1.37.dist-info/LICENSE,sha256=B0yqgaHuSdhN7T3OBmgQSiDTy8HqT5Oe_dLypRe4Ra4,1073
50
- falyx-0.1.37.dist-info/METADATA,sha256=8JFkRdWqbMFVlG16bZPKD6XABilRSFQcpeKQFxPfCJY,5521
51
- falyx-0.1.37.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
52
- falyx-0.1.37.dist-info/entry_points.txt,sha256=j8owOSl2j1Ss8DtGMnKfgehKaolqnIPhVFHaUBLUnMs,45
53
- falyx-0.1.37.dist-info/RECORD,,