bear-utils 0.9.8__tar.gz → 0.9.9__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.
Files changed (131) hide show
  1. {bear_utils-0.9.8 → bear_utils-0.9.9}/PKG-INFO +1 -1
  2. bear_utils-0.9.9/src/bear_utils/_internal/_version.py +1 -0
  3. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/events/events_class.py +14 -3
  4. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/events/events_module.py +8 -7
  5. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/extras/_async_helpers.py +40 -12
  6. bear_utils-0.9.8/src/bear_utils/_internal/_version.py +0 -1
  7. {bear_utils-0.9.8 → bear_utils-0.9.9}/.gitignore +0 -0
  8. {bear_utils-0.9.8 → bear_utils-0.9.9}/.python-version +0 -0
  9. {bear_utils-0.9.8 → bear_utils-0.9.9}/AGENTS.md +0 -0
  10. {bear_utils-0.9.8 → bear_utils-0.9.9}/README.md +0 -0
  11. {bear_utils-0.9.8 → bear_utils-0.9.9}/config/coverage.ini +0 -0
  12. {bear_utils-0.9.8 → bear_utils-0.9.9}/config/default.toml +0 -0
  13. {bear_utils-0.9.8 → bear_utils-0.9.9}/config/git-changelog.toml +0 -0
  14. {bear_utils-0.9.8 → bear_utils-0.9.9}/config/pytest.ini +0 -0
  15. {bear_utils-0.9.8 → bear_utils-0.9.9}/config/ruff.toml +0 -0
  16. {bear_utils-0.9.8 → bear_utils-0.9.9}/directory_structure.txt +0 -0
  17. {bear_utils-0.9.8 → bear_utils-0.9.9}/directory_structure.xml +0 -0
  18. {bear_utils-0.9.8 → bear_utils-0.9.9}/maskfile.md +0 -0
  19. {bear_utils-0.9.8 → bear_utils-0.9.9}/noxfile.py +0 -0
  20. {bear_utils-0.9.8 → bear_utils-0.9.9}/pyproject.toml +0 -0
  21. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/__init__.py +0 -0
  22. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/__main__.py +0 -0
  23. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/_internal/__init__.py +0 -0
  24. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/_internal/cli.py +0 -0
  25. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/_internal/debug.py +0 -0
  26. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/ai/__init__.py +0 -0
  27. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/ai/ai_helpers/__init__.py +0 -0
  28. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/ai/ai_helpers/_common.py +0 -0
  29. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/ai/ai_helpers/_config.py +0 -0
  30. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/ai/ai_helpers/_parsers.py +0 -0
  31. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/ai/ai_helpers/_types.py +0 -0
  32. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/cache/__init__.py +0 -0
  33. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/cli/__init__.py +0 -0
  34. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/cli/_args.py +0 -0
  35. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/cli/_get_version.py +0 -0
  36. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/cli/commands.py +0 -0
  37. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/cli/prompt_helpers.py +0 -0
  38. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/cli/shell/__init__.py +0 -0
  39. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/cli/shell/_base_command.py +0 -0
  40. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/cli/shell/_base_shell.py +0 -0
  41. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/cli/shell/_common.py +0 -0
  42. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/cli/typer_bridge.py +0 -0
  43. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/config/__init__.py +0 -0
  44. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/config/config_manager.py +0 -0
  45. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/config/dir_manager.py +0 -0
  46. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/config/settings_manager.py +0 -0
  47. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/constants/__init__.py +0 -0
  48. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/constants/_exceptions.py +0 -0
  49. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/constants/_exit_code.py +0 -0
  50. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/constants/_http_status_code.py +0 -0
  51. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/constants/_lazy_typing.py +0 -0
  52. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/constants/_meta.py +0 -0
  53. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/constants/date_related.py +0 -0
  54. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/constants/time_related.py +0 -0
  55. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/database/__init__.py +0 -0
  56. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/database/_db_manager.py +0 -0
  57. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/events/__init__.py +0 -0
  58. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/extras/__init__.py +0 -0
  59. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/extras/_tools.py +0 -0
  60. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/extras/_zapper.py +0 -0
  61. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/extras/platform_utils.py +0 -0
  62. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/extras/responses/__init__.py +0 -0
  63. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/extras/responses/function_response.py +0 -0
  64. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/extras/wrappers/__init__.py +0 -0
  65. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/extras/wrappers/add_methods.py +0 -0
  66. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/extras/wrappers/string_io.py +0 -0
  67. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/files/__init__.py +0 -0
  68. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/files/file_handlers/__init__.py +0 -0
  69. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/files/file_handlers/_base_file_handler.py +0 -0
  70. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/files/file_handlers/file_handler_factory.py +0 -0
  71. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/files/file_handlers/json_file_handler.py +0 -0
  72. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/files/file_handlers/log_file_handler.py +0 -0
  73. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/files/file_handlers/toml_file_handler.py +0 -0
  74. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/files/file_handlers/txt_file_handler.py +0 -0
  75. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/files/file_handlers/yaml_file_handler.py +0 -0
  76. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/files/ignore_parser.py +0 -0
  77. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/graphics/__init__.py +0 -0
  78. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/graphics/bear_gradient.py +0 -0
  79. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/graphics/font/__init__.py +0 -0
  80. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/graphics/font/_raw_block_letters.py +0 -0
  81. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/graphics/font/_theme.py +0 -0
  82. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/graphics/font/_utils.py +0 -0
  83. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/graphics/font/block_font.py +0 -0
  84. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/graphics/font/glitch_font.py +0 -0
  85. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/graphics/image_helpers.py +0 -0
  86. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/gui/__init__.py +0 -0
  87. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/gui/gui_tools/__init__.py +0 -0
  88. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/gui/gui_tools/_settings.py +0 -0
  89. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/gui/gui_tools/_types.py +0 -0
  90. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/gui/gui_tools/qt_app.py +0 -0
  91. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/gui/gui_tools/qt_color_picker.py +0 -0
  92. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/gui/gui_tools/qt_file_handler.py +0 -0
  93. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/gui/gui_tools/qt_input_dialog.py +0 -0
  94. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/logger_manager/__init__.py +0 -0
  95. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/logger_manager/_common.py +0 -0
  96. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/logger_manager/_log_level.py +0 -0
  97. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/logger_manager/_logger_misc.py +0 -0
  98. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/logger_manager/_styles.py +0 -0
  99. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/logger_manager/logger_protocol.py +0 -0
  100. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/logger_manager/loggers/__init__.py +0 -0
  101. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/logger_manager/loggers/_console.py +0 -0
  102. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/logger_manager/loggers/_level_sin.py +0 -0
  103. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/logger_manager/loggers/_logger.py +0 -0
  104. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/logger_manager/loggers/base_logger.py +0 -0
  105. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/logger_manager/loggers/base_logger.pyi +0 -0
  106. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/logger_manager/loggers/basic_logger/__init__.py +0 -0
  107. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/logger_manager/loggers/basic_logger/logger.py +0 -0
  108. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/logger_manager/loggers/basic_logger/logger.pyi +0 -0
  109. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/logger_manager/loggers/buffer_logger.py +0 -0
  110. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/logger_manager/loggers/console_logger.py +0 -0
  111. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/logger_manager/loggers/console_logger.pyi +0 -0
  112. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/logger_manager/loggers/fastapi_logger.py +0 -0
  113. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/logger_manager/loggers/file_logger.py +0 -0
  114. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/logger_manager/loggers/simple_logger.py +0 -0
  115. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/logger_manager/loggers/sub_logger.py +0 -0
  116. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/logger_manager/loggers/sub_logger.pyi +0 -0
  117. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/monitoring/__init__.py +0 -0
  118. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/monitoring/_common.py +0 -0
  119. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/monitoring/host_monitor.py +0 -0
  120. {bear_utils-0.9.8 → bear_utils-0.9.9}/src/bear_utils/time/__init__.py +0 -0
  121. {bear_utils-0.9.8 → bear_utils-0.9.9}/tests/__init__.py +0 -0
  122. {bear_utils-0.9.8 → bear_utils-0.9.9}/tests/test_add_ord_suffix.py +0 -0
  123. {bear_utils-0.9.8 → bear_utils-0.9.9}/tests/test_clipboard.py +0 -0
  124. {bear_utils-0.9.8 → bear_utils-0.9.9}/tests/test_database_manager.py +0 -0
  125. {bear_utils-0.9.8 → bear_utils-0.9.9}/tests/test_default_shell.py +0 -0
  126. {bear_utils-0.9.8 → bear_utils-0.9.9}/tests/test_font_utils.py +0 -0
  127. {bear_utils-0.9.8 → bear_utils-0.9.9}/tests/test_function_response.py +0 -0
  128. {bear_utils-0.9.8 → bear_utils-0.9.9}/tests/test_gradient.py +0 -0
  129. {bear_utils-0.9.8 → bear_utils-0.9.9}/tests/test_logger.py +0 -0
  130. {bear_utils-0.9.8 → bear_utils-0.9.9}/tests/test_platform_utils.py +0 -0
  131. {bear_utils-0.9.8 → bear_utils-0.9.9}/tests/test_prompt_helpers.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: bear-utils
3
- Version: 0.9.8
3
+ Version: 0.9.9
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
@@ -0,0 +1 @@
1
+ __version__ = "0.9.9"
@@ -15,14 +15,25 @@ Callback = Callable[..., Any]
15
15
 
16
16
 
17
17
  class Events:
18
- """Simple wrapper exposing :mod:`events_module` functionality as methods."""
18
+ """Simple wrapper exposing :mod:`events_module` functionality as methods.
19
19
 
20
- # Method names mirror functions from ``events_module`` for familiarity
20
+ Method names mirror functions from ``events_module`` for familiarity
21
+ """
21
22
 
22
- def event_handler(self, event_name: str, func: Callback | None = None):
23
+ def event_handler(
24
+ self, event_name: str, func: Callback | None = None
25
+ ) -> Callable[[Callable[..., Any]], Callable[..., Any]] | Callable[..., Any]:
23
26
  """Register ``func`` as a handler for ``event_name``.
24
27
 
25
28
  Can be used as a decorator when ``func`` is omitted.
29
+
30
+ Args:
31
+ event_name (str): The name of the event to handle.
32
+ func (Callable, optional): The function to register as a handler. If omitted, returns
33
+ a decorator that can be used to register a handler function.
34
+
35
+ Returns:
36
+ Callable: If ``func`` is provided, returns the function itself. If ``func`` is None, returns a decorator that can be used to register a handler function.
26
37
  """
27
38
  if func is None:
28
39
  return _event_handler(event_name)
@@ -1,6 +1,5 @@
1
1
  """Event handling module for Bear Utils."""
2
2
 
3
- import asyncio
4
3
  from collections import defaultdict
5
4
  from collections.abc import Callable
6
5
  from functools import wraps
@@ -9,7 +8,7 @@ from typing import Any
9
8
  import weakref
10
9
  from weakref import WeakMethod, ref
11
10
 
12
- from bear_utils.extras._async_helpers import is_async_function
11
+ from bear_utils.extras._async_helpers import AsyncResponseModel, create_async_task, is_async_function
13
12
 
14
13
  Callback = Callable[..., Any]
15
14
 
@@ -45,18 +44,20 @@ def set_handler(name: str, func: Callback) -> None:
45
44
  _event_registry[name].add(ref(func, _make_callback(name)))
46
45
 
47
46
 
48
- def dispatch_event(name: str, *args, **kwargs) -> Any | None:
47
+ def dispatch_event(name: str, single: bool = False, *args, **kwargs) -> list[Any]:
49
48
  """Dispatch an event to all registered handlers."""
50
49
  results: list[Any] = []
51
50
  for func in _event_registry.get(name, []):
52
51
  if is_async_function(func):
53
- result: Any = asyncio.run(func(*args, **kwargs)) # FIXME: This will crash if called from an async context
52
+ task: AsyncResponseModel = create_async_task(func(*args, **kwargs))
53
+ result = task.get_conditional_result(timeout=1)
54
+ results.append(result)
54
55
  else:
55
56
  result: Any = func(*args, **kwargs)
56
57
  results.append(result)
57
- if not results:
58
- return None
59
- return results[0] if len(results) == 1 else results
58
+ if single and len(results) == 1:
59
+ return results[0]
60
+ return results
60
61
 
61
62
 
62
63
  def event_handler(event_name: str) -> Callable[[Callback], Callback]:
@@ -3,37 +3,65 @@ from asyncio import AbstractEventLoop, Task
3
3
  from collections.abc import Callable
4
4
  from contextlib import suppress
5
5
  import inspect
6
+ import time
7
+ from typing import Any
6
8
 
7
9
  from pydantic import BaseModel, Field
8
10
 
9
11
 
12
+ def is_async_function(func: Callable) -> bool:
13
+ """Check if a function is asynchronous.
14
+
15
+ Args:
16
+ func (Callable): The function/method to check.
17
+
18
+ Returns:
19
+ bool: True if the function is asynchronous, False otherwise.
20
+ """
21
+ return inspect.iscoroutinefunction(func) or inspect.isasyncgenfunction(func) or inspect.isasyncgen(func)
22
+
23
+
10
24
  class AsyncResponseModel(BaseModel):
11
25
  """A model to handle asynchronous operations with a function and its arguments."""
12
26
 
13
27
  loop: AbstractEventLoop | None = Field(default=None, description="The event loop to run the function in.")
14
28
  task: Task | None = Field(default=None, description="The task created for the asynchronous function.")
15
29
  before_loop: bool = Field(default=False, description="If the function was called from a running loop.")
30
+ result: Any = Field(default=None, description="The result of the completed task.")
16
31
 
17
32
  model_config = {"arbitrary_types_allowed": True}
18
33
 
34
+ @property
35
+ def done(self) -> bool:
36
+ """Check if the task is completed."""
37
+ return self.task is not None and self.task.done()
38
+
39
+ def get_result(self) -> Any:
40
+ """Get the result of the completed task."""
41
+ if not self.task:
42
+ raise ValueError("No task available")
43
+ if not self.task.done():
44
+ raise ValueError("Task not completed yet")
45
+ if self.result is None:
46
+ self.result = self.task.result()
47
+ return self.result
48
+
49
+ def get_conditional_result(self, timeout: float = 10.0) -> Any:
50
+ if self.loop and self.task and not self.before_loop:
51
+ self.loop.run_until_complete(self.task)
52
+ start_time: float = time.monotonic()
53
+ while not self.done:
54
+ if time.monotonic() - start_time > timeout:
55
+ raise TimeoutError("Task timed out")
56
+ time.sleep(0.1)
57
+ return self.get_result()
58
+
19
59
  def conditional_run(self) -> None:
20
60
  """Run the event loop until the task is complete if not in a running loop."""
21
61
  if self.loop and self.task and not self.before_loop:
22
62
  self.loop.run_until_complete(self.task)
23
63
 
24
64
 
25
- def is_async_function(func: Callable) -> bool:
26
- """Check if a function is asynchronous.
27
-
28
- Args:
29
- func (Callable): The function/method to check.
30
-
31
- Returns:
32
- bool: True if the function is asynchronous, False otherwise.
33
- """
34
- return inspect.iscoroutinefunction(func) or inspect.isasyncgenfunction(func) or inspect.isasyncgen(func)
35
-
36
-
37
65
  def in_async_loop() -> bool:
38
66
  """Check if the current context is already in an async loop.
39
67
 
@@ -1 +0,0 @@
1
- __version__ = "0.9.8"
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