bear-utils 0.8.24__tar.gz → 0.8.25__tar.gz
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.
- {bear_utils-0.8.24 → bear_utils-0.8.25}/.bumpversion.cfg +1 -1
- {bear_utils-0.8.24 → bear_utils-0.8.25}/PKG-INFO +2 -2
- {bear_utils-0.8.24 → bear_utils-0.8.25}/README.md +1 -1
- {bear_utils-0.8.24 → bear_utils-0.8.25}/pyproject.toml +1 -1
- {bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/cli/prompt_helpers.py +12 -14
- {bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/cli/shell/_base_command.py +1 -4
- {bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/cli/typer_bridge.py +1 -1
- {bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/extras/responses/function_response.py +103 -54
- bear_utils-0.8.25/src/bear_utils/extras/wrappers/string_io.py +46 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/tests/test_function_response.py +1 -12
- {bear_utils-0.8.24 → bear_utils-0.8.25}/tests/test_gradient.py +24 -11
- {bear_utils-0.8.24 → bear_utils-0.8.25}/tests/test_prompt_helpers.py +8 -8
- {bear_utils-0.8.24 → bear_utils-0.8.25}/.gitignore +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/.python-version +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/AGENTS.md +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/config/coverage.ini +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/config/default.toml +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/config/git-changelog.toml +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/config/pytest.ini +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/config/ruff.toml +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/config/vscode/launch.json +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/config/vscode/settings.json +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/config/vscode/tasks.json +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/directory_structure.txt +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/directory_structure.xml +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/maskfile.md +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/noxfile.py +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/__init__.py +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/__main__.py +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/_internal/__init__.py +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/_internal/cli.py +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/_internal/debug.py +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/ai/__init__.py +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/ai/ai_helpers/__init__.py +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/ai/ai_helpers/_common.py +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/ai/ai_helpers/_config.py +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/ai/ai_helpers/_parsers.py +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/ai/ai_helpers/_types.py +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/cache/__init__.py +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/cli/__init__.py +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/cli/commands.py +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/cli/shell/__init__.py +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/cli/shell/_base_shell.py +1 -1
- {bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/cli/shell/_common.py +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/config/__init__.py +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/config/config_manager.py +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/config/dir_manager.py +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/config/settings_manager.py +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/constants/__init__.py +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/constants/_exceptions.py +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/constants/_lazy_typing.py +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/constants/date_related.py +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/constants/server.py +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/constants/time_related.py +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/database/__init__.py +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/database/_db_manager.py +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/events/__init__.py +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/events/events_class.py +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/events/events_module.py +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/extras/__init__.py +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/extras/_async_helpers.py +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/extras/_tools.py +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/extras/platform_utils.py +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/extras/responses/__init__.py +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/extras/wrappers/__init__.py +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/extras/wrappers/add_methods.py +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/files/__init__.py +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/files/file_handlers/__init__.py +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/files/file_handlers/_base_file_handler.py +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/files/file_handlers/file_handler_factory.py +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/files/file_handlers/json_file_handler.py +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/files/file_handlers/log_file_handler.py +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/files/file_handlers/toml_file_handler.py +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/files/file_handlers/txt_file_handler.py +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/files/file_handlers/yaml_file_handler.py +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/files/ignore_parser.py +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/graphics/__init__.py +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/graphics/bear_gradient.py +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/graphics/image_helpers.py +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/gui/__init__.py +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/gui/gui_tools/__init__.py +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/gui/gui_tools/_settings.py +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/gui/gui_tools/_types.py +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/gui/gui_tools/qt_app.py +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/gui/gui_tools/qt_color_picker.py +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/gui/gui_tools/qt_file_handler.py +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/gui/gui_tools/qt_input_dialog.py +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/logger_manager/__init__.py +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/logger_manager/_common.py +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/logger_manager/_console_junk.py +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/logger_manager/_log_level.py +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/logger_manager/_styles.py +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/logger_manager/logger_protocol.py +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/logger_manager/loggers/__init__.py +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/logger_manager/loggers/_level_sin.py +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/logger_manager/loggers/base_logger.py +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/logger_manager/loggers/base_logger.pyi +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/logger_manager/loggers/basic_logger/__init__.py +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/logger_manager/loggers/basic_logger/logger.py +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/logger_manager/loggers/basic_logger/logger.pyi +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/logger_manager/loggers/buffer_logger.py +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/logger_manager/loggers/console_logger.py +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/logger_manager/loggers/console_logger.pyi +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/logger_manager/loggers/fastapi_logger.py +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/logger_manager/loggers/file_logger.py +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/logger_manager/loggers/simple_logger.py +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/logger_manager/loggers/sub_logger.py +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/logger_manager/loggers/sub_logger.pyi +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/monitoring/__init__.py +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/monitoring/_common.py +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/monitoring/host_monitor.py +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/time/__init__.py +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/tests/__init__.py +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/tests/test_add_ord_suffix.py +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/tests/test_clipboard.py +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/tests/test_database_manager.py +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/tests/test_default_shell.py +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/tests/test_logger.py +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/tests/test_platform_utils.py +0 -0
- {bear_utils-0.8.24 → bear_utils-0.8.25}/uv.lock +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: bear-utils
|
3
|
-
Version: 0.8.
|
3
|
+
Version: 0.8.25
|
4
4
|
Summary: Various utilities for Bear programmers, including a rich logging utility, a disk cache, and a SQLite database wrapper amongst other things.
|
5
5
|
Author-email: chaz <bright.lid5647@fastmail.com>
|
6
6
|
Requires-Python: >=3.12
|
@@ -25,7 +25,7 @@ Provides-Extra: gui
|
|
25
25
|
Requires-Dist: pyqt6>=6.9.0; extra == 'gui'
|
26
26
|
Description-Content-Type: text/markdown
|
27
27
|
|
28
|
-
# Bear Utils v# Bear Utils v0.8.
|
28
|
+
# Bear Utils v# Bear Utils v0.8.25
|
29
29
|
|
30
30
|
Personal set of tools and utilities for Python projects, focusing on modularity and ease of use. This library includes components for caching, database management, logging, time handling, file operations, CLI prompts, image processing, clipboard interaction, gradient utilities, event systems, and async helpers.
|
31
31
|
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# Bear Utils v# Bear Utils v0.8.
|
1
|
+
# Bear Utils v# Bear Utils v0.8.25
|
2
2
|
|
3
3
|
Personal set of tools and utilities for Python projects, focusing on modularity and ease of use. This library includes components for caching, database management, logging, time handling, file operations, CLI prompts, image processing, clipboard interaction, gradient utilities, event systems, and async helpers.
|
4
4
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
[project]
|
2
2
|
name = "bear-utils"
|
3
|
-
version = "0.8.
|
3
|
+
version = "0.8.25"
|
4
4
|
description = "Various utilities for Bear programmers, including a rich logging utility, a disk cache, and a SQLite database wrapper amongst other things."
|
5
5
|
authors = [{ name = "chaz", email = "bright.lid5647@fastmail.com" }]
|
6
6
|
readme = "README.md"
|
@@ -107,26 +107,25 @@ def ask_yes_no(question: str, default: bool | None = None) -> bool | None:
|
|
107
107
|
Returns:
|
108
108
|
True for yes, False for no, or None if user exits
|
109
109
|
"""
|
110
|
-
console,
|
110
|
+
console, _ = get_console("prompt_helpers.py")
|
111
111
|
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
response: str = prompt("> ").strip().lower()
|
112
|
+
while True:
|
113
|
+
try:
|
114
|
+
response: str = prompt(f"{question}\n> ").strip().lower()
|
116
115
|
if not response:
|
117
116
|
if default is not None:
|
118
117
|
return default
|
119
|
-
|
118
|
+
console.print("Please enter 'yes', 'no', or 'exit'.")
|
120
119
|
continue
|
121
120
|
if _parse_exit(response):
|
122
121
|
return None
|
123
122
|
try:
|
124
123
|
return _parse_bool(response)
|
125
124
|
except ValueError:
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
125
|
+
console.print("Invalid input. Please enter 'yes', 'no', or 'exit'.", style="red")
|
126
|
+
except KeyboardInterrupt:
|
127
|
+
console.print("KeyboardInterrupt: Exiting the prompt.", style="yellow")
|
128
|
+
return None
|
130
129
|
|
131
130
|
|
132
131
|
def restricted_prompt(
|
@@ -165,16 +164,15 @@ def restricted_prompt(
|
|
165
164
|
|
166
165
|
try:
|
167
166
|
while True:
|
168
|
-
console.print(question)
|
169
167
|
response: str = prompt(
|
170
|
-
"> ",
|
168
|
+
f"{question}\n> ",
|
171
169
|
completer=completer,
|
172
170
|
validator=OptionValidator(),
|
173
171
|
complete_while_typing=True,
|
174
172
|
).strip()
|
175
173
|
comparison_response: str = response if case_sensitive else response.lower()
|
176
174
|
if not response:
|
177
|
-
console.
|
175
|
+
console.print("Please enter a valid option or 'exit'.", style="red")
|
178
176
|
continue
|
179
177
|
if comparison_response == comparison_exit:
|
180
178
|
return None
|
@@ -184,5 +182,5 @@ def restricted_prompt(
|
|
184
182
|
return valid_options[idx]
|
185
183
|
return response
|
186
184
|
except KeyboardInterrupt:
|
187
|
-
console.
|
185
|
+
console.print("KeyboardInterrupt: Exiting the prompt.", style="yellow")
|
188
186
|
return None
|
@@ -41,7 +41,7 @@ class TyperBridge(SingletonBase):
|
|
41
41
|
self.console: AsyncLoggerProtocol | LoggerProtocol | Console = console or Console()
|
42
42
|
self.command_meta: dict[str, CommandMeta] = {}
|
43
43
|
|
44
|
-
def
|
44
|
+
def alias(self, *alias_names: str) -> Callable[..., Callable[..., Any]]:
|
45
45
|
"""Register aliases as hidden Typer commands."""
|
46
46
|
|
47
47
|
def decorator(func: Callable[..., Any]) -> Callable[..., Any]:
|
{bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/extras/responses/function_response.py
RENAMED
@@ -41,12 +41,24 @@ class FunctionResponse(BaseModel):
|
|
41
41
|
"arbitrary_types_allowed": True,
|
42
42
|
}
|
43
43
|
|
44
|
+
def _has_attr(self, key: str) -> bool:
|
45
|
+
"""Check if the attribute exists in the attrs Namespace."""
|
46
|
+
return hasattr(self.attrs, key)
|
47
|
+
|
48
|
+
def _get_attr(self, key: str, default: Any = None) -> Any:
|
49
|
+
"""Get the attribute from the attrs Namespace, returning default if not found."""
|
50
|
+
if self._has_attr(key):
|
51
|
+
return getattr(self.attrs, key, default)
|
52
|
+
return default
|
53
|
+
|
54
|
+
def _get_attrs(self) -> dict[str, Any]:
|
55
|
+
"""Get all attributes from the attrs Namespace as a dictionary."""
|
56
|
+
return {k: getattr(self.attrs, k, None) for k in self.attrs.__dict__ if not k.startswith("_")}
|
57
|
+
|
44
58
|
def __getattr__(self, key: str, default: Any = None) -> Any:
|
45
59
|
if key in FunctionResponse.model_fields:
|
46
60
|
raise AttributeError(f"This should never be called, {key} is a model field.")
|
47
|
-
|
48
|
-
return getattr(self.attrs, key)
|
49
|
-
return default
|
61
|
+
return self._get_attr(key, default)
|
50
62
|
|
51
63
|
def __setattr__(self, key: str, value: Any) -> None:
|
52
64
|
if key in FunctionResponse.model_fields:
|
@@ -58,19 +70,23 @@ class FunctionResponse(BaseModel):
|
|
58
70
|
"""Return a string representation of Response."""
|
59
71
|
parts: list[str] = []
|
60
72
|
|
61
|
-
def add(k: str, v: Any, _bool: bool = True,
|
73
|
+
def add(k: str, v: Any, _bool: bool = True, fmt_func: Callable | None = None) -> None:
|
62
74
|
if _bool:
|
63
|
-
formatted_value: str =
|
75
|
+
formatted_value: str = fmt_func(v) if fmt_func else repr(v)
|
64
76
|
parts.append(f"{k}={formatted_value}")
|
65
77
|
|
66
78
|
add("name", self.name, bool(self.name))
|
67
|
-
add("returncode", self.returncode, self.returncode != 0)
|
68
|
-
add("success", self.success, bool(self.returncode))
|
69
79
|
add("content", ", ".join(self.content), bool(self.content))
|
70
|
-
add("error", ", ".join(self.error), bool(self.error))
|
71
|
-
add("extra", self.extra, bool(self.extra), json.dumps)
|
72
|
-
add("number_of_tasks", self.number_of_tasks, self.number_of_tasks > 0)
|
73
80
|
|
81
|
+
# error state depends on returncode or error
|
82
|
+
add("error", ", ".join(self.error), self.error_state)
|
83
|
+
add("success", self.success, _bool=True)
|
84
|
+
add("returncode", self.returncode, self.error_state)
|
85
|
+
add("number_of_tasks", self.number_of_tasks, self.error_state)
|
86
|
+
add("extra", self.extra, bool(self.extra), json.dumps)
|
87
|
+
attrs = self._get_attrs()
|
88
|
+
for attr in attrs:
|
89
|
+
add(attr, attrs[attr])
|
74
90
|
return f"Response({', '.join(parts)})"
|
75
91
|
|
76
92
|
def __str__(self) -> str:
|
@@ -139,28 +155,19 @@ class FunctionResponse(BaseModel):
|
|
139
155
|
content: str = process.stdout.strip() if process.stdout else ""
|
140
156
|
error: str = process.stderr.strip() if process.stderr else ""
|
141
157
|
|
142
|
-
if returncode == 0 and not content and error:
|
158
|
+
if returncode == 0 and not content and error: # Some processes return empty stdout on success
|
143
159
|
error, content = content, error
|
144
|
-
|
145
160
|
return cls().add(returncode=returncode, content=content, error=error, **kwargs)
|
146
161
|
|
147
|
-
|
148
|
-
|
149
|
-
if
|
150
|
-
|
151
|
-
self.sub_tasks.append(response)
|
152
|
-
return self.add(
|
153
|
-
content=response.content,
|
154
|
-
error=response.error,
|
155
|
-
returncode=response.returncode,
|
156
|
-
log_output=kwargs.pop("log_output", False),
|
157
|
-
**kwargs,
|
158
|
-
)
|
162
|
+
@property
|
163
|
+
def error_state(self) -> bool:
|
164
|
+
"""Check if the returncode or error field indicates an error state."""
|
165
|
+
return self.returncode != 0 or bool(self.error)
|
159
166
|
|
160
167
|
@property
|
161
168
|
def success(self) -> bool:
|
162
169
|
"""Check if the response indicates success."""
|
163
|
-
return self.returncode == 0
|
170
|
+
return self.returncode == 0 and not bool(self.error)
|
164
171
|
|
165
172
|
def sub_task(
|
166
173
|
self,
|
@@ -185,13 +192,15 @@ class FunctionResponse(BaseModel):
|
|
185
192
|
|
186
193
|
def successful(
|
187
194
|
self,
|
188
|
-
content: str | list[str] | CompletedProcess,
|
195
|
+
content: str | list[str] | CompletedProcess | FunctionResponse,
|
189
196
|
error: str | list[str] = "",
|
190
197
|
returncode: int | None = None,
|
198
|
+
log_output: bool = False,
|
191
199
|
**kwargs,
|
192
200
|
) -> Self:
|
193
201
|
"""Set the response to a success state with optional content."""
|
194
|
-
|
202
|
+
return_code: int = returncode if returncode is not None else 0
|
203
|
+
self.add(content=content, error=error, returncode=return_code, log_output=log_output, **kwargs)
|
195
204
|
return self
|
196
205
|
|
197
206
|
def fail(
|
@@ -199,16 +208,17 @@ class FunctionResponse(BaseModel):
|
|
199
208
|
content: list[str] | str | CompletedProcess = "",
|
200
209
|
error: str | list[str] = "",
|
201
210
|
returncode: int | None = None,
|
211
|
+
log_output: bool = False,
|
202
212
|
**kwargs,
|
203
213
|
) -> Self:
|
204
214
|
"""Set the response to a failure state with an error message."""
|
205
|
-
|
215
|
+
return_code: int = returncode if returncode is not None else 1
|
216
|
+
self.add(content=content, error=error, returncode=return_code, log_output=log_output, **kwargs)
|
206
217
|
return self
|
207
218
|
|
208
219
|
def _add_item(self, item: str, target_list: list[str]) -> None:
|
209
220
|
"""Append an item to the target list if not empty."""
|
210
|
-
if item != ""
|
211
|
-
target_list.append(item)
|
221
|
+
target_list.append(item) if item != "" else None
|
212
222
|
|
213
223
|
def _add_to_list(self, items: str | list[str], target_list: list[str], name: str | None = None) -> None:
|
214
224
|
"""Append items to the target list with optional name prefix."""
|
@@ -222,24 +232,24 @@ class FunctionResponse(BaseModel):
|
|
222
232
|
raise ValueError(f"Failed to add items: {e!s}") from e
|
223
233
|
|
224
234
|
def _add_content(self, content: str | list[str], name: str | None = None) -> None:
|
225
|
-
"""
|
226
|
-
self._add_to_list(content, self.content, name)
|
235
|
+
"""Add content to the FunctionResponse content list."""
|
236
|
+
return self._add_to_list(items=content, target_list=self.content, name=name)
|
227
237
|
|
228
238
|
def _add_error(self, error: str | list[str], name: str | None = None) -> None:
|
229
|
-
"""
|
230
|
-
self._add_to_list(error, self.error, name)
|
239
|
+
"""Add error messages to the FunctionResponse error list."""
|
240
|
+
return self._add_to_list(items=error, target_list=self.error, name=name)
|
231
241
|
|
232
242
|
def _handle_function_response(self, func_response: FunctionResponse) -> None:
|
233
243
|
"""Handle a FunctionResponse object and update the current response."""
|
234
244
|
if func_response.extra:
|
235
245
|
self.extra.update(func_response.extra)
|
236
|
-
self.
|
237
|
-
self.
|
246
|
+
self._add_content(func_response.content, name=func_response.name)
|
247
|
+
self._add_error(func_response.error, name=func_response.name)
|
238
248
|
|
239
249
|
def _handle_completed_process(self, result: CompletedProcess[str]) -> None:
|
240
250
|
"""Handle a CompletedProcess object and update the FunctionResponse."""
|
241
|
-
self._add_content(
|
242
|
-
self._add_error(
|
251
|
+
self._add_content(result.stdout.strip())
|
252
|
+
self._add_error(result.stderr.strip())
|
243
253
|
self.returncode = result.returncode
|
244
254
|
|
245
255
|
def _handle_content(self, content: list[str] | str | FunctionResponse | CompletedProcess | Any) -> None:
|
@@ -249,7 +259,7 @@ class FunctionResponse(BaseModel):
|
|
249
259
|
elif isinstance(content, CompletedProcess):
|
250
260
|
self._handle_completed_process(result=content)
|
251
261
|
elif isinstance(content, (str | list)):
|
252
|
-
self.
|
262
|
+
self._add_to_list(content, self.content)
|
253
263
|
else:
|
254
264
|
return
|
255
265
|
self.number_of_tasks += 1
|
@@ -293,7 +303,7 @@ class FunctionResponse(BaseModel):
|
|
293
303
|
if content is not None:
|
294
304
|
self._handle_content(content=content)
|
295
305
|
if error is not None and isinstance(error, (str | list)):
|
296
|
-
self.
|
306
|
+
self._add_to_list(error, target_list=self.error)
|
297
307
|
if isinstance(returncode, int):
|
298
308
|
self.returncode = returncode
|
299
309
|
if isinstance(extra, dict):
|
@@ -302,9 +312,7 @@ class FunctionResponse(BaseModel):
|
|
302
312
|
self._log_handling(content=content, error=error, logger=self.logger)
|
303
313
|
except Exception as e:
|
304
314
|
raise ValueError(f"Failed to add content: {e!s}") from e
|
305
|
-
if to_dict
|
306
|
-
return self.done(to_dict=True)
|
307
|
-
return self
|
315
|
+
return self.done(to_dict=True) if to_dict else self
|
308
316
|
|
309
317
|
def _log_handling(
|
310
318
|
self,
|
@@ -350,17 +358,34 @@ class FunctionResponse(BaseModel):
|
|
350
358
|
res.conditional_run()
|
351
359
|
|
352
360
|
@overload
|
353
|
-
def done(
|
361
|
+
def done(
|
362
|
+
self,
|
363
|
+
to_dict: Literal[True],
|
364
|
+
suppress: list[str] | None = None,
|
365
|
+
include: list[str] | None = None,
|
366
|
+
) -> dict[str, Any]: ...
|
354
367
|
|
355
368
|
@overload
|
356
|
-
def done(
|
369
|
+
def done(
|
370
|
+
self,
|
371
|
+
to_dict: Literal[False],
|
372
|
+
suppress: list[str] | None = None,
|
373
|
+
include: list[str] | None = None,
|
374
|
+
) -> Self: ...
|
357
375
|
|
358
|
-
def done(
|
376
|
+
def done(
|
377
|
+
self,
|
378
|
+
to_dict: bool = False,
|
379
|
+
suppress: list[str] | None = None,
|
380
|
+
include: list[str] | None = None,
|
381
|
+
) -> dict[str, Any] | Self:
|
359
382
|
"""Convert the FunctionResponse to a dictionary or return the instance itself.
|
360
383
|
|
361
384
|
Args:
|
362
385
|
to_dict (bool): If True, return a dictionary representation.
|
363
386
|
If False, return the FunctionResponse instance.
|
387
|
+
suppress (list[str] | None): List of keys to suppress in the output dictionary.
|
388
|
+
include (list[str] | None): List of keys to include in the output dictionary.
|
364
389
|
|
365
390
|
Returns:
|
366
391
|
dict[str, Any] | Self: The dictionary representation or the FunctionResponse instance.
|
@@ -371,36 +396,60 @@ class FunctionResponse(BaseModel):
|
|
371
396
|
if suppress is None:
|
372
397
|
suppress = []
|
373
398
|
|
399
|
+
if include is None:
|
400
|
+
include = []
|
401
|
+
|
374
402
|
result: dict[str, Any] = {}
|
375
403
|
|
376
404
|
def add(k: str, v: Any, _bool: bool = True) -> None:
|
377
405
|
if k not in suppress and _bool:
|
378
406
|
result[k] = v
|
379
407
|
|
408
|
+
def dict_include(_bool: bool = True) -> dict[str, Any]:
|
409
|
+
result.update(self.extra)
|
410
|
+
for k in include:
|
411
|
+
if hasattr(self.attrs, k) and _bool:
|
412
|
+
result[k] = getattr(self.attrs, k)
|
413
|
+
return result
|
414
|
+
|
380
415
|
add("name", self.name, bool(self.name))
|
381
|
-
add("success", self.success)
|
382
|
-
add("returncode", self.returncode, self.returncode > 0)
|
383
|
-
add("number_of_tasks", self.number_of_tasks, (self.number_of_tasks > 0 and not self.success))
|
384
416
|
add("content", self.content, bool(self.content))
|
385
|
-
add("
|
386
|
-
|
387
|
-
|
417
|
+
add("success", self.success, _bool=True)
|
418
|
+
# depends on the error state
|
419
|
+
add("error", self.error, self.error_state)
|
420
|
+
add("returncode", self.returncode, self.error_state)
|
421
|
+
add("number_of_tasks", self.number_of_tasks, self.error_state)
|
422
|
+
|
423
|
+
return dict_include()
|
388
424
|
|
389
425
|
|
390
426
|
def success(
|
391
427
|
content: str | list[str] | CompletedProcess[str] | FunctionResponse,
|
392
428
|
error: str = "",
|
429
|
+
log_output: bool = False,
|
393
430
|
**kwargs,
|
394
431
|
) -> FunctionResponse:
|
395
432
|
"""Create a successful FunctionResponse."""
|
396
|
-
|
433
|
+
res = FunctionResponse()
|
434
|
+
return res.successful(content, error, 0, log_output, **kwargs)
|
397
435
|
|
398
436
|
|
399
437
|
def fail(
|
400
438
|
content: str | list[str] | CompletedProcess[str] = "",
|
401
439
|
error: str | list[str] = "",
|
402
440
|
returncode: int | None = None,
|
441
|
+
log_output: bool = False,
|
403
442
|
**kwargs,
|
404
443
|
) -> FunctionResponse:
|
405
444
|
"""Create a failed FunctionResponse."""
|
406
|
-
|
445
|
+
res = FunctionResponse()
|
446
|
+
return res.fail(content, error, returncode, log_output, **kwargs)
|
447
|
+
|
448
|
+
|
449
|
+
if __name__ == "__main__":
|
450
|
+
# For testing purposes, you can run this module directly.
|
451
|
+
|
452
|
+
response = FunctionResponse(name="test_function")
|
453
|
+
response.add(content=["This is a test content."], error=["No errors."], returncode=1, extra={"smelly": "value"})
|
454
|
+
response.poop = "farts"
|
455
|
+
print(response.done(to_dict=True))
|
@@ -0,0 +1,46 @@
|
|
1
|
+
"""A Simple wrapper around StringIO to make things easier."""
|
2
|
+
|
3
|
+
from io import BytesIO, StringIO
|
4
|
+
from typing import Any, cast
|
5
|
+
|
6
|
+
|
7
|
+
class BaseIOWrapper[T: StringIO | BytesIO]:
|
8
|
+
"""A Base wrapper around IO objects to make things easier."""
|
9
|
+
|
10
|
+
def __init__(self, io_obj: T | Any) -> None:
|
11
|
+
"""Initialize the IOWrapper with a IO Object object."""
|
12
|
+
if not isinstance(io_obj, (StringIO | BytesIO)):
|
13
|
+
raise TypeError("io_obj must be an instance of StringIO or BytesIO")
|
14
|
+
self._value: T = cast("T", io_obj)
|
15
|
+
self._cached_value = None
|
16
|
+
|
17
|
+
def _reset_io(self) -> None:
|
18
|
+
"""Reset the current a IO Object."""
|
19
|
+
self._value.truncate(0)
|
20
|
+
self._value.seek(0)
|
21
|
+
self._cached_value = None
|
22
|
+
|
23
|
+
|
24
|
+
class StringIOWrapper(BaseIOWrapper[StringIO]):
|
25
|
+
"""A Simple wrapper around StringIO to make things easier."""
|
26
|
+
|
27
|
+
def __init__(self, **kwargs) -> None:
|
28
|
+
"""Initialize the IOWrapper with a a IO Object object."""
|
29
|
+
super().__init__(StringIO(**kwargs))
|
30
|
+
self._cached_value: str = ""
|
31
|
+
|
32
|
+
def _reset_io(self) -> None:
|
33
|
+
"""Reset the current a IO Object."""
|
34
|
+
self._value.truncate(0)
|
35
|
+
self._value.seek(0)
|
36
|
+
self._cached_value = ""
|
37
|
+
|
38
|
+
def write(self, *values: str) -> None:
|
39
|
+
"""Write values to the a IO Object object."""
|
40
|
+
for value in values:
|
41
|
+
self._value.write(value)
|
42
|
+
|
43
|
+
def getvalue(self) -> str:
|
44
|
+
"""Get the string value from the a IO Object object."""
|
45
|
+
self._cached_value = self._value.getvalue()
|
46
|
+
return self._cached_value
|
@@ -507,16 +507,6 @@ class TestDoneMethod:
|
|
507
507
|
assert "name" not in result
|
508
508
|
assert "success" not in result
|
509
509
|
|
510
|
-
def test_done_with_suppress_failure(self):
|
511
|
-
"""Test done() with FAILURE suppress list."""
|
512
|
-
response = FunctionResponse(name="test", content=["output"], returncode=1)
|
513
|
-
result = response.done(to_dict=True, suppress=FAILURE)
|
514
|
-
|
515
|
-
expected = {"success": False, "returncode": 1, "content": ["output"]}
|
516
|
-
|
517
|
-
assert result == expected
|
518
|
-
assert "name" not in result
|
519
|
-
|
520
510
|
def test_done_with_custom_suppress(self):
|
521
511
|
"""Test done() with custom suppress list."""
|
522
512
|
response = FunctionResponse(name="test", content=["output"], number_of_tasks=5)
|
@@ -565,7 +555,7 @@ class TestStringRepresentation:
|
|
565
555
|
"""Test repr with minimal data."""
|
566
556
|
response = FunctionResponse()
|
567
557
|
result = repr(response)
|
568
|
-
assert
|
558
|
+
assert "Response(" in result
|
569
559
|
|
570
560
|
def test_repr_full(self):
|
571
561
|
"""Test repr with all fields populated."""
|
@@ -637,7 +627,6 @@ class TestComplexScenarios:
|
|
637
627
|
|
638
628
|
result = response.done(to_dict=True)
|
639
629
|
|
640
|
-
# SUCCESS suppresses "name" and "success", so check what actually remains
|
641
630
|
assert "content" in result
|
642
631
|
assert "number_of_tasks" not in result # This will only be here in failures
|
643
632
|
assert "name" in result
|
@@ -21,17 +21,6 @@ def test_gradients_visual():
|
|
21
21
|
health_bar = "█" * (health // 5)
|
22
22
|
console.print(f"HP: {health:3d}/100 {health_bar:<20}", style=color.rgb)
|
23
23
|
|
24
|
-
console.print("\n" + "=" * 50 + "\n")
|
25
|
-
|
26
|
-
# Reversed: Infection/Damage meter (Green = good, Red = bad)
|
27
|
-
console.print("[bold red]Infection Level (0% = Healthy, 100% = Critical):[/bold red]")
|
28
|
-
health_gradient.reverse = True
|
29
|
-
for infection in range(0, 101, 10):
|
30
|
-
color: ColorTriplet = health_gradient.map_to_color(0, 100, infection)
|
31
|
-
infection_bar = "█" * (infection // 5)
|
32
|
-
status = "🦠" if infection > 70 else "⚠️" if infection > 30 else "✅"
|
33
|
-
console.print(f"Infection: {infection:3d}% {infection_bar:<20} {status}", style=color.rgb)
|
34
|
-
|
35
24
|
health_scenarios = [
|
36
25
|
(5, "💀 Nearly Dead"),
|
37
26
|
(25, "🩸 Critical Condition"),
|
@@ -45,3 +34,27 @@ def test_gradients_visual():
|
|
45
34
|
for hp, status in health_scenarios:
|
46
35
|
color: ColorTriplet = health_gradient.map_to_color(0, 100, hp)
|
47
36
|
console.print(f"{status}: {hp}/100 HP", style=color.rgb)
|
37
|
+
|
38
|
+
console.print("\n" + "=" * 50 + "\n")
|
39
|
+
|
40
|
+
# Reversed: Infection/Damage meter (Green = good, Red = bad)
|
41
|
+
console.print("[bold red]Infection Level (0% = Healthy, 100% = Critical):[/bold red]")
|
42
|
+
health_gradient.reverse = True
|
43
|
+
for infection in range(0, 101, 10):
|
44
|
+
color: ColorTriplet = health_gradient.map_to_color(0, 100, infection)
|
45
|
+
infection_bar = "█" * (infection // 5)
|
46
|
+
status = "🦠" if infection > 70 else "⚠️" if infection > 30 else "✅"
|
47
|
+
console.print(f"Infection: {infection:3d}% {infection_bar:<20} {status}", style=color.rgb)
|
48
|
+
|
49
|
+
infected_scenarios = [
|
50
|
+
(5, "✅ Healthy"),
|
51
|
+
(25, "⚠️ Mild Infection"),
|
52
|
+
(50, "🦠 Moderate Infection"),
|
53
|
+
(75, "🦠 Severe Infection"),
|
54
|
+
(100, "💀 Critical Condition"),
|
55
|
+
]
|
56
|
+
|
57
|
+
console.print("[bold red]Infection Status Examples:[/bold red]")
|
58
|
+
for ip, status in infected_scenarios:
|
59
|
+
color: ColorTriplet = health_gradient.map_to_color(0, 100, ip)
|
60
|
+
console.print(f"{status}: {ip}/100 Infection", style=color.rgb)
|
@@ -111,7 +111,7 @@ class TestAskQuestion:
|
|
111
111
|
|
112
112
|
assert result == "hello world"
|
113
113
|
mock_console.print.assert_called_with("Enter text: ")
|
114
|
-
|
114
|
+
mock_console.verbose.assert_called_with("str detected")
|
115
115
|
|
116
116
|
@patch("bear_utils.cli.prompt_helpers.prompt")
|
117
117
|
@patch("bear_utils.cli.prompt_helpers.get_console")
|
@@ -126,7 +126,7 @@ class TestAskQuestion:
|
|
126
126
|
|
127
127
|
assert result == 42
|
128
128
|
assert isinstance(result, int)
|
129
|
-
|
129
|
+
mock_console.verbose.assert_called_with("int detected")
|
130
130
|
|
131
131
|
@patch("bear_utils.cli.prompt_helpers.prompt")
|
132
132
|
@patch("bear_utils.cli.prompt_helpers.get_console")
|
@@ -140,7 +140,7 @@ class TestAskQuestion:
|
|
140
140
|
result = ask_question("Continue? ", bool)
|
141
141
|
|
142
142
|
assert result is True
|
143
|
-
|
143
|
+
mock_console.verbose.assert_called_with("bool detected")
|
144
144
|
|
145
145
|
@patch("bear_utils.cli.prompt_helpers.prompt")
|
146
146
|
@patch("bear_utils.cli.prompt_helpers.get_console")
|
@@ -168,7 +168,7 @@ class TestAskQuestion:
|
|
168
168
|
|
169
169
|
assert result == 42
|
170
170
|
# Should have shown error for invalid input
|
171
|
-
|
171
|
+
mock_console.error.assert_called_with(
|
172
172
|
"Invalid input: invalid literal for int() with base 10: 'not_a_number'. Please enter a valid int."
|
173
173
|
)
|
174
174
|
|
@@ -257,7 +257,7 @@ class TestAskYesNo:
|
|
257
257
|
result = ask_yes_no("Continue? ")
|
258
258
|
|
259
259
|
assert result is True
|
260
|
-
|
260
|
+
mock_console.print.assert_called_with("Invalid input. Please enter 'yes', 'no', or 'exit'.", style="red")
|
261
261
|
|
262
262
|
@patch("bear_utils.cli.prompt_helpers.prompt")
|
263
263
|
@patch("bear_utils.cli.prompt_helpers.get_console")
|
@@ -271,7 +271,7 @@ class TestAskYesNo:
|
|
271
271
|
result = ask_yes_no("Continue? ")
|
272
272
|
|
273
273
|
assert result is None
|
274
|
-
|
274
|
+
mock_console.print.assert_called_with("KeyboardInterrupt: Exiting the prompt.", style="yellow")
|
275
275
|
|
276
276
|
|
277
277
|
class TestRestrictedPrompt:
|
@@ -354,7 +354,7 @@ class TestRestrictedPrompt:
|
|
354
354
|
result = restricted_prompt("Choose: ", ["option1", "option2"])
|
355
355
|
|
356
356
|
assert result == "option1"
|
357
|
-
|
357
|
+
mock_console.print.assert_called_with("Please enter a valid option or 'exit'.", style="red")
|
358
358
|
|
359
359
|
@patch("bear_utils.cli.prompt_helpers.prompt")
|
360
360
|
@patch("bear_utils.cli.prompt_helpers.get_console")
|
@@ -368,7 +368,7 @@ class TestRestrictedPrompt:
|
|
368
368
|
result = restricted_prompt("Choose: ", ["option1", "option2"])
|
369
369
|
|
370
370
|
assert result is None
|
371
|
-
|
371
|
+
mock_console.print.assert_called_with("KeyboardInterrupt: Exiting the prompt.", style="yellow")
|
372
372
|
|
373
373
|
|
374
374
|
class TestPromptHelpersIntegration:
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -13,8 +13,8 @@ import subprocess
|
|
13
13
|
from subprocess import CompletedProcess
|
14
14
|
from typing import Self, override
|
15
15
|
|
16
|
-
from bear_utils.logger_manager.logger_protocol import LoggerProtocol
|
17
16
|
from bear_utils.logger_manager import VERBOSE, BaseLogger, SubConsoleLogger
|
17
|
+
from bear_utils.logger_manager.logger_protocol import LoggerProtocol
|
18
18
|
|
19
19
|
from ._base_command import BaseShellCommand
|
20
20
|
from ._common import DEFAULT_SHELL
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/files/file_handlers/_base_file_handler.py
RENAMED
File without changes
|
{bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/files/file_handlers/file_handler_factory.py
RENAMED
File without changes
|
{bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/files/file_handlers/json_file_handler.py
RENAMED
File without changes
|
{bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/files/file_handlers/log_file_handler.py
RENAMED
File without changes
|
{bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/files/file_handlers/toml_file_handler.py
RENAMED
File without changes
|
{bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/files/file_handlers/txt_file_handler.py
RENAMED
File without changes
|
{bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/files/file_handlers/yaml_file_handler.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/logger_manager/loggers/base_logger.py
RENAMED
File without changes
|
{bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/logger_manager/loggers/base_logger.pyi
RENAMED
File without changes
|
File without changes
|
{bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/logger_manager/loggers/basic_logger/logger.py
RENAMED
File without changes
|
File without changes
|
{bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/logger_manager/loggers/buffer_logger.py
RENAMED
File without changes
|
{bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/logger_manager/loggers/console_logger.py
RENAMED
File without changes
|
{bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/logger_manager/loggers/console_logger.pyi
RENAMED
File without changes
|
{bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/logger_manager/loggers/fastapi_logger.py
RENAMED
File without changes
|
{bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/logger_manager/loggers/file_logger.py
RENAMED
File without changes
|
{bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/logger_manager/loggers/simple_logger.py
RENAMED
File without changes
|
File without changes
|
{bear_utils-0.8.24 → bear_utils-0.8.25}/src/bear_utils/logger_manager/loggers/sub_logger.pyi
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|