falyx 0.1.44__py3-none-any.whl → 0.1.46__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
@@ -97,7 +97,7 @@ def main() -> Any:
97
97
  init_project,
98
98
  aliases=["init"],
99
99
  argument_config=init_config,
100
- help_epilogue="If no name is provided, the current directory will be used.",
100
+ help_epilog="If no name is provided, the current directory will be used.",
101
101
  )
102
102
  flx.add_command(
103
103
  "G",
falyx/command.py CHANGED
@@ -111,7 +111,7 @@ class Command(BaseModel):
111
111
  hidden: bool = False
112
112
  aliases: list[str] = Field(default_factory=list)
113
113
  help_text: str = ""
114
- help_epilogue: str = ""
114
+ help_epilog: str = ""
115
115
  style: str = OneColors.WHITE
116
116
  confirm: bool = False
117
117
  confirm_message: str = "Are you sure?"
@@ -128,7 +128,7 @@ class Command(BaseModel):
128
128
  tags: list[str] = Field(default_factory=list)
129
129
  logging_hooks: bool = False
130
130
  options_manager: OptionsManager = Field(default_factory=OptionsManager)
131
- arg_parser: CommandArgumentParser = Field(default_factory=CommandArgumentParser)
131
+ arg_parser: CommandArgumentParser | None = None
132
132
  arguments: list[dict[str, Any]] = Field(default_factory=list)
133
133
  argument_config: Callable[[CommandArgumentParser], None] | None = None
134
134
  custom_parser: ArgParserProtocol | None = None
@@ -167,6 +167,12 @@ class Command(BaseModel):
167
167
  raw_args,
168
168
  )
169
169
  return ((), {})
170
+ if not isinstance(self.arg_parser, CommandArgumentParser):
171
+ logger.warning(
172
+ "[Command:%s] No argument parser configured, using default parsing.",
173
+ self.key,
174
+ )
175
+ return ((), {})
170
176
  return await self.arg_parser.parse_args_split(
171
177
  raw_args, from_validate=from_validate
172
178
  )
@@ -183,7 +189,9 @@ class Command(BaseModel):
183
189
  def get_argument_definitions(self) -> list[dict[str, Any]]:
184
190
  if self.arguments:
185
191
  return self.arguments
186
- elif callable(self.argument_config):
192
+ elif callable(self.argument_config) and isinstance(
193
+ self.arg_parser, CommandArgumentParser
194
+ ):
187
195
  self.argument_config(self.arg_parser)
188
196
  elif self.auto_args:
189
197
  if isinstance(self.action, BaseAction):
@@ -219,8 +227,17 @@ class Command(BaseModel):
219
227
  if self.logging_hooks and isinstance(self.action, BaseAction):
220
228
  register_debug_hooks(self.action.hooks)
221
229
 
222
- for arg_def in self.get_argument_definitions():
223
- self.arg_parser.add_argument(*arg_def.pop("flags"), **arg_def)
230
+ if self.arg_parser is None:
231
+ self.arg_parser = CommandArgumentParser(
232
+ command_key=self.key,
233
+ command_description=self.description,
234
+ command_style=self.style,
235
+ help_text=self.help_text,
236
+ help_epilog=self.help_epilog,
237
+ aliases=self.aliases,
238
+ )
239
+ for arg_def in self.get_argument_definitions():
240
+ self.arg_parser.add_argument(*arg_def.pop("flags"), **arg_def)
224
241
 
225
242
  def _inject_options_manager(self) -> None:
226
243
  """Inject the options manager into the action if applicable."""
falyx/config.py CHANGED
@@ -102,7 +102,7 @@ class RawCommand(BaseModel):
102
102
  retry_policy: RetryPolicy = Field(default_factory=RetryPolicy)
103
103
  hidden: bool = False
104
104
  help_text: str = ""
105
- help_epilogue: str = ""
105
+ help_epilog: str = ""
106
106
 
107
107
  @field_validator("retry_policy")
108
108
  @classmethod
@@ -118,14 +118,6 @@ def convert_commands(raw_commands: list[dict[str, Any]]) -> list[Command]:
118
118
  commands = []
119
119
  for entry in raw_commands:
120
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
- )
129
121
  commands.append(
130
122
  Command.model_validate(
131
123
  {
@@ -133,7 +125,6 @@ def convert_commands(raw_commands: list[dict[str, Any]]) -> list[Command]:
133
125
  "action": wrap_if_needed(
134
126
  import_action(raw_command.action), name=raw_command.description
135
127
  ),
136
- "arg_parser": parser,
137
128
  }
138
129
  )
139
130
  )
falyx/falyx.py CHANGED
@@ -88,6 +88,11 @@ class CommandValidator(Validator):
88
88
 
89
89
  async def validate_async(self, document) -> None:
90
90
  text = document.text
91
+ if not text:
92
+ raise ValidationError(
93
+ message=self.error_message,
94
+ cursor_position=len(text),
95
+ )
91
96
  is_preview, choice, _, __ = await self.falyx.get_command(text, from_validate=True)
92
97
  if is_preview:
93
98
  return None
@@ -157,6 +162,7 @@ class Falyx:
157
162
  description: str | None = "Falyx CLI - Run structured async command workflows.",
158
163
  epilog: str | None = None,
159
164
  version: str = __version__,
165
+ version_style: str = OneColors.BLUE_b,
160
166
  prompt: str | AnyFormattedText = "> ",
161
167
  columns: int = 3,
162
168
  bottom_bar: BottomBar | str | Callable[[], Any] | None = None,
@@ -180,6 +186,7 @@ class Falyx:
180
186
  self.description: str | None = description
181
187
  self.epilog: str | None = epilog
182
188
  self.version: str = version
189
+ self.version_style: str = version_style
183
190
  self.prompt: str | AnyFormattedText = prompt
184
191
  self.columns: int = columns
185
192
  self.commands: dict[str, Command] = CaseInsensitiveDict()
@@ -359,7 +366,6 @@ class Falyx:
359
366
  action=Action("Help", self._show_help),
360
367
  style=OneColors.LIGHT_YELLOW,
361
368
  arg_parser=parser,
362
- auto_args=False,
363
369
  )
364
370
 
365
371
  def _get_completer(self) -> WordCompleter:
@@ -616,7 +622,7 @@ class Falyx:
616
622
  hidden: bool = False,
617
623
  aliases: list[str] | None = None,
618
624
  help_text: str = "",
619
- help_epilogue: str = "",
625
+ help_epilog: str = "",
620
626
  style: str = OneColors.WHITE,
621
627
  confirm: bool = False,
622
628
  confirm_message: str = "Are you sure?",
@@ -655,15 +661,6 @@ class Falyx:
655
661
  "arg_parser must be an instance of CommandArgumentParser."
656
662
  )
657
663
  arg_parser = arg_parser
658
- else:
659
- arg_parser = CommandArgumentParser(
660
- command_key=key,
661
- command_description=description,
662
- command_style=style,
663
- help_text=help_text,
664
- help_epilogue=help_epilogue,
665
- aliases=aliases,
666
- )
667
664
 
668
665
  command = Command(
669
666
  key=key,
@@ -674,7 +671,7 @@ class Falyx:
674
671
  hidden=hidden,
675
672
  aliases=aliases if aliases else [],
676
673
  help_text=help_text,
677
- help_epilogue=help_epilogue,
674
+ help_epilog=help_epilog,
678
675
  style=style,
679
676
  confirm=confirm,
680
677
  confirm_message=confirm_message,
@@ -1098,7 +1095,7 @@ class Falyx:
1098
1095
  sys.exit(0)
1099
1096
 
1100
1097
  if self.cli_args.command == "version" or self.cli_args.version:
1101
- self.console.print(f"[{OneColors.BLUE_b}]Falyx CLI v{__version__}[/]")
1098
+ self.console.print(f"[{self.version_style}]{self.program} v{__version__}[/]")
1102
1099
  sys.exit(0)
1103
1100
 
1104
1101
  if self.cli_args.command == "preview":
falyx/parsers/argparse.py CHANGED
@@ -12,6 +12,7 @@ from rich.text import Text
12
12
 
13
13
  from falyx.action.base import BaseAction
14
14
  from falyx.exceptions import CommandArgumentError
15
+ from falyx.parsers.utils import coerce_value
15
16
  from falyx.signals import HelpSignal
16
17
 
17
18
 
@@ -154,7 +155,7 @@ class CommandArgumentParser:
154
155
  command_description: str = "",
155
156
  command_style: str = "bold",
156
157
  help_text: str = "",
157
- help_epilogue: str = "",
158
+ help_epilog: str = "",
158
159
  aliases: list[str] | None = None,
159
160
  ) -> None:
160
161
  """Initialize the CommandArgumentParser."""
@@ -163,7 +164,7 @@ class CommandArgumentParser:
163
164
  self.command_description: str = command_description
164
165
  self.command_style: str = command_style
165
166
  self.help_text: str = help_text
166
- self.help_epilogue: str = help_epilogue
167
+ self.help_epilog: str = help_epilog
167
168
  self.aliases: list[str] = aliases or []
168
169
  self._arguments: list[Argument] = []
169
170
  self._positional: dict[str, Argument] = {}
@@ -290,7 +291,7 @@ class CommandArgumentParser:
290
291
  for choice in choices:
291
292
  if not isinstance(choice, expected_type):
292
293
  try:
293
- expected_type(choice)
294
+ coerce_value(choice, expected_type)
294
295
  except Exception:
295
296
  raise CommandArgumentError(
296
297
  f"Invalid choice {choice!r}: not coercible to {expected_type.__name__}"
@@ -303,7 +304,7 @@ class CommandArgumentParser:
303
304
  """Validate the default value type."""
304
305
  if default is not None and not isinstance(default, expected_type):
305
306
  try:
306
- expected_type(default)
307
+ coerce_value(default, expected_type)
307
308
  except Exception:
308
309
  raise CommandArgumentError(
309
310
  f"Default value {default!r} for '{dest}' cannot be coerced to {expected_type.__name__}"
@@ -316,7 +317,7 @@ class CommandArgumentParser:
316
317
  for item in default:
317
318
  if not isinstance(item, expected_type):
318
319
  try:
319
- expected_type(item)
320
+ coerce_value(item, expected_type)
320
321
  except Exception:
321
322
  raise CommandArgumentError(
322
323
  f"Default list value {default!r} for '{dest}' cannot be coerced to {expected_type.__name__}"
@@ -595,7 +596,7 @@ class CommandArgumentParser:
595
596
  i += new_i
596
597
 
597
598
  try:
598
- typed = [spec.type(v) for v in values]
599
+ typed = [coerce_value(value, spec.type) for value in values]
599
600
  except Exception:
600
601
  raise CommandArgumentError(
601
602
  f"Invalid value for '{spec.dest}': expected {spec.type.__name__}"
@@ -680,7 +681,9 @@ class CommandArgumentParser:
680
681
  ), "resolver should be an instance of BaseAction"
681
682
  values, new_i = self._consume_nargs(args, i + 1, spec)
682
683
  try:
683
- typed_values = [spec.type(value) for value in values]
684
+ typed_values = [
685
+ coerce_value(value, spec.type) for value in values
686
+ ]
684
687
  except ValueError:
685
688
  raise CommandArgumentError(
686
689
  f"Invalid value for '{spec.dest}': expected {spec.type.__name__}"
@@ -709,7 +712,9 @@ class CommandArgumentParser:
709
712
  assert result.get(spec.dest) is not None, "dest should not be None"
710
713
  values, new_i = self._consume_nargs(args, i + 1, spec)
711
714
  try:
712
- typed_values = [spec.type(value) for value in values]
715
+ typed_values = [
716
+ coerce_value(value, spec.type) for value in values
717
+ ]
713
718
  except ValueError:
714
719
  raise CommandArgumentError(
715
720
  f"Invalid value for '{spec.dest}': expected {spec.type.__name__}"
@@ -724,7 +729,9 @@ class CommandArgumentParser:
724
729
  assert result.get(spec.dest) is not None, "dest should not be None"
725
730
  values, new_i = self._consume_nargs(args, i + 1, spec)
726
731
  try:
727
- typed_values = [spec.type(value) for value in values]
732
+ typed_values = [
733
+ coerce_value(value, spec.type) for value in values
734
+ ]
728
735
  except ValueError:
729
736
  raise CommandArgumentError(
730
737
  f"Invalid value for '{spec.dest}': expected {spec.type.__name__}"
@@ -735,7 +742,9 @@ class CommandArgumentParser:
735
742
  else:
736
743
  values, new_i = self._consume_nargs(args, i + 1, spec)
737
744
  try:
738
- typed_values = [spec.type(v) for v in values]
745
+ typed_values = [
746
+ coerce_value(value, spec.type) for value in values
747
+ ]
739
748
  except ValueError:
740
749
  raise CommandArgumentError(
741
750
  f"Invalid value for '{spec.dest}': expected {spec.type.__name__}"
@@ -908,9 +917,9 @@ class CommandArgumentParser:
908
917
  arg_line.append(help_text)
909
918
  self.console.print(arg_line)
910
919
 
911
- # Epilogue
912
- if self.help_epilogue:
913
- self.console.print("\n" + self.help_epilogue, style="dim")
920
+ # Epilog
921
+ if self.help_epilog:
922
+ self.console.print("\n" + self.help_epilog, style="dim")
914
923
 
915
924
  def __eq__(self, other: object) -> bool:
916
925
  if not isinstance(other, CommandArgumentParser):
falyx/parsers/utils.py CHANGED
@@ -1,10 +1,79 @@
1
- from typing import Any
1
+ import types
2
+ from datetime import datetime
3
+ from enum import EnumMeta
4
+ from typing import Any, Literal, Union, get_args, get_origin
5
+
6
+ from dateutil import parser as date_parser
2
7
 
3
8
  from falyx.action.base import BaseAction
4
9
  from falyx.logger import logger
5
10
  from falyx.parsers.signature import infer_args_from_func
6
11
 
7
12
 
13
+ def coerce_bool(value: str) -> bool:
14
+ if isinstance(value, bool):
15
+ return value
16
+ value = value.strip().lower()
17
+ if value in {"true", "1", "yes", "on"}:
18
+ return True
19
+ elif value in {"false", "0", "no", "off"}:
20
+ return False
21
+ return bool(value)
22
+
23
+
24
+ def coerce_enum(value: Any, enum_type: EnumMeta) -> Any:
25
+ if isinstance(value, enum_type):
26
+ return value
27
+
28
+ if isinstance(value, str):
29
+ try:
30
+ return enum_type[value]
31
+ except KeyError:
32
+ pass
33
+
34
+ base_type = type(next(iter(enum_type)).value)
35
+ print(base_type)
36
+ try:
37
+ coerced_value = base_type(value)
38
+ return enum_type(coerced_value)
39
+ except (ValueError, TypeError):
40
+ raise ValueError(f"Value '{value}' could not be coerced to enum type {enum_type}")
41
+
42
+
43
+ def coerce_value(value: str, target_type: type) -> Any:
44
+ origin = get_origin(target_type)
45
+ args = get_args(target_type)
46
+
47
+ if origin is Literal:
48
+ if value not in args:
49
+ raise ValueError(
50
+ f"Value '{value}' is not a valid literal for type {target_type}"
51
+ )
52
+ return value
53
+
54
+ if isinstance(target_type, types.UnionType) or get_origin(target_type) is Union:
55
+ for arg in args:
56
+ try:
57
+ return coerce_value(value, arg)
58
+ except Exception:
59
+ continue
60
+ raise ValueError(f"Value '{value}' could not be coerced to any of {args!r}")
61
+
62
+ if isinstance(target_type, EnumMeta):
63
+ return coerce_enum(value, target_type)
64
+
65
+ if target_type is bool:
66
+ return coerce_bool(value)
67
+
68
+ if target_type is datetime:
69
+ try:
70
+ return date_parser.parse(value)
71
+ except ValueError as e:
72
+ raise ValueError(f"Value '{value}' could not be parsed as a datetime") from e
73
+
74
+ return target_type(value)
75
+
76
+
8
77
  def same_argument_definitions(
9
78
  actions: list[Any],
10
79
  arg_metadata: dict[str, str | dict[str, Any]] | None = None,
falyx/version.py CHANGED
@@ -1 +1 @@
1
- __version__ = "0.1.44"
1
+ __version__ = "0.1.46"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: falyx
3
- Version: 0.1.44
3
+ Version: 0.1.46
4
4
  Summary: Reliable and introspectable async CLI action framework.
5
5
  License: MIT
6
6
  Author: Roland Thomas Jr
@@ -15,6 +15,7 @@ Classifier: Programming Language :: Python :: 3.13
15
15
  Requires-Dist: aiohttp (>=3.11,<4.0)
16
16
  Requires-Dist: prompt_toolkit (>=3.0,<4.0)
17
17
  Requires-Dist: pydantic (>=2.0,<3.0)
18
+ Requires-Dist: python-dateutil (>=2.8,<3.0)
18
19
  Requires-Dist: python-json-logger (>=3.3.0,<4.0.0)
19
20
  Requires-Dist: pyyaml (>=6.0,<7.0)
20
21
  Requires-Dist: rich (>=13.0,<14.0)
@@ -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=yrNF4m7kwKX9dFn-Q_ci1N6BJCC_ltw2p0HcUDqEuas,3423
3
+ falyx/__main__.py,sha256=186MGZUMtx-hCH7QsBqcN-68hYg747LOSk3rlc_23_c,3421
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,13 +23,13 @@ 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=x9IuXT3iAArX9MXZ5yLRyaeqIHqklPV_39UlMs2wuuQ,15752
27
- falyx/config.py,sha256=BBDRv5uj0teydBm25eTIvEl9hKQqGGGX-Z6H9EHOHHw,10077
26
+ falyx/command.py,sha256=cfML3Bc6Fg1GNQReLzonR5OtA7oZaeJtWwjLI8utr7w,16414
27
+ falyx/config.py,sha256=WCjL8TheQ6OjwxhsnvuKnJHcIAT2XVEPaw0zxqYNTCU,9701
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=nMFc-fRqab28gRB7ov62C1YILEZZOAJvExKL-d4tTiI,48088
32
+ falyx/falyx.py,sha256=59Dqh8U7sR4MZcklmNoJJVEOGcpUULWiEcy-uGZeQ0U,48002
33
33
  falyx/hook_manager.py,sha256=TFuHQnAncS_rk6vuw-VSx8bnAppLuHfrZCrzLwqcO9o,2979
34
34
  falyx/hooks.py,sha256=xMfQROib0BNsaQF4AXJpmCiGePoE1f1xpcdibgnVZWM,2913
35
35
  falyx/init.py,sha256=VZ3rYMxo7g01EraYATdl_pRN4ZqrsVueo2ZFx54gojo,3326
@@ -38,10 +38,10 @@ 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=ZfPmbtEUechDvgl99-lWhTXmFnXS_FMXJ_xb8KGEJLo,448
41
- falyx/parsers/argparse.py,sha256=WB8InZJ_WOaqi6J80IfnxInRyJ7aBCP0sv0zalo8al0,36924
41
+ falyx/parsers/argparse.py,sha256=lXhGvumL2XRHhJzE0anVnTy23XZLikCn7nZAkMf8ZdE,37301
42
42
  falyx/parsers/parsers.py,sha256=MXWC8OQ3apDaeKfY0O4J8NnkxofWVOCRnKatC00lGm0,8796
43
43
  falyx/parsers/signature.py,sha256=PfDe432PYcJDhDXguNzumFqWjDLk13s6jhZF33r__AM,2326
44
- falyx/parsers/utils.py,sha256=Z4qLu8NVIprcHK2RDXoISpcDKBUii3n05G9mlgiPDgw,889
44
+ falyx/parsers/utils.py,sha256=w_UzvvP62EDKXWSf3jslEsJfd45usGyFqXKNziQhLRI,2893
45
45
  falyx/prompt_utils.py,sha256=qgk0bXs7mwzflqzWyFhEOTpKQ_ZtMIqGhKeg-ocwNnE,1542
46
46
  falyx/protocols.py,sha256=-9GbCBUzzsEgw2_KOCYqxxzWJuez0eHmwnZp_ShY0jc,493
47
47
  falyx/retry.py,sha256=sGRE9QhdZK98M99G8F15WUsJ_fYLNyLlCgu3UANaSQs,3744
@@ -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=AoJtnEXXv6E20uj57ChQUsGoLfKG8mvSQpdz97tcyis,23
57
- falyx-0.1.44.dist-info/LICENSE,sha256=B0yqgaHuSdhN7T3OBmgQSiDTy8HqT5Oe_dLypRe4Ra4,1073
58
- falyx-0.1.44.dist-info/METADATA,sha256=4Ug2vw0YvPHn_0o9o4Wij4XiSHG5Nk_kstjOYPp51mM,5517
59
- falyx-0.1.44.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
60
- falyx-0.1.44.dist-info/entry_points.txt,sha256=j8owOSl2j1Ss8DtGMnKfgehKaolqnIPhVFHaUBLUnMs,45
61
- falyx-0.1.44.dist-info/RECORD,,
56
+ falyx/version.py,sha256=X3e_85I7oZGwZD8nW9SBKEUbQU7-_3W9FXuicrfxHjc,23
57
+ falyx-0.1.46.dist-info/LICENSE,sha256=B0yqgaHuSdhN7T3OBmgQSiDTy8HqT5Oe_dLypRe4Ra4,1073
58
+ falyx-0.1.46.dist-info/METADATA,sha256=sKgexNI7YEsZiUNO2LTxZSmlJheEm_nj0WnVkZsZXhI,5561
59
+ falyx-0.1.46.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
60
+ falyx-0.1.46.dist-info/entry_points.txt,sha256=j8owOSl2j1Ss8DtGMnKfgehKaolqnIPhVFHaUBLUnMs,45
61
+ falyx-0.1.46.dist-info/RECORD,,
File without changes