falyx 0.1.39__py3-none-any.whl → 0.1.41__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/__main__.py CHANGED
@@ -8,13 +8,12 @@ Licensed under the MIT License. See LICENSE file for details.
8
8
  import asyncio
9
9
  import os
10
10
  import sys
11
- from argparse import Namespace
12
11
  from pathlib import Path
13
12
  from typing import Any
14
13
 
15
14
  from falyx.config import loader
16
15
  from falyx.falyx import Falyx
17
- from falyx.parsers import FalyxParsers, get_arg_parsers
16
+ from falyx.parsers import CommandArgumentParser
18
17
 
19
18
 
20
19
  def find_falyx_config() -> Path | None:
@@ -39,45 +38,40 @@ def bootstrap() -> Path | None:
39
38
  return config_path
40
39
 
41
40
 
42
- def get_falyx_parsers() -> FalyxParsers:
43
- falyx_parsers: FalyxParsers = get_arg_parsers()
44
- init_parser = falyx_parsers.subparsers.add_parser(
45
- "init", help="Create a new Falyx CLI project"
41
+ def init_config(parser: CommandArgumentParser) -> None:
42
+ parser.add_argument(
43
+ "name",
44
+ type=str,
45
+ help="Name of the new Falyx project",
46
+ default=".",
47
+ nargs="?",
46
48
  )
47
- init_parser.add_argument("name", nargs="?", default=".", help="Project directory")
48
- falyx_parsers.subparsers.add_parser(
49
- "init-global", help="Set up ~/.config/falyx with example tasks"
50
- )
51
- return falyx_parsers
52
-
53
-
54
- def run(args: Namespace) -> Any:
55
- if args.command == "init":
56
- from falyx.init import init_project
57
-
58
- init_project(args.name)
59
- return
60
49
 
61
- if args.command == "init-global":
62
- from falyx.init import init_global
63
-
64
- init_global()
65
- return
66
50
 
51
+ def main() -> Any:
67
52
  bootstrap_path = bootstrap()
68
53
  if not bootstrap_path:
69
- print("No Falyx config file found. Exiting.")
70
- return None
54
+ from falyx.init import init_global, init_project
55
+
56
+ flx: Falyx = Falyx()
57
+ flx.add_command(
58
+ "I",
59
+ "Initialize a new Falyx project",
60
+ init_project,
61
+ aliases=["init"],
62
+ argument_config=init_config,
63
+ )
64
+ flx.add_command(
65
+ "G",
66
+ "Initialize Falyx global configuration",
67
+ init_global,
68
+ aliases=["init-global"],
69
+ )
70
+ else:
71
+ flx = loader(bootstrap_path)
71
72
 
72
- flx: Falyx = loader(bootstrap_path)
73
73
  return asyncio.run(flx.run())
74
74
 
75
75
 
76
- def main():
77
- parsers = get_falyx_parsers()
78
- args = parsers.parse_args()
79
- run(args)
80
-
81
-
82
76
  if __name__ == "__main__":
83
77
  main()
falyx/command.py CHANGED
@@ -307,6 +307,14 @@ class Command(BaseModel):
307
307
 
308
308
  return FormattedText(prompt)
309
309
 
310
+ @property
311
+ def usage(self) -> str:
312
+ """Generate a help string for the command arguments."""
313
+ if not self.arg_parser:
314
+ return "No arguments defined."
315
+
316
+ return self.arg_parser.get_usage(plain_text=True)
317
+
310
318
  def log_summary(self) -> None:
311
319
  if self._context:
312
320
  self._context.log_summary()
falyx/config.py CHANGED
@@ -18,6 +18,7 @@ from falyx.action.base import BaseAction
18
18
  from falyx.command import Command
19
19
  from falyx.falyx import Falyx
20
20
  from falyx.logger import logger
21
+ from falyx.parsers import CommandArgumentParser
21
22
  from falyx.retry import RetryPolicy
22
23
  from falyx.themes import OneColors
23
24
 
@@ -101,6 +102,7 @@ class RawCommand(BaseModel):
101
102
  retry_policy: RetryPolicy = Field(default_factory=RetryPolicy)
102
103
  hidden: bool = False
103
104
  help_text: str = ""
105
+ help_epilogue: str = ""
104
106
 
105
107
  @field_validator("retry_policy")
106
108
  @classmethod
@@ -116,6 +118,14 @@ def convert_commands(raw_commands: list[dict[str, Any]]) -> list[Command]:
116
118
  commands = []
117
119
  for entry in raw_commands:
118
120
  raw_command = RawCommand(**entry)
121
+ parser = CommandArgumentParser(
122
+ command_key=raw_command.key,
123
+ command_description=raw_command.description,
124
+ command_style=raw_command.style,
125
+ help_text=raw_command.help_text,
126
+ help_epilogue=raw_command.help_epilogue,
127
+ aliases=raw_command.aliases,
128
+ )
119
129
  commands.append(
120
130
  Command.model_validate(
121
131
  {
@@ -123,9 +133,11 @@ def convert_commands(raw_commands: list[dict[str, Any]]) -> list[Command]:
123
133
  "action": wrap_if_needed(
124
134
  import_action(raw_command.action), name=raw_command.description
125
135
  ),
136
+ "arg_parser": parser,
126
137
  }
127
138
  )
128
139
  )
140
+
129
141
  return commands
130
142
 
131
143
 
falyx/falyx.py CHANGED
@@ -59,7 +59,7 @@ from falyx.execution_registry import ExecutionRegistry as er
59
59
  from falyx.hook_manager import Hook, HookManager, HookType
60
60
  from falyx.logger import logger
61
61
  from falyx.options_manager import OptionsManager
62
- from falyx.parsers import CommandArgumentParser, get_arg_parsers
62
+ from falyx.parsers import CommandArgumentParser, FalyxParsers, get_arg_parsers
63
63
  from falyx.protocols import ArgParserProtocol
64
64
  from falyx.retry import RetryPolicy
65
65
  from falyx.signals import BackSignal, CancelSignal, HelpSignal, QuitSignal
@@ -152,6 +152,11 @@ class Falyx:
152
152
  self,
153
153
  title: str | Markdown = "Menu",
154
154
  *,
155
+ program: str | None = "falyx",
156
+ usage: str | None = None,
157
+ description: str | None = "Falyx CLI - Run structured async command workflows.",
158
+ epilog: str | None = None,
159
+ version: str = __version__,
155
160
  prompt: str | AnyFormattedText = "> ",
156
161
  columns: int = 3,
157
162
  bottom_bar: BottomBar | str | Callable[[], Any] | None = None,
@@ -170,6 +175,11 @@ class Falyx:
170
175
  ) -> None:
171
176
  """Initializes the Falyx object."""
172
177
  self.title: str | Markdown = title
178
+ self.program: str | None = program
179
+ self.usage: str | None = usage
180
+ self.description: str | None = description
181
+ self.epilog: str | None = epilog
182
+ self.version: str = version
173
183
  self.prompt: str | AnyFormattedText = prompt
174
184
  self.columns: int = columns
175
185
  self.commands: dict[str, Command] = CaseInsensitiveDict()
@@ -776,6 +786,8 @@ class Falyx:
776
786
  logger.info("Command '%s' selected.", choice)
777
787
  if is_preview:
778
788
  return True, name_map[choice], args, kwargs
789
+ elif self.mode in {FalyxMode.RUN, FalyxMode.RUN_ALL, FalyxMode.PREVIEW}:
790
+ return False, name_map[choice], args, kwargs
779
791
  try:
780
792
  args, kwargs = await name_map[choice].parse_args(
781
793
  input_args, from_validate
@@ -1013,12 +1025,35 @@ class Falyx:
1013
1025
  if self.exit_message:
1014
1026
  self.print_message(self.exit_message)
1015
1027
 
1016
- async def run(self) -> None:
1028
+ async def run(
1029
+ self,
1030
+ falyx_parsers: FalyxParsers | None = None,
1031
+ callback: Callable[..., Any] | None = None,
1032
+ ) -> None:
1017
1033
  """Run Falyx CLI with structured subcommands."""
1018
- if not self.cli_args:
1019
- self.cli_args = get_arg_parsers().root.parse_args()
1034
+ if self.cli_args:
1035
+ raise FalyxError(
1036
+ "Run is incompatible with CLI arguments. Use 'run_key' instead."
1037
+ )
1038
+ if falyx_parsers:
1039
+ if not isinstance(falyx_parsers, FalyxParsers):
1040
+ raise FalyxError("falyx_parsers must be an instance of FalyxParsers.")
1041
+ else:
1042
+ falyx_parsers = get_arg_parsers(
1043
+ self.program,
1044
+ self.usage,
1045
+ self.description,
1046
+ self.epilog,
1047
+ commands=self.commands,
1048
+ )
1049
+ self.cli_args = falyx_parsers.parse_args()
1020
1050
  self.options.from_namespace(self.cli_args, "cli_args")
1021
1051
 
1052
+ if callback:
1053
+ if not callable(callback):
1054
+ raise FalyxError("Callback must be a callable function.")
1055
+ callback(self.cli_args)
1056
+
1022
1057
  if not self.options.get("never_prompt"):
1023
1058
  self.options.set("never_prompt", self._never_prompt)
1024
1059
 
@@ -1073,11 +1108,24 @@ class Falyx:
1073
1108
  args, kwargs = await command.parse_args(self.cli_args.command_args)
1074
1109
  except HelpSignal:
1075
1110
  sys.exit(0)
1111
+ except CommandArgumentError as error:
1112
+ self.console.print(f"[{OneColors.DARK_RED}]❌ ['{command.key}'] {error}")
1113
+ command.show_help()
1114
+ sys.exit(1)
1076
1115
  try:
1077
1116
  await self.run_key(self.cli_args.name, args=args, kwargs=kwargs)
1078
1117
  except FalyxError as error:
1079
1118
  self.console.print(f"[{OneColors.DARK_RED}]❌ Error: {error}[/]")
1080
1119
  sys.exit(1)
1120
+ except QuitSignal:
1121
+ logger.info("[QuitSignal]. <- Exiting run.")
1122
+ sys.exit(0)
1123
+ except BackSignal:
1124
+ logger.info("[BackSignal]. <- Exiting run.")
1125
+ sys.exit(0)
1126
+ except CancelSignal:
1127
+ logger.info("[CancelSignal]. <- Exiting run.")
1128
+ sys.exit(0)
1081
1129
 
1082
1130
  if self.cli_args.summary:
1083
1131
  er.summary()
falyx/init.py CHANGED
@@ -11,9 +11,7 @@ TEMPLATE_TASKS = """\
11
11
  import asyncio
12
12
  import json
13
13
 
14
- from falyx.action import Action, ChainedAction
15
- from falyx.io_action import ShellAction
16
- from falyx.selection_action import SelectionAction
14
+ from falyx.action import Action, ChainedAction, ShellAction, SelectionAction
17
15
 
18
16
 
19
17
  post_ids = ["1", "2", "3", "4", "5"]
@@ -103,7 +101,7 @@ commands:
103
101
  console = Console(color_system="auto")
104
102
 
105
103
 
106
- def init_project(name: str = ".") -> None:
104
+ def init_project(name: str) -> None:
107
105
  target = Path(name).resolve()
108
106
  target.mkdir(parents=True, exist_ok=True)
109
107
 
falyx/parsers/argparse.py CHANGED
@@ -168,6 +168,7 @@ class CommandArgumentParser:
168
168
  self._arguments: list[Argument] = []
169
169
  self._positional: dict[str, Argument] = {}
170
170
  self._keyword: dict[str, Argument] = {}
171
+ self._keyword_list: list[Argument] = []
171
172
  self._flag_map: dict[str, Argument] = {}
172
173
  self._dest_set: set[str] = set()
173
174
  self._add_help()
@@ -488,6 +489,8 @@ class CommandArgumentParser:
488
489
  self._arguments.append(argument)
489
490
  if positional:
490
491
  self._positional[dest] = argument
492
+ else:
493
+ self._keyword_list.append(argument)
491
494
 
492
495
  def get_argument(self, dest: str) -> Argument | None:
493
496
  return next((a for a in self._arguments if a.dest == dest), None)
@@ -832,11 +835,11 @@ class CommandArgumentParser:
832
835
  kwargs_dict[arg.dest] = parsed[arg.dest]
833
836
  return tuple(args_list), kwargs_dict
834
837
 
835
- def render_help(self) -> None:
838
+ def get_options_text(self, plain_text=False) -> str:
836
839
  # Options
837
840
  # Add all keyword arguments to the options list
838
841
  options_list = []
839
- for arg in self._keyword.values():
842
+ for arg in self._keyword_list:
840
843
  choice_text = arg.get_choice_text()
841
844
  if choice_text:
842
845
  options_list.extend([f"[{arg.flags[0]} {choice_text}]"])
@@ -848,19 +851,39 @@ class CommandArgumentParser:
848
851
  choice_text = arg.get_choice_text()
849
852
  if isinstance(arg.nargs, int):
850
853
  choice_text = " ".join([choice_text] * arg.nargs)
851
- options_list.append(escape(choice_text))
852
-
853
- options_text = " ".join(options_list)
854
- command_keys = " | ".join(
855
- [f"[{self.command_style}]{self.command_key}[/{self.command_style}]"]
856
- + [
857
- f"[{self.command_style}]{alias}[/{self.command_style}]"
858
- for alias in self.aliases
859
- ]
860
- )
854
+ if plain_text:
855
+ options_list.append(choice_text)
856
+ else:
857
+ options_list.append(escape(choice_text))
858
+
859
+ return " ".join(options_list)
861
860
 
862
- usage = f"usage: {command_keys} {options_text}"
863
- self.console.print(f"[bold]{usage}[/bold]\n")
861
+ def get_command_keys_text(self, plain_text=False) -> str:
862
+ if plain_text:
863
+ command_keys = " | ".join(
864
+ [f"{self.command_key}"] + [f"{alias}" for alias in self.aliases]
865
+ )
866
+ else:
867
+ command_keys = " | ".join(
868
+ [f"[{self.command_style}]{self.command_key}[/{self.command_style}]"]
869
+ + [
870
+ f"[{self.command_style}]{alias}[/{self.command_style}]"
871
+ for alias in self.aliases
872
+ ]
873
+ )
874
+ return command_keys
875
+
876
+ def get_usage(self, plain_text=False) -> str:
877
+ """Get the usage text for the command."""
878
+ command_keys = self.get_command_keys_text(plain_text)
879
+ options_text = self.get_options_text(plain_text)
880
+ if options_text:
881
+ return f"{command_keys} {options_text}"
882
+ return command_keys
883
+
884
+ def render_help(self) -> None:
885
+ usage = self.get_usage()
886
+ self.console.print(f"[bold]usage: {usage}[/bold]\n")
864
887
 
865
888
  # Description
866
889
  if self.help_text:
@@ -877,7 +900,7 @@ class CommandArgumentParser:
877
900
  arg_line.append(help_text)
878
901
  self.console.print(arg_line)
879
902
  self.console.print("[bold]options:[/bold]")
880
- for arg in self._keyword.values():
903
+ for arg in self._keyword_list:
881
904
  flags = ", ".join(arg.flags)
882
905
  flags_choice = f"{flags} {arg.get_choice_text()}"
883
906
  arg_line = Text(f" {flags_choice:<30} ")
falyx/parsers/parsers.py CHANGED
@@ -2,10 +2,18 @@
2
2
  """parsers.py
3
3
  This module contains the argument parsers used for the Falyx CLI.
4
4
  """
5
- from argparse import REMAINDER, ArgumentParser, Namespace, _SubParsersAction
5
+ from argparse import (
6
+ REMAINDER,
7
+ ArgumentParser,
8
+ Namespace,
9
+ RawDescriptionHelpFormatter,
10
+ _SubParsersAction,
11
+ )
6
12
  from dataclasses import asdict, dataclass
7
13
  from typing import Any, Sequence
8
14
 
15
+ from falyx.command import Command
16
+
9
17
 
10
18
  @dataclass
11
19
  class FalyxParsers:
@@ -47,6 +55,7 @@ def get_arg_parsers(
47
55
  add_help: bool = True,
48
56
  allow_abbrev: bool = True,
49
57
  exit_on_error: bool = True,
58
+ commands: dict[str, Command] | None = None,
50
59
  ) -> FalyxParsers:
51
60
  """Returns the argument parser for the CLI."""
52
61
  parser = ArgumentParser(
@@ -79,8 +88,25 @@ def get_arg_parsers(
79
88
  parser.add_argument("--version", action="store_true", help="Show Falyx version")
80
89
  subparsers = parser.add_subparsers(dest="command")
81
90
 
82
- run_parser = subparsers.add_parser("run", help="Run a specific command")
83
- run_parser.add_argument("name", help="Key, alias, or description of the command")
91
+ run_description = "Run a command by its key or alias."
92
+ run_epilog = ["commands:"]
93
+ if isinstance(commands, dict):
94
+ for command in commands.values():
95
+ run_epilog.append(command.usage)
96
+ command_description = command.description or command.help_text
97
+ run_epilog.append(f" {command_description}")
98
+ run_epilog.append(" ")
99
+ run_epilog.append(
100
+ "Tip: Use 'falyx run ?[COMMAND]' to preview commands by their key or alias."
101
+ )
102
+ run_parser = subparsers.add_parser(
103
+ "run",
104
+ help="Run a specific command",
105
+ description=run_description,
106
+ epilog="\n".join(run_epilog),
107
+ formatter_class=RawDescriptionHelpFormatter,
108
+ )
109
+ run_parser.add_argument("name", help="Run a command by its key or alias")
84
110
  run_parser.add_argument(
85
111
  "--summary",
86
112
  action="store_true",
falyx/version.py CHANGED
@@ -1 +1 @@
1
- __version__ = "0.1.39"
1
+ __version__ = "0.1.41"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: falyx
3
- Version: 0.1.39
3
+ Version: 0.1.41
4
4
  Summary: Reliable and introspectable async CLI action framework.
5
5
  License: MIT
6
6
  Author: Roland Thomas Jr
@@ -1,6 +1,6 @@
1
1
  falyx/.pytyped,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
2
  falyx/__init__.py,sha256=Gh88lQ5pbD7xbGWrBgslE2kSTZKY9TkvKSa53rZ3l8U,305
3
- falyx/__main__.py,sha256=g_LwJieofK3DJzCYtpkAMEeOXhzSLQenb7pRVUqcf-Y,2152
3
+ falyx/__main__.py,sha256=8abZbfytyFcSccyEZzlX3E2Krto1tVr1pRI_ep9KcUs,1911
4
4
  falyx/action/.pytyped,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
5
  falyx/action/__init__.py,sha256=4E3Rb0GgGcmggrPJh0YFiwbVgN_PQjIzL06-Z3qMReo,1247
6
6
  falyx/action/action.py,sha256=w6xDbsB1SlMPSvpo2Dh0e11lRGP6a4E3K6AdfjlEqGY,5759
@@ -23,23 +23,23 @@ falyx/action/signal_action.py,sha256=5UMqvzy7fBnLANGwYUWoe1VRhrr7e-yOVeLdOnCBiJo
23
23
  falyx/action/types.py,sha256=NfZz1ufZuvCgp-he2JIItbnjX7LjOUadjtKbjpRlSIY,1399
24
24
  falyx/action/user_input_action.py,sha256=7kL5G7L0j2LuLvHu-CMwOaHyEisagE7O_2G2EhqWRr8,3483
25
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
26
+ falyx/command.py,sha256=M-XZDKKMhjHYF5mcn0Pdc_mXmvLlEmKk2l84sGS66jc,14864
27
+ falyx/config.py,sha256=BBDRv5uj0teydBm25eTIvEl9hKQqGGGX-Z6H9EHOHHw,10077
28
28
  falyx/context.py,sha256=NfBpxzFzn-dYP6I3wrtGFucqm__UZo4SSBLmM8yYayE,10330
29
29
  falyx/debug.py,sha256=IRpYtdH8yeXJEsfP5rASALmBQb2U_EwrTudF2GIDdZY,1545
30
30
  falyx/exceptions.py,sha256=kK9k1v7LVNjJSwYztRa9Krhr3ZOI-6Htq2ZjlYICPKg,922
31
31
  falyx/execution_registry.py,sha256=rctsz0mrIHPToLZqylblVjDdKWdq1x_JBc8GwMP5sJ8,4710
32
- falyx/falyx.py,sha256=rz4md-dOMOuFsdZ8lLMeIFz82PKgj8fpeegZRtHOETs,44741
32
+ falyx/falyx.py,sha256=v4G-OUzzU5N6HD2LDmlA9IDXb3uFe_HNCUUFwxi1qn4,46717
33
33
  falyx/hook_manager.py,sha256=TFuHQnAncS_rk6vuw-VSx8bnAppLuHfrZCrzLwqcO9o,2979
34
34
  falyx/hooks.py,sha256=xMfQROib0BNsaQF4AXJpmCiGePoE1f1xpcdibgnVZWM,2913
35
- falyx/init.py,sha256=abcSlPmxVeByLIHdUkNjqtO_tEkO3ApC6f9WbxsSEWg,3393
35
+ falyx/init.py,sha256=VZ3rYMxo7g01EraYATdl_pRN4ZqrsVueo2ZFx54gojo,3326
36
36
  falyx/logger.py,sha256=1Mfb_vJFJ1tQwziuyU2p-cSMi2Js8N2byniFEnI6vOQ,132
37
37
  falyx/menu.py,sha256=E580qZsx08bnWcqRVjJuD2Fy8Zh_1zIexp5f0lC7L2c,3745
38
38
  falyx/options_manager.py,sha256=dFAnQw543tQ6Xupvh1PwBrhiSWlSACHw8K-sHP_lUh4,2842
39
39
  falyx/parsers/.pytyped,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
40
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
41
+ falyx/parsers/argparse.py,sha256=WB8InZJ_WOaqi6J80IfnxInRyJ7aBCP0sv0zalo8al0,36924
42
+ falyx/parsers/parsers.py,sha256=EUArQTJkrpgrCa6qCc1zZXTX4GOZXnSvsQhEvzgDyQ8,6538
43
43
  falyx/parsers/signature.py,sha256=i4iOiJxv70sxQYivKKXC_YOsShRUYfcI8Cjq8yVZvMo,2262
44
44
  falyx/parsers/utils.py,sha256=Z4qLu8NVIprcHK2RDXoISpcDKBUii3n05G9mlgiPDgw,889
45
45
  falyx/prompt_utils.py,sha256=qgk0bXs7mwzflqzWyFhEOTpKQ_ZtMIqGhKeg-ocwNnE,1542
@@ -53,9 +53,9 @@ falyx/themes/__init__.py,sha256=1CZhEUCin9cUk8IGYBUFkVvdHRNNJBEFXccHwpUKZCA,284
53
53
  falyx/themes/colors.py,sha256=4aaeAHJetmeNInI0Zytg4E3YqKfPFelpf04vtjSvsS8,19776
54
54
  falyx/utils.py,sha256=U45xnZFUdoFC4xiji_9S1jHS5V7MvxSDtufP8EgB0SM,6732
55
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,,
56
+ falyx/version.py,sha256=y9uk7vaddYq7x48m1qAG2qgbHu814vUzjs_fjnrQ3Es,23
57
+ falyx-0.1.41.dist-info/LICENSE,sha256=B0yqgaHuSdhN7T3OBmgQSiDTy8HqT5Oe_dLypRe4Ra4,1073
58
+ falyx-0.1.41.dist-info/METADATA,sha256=CajQhPtTIGTUkRJw7mYcyGh-7JUie9IPER3RS31zsDw,5517
59
+ falyx-0.1.41.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
60
+ falyx-0.1.41.dist-info/entry_points.txt,sha256=j8owOSl2j1Ss8DtGMnKfgehKaolqnIPhVFHaUBLUnMs,45
61
+ falyx-0.1.41.dist-info/RECORD,,
File without changes