argenta 1.0.7__py3-none-any.whl → 1.1.1__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.
argenta/__init__.py CHANGED
@@ -0,0 +1,10 @@
1
+ __all__ = [
2
+ 'App',
3
+ 'Orchestrator',
4
+ 'Router',
5
+ ]
6
+
7
+
8
+ from argenta.app import App
9
+ from argenta.orchestrator import Orchestrator
10
+ from argenta.router import Router
argenta/app/__init__.py CHANGED
@@ -1,3 +1,12 @@
1
- __all__ = ["App"]
1
+ __all__ = [
2
+ "App",
3
+ "PredefinedMessages",
4
+ "DynamicDividingLine",
5
+ "StaticDividingLine",
6
+ "AutoCompleter"
7
+ ]
2
8
 
3
9
  from argenta.app.models import App
10
+ from argenta.app.defaults import PredefinedMessages
11
+ from argenta.app.dividing_line.models import DynamicDividingLine, StaticDividingLine
12
+ from argenta.app.autocompleter.entity import AutoCompleter
@@ -13,10 +13,10 @@ class AutoCompleter:
13
13
  :param autocomplete_button: the button for auto-completion
14
14
  :return: None
15
15
  """
16
- self.history_filename = history_filename
17
- self.autocomplete_button = autocomplete_button
16
+ self.history_filename: str | None = history_filename
17
+ self.autocomplete_button: str = autocomplete_button
18
18
 
19
- def _complete(self, text, state) -> str | None:
19
+ def _complete(self, text: str, state: int) -> str | None:
20
20
  """
21
21
  Private. Auto-completion function
22
22
  :param text: part of the command being entered
@@ -24,7 +24,7 @@ class AutoCompleter:
24
24
  :return: the desired candidate as str or None
25
25
  """
26
26
  matches: list[str] = sorted(
27
- cmd for cmd in self.get_history_items() if cmd.startswith(text)
27
+ cmd for cmd in _get_history_items() if cmd.startswith(text)
28
28
  )
29
29
  if len(matches) > 1:
30
30
  common_prefix = matches[0]
@@ -38,7 +38,7 @@ class AutoCompleter:
38
38
  i += 1
39
39
  common_prefix = common_prefix[:i]
40
40
  if state == 0:
41
- readline.insert_text(common_prefix[len(text) :])
41
+ readline.insert_text(common_prefix[len(text) :])
42
42
  readline.redisplay()
43
43
  return None
44
44
  elif len(matches) == 1:
@@ -54,10 +54,10 @@ class AutoCompleter:
54
54
  """
55
55
  if self.history_filename:
56
56
  if os.path.exists(self.history_filename):
57
- readline.read_history_file(self.history_filename)
57
+ readline.read_history_file(self.history_filename)
58
58
  else:
59
59
  for line in all_commands:
60
- readline.add_history(line)
60
+ readline.add_history(line)
61
61
 
62
62
  readline.set_completer(self._complete)
63
63
  readline.set_completer_delims(readline.get_completer_delims().replace(" ", ""))
@@ -69,7 +69,7 @@ class AutoCompleter:
69
69
  :return: None
70
70
  """
71
71
  if self.history_filename:
72
- readline.write_history_file(self.history_filename)
72
+ readline.write_history_file(self.history_filename)
73
73
  with open(self.history_filename, "r") as history_file:
74
74
  raw_history = history_file.read()
75
75
  pretty_history: list[str] = []
@@ -77,15 +77,14 @@ class AutoCompleter:
77
77
  if line.split()[0] in all_commands:
78
78
  pretty_history.append(line)
79
79
  with open(self.history_filename, "w") as history_file:
80
- history_file.write("\n".join(pretty_history))
80
+ _ = history_file.write("\n".join(pretty_history))
81
81
 
82
- @staticmethod
83
- def get_history_items() -> list[str] | list[Never]:
84
- """
85
- Private. Returns a list of all commands entered by the user
86
- :return: all commands entered by the user as list[str] | list[Never]
87
- """
88
- return [
89
- readline.get_history_item(i)
90
- for i in range(1, readline.get_current_history_length() + 1)
91
- ]
82
+ def _get_history_items() -> list[str] | list[Never]:
83
+ """
84
+ Private. Returns a list of all commands entered by the user
85
+ :return: all commands entered by the user as list[str] | list[Never]
86
+ """
87
+ return [
88
+ readline.get_history_item(i)
89
+ for i in range(1, readline.get_current_history_length() + 1)
90
+ ]
argenta/app/defaults.py CHANGED
@@ -5,7 +5,6 @@ class PredefinedMessages(StrEnum):
5
5
  """
6
6
  Public. A dataclass with predetermined messages for quick use
7
7
  """
8
-
9
8
  USAGE = "[b dim]Usage[/b dim]: [i]<command> <[green]flags[/green]>[/i]"
10
9
  HELP = "[b dim]Help[/b dim]: [i]<command>[/i] [b red]--help[/b red]"
11
10
  AUTOCOMPLETE = "[b dim]Autocomplete[/b dim]: [i]<part>[/i] [bold]<tab>"
@@ -8,7 +8,7 @@ class BaseDividingLine(ABC):
8
8
  :param unit_part: the single part of the dividing line
9
9
  :return: None
10
10
  """
11
- self._unit_part = unit_part
11
+ self._unit_part: str = unit_part
12
12
 
13
13
  def get_unit_part(self) -> str:
14
14
  """
@@ -22,7 +22,7 @@ class BaseDividingLine(ABC):
22
22
 
23
23
 
24
24
  class StaticDividingLine(BaseDividingLine):
25
- def __init__(self, unit_part: str = "-", length: int = 25) -> None:
25
+ def __init__(self, unit_part: str = "-", *, length: int = 25) -> None:
26
26
  """
27
27
  Public. The static dividing line
28
28
  :param unit_part: the single part of the dividing line
@@ -30,9 +30,9 @@ class StaticDividingLine(BaseDividingLine):
30
30
  :return: None
31
31
  """
32
32
  super().__init__(unit_part)
33
- self.length = length
33
+ self.length: int = length
34
34
 
35
- def get_full_static_line(self, is_override: bool) -> str:
35
+ def get_full_static_line(self, *, is_override: bool) -> str:
36
36
  """
37
37
  Private. Returns the full line of the dividing line
38
38
  :param is_override: has the default text layout been redefined
@@ -53,7 +53,7 @@ class DynamicDividingLine(BaseDividingLine):
53
53
  """
54
54
  super().__init__(unit_part)
55
55
 
56
- def get_full_dynamic_line(self, length: int, is_override: bool) -> str:
56
+ def get_full_dynamic_line(self, *, length: int, is_override: bool) -> str:
57
57
  """
58
58
  Private. Returns the full line of the dividing line
59
59
  :param length: the length of the dividing line
argenta/app/models.py CHANGED
@@ -1,29 +1,37 @@
1
- from typing import Callable
2
- from rich.console import Console
3
- from rich.markup import escape
4
- from art import text2art
5
- from contextlib import redirect_stdout
6
1
  import io
7
2
  import re
3
+ from contextlib import redirect_stdout
4
+ from typing import Never, TypeAlias
5
+
6
+ from art import text2art # pyright: ignore[reportMissingTypeStubs, reportUnknownVariableType]
7
+ from rich.console import Console
8
+ from rich.markup import escape
8
9
 
9
- from argenta.command.models import Command, InputCommand
10
- from argenta.router import Router
11
- from argenta.router.defaults import system_router
12
10
  from argenta.app.autocompleter import AutoCompleter
13
- from argenta.app.dividing_line.models import StaticDividingLine, DynamicDividingLine
11
+ from argenta.app.dividing_line.models import DynamicDividingLine, StaticDividingLine
12
+ from argenta.app.protocols import (
13
+ DescriptionMessageGenerator,
14
+ EmptyCommandHandler,
15
+ NonStandardBehaviorHandler,
16
+ Printer,
17
+ )
18
+ from argenta.app.registered_routers.entity import RegisteredRouters
14
19
  from argenta.command.exceptions import (
15
- UnprocessedInputFlagException,
16
- RepeatedInputFlagsException,
17
20
  EmptyInputCommandException,
18
- BaseInputCommandException,
21
+ InputCommandException,
22
+ RepeatedInputFlagsException,
23
+ UnprocessedInputFlagException,
19
24
  )
20
- from argenta.app.registered_routers.entity import RegisteredRouters
25
+ from argenta.command.models import Command, InputCommand
21
26
  from argenta.response import Response
27
+ from argenta.router import Router
28
+ from argenta.router.defaults import system_router
22
29
 
30
+ Matches: TypeAlias = list[str] | list[Never]
23
31
 
24
32
 
25
33
  class BaseApp:
26
- def __init__(self, prompt: str,
34
+ def __init__(self, *, prompt: str,
27
35
  initial_message: str,
28
36
  farewell_message: str,
29
37
  exit_command: Command,
@@ -33,57 +41,44 @@ class BaseApp:
33
41
  repeat_command_groups: bool,
34
42
  override_system_messages: bool,
35
43
  autocompleter: AutoCompleter,
36
- print_func: Callable[[str], None]) -> None:
37
- self._prompt = prompt
38
- self._print_func = print_func
39
- self._exit_command = exit_command
40
- self._system_router_title = system_router_title
41
- self._dividing_line = dividing_line
42
- self._ignore_command_register = ignore_command_register
43
- self._repeat_command_groups_description = repeat_command_groups
44
- self._override_system_messages = override_system_messages
45
- self._autocompleter = autocompleter
46
-
47
- self._farewell_message = farewell_message
48
- self._initial_message = initial_message
49
-
50
- self._description_message_gen: Callable[[str, str], str] = lambda command, description: f"{command} *=*=* {description}"
44
+ print_func: Printer) -> None:
45
+ self._prompt: str = prompt
46
+ self._print_func: Printer = print_func
47
+ self._exit_command: Command = exit_command
48
+ self._system_router_title: str | None = system_router_title
49
+ self._dividing_line: StaticDividingLine | DynamicDividingLine = dividing_line
50
+ self._ignore_command_register: bool = ignore_command_register
51
+ self._repeat_command_groups_description: bool = repeat_command_groups
52
+ self._override_system_messages: bool = override_system_messages
53
+ self._autocompleter: AutoCompleter = autocompleter
54
+
55
+ self._farewell_message: str = farewell_message
56
+ self._initial_message: str = initial_message
57
+
58
+ self._description_message_gen: DescriptionMessageGenerator = lambda command, description: f"{command} *=*=* {description}"
51
59
  self._registered_routers: RegisteredRouters = RegisteredRouters()
52
60
  self._messages_on_startup: list[str] = []
53
61
 
54
62
  self._matching_lower_triggers_with_routers: dict[str, Router] = {}
55
63
  self._matching_default_triggers_with_routers: dict[str, Router] = {}
56
64
 
57
- if self._ignore_command_register:
58
- self._current_matching_triggers_with_routers: dict[str, Router] = self._matching_lower_triggers_with_routers
59
- else:
60
- self._current_matching_triggers_with_routers: dict[str, Router] = self._matching_default_triggers_with_routers
65
+ self._current_matching_triggers_with_routers: dict[str, Router] = self._matching_lower_triggers_with_routers if self._ignore_command_register else self._matching_default_triggers_with_routers
61
66
 
62
- self._incorrect_input_syntax_handler: Callable[[str], None] = (
63
- lambda raw_command: print_func(f"Incorrect flag syntax: {raw_command}")
64
- )
65
- self._repeated_input_flags_handler: Callable[[str], None] = (
66
- lambda raw_command: print_func(f"Repeated input flags: {raw_command}")
67
- )
68
- self._empty_input_command_handler: Callable[[], None] = lambda: print_func(
69
- "Empty input command"
70
- )
71
- self._unknown_command_handler: Callable[[InputCommand], None] = (
72
- lambda command: print_func(f"Unknown command: {command.get_trigger()}")
73
- )
74
- self._exit_command_handler: Callable[[Response], None] = (
75
- lambda response: print_func(self._farewell_message)
76
- )
67
+ self._incorrect_input_syntax_handler: NonStandardBehaviorHandler[str] = lambda _: print_func(f"Incorrect flag syntax: {_}")
68
+ self._repeated_input_flags_handler: NonStandardBehaviorHandler[str] = lambda _: print_func(f"Repeated input flags: {_}")
69
+ self._empty_input_command_handler: EmptyCommandHandler = lambda: print_func("Empty input command")
70
+ self._unknown_command_handler: NonStandardBehaviorHandler[InputCommand] = lambda _: print_func(f"Unknown command: {_.trigger}")
71
+ self._exit_command_handler: NonStandardBehaviorHandler[Response] = lambda _: print_func(self._farewell_message)
77
72
 
78
- def set_description_message_pattern(self, _: Callable[[str, str], str]) -> None:
73
+ def set_description_message_pattern(self, _: DescriptionMessageGenerator, /) -> None:
79
74
  """
80
75
  Public. Sets the output pattern of the available commands
81
76
  :param _: output pattern of the available commands
82
77
  :return: None
83
78
  """
84
- self._description_message_gen: Callable[[str, str], str] = _
79
+ self._description_message_gen = _
85
80
 
86
- def set_incorrect_input_syntax_handler(self, _: Callable[[str], None]) -> None:
81
+ def set_incorrect_input_syntax_handler(self, _: NonStandardBehaviorHandler[str], /) -> None:
87
82
  """
88
83
  Public. Sets the handler for incorrect flags when entering a command
89
84
  :param _: handler for incorrect flags when entering a command
@@ -91,7 +86,7 @@ class BaseApp:
91
86
  """
92
87
  self._incorrect_input_syntax_handler = _
93
88
 
94
- def set_repeated_input_flags_handler(self, _: Callable[[str], None]) -> None:
89
+ def set_repeated_input_flags_handler(self, _: NonStandardBehaviorHandler[str], /) -> None:
95
90
  """
96
91
  Public. Sets the handler for repeated flags when entering a command
97
92
  :param _: handler for repeated flags when entering a command
@@ -99,7 +94,7 @@ class BaseApp:
99
94
  """
100
95
  self._repeated_input_flags_handler = _
101
96
 
102
- def set_unknown_command_handler(self, _: Callable[[str], None]) -> None:
97
+ def set_unknown_command_handler(self, _: NonStandardBehaviorHandler[InputCommand], /) -> None:
103
98
  """
104
99
  Public. Sets the handler for unknown commands when entering a command
105
100
  :param _: handler for unknown commands when entering a command
@@ -107,7 +102,7 @@ class BaseApp:
107
102
  """
108
103
  self._unknown_command_handler = _
109
104
 
110
- def set_empty_command_handler(self, _: Callable[[], None]) -> None:
105
+ def set_empty_command_handler(self, _: EmptyCommandHandler, /) -> None:
111
106
  """
112
107
  Public. Sets the handler for empty commands when entering a command
113
108
  :param _: handler for empty commands when entering a command
@@ -115,7 +110,7 @@ class BaseApp:
115
110
  """
116
111
  self._empty_input_command_handler = _
117
112
 
118
- def set_exit_command_handler(self, _: Callable[[], None]) -> None:
113
+ def set_exit_command_handler(self, _: NonStandardBehaviorHandler[Response], /) -> None:
119
114
  """
120
115
  Public. Sets the handler for exit command when entering a command
121
116
  :param _: handler for exit command when entering a command
@@ -131,11 +126,12 @@ class BaseApp:
131
126
  for registered_router in self._registered_routers:
132
127
  if registered_router.title:
133
128
  self._print_func(registered_router.title)
134
- for command_handler in registered_router.get_command_handlers():
129
+ for command_handler in registered_router.command_handlers:
130
+ handled_command = command_handler.handled_command
135
131
  self._print_func(
136
132
  self._description_message_gen(
137
- command_handler.get_handled_command().get_trigger(),
138
- command_handler.get_handled_command().get_description(),
133
+ handled_command.trigger,
134
+ handled_command.description,
139
135
  )
140
136
  )
141
137
  self._print_func("")
@@ -146,16 +142,7 @@ class BaseApp:
146
142
  :param text: framed text
147
143
  :return: None
148
144
  """
149
- if isinstance(self._dividing_line, StaticDividingLine):
150
- self._print_func(
151
- self._dividing_line.get_full_static_line(self._override_system_messages)
152
- )
153
- print(text.strip("\n"))
154
- self._print_func(
155
- self._dividing_line.get_full_static_line(self._override_system_messages)
156
- )
157
-
158
- elif isinstance(self._dividing_line, DynamicDividingLine):
145
+ if isinstance(self._dividing_line, DynamicDividingLine):
159
146
  clear_text = re.sub(r"\u001b\[[0-9;]*m", "", text)
160
147
  max_length_line = max([len(line) for line in clear_text.split("\n")])
161
148
  max_length_line = (
@@ -168,15 +155,27 @@ class BaseApp:
168
155
 
169
156
  self._print_func(
170
157
  self._dividing_line.get_full_dynamic_line(
171
- max_length_line, self._override_system_messages
158
+ length=max_length_line, is_override=self._override_system_messages
172
159
  )
173
160
  )
174
161
  print(text.strip("\n"))
175
162
  self._print_func(
176
163
  self._dividing_line.get_full_dynamic_line(
177
- max_length_line, self._override_system_messages
164
+ length=max_length_line, is_override=self._override_system_messages
178
165
  )
179
166
  )
167
+
168
+ elif isinstance(self._dividing_line, StaticDividingLine): # pyright: ignore[reportUnnecessaryIsInstance]
169
+ self._print_func(
170
+ self._dividing_line.get_full_static_line(is_override=self._override_system_messages)
171
+ )
172
+ print(text.strip("\n"))
173
+ self._print_func(
174
+ self._dividing_line.get_full_static_line(is_override=self._override_system_messages)
175
+ )
176
+
177
+ else:
178
+ raise NotImplementedError
180
179
 
181
180
  def _is_exit_command(self, command: InputCommand) -> bool:
182
181
  """
@@ -184,20 +183,21 @@ class BaseApp:
184
183
  :param command: command to check
185
184
  :return: is it an exit command or not as bool
186
185
  """
186
+ trigger = command.trigger
187
+ exit_trigger = self._exit_command.trigger
187
188
  if self._ignore_command_register:
188
189
  if (
189
- command.get_trigger().lower()
190
- == self._exit_command.get_trigger().lower()
190
+ trigger.lower() == exit_trigger.lower()
191
191
  ):
192
192
  return True
193
- elif command.get_trigger().lower() in [
194
- x.lower() for x in self._exit_command.get_aliases()
193
+ elif trigger.lower() in [
194
+ x.lower() for x in self._exit_command.aliases
195
195
  ]:
196
196
  return True
197
197
  else:
198
- if command.get_trigger() == self._exit_command.get_trigger():
198
+ if trigger == exit_trigger:
199
199
  return True
200
- elif command.get_trigger() in self._exit_command.get_aliases():
200
+ elif trigger in self._exit_command.aliases:
201
201
  return True
202
202
  return False
203
203
 
@@ -207,7 +207,7 @@ class BaseApp:
207
207
  :param command: command to check
208
208
  :return: is it an unknown command or not as bool
209
209
  """
210
- input_command_trigger = command.get_trigger()
210
+ input_command_trigger = command.trigger
211
211
  if self._ignore_command_register:
212
212
  if input_command_trigger.lower() in list(self._current_matching_triggers_with_routers.keys()):
213
213
  return False
@@ -217,7 +217,7 @@ class BaseApp:
217
217
  return True
218
218
 
219
219
  def _error_handler(
220
- self, error: BaseInputCommandException, raw_command: str
220
+ self, error: InputCommandException, raw_command: str
221
221
  ) -> None:
222
222
  """
223
223
  Private. Handles parsing errors of the entered command
@@ -240,23 +240,25 @@ class BaseApp:
240
240
  system_router.title = self._system_router_title
241
241
 
242
242
  @system_router.command(self._exit_command)
243
- def exit_command(response: Response) -> None:
243
+ def _(response: Response) -> None:
244
244
  self._exit_command_handler(response)
245
245
 
246
- if system_router not in self._registered_routers.get_registered_routers():
247
- system_router.set_command_register_ignore(self._ignore_command_register)
246
+ if system_router not in self._registered_routers.registered_routers:
247
+ system_router.command_register_ignore = self._ignore_command_register
248
248
  self._registered_routers.add_registered_router(system_router)
249
249
 
250
250
  def _most_similar_command(self, unknown_command: str) -> str | None:
251
251
  all_commands = list(self._current_matching_triggers_with_routers.keys())
252
-
253
- matches: list[str] | list = sorted(
252
+
253
+ matches_startswith_unknown_command: Matches = sorted(
254
254
  cmd for cmd in all_commands if cmd.startswith(unknown_command)
255
255
  )
256
- if not matches:
257
- matches: list[str] | list = sorted(
258
- cmd for cmd in all_commands if unknown_command.startswith(cmd)
259
- )
256
+ matches_startswith_cmd: Matches = sorted(
257
+ cmd for cmd in all_commands if unknown_command.startswith(cmd)
258
+ )
259
+
260
+ matches: Matches = matches_startswith_unknown_command or matches_startswith_cmd
261
+
260
262
  if len(matches) == 1:
261
263
  return matches[0]
262
264
  elif len(matches) > 1:
@@ -272,9 +274,9 @@ class BaseApp:
272
274
  self._prompt = f"[italic dim bold]{self._prompt}"
273
275
  self._initial_message = ("\n" + f"[bold red]{text2art(self._initial_message, font='tarty1')}" + "\n")
274
276
  self._farewell_message = (
275
- "[bold red]\n\n"
276
- + text2art(self._farewell_message, font="chanky")
277
- + "\n[/bold red]\n"
277
+ "[bold red]\n\n" +
278
+ str(text2art(self._farewell_message, font="chanky")) + # pyright: ignore[reportUnknownArgumentType]
279
+ "\n[/bold red]\n" +
278
280
  "[red i]github.com/koloideal/Argenta[/red i] | [red bold i]made by kolo[/red bold i]\n"
279
281
  )
280
282
  self._description_message_gen = lambda command, description: (
@@ -287,7 +289,7 @@ class BaseApp:
287
289
  self._empty_input_command_handler = lambda: self._print_func("[red bold]Empty input command")
288
290
 
289
291
  def unknown_command_handler(command: InputCommand) -> None:
290
- cmd_trg: str = command.get_trigger()
292
+ cmd_trg: str = command.trigger
291
293
  mst_sim_cmd: str | None = self._most_similar_command(cmd_trg)
292
294
  first_part_of_text = f"[red]Unknown command:[/red] [blue]{escape(cmd_trg)}[/blue]"
293
295
  second_part_of_text = (
@@ -299,7 +301,7 @@ class BaseApp:
299
301
 
300
302
  self._unknown_command_handler = unknown_command_handler
301
303
 
302
- def pre_cycle_setup(self) -> None:
304
+ def _pre_cycle_setup(self) -> None:
303
305
  """
304
306
  Private. Configures various aspects of the application before the start of the cycle
305
307
  :return: None
@@ -307,8 +309,8 @@ class BaseApp:
307
309
  self._setup_system_router()
308
310
 
309
311
  for router_entity in self._registered_routers:
310
- router_triggers = router_entity.get_triggers()
311
- router_aliases = router_entity.get_aliases()
312
+ router_triggers = router_entity.triggers
313
+ router_aliases = router_entity.aliases
312
314
  combined = router_triggers + router_aliases
313
315
 
314
316
  for trigger in combined:
@@ -337,20 +339,28 @@ class BaseApp:
337
339
  self._print_command_group_description()
338
340
 
339
341
 
342
+ AVAILABLE_DIVIDING_LINES: TypeAlias = StaticDividingLine | DynamicDividingLine
343
+ DEFAULT_DIVIDING_LINE: StaticDividingLine = StaticDividingLine()
344
+
345
+ DEFAULT_PRINT_FUNC: Printer = Console().print
346
+ DEFAULT_AUTOCOMPLETER: AutoCompleter = AutoCompleter()
347
+ DEFAULT_EXIT_COMMAND: Command = Command("Q", description="Exit command")
348
+
349
+
340
350
  class App(BaseApp):
341
351
  def __init__(
342
- self,
343
- prompt: str = "What do you want to do?\n",
352
+ self, *,
353
+ prompt: str = "What do you want to do?\n\n",
344
354
  initial_message: str = "Argenta\n",
345
355
  farewell_message: str = "\nSee you\n",
346
- exit_command: Command = Command("Q", "Exit command"),
356
+ exit_command: Command = DEFAULT_EXIT_COMMAND,
347
357
  system_router_title: str | None = "System points:",
348
358
  ignore_command_register: bool = True,
349
- dividing_line: StaticDividingLine | DynamicDividingLine = StaticDividingLine(),
359
+ dividing_line: AVAILABLE_DIVIDING_LINES = DEFAULT_DIVIDING_LINE,
350
360
  repeat_command_groups: bool = True,
351
361
  override_system_messages: bool = False,
352
- autocompleter: AutoCompleter = AutoCompleter(),
353
- print_func: Callable[[str], None] = Console().print,
362
+ autocompleter: AutoCompleter = DEFAULT_AUTOCOMPLETER,
363
+ print_func: Printer = DEFAULT_PRINT_FUNC,
354
364
  ) -> None:
355
365
  """
356
366
  Public. The essence of the application itself.
@@ -387,7 +397,7 @@ class App(BaseApp):
387
397
  Private. Starts the user input processing cycle
388
398
  :return: None
389
399
  """
390
- self.pre_cycle_setup()
400
+ self._pre_cycle_setup()
391
401
  while True:
392
402
  if self._repeat_command_groups_description:
393
403
  self._print_command_group_description()
@@ -396,11 +406,11 @@ class App(BaseApp):
396
406
 
397
407
  try:
398
408
  input_command: InputCommand = InputCommand.parse(raw_command=raw_command)
399
- except BaseInputCommandException as error:
400
- with redirect_stdout(io.StringIO()) as f:
409
+ except InputCommandException as error:
410
+ with redirect_stdout(io.StringIO()) as stderr:
401
411
  self._error_handler(error, raw_command)
402
- res: str = f.getvalue()
403
- self._print_framed_text(res)
412
+ stderr_result: str = stderr.getvalue()
413
+ self._print_framed_text(stderr_result)
404
414
  continue
405
415
 
406
416
  if self._is_exit_command(input_command):
@@ -409,29 +419,30 @@ class App(BaseApp):
409
419
  return
410
420
 
411
421
  if self._is_unknown_command(input_command):
412
- with redirect_stdout(io.StringIO()) as f:
422
+ with redirect_stdout(io.StringIO()) as stdout:
413
423
  self._unknown_command_handler(input_command)
414
- res: str = f.getvalue()
415
- self._print_framed_text(res)
424
+ stdout_res: str = stdout.getvalue()
425
+ self._print_framed_text(stdout_res)
416
426
  continue
417
427
 
418
- processing_router = self._current_matching_triggers_with_routers[input_command.get_trigger().lower()]
428
+ processing_router = self._current_matching_triggers_with_routers[input_command.trigger.lower()]
419
429
 
420
430
  if processing_router.disable_redirect_stdout:
421
431
  if isinstance(self._dividing_line, StaticDividingLine):
422
- self._print_func(self._dividing_line.get_full_static_line(self._override_system_messages))
432
+ self._print_func(self._dividing_line.get_full_static_line(is_override=self._override_system_messages))
423
433
  processing_router.finds_appropriate_handler(input_command)
424
- self._print_func(self._dividing_line.get_full_static_line(self._override_system_messages))
434
+ self._print_func(self._dividing_line.get_full_static_line(is_override=self._override_system_messages))
425
435
  else:
426
- self._print_func(StaticDividingLine(self._dividing_line.get_unit_part()).get_full_static_line(self._override_system_messages))
436
+ dividing_line_unit_part: str = self._dividing_line.get_unit_part()
437
+ self._print_func(StaticDividingLine(dividing_line_unit_part).get_full_static_line(is_override=self._override_system_messages))
427
438
  processing_router.finds_appropriate_handler(input_command)
428
- self._print_func(StaticDividingLine(self._dividing_line.get_unit_part()).get_full_static_line(self._override_system_messages))
439
+ self._print_func(StaticDividingLine(dividing_line_unit_part).get_full_static_line(is_override=self._override_system_messages))
429
440
  else:
430
- with redirect_stdout(io.StringIO()) as f:
441
+ with redirect_stdout(io.StringIO()) as stdout:
431
442
  processing_router.finds_appropriate_handler(input_command)
432
- res: str = f.getvalue()
433
- if res:
434
- self._print_framed_text(res)
443
+ stdout_result: str = stdout.getvalue()
444
+ if stdout_result:
445
+ self._print_framed_text(stdout_result)
435
446
 
436
447
  def include_router(self, router: Router) -> None:
437
448
  """
@@ -439,7 +450,7 @@ class App(BaseApp):
439
450
  :param router: registered router
440
451
  :return: None
441
452
  """
442
- router.set_command_register_ignore(self._ignore_command_register)
453
+ router.command_register_ignore = self._ignore_command_register
443
454
  self._registered_routers.add_registered_router(router)
444
455
 
445
456
  def include_routers(self, *routers: Router) -> None:
@@ -0,0 +1,22 @@
1
+ from typing import Protocol, TypeVar
2
+
3
+ T = TypeVar('T', contravariant=True) # noqa: WPS111
4
+
5
+
6
+ class NonStandardBehaviorHandler(Protocol[T]):
7
+ def __call__(self, __param: T) -> None:
8
+ raise NotImplementedError
9
+
10
+ class EmptyCommandHandler(Protocol):
11
+ def __call__(self) -> None:
12
+ raise NotImplementedError
13
+
14
+
15
+ class Printer(Protocol):
16
+ def __call__(self, __text: str) -> None:
17
+ raise NotImplementedError
18
+
19
+
20
+ class DescriptionMessageGenerator(Protocol):
21
+ def __call__(self, __first_param: str, __second_param: str) -> str:
22
+ raise NotImplementedError