danielutils 1.0.36__tar.gz → 1.0.38__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 (271) hide show
  1. {danielutils-1.0.36/danielutils.egg-info → danielutils-1.0.38}/PKG-INFO +1 -1
  2. danielutils-1.0.38/danielutils/async_/__init__.py +6 -0
  3. danielutils-1.0.38/danielutils/async_/async_cmd.py +23 -0
  4. danielutils-1.0.38/danielutils/async_/async_layered_command.py +107 -0
  5. danielutils-1.0.38/danielutils/async_/async_worker_pool.py +89 -0
  6. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/async_/utils.py +17 -1
  7. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/java/__init__.py +2 -2
  8. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/logging_/builtin_impls/file_logger.py +1 -1
  9. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/reflection/class_/class_reflection.py +4 -4
  10. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/reflection/class_info.py +1 -1
  11. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/retry_executor/backoff_strategy.py +1 -1
  12. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/retry_executor/retry_executor.py +1 -1
  13. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/testing/unittest_/auto_cwd_testcase.py +3 -3
  14. {danielutils-1.0.36 → danielutils-1.0.38/danielutils.egg-info}/PKG-INFO +1 -1
  15. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils.egg-info/SOURCES.txt +2 -0
  16. {danielutils-1.0.36 → danielutils-1.0.38}/pyproject.toml +1 -1
  17. danielutils-1.0.36/danielutils/async_/__init__.py +0 -4
  18. danielutils-1.0.36/danielutils/async_/async_worker_pool.py +0 -65
  19. {danielutils-1.0.36 → danielutils-1.0.38}/LICENSE +0 -0
  20. {danielutils-1.0.36 → danielutils-1.0.38}/MANIFEST.in +0 -0
  21. {danielutils-1.0.36 → danielutils-1.0.38}/README.md +0 -0
  22. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/__init__.py +0 -0
  23. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/abstractions/__init__.py +0 -0
  24. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/abstractions/database/__init__.py +0 -0
  25. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/abstractions/database/cached_database.py +0 -0
  26. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/abstractions/database/database.py +0 -0
  27. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/abstractions/database/redis_database.py +0 -0
  28. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/abstractions/multiprogramming/__init__.py +0 -0
  29. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/abstractions/multiprogramming/multi_id.py +0 -0
  30. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/abstractions/multiprogramming/worker.py +0 -0
  31. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/abstractions/multiprogramming/worker_pool.py +0 -0
  32. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/abstractions/repl.py +0 -0
  33. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/aliases.py +0 -0
  34. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/async_/async_retry_executor.py +0 -0
  35. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/async_/time_strategy.py +0 -0
  36. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/better_builtins/__init__.py +0 -0
  37. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/better_builtins/counter.py +0 -0
  38. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/better_builtins/frange.py +0 -0
  39. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/better_builtins/typed_builtins/__init__.py +0 -0
  40. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/better_builtins/typed_builtins/factory.py +0 -0
  41. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/better_builtins/typed_builtins/tdict.py +0 -0
  42. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/better_builtins/typed_builtins/tlist.py +0 -0
  43. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/better_builtins/typed_builtins/tset.py +0 -0
  44. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/better_builtins/typed_builtins/ttuple.py +0 -0
  45. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/colors.py +0 -0
  46. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/context_managers/__init__.py +0 -0
  47. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/context_managers/attr_context.py +0 -0
  48. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/context_managers/multi_context.py +0 -0
  49. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/context_managers/optional_context.py +0 -0
  50. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/context_managers/state_context.py +0 -0
  51. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/context_managers/temporary_file.py +0 -0
  52. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/convenience.py +0 -0
  53. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/conversions/__init__.py +0 -0
  54. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/conversions/main_conversions.py +0 -0
  55. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/conversions/specialized_conversions/__init__.py +0 -0
  56. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/conversions/specialized_conversions/to_hex.py +0 -0
  57. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/conversions/specialized_conversions/to_int.py +0 -0
  58. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/custom_types.py +0 -0
  59. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/data_structures/__init__.py +0 -0
  60. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/data_structures/algorithms.py +0 -0
  61. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/data_structures/comparer.py +0 -0
  62. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/data_structures/default_dict.py +0 -0
  63. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/data_structures/functions.py +0 -0
  64. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/data_structures/graph/__init__.py +0 -0
  65. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/data_structures/graph/binary_node.py +0 -0
  66. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/data_structures/graph/graph.py +0 -0
  67. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/data_structures/graph/multinode.py +0 -0
  68. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/data_structures/graph/node.py +0 -0
  69. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/data_structures/heap/__init__.py +0 -0
  70. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/data_structures/heap/heap.py +0 -0
  71. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/data_structures/heap/max_heap.py +0 -0
  72. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/data_structures/heap/min_heap.py +0 -0
  73. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/data_structures/queue/__init__.py +0 -0
  74. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/data_structures/queue/atomic_queue.py +0 -0
  75. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/data_structures/queue/priority_queue.py +0 -0
  76. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/data_structures/queue/queue.py +0 -0
  77. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/data_structures/stack.py +0 -0
  78. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/data_structures/trees/__init__.py +0 -0
  79. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/data_structures/trees/binary_syntax_tree.py +0 -0
  80. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/data_structures/trees/binary_tree.py +0 -0
  81. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/date.py +0 -0
  82. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/date_time.py +0 -0
  83. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/decorators/__init__.py +0 -0
  84. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/decorators/atomic.py +0 -0
  85. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/decorators/attach.py +0 -0
  86. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/decorators/chain_decorators.py +0 -0
  87. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/decorators/decorate_conditionally.py +0 -0
  88. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/decorators/delay_call.py +0 -0
  89. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/decorators/deprecate.py +0 -0
  90. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/decorators/final.py +0 -0
  91. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/decorators/limit_recursion.py +0 -0
  92. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/decorators/memo.py +0 -0
  93. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/decorators/normalize_decorator.py +0 -0
  94. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/decorators/overload.py +0 -0
  95. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/decorators/partially_implemented.py +0 -0
  96. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/decorators/processify.py +0 -0
  97. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/decorators/property.py +0 -0
  98. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/decorators/singleton.py +0 -0
  99. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/decorators/threadify.py +0 -0
  100. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/decorators/timeout.py +0 -0
  101. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/decorators/total_ordering.py +0 -0
  102. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/decorators/validate.py +0 -0
  103. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/exceptions.py +0 -0
  104. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/file_specifications/__init__.py +0 -0
  105. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/functions/__init__.py +0 -0
  106. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/functions/areoneof.py +0 -0
  107. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/functions/check_foreach.py +0 -0
  108. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/functions/factorial.py +0 -0
  109. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/functions/flatten.py +0 -0
  110. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/functions/foreach.py +0 -0
  111. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/functions/isoftype.py +0 -0
  112. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/functions/isoneof.py +0 -0
  113. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/functions/multiloop.py +0 -0
  114. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/functions/parallel_for.py +0 -0
  115. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/functions/partition.py +0 -0
  116. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/functions/powerset.py +0 -0
  117. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/functions/subseteq.py +0 -0
  118. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/functions/types_subseteq.py +0 -0
  119. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/generators/__init__.py +0 -0
  120. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/generators/conditional_generator.py +0 -0
  121. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/generators/generator_from_stream.py +0 -0
  122. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/generators/join_generators.py +0 -0
  123. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/internet.py +0 -0
  124. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/io_.py +0 -0
  125. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/java/interfaces/__init__.py +0 -0
  126. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/java/interfaces/comparable.py +0 -0
  127. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/java/java_interface.py +0 -0
  128. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/logging_/__init__.py +0 -0
  129. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/logging_/builtin_impls/__init__.py +0 -0
  130. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/logging_/builtin_impls/print_logger.py +0 -0
  131. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/logging_/log_level.py +0 -0
  132. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/logging_/logger.py +0 -0
  133. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/logging_/logger_strategy_impl_base.py +0 -0
  134. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/lombok/__init__.py +0 -0
  135. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/lombok/builder.py +0 -0
  136. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/math_/__init__.py +0 -0
  137. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/math_/constants.py +0 -0
  138. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/math_/functions.py +0 -0
  139. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/math_/math_print.py +0 -0
  140. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/math_/math_symbols.py +0 -0
  141. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/metaclasses/__init__.py +0 -0
  142. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/metaclasses/atomic_class_meta.py +0 -0
  143. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/metaclasses/implicit_data_deleter_meta.py +0 -0
  144. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/metaclasses/instance_cache_meta.py +0 -0
  145. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/metaclasses/interface.py +0 -0
  146. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/metaclasses/overload_meta.py +0 -0
  147. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/mock_/__init__.py +0 -0
  148. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/mock_/mock_database.py +0 -0
  149. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/mock_/mock_module.py +0 -0
  150. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/path.py +0 -0
  151. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/print_.py +0 -0
  152. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/progress_bar/__init__.py +0 -0
  153. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/progress_bar/ascii_progress_bar.py +0 -0
  154. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/progress_bar/progress_bar.py +0 -0
  155. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/progress_bar/progress_bar_pool.py +0 -0
  156. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/protocols/__init__.py +0 -0
  157. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/protocols/dictable.py +0 -0
  158. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/protocols/evaluable.py +0 -0
  159. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/protocols/serializable.py +0 -0
  160. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/py.typed +0 -0
  161. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/random_.py +0 -0
  162. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/reflection/__init__.py +0 -0
  163. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/reflection/argument_info.py +0 -0
  164. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/reflection/class_/__init__.py +0 -0
  165. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/reflection/decoration_info.py +0 -0
  166. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/reflection/file/__init__.py +0 -0
  167. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/reflection/file/file_reflection.py +0 -0
  168. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/reflection/function/__init__.py +0 -0
  169. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/reflection/function/function_reflections.py +0 -0
  170. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/reflection/function_info.py +0 -0
  171. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/reflection/interpreter/__init__.py +0 -0
  172. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/reflection/interpreter/callstack.py +0 -0
  173. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/reflection/interpreter/get_traceback.py +0 -0
  174. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/reflection/interpreter/interpreter.py +0 -0
  175. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/reflection/interpreter/is_debugging.py +0 -0
  176. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/reflection/interpreter/os_.py +0 -0
  177. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/reflection/interpreter/packages.py +0 -0
  178. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/reflection/interpreter/python_version.py +0 -0
  179. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/reflection/interpreter/signals.py +0 -0
  180. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/reflection/interpreter/tracer.py +0 -0
  181. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/reflection/module/__init__.py +0 -0
  182. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/reflection/module/module_reflections.py +0 -0
  183. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/reflection/module/package_reflection.py +0 -0
  184. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/retry_executor/__init__.py +0 -0
  185. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/retry_executor/backoff_strategies/__init__.py +0 -0
  186. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/retry_executor/backoff_strategies/constant_backoff.py +0 -0
  187. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/retry_executor/backoff_strategies/exponential_backoff.py +0 -0
  188. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/retry_executor/backoff_strategies/functional_backoff.py +0 -0
  189. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/retry_executor/backoff_strategies/linear_backoff.py +0 -0
  190. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/retry_executor/backoff_strategies/multiplicative_backoff.py +0 -0
  191. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/retry_executor/backoff_strategies/no_backoff.py +0 -0
  192. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/snippets/__init__.py +0 -0
  193. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/snippets/try_get.py +0 -0
  194. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/system/__init__.py +0 -0
  195. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/system/independent.py +0 -0
  196. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/system/layered_command.py +0 -0
  197. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/system/windows/__init__.py +0 -0
  198. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/system/windows/utils/__init__.py +0 -0
  199. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/system/windows/utils/filetime.py +0 -0
  200. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/system/windows/win32_ctime.py +0 -0
  201. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/system/windows/windows.py +0 -0
  202. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/testing/__init__.py +0 -0
  203. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/testing/unittest_/__init__.py +0 -0
  204. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/testing/unittest_/always_teardown_testcase.py +0 -0
  205. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/text.py +0 -0
  206. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/time.py +0 -0
  207. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/university/__init__.py +0 -0
  208. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/university/computability_and_complexity/__init__.py +0 -0
  209. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/university/computability_and_complexity/discreate_finite_automaton.py +0 -0
  210. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/university/computability_and_complexity/languages/__init__.py +0 -0
  211. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/university/computability_and_complexity/languages/language.py +0 -0
  212. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/university/computability_and_complexity/languages/sat.py +0 -0
  213. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/university/computability_and_complexity/turing_machine.py +0 -0
  214. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/university/databases/__init__.py +0 -0
  215. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/university/databases/all.py +0 -0
  216. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/university/image_proccesing/__init__.py +0 -0
  217. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/university/image_proccesing/encoding/__init__.py +0 -0
  218. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/university/image_proccesing/encoding/encoding.py +0 -0
  219. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/university/image_proccesing/encoding/lossless/__init__.py +0 -0
  220. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/university/image_proccesing/encoding/lossless/huffman.py +0 -0
  221. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/university/image_proccesing/encoding/lossless/lossless_encoding.py +0 -0
  222. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/university/image_proccesing/encoding/lossless/lzw.py +0 -0
  223. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/university/image_proccesing/encoding/lossless/run_length.py +0 -0
  224. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/university/image_proccesing/encoding/lossy/__init__.py +0 -0
  225. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/university/image_proccesing/encoding/lossy/lossy_encoding.py +0 -0
  226. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/university/image_proccesing/tansformations/__init__.py +0 -0
  227. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/university/image_proccesing/tansformations/gaussian.py +0 -0
  228. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/university/image_proccesing/tansformations/gradient.py +0 -0
  229. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/university/image_proccesing/tansformations/hough.py +0 -0
  230. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/university/image_proccesing/tansformations/laplacian.py +0 -0
  231. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/university/image_proccesing/tansformations/transformation.py +0 -0
  232. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/university/linear_algebra/__init__.py +0 -0
  233. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/university/linear_algebra/matrix.py +0 -0
  234. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/university/machine_learning/__init__.py +0 -0
  235. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/university/machine_learning/activation_functions/__init__.py +0 -0
  236. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/university/machine_learning/activation_functions/activation_function.py +0 -0
  237. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/university/machine_learning/activation_functions/relu.py +0 -0
  238. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/university/machine_learning/neuron.py +0 -0
  239. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/university/oop/__init__.py +0 -0
  240. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/university/oop/observer.py +0 -0
  241. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/university/oop/strategy.py +0 -0
  242. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/university/probability/__init__.py +0 -0
  243. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/university/probability/conditional_variable/__init__.py +0 -0
  244. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/university/probability/conditional_variable/conditional_variable.py +0 -0
  245. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/university/probability/conditional_variable/continuous/__init__.py +0 -0
  246. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/university/probability/conditional_variable/discrete/__init__.py +0 -0
  247. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/university/probability/conditional_variable/discrete/bernoulli.py +0 -0
  248. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/university/probability/conditional_variable/discrete/binomial.py +0 -0
  249. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/university/probability/conditional_variable/discrete/conditional_from_discrete_probability_func.py +0 -0
  250. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/university/probability/conditional_variable/discrete/discrete.py +0 -0
  251. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/university/probability/conditional_variable/discrete/geometric.py +0 -0
  252. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/university/probability/conditional_variable/discrete/poisson.py +0 -0
  253. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/university/probability/conditional_variable/discrete/uniform.py +0 -0
  254. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/university/probability/distributions.py +0 -0
  255. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/university/probability/expressions/__init__.py +0 -0
  256. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/university/probability/expressions/accumulation_expression.py +0 -0
  257. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/university/probability/expressions/probability_expression.py +0 -0
  258. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/university/probability/funcs/__init__.py +0 -0
  259. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/university/probability/funcs/covariance.py +0 -0
  260. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/university/probability/funcs/expected_value.py +0 -0
  261. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/university/probability/funcs/probability_function.py +0 -0
  262. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/university/probability/funcs/variance.py +0 -0
  263. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/university/probability/operator.py +0 -0
  264. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/university/probability/protocols.py +0 -0
  265. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/university/probability/supp.py +0 -0
  266. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/university/probability/transformation.py +0 -0
  267. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils/versioned_imports.py +0 -0
  268. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils.egg-info/dependency_links.txt +0 -0
  269. {danielutils-1.0.36 → danielutils-1.0.38}/danielutils.egg-info/top_level.txt +0 -0
  270. {danielutils-1.0.36 → danielutils-1.0.38}/setup.cfg +0 -0
  271. {danielutils-1.0.36 → danielutils-1.0.38}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: danielutils
3
- Version: 1.0.36
3
+ Version: 1.0.38
4
4
  Summary: A python utils library for things I find useful
5
5
  Author-email: danielnachumdev <danielnachumdev@gmail.com>
6
6
  License: MIT License
@@ -0,0 +1,6 @@
1
+ from .async_cmd import *
2
+ from .async_layered_command import *
3
+ from .async_retry_executor import *
4
+ from .async_worker_pool import *
5
+ from .time_strategy import *
6
+ from .utils import *
@@ -0,0 +1,23 @@
1
+ import asyncio
2
+ from typing import Tuple, Optional
3
+
4
+
5
+ async def async_cmd(
6
+ cmd: str,
7
+ *,
8
+ capture_stdout: bool = False,
9
+ capture_stderr: bool = False
10
+ ) -> Tuple[int, Optional[bytes], Optional[bytes]]:
11
+ kwargs = {}
12
+ if capture_stdout:
13
+ kwargs['stdout'] = asyncio.subprocess.PIPE
14
+ if capture_stderr:
15
+ kwargs['stderr'] = asyncio.subprocess.PIPE
16
+ process = await asyncio.create_subprocess_shell(cmd, **kwargs) # type:ignore
17
+ stdout, stderr = await process.communicate()
18
+ return process.returncode, stdout, stderr
19
+
20
+
21
+ __all__ = [
22
+ 'async_cmd',
23
+ ]
@@ -0,0 +1,107 @@
1
+ import sys
2
+ from typing import Optional, Tuple, List
3
+
4
+ from .async_cmd import async_cmd
5
+
6
+
7
+ class AsyncLayeredCommand:
8
+ class_capture_stdout: bool = True
9
+ class_capture_stderr: bool = True
10
+ class_raise_on_fail: bool = False
11
+ class_verbose: bool = False
12
+ _class_prev_instance: Optional['AsyncLayeredCommand'] = None
13
+ _id: int = 0
14
+
15
+ @property
16
+ def prev(self):
17
+ return self._prev_instance
18
+
19
+ @prev.setter
20
+ def prev(self, value: Optional['AsyncLayeredCommand'] = None):
21
+ self._prev_instance = value
22
+
23
+ def __init__(
24
+ self,
25
+ command: Optional[str] = None,
26
+ *,
27
+ prev_instance: Optional['AsyncLayeredCommand'] = None,
28
+ instance_capture_stdout: Optional[bool] = None,
29
+ instance_capture_stderr: Optional[bool] = None,
30
+ instance_raise_on_fail: Optional[bool] = None,
31
+ instance_verbose: Optional[bool] = None
32
+ ):
33
+ self._command = command if command is not None else ""
34
+ self._instance_capture_stdout = instance_capture_stdout
35
+ self._instance_capture_stderr = instance_capture_stderr
36
+ self._instance_raise_on_fail = instance_raise_on_fail
37
+ self._instance_verbose = instance_verbose
38
+ self._prev_instance = prev_instance if prev_instance is not None else AsyncLayeredCommand._class_prev_instance
39
+ self._cur_class_prev_instance = AsyncLayeredCommand._class_prev_instance
40
+ AsyncLayeredCommand._class_prev_instance = self
41
+ self._has_entered: bool = False
42
+
43
+ def __enter__(self):
44
+ self._open()
45
+ return self
46
+
47
+ def __exit__(self, exc_type, exc_val, exc_tb):
48
+ if self.prev is self._cur_class_prev_instance:
49
+ AsyncLayeredCommand._class_prev_instance = self.prev
50
+
51
+ def _open(self) -> None:
52
+ self._has_entered = True
53
+
54
+ def _build_command(self, *commands: str) -> str:
55
+ res = ""
56
+ if self.prev is not None:
57
+ prev = self.prev._build_command()
58
+ res += f"{prev} & " if prev != "" else ""
59
+ if self._command != "":
60
+ return res + " & ".join([self._command, *commands])
61
+ return res + " & ".join(commands)
62
+
63
+ def _error(self, predicate: bool, command: str, code: int, command_verbose: Optional[bool]) -> None:
64
+ if predicate:
65
+ verbose = self._merge_values(command_verbose, self._instance_verbose, AsyncLayeredCommand.class_verbose)
66
+ if verbose:
67
+ raise RuntimeError(f"command '{command}' failed with exit code {code}")
68
+ sys.exit(1)
69
+
70
+ @staticmethod
71
+ def _merge_values(command: Optional[bool], instance: Optional[bool], class_: bool) -> bool:
72
+ return command if command is not None else (instance if instance is not None else class_)
73
+
74
+ async def execute(
75
+ self,
76
+ *commands: str,
77
+ command_capture_stdout: Optional[bool] = None,
78
+ command_capture_stderr: Optional[bool] = None,
79
+ command_raise_on_fail: Optional[bool] = None,
80
+ command_verbose: Optional[bool] = None
81
+ ) -> Tuple[int, List[str], List[str]]:
82
+ if not self._has_entered:
83
+ raise RuntimeError(
84
+ "LayeredCommand must be used with a context manager. Use as: `with LayeredCommand(...) as l1:`")
85
+ capture_stdout = self._merge_values(command_capture_stdout, self._instance_capture_stdout,
86
+ self.class_capture_stdout)
87
+ capture_stderr = self._merge_values(command_capture_stderr, self._instance_capture_stderr,
88
+ self.class_capture_stderr)
89
+ raise_on_fail = self._merge_values(command_raise_on_fail, self._instance_raise_on_fail,
90
+ self.class_raise_on_fail)
91
+
92
+ command = self._build_command(*commands)
93
+ if not capture_stdout and not capture_stderr:
94
+ code = (await async_cmd(command))[0]
95
+ self._error(raise_on_fail and code != 0, command, code, command_verbose)
96
+ return code, [], []
97
+
98
+ code, stdout, stderr = await async_cmd(command, capture_stdout=True, capture_stderr=True)
99
+ return code, stdout.decode().splitlines(), stderr.decode().splitlines()
100
+
101
+ async def __call__(self, *args, **kwargs) -> Tuple[int, List[str], List[str]]:
102
+ return await self.execute(*args, **kwargs)
103
+
104
+
105
+ __all__ = [
106
+ 'AsyncLayeredCommand'
107
+ ]
@@ -0,0 +1,89 @@
1
+ import asyncio
2
+ import json
3
+ from datetime import datetime
4
+ from typing import Callable, Literal, Optional, Coroutine, List, Iterable, Any, Mapping
5
+
6
+
7
+ class AsyncWorkerPool:
8
+ DEFAULT_ORDER_IF_KEY_EXISTS = (
9
+ "pool", "timestamp", "worker", "task", "tasks", "level", "message", "exception"
10
+ )
11
+
12
+ def __init__(self, pool_name: str, num_workers: int = 5) -> None:
13
+ self.num_workers = num_workers
14
+ self.pool_name = pool_name
15
+ self.queue = asyncio.Queue()
16
+ self.workers = []
17
+
18
+ async def worker(self, worker_id) -> None:
19
+ """Worker coroutine that continuously fetches and executes tasks from the queue."""
20
+ task_names = []
21
+ task_index = 0
22
+ while True:
23
+ task = await self.queue.get()
24
+ if task is None: # Sentinel value to shut down the worker
25
+ break
26
+ func, args, kwargs, name = task
27
+ task_names.append(name)
28
+ task_index = len(task_names)
29
+ self.info(f"Started task {task_index}", task=name, worker_id=worker_id)
30
+ try:
31
+ await func(*args, **kwargs)
32
+ except Exception as e:
33
+ self.error(f"Failed task {task_index}", exception=e, worker_id=worker_id, task=name)
34
+
35
+ self.info(f"Finished task {task_index}", worker_id=worker_id, task=name)
36
+ self.queue.task_done()
37
+ self.info(f"Done. Executed {task_index} tasks", worker_id=worker_id, tasks=task_names)
38
+
39
+ async def start(self) -> None:
40
+ """Starts the worker pool."""
41
+ self.workers = [asyncio.create_task(self.worker(i + 1)) for i in range(self.num_workers)]
42
+
43
+ async def submit(
44
+ self,
45
+ func: Callable[..., Coroutine[None, None, None]],
46
+ args: Optional[Iterable[Any]] = None,
47
+ kwargs: Optional[Mapping[Any, Any]] = None,
48
+ name: Optional[str] = None
49
+ ) -> None:
50
+ """Submit a new task to the queue."""
51
+ await self.queue.put((func, args or (), kwargs or {}, name))
52
+
53
+ async def join(self) -> None:
54
+ """Stops the worker pool by waiting for all tasks to complete and shutting down workers."""
55
+ await self.queue.join() # Wait until all tasks are processed
56
+ for _ in range(self.num_workers):
57
+ await self.queue.put(None) # Send sentinel values to stop workers
58
+ await asyncio.gather(*self.workers) # Wait for workers to finish
59
+
60
+ @classmethod
61
+ def log(
62
+ self,
63
+ level: Literal["INFO", "WARNING", "ERROR"],
64
+ message: str,
65
+ order: Optional[List[str]] = DEFAULT_ORDER_IF_KEY_EXISTS,
66
+ **kwargs
67
+ ) -> None:
68
+ kwargs["level"] = level
69
+ kwargs["message"] = message
70
+ kwargs["timestamp"] = datetime.now().isoformat()
71
+ ordered_kwargs = kwargs
72
+ if order:
73
+ ordered_kwargs = {key: kwargs[key] for key in order if key in kwargs}
74
+ ordered_kwargs.update(kwargs)
75
+ print(json.dumps(ordered_kwargs, default=str))
76
+
77
+ def info(self, message: str, **kwargs) -> None:
78
+ self.log("INFO", message, pool=self.pool_name, **kwargs)
79
+
80
+ def warn(self, message: str, **kwargs) -> None:
81
+ self.log("WARNING", message, pool=self.pool_name, **kwargs)
82
+
83
+ def error(self, message: str, **kwargs) -> None:
84
+ self.log("ERROR", message, pool=self.pool_name, **kwargs)
85
+
86
+
87
+ __all__ = [
88
+ "AsyncWorkerPool",
89
+ ]
@@ -1,6 +1,6 @@
1
1
  import asyncio
2
2
  from asyncio import Task
3
- from typing import List, Coroutine, Any, Tuple, Optional, Set
3
+ from typing import List, Coroutine, Any, Tuple, Optional, Set, AsyncIterator, Iterator, TypeVar
4
4
 
5
5
 
6
6
  async def return_first(coros: List[Coroutine], timeout: Optional[int] = None) -> List[Tuple[int, Any]]:
@@ -26,7 +26,23 @@ async def return_all(coros: List[Coroutine], timeout: Optional[int] = None) -> L
26
26
  return [task.result() for task in done]
27
27
 
28
28
 
29
+ async def cast_aiter(itr: Iterator) -> AsyncIterator:
30
+ for x in itr:
31
+ yield x
32
+
33
+
34
+ T = TypeVar("T")
35
+
36
+
37
+ async def async_enumerate(iterable: AsyncIterator[T], start: int = 0) -> AsyncIterator[Tuple[int, T]]:
38
+ index = start
39
+ async for item in iterable:
40
+ yield index, item
41
+ index += 1
42
+
43
+
29
44
  __all__ = [
30
45
  "return_first",
31
46
  "return_all",
47
+ 'cast_aiter'
32
48
  ]
@@ -1,7 +1,7 @@
1
1
  try:
2
- from reflection import get_python_version
3
- except ImportError:
4
2
  from ..reflection import get_python_version # type:ignore
3
+ except ImportError:
4
+ from reflection import get_python_version
5
5
 
6
6
  if get_python_version() >= (3, 10):
7
7
  from .interfaces import *
@@ -1,6 +1,6 @@
1
1
  from pathlib import Path
2
2
 
3
- from danielutils import delete_file, directory_exists, create_directory
3
+ from ...io_ import delete_file, directory_exists, create_directory
4
4
 
5
5
  from ..logger_strategy_impl_base import LoggerStrategyImplBase
6
6
 
@@ -115,7 +115,7 @@ class FunctionDeclaration:
115
115
  generics=self.generics,
116
116
  )
117
117
  dct.update(override_kwargs)
118
- return FunctionDeclaration(**dct)
118
+ return FunctionDeclaration(**dct) # type:ignore
119
119
 
120
120
  @property
121
121
  def has_generics(self) -> bool:
@@ -141,13 +141,13 @@ class FunctionDeclaration:
141
141
  parameters.append(arg)
142
142
  res = []
143
143
  for code, name, args, ret in func_pattern.findall(src):
144
- name: str = name.strip()
145
- args: Optional[str] = remove_whitespace(args) if args is not None else None
144
+ name: str = name.strip() # type:ignore
145
+ args: Optional[str] = remove_whitespace(args) if args is not None else None # type:ignore
146
146
  arguments = []
147
147
  if args is not None:
148
148
  for arg in split_args(args):
149
149
  arguments.append(Argument(*arg_pattern.match(remove_whitespace(arg)).groups()))
150
- ret: Optional[str] = ret.strip() if ret is not None and len(ret) != 0 else None
150
+ ret: Optional[str] = ret.strip() if ret is not None and len(ret) != 0 else None # type:ignore
151
151
  res.append(FunctionDeclaration(name, tuple(arguments), ret, decorators=None, generics=tuple(parameters)))
152
152
 
153
153
  return res
@@ -5,7 +5,7 @@ from typing import Optional, List, Iterable, Type, TypeVar, Generic, get_origin
5
5
  from .function_info import FunctionInfo
6
6
  from .decoration_info import DecorationInfo
7
7
  from .argument_info import ArgumentInfo
8
- from danielutils.functions import isoftype
8
+ from ..functions import isoftype
9
9
 
10
10
  T = TypeVar("T")
11
11
 
@@ -1,4 +1,4 @@
1
- from danielutils import Supplier
1
+ from ..aliases import Supplier
2
2
 
3
3
 
4
4
  class BackOffStrategy:
@@ -1,7 +1,7 @@
1
1
  import time
2
2
  from typing import Generic, TypeVar, Optional
3
3
 
4
- from danielutils import Supplier, Consumer
4
+ from ..aliases import Supplier, Consumer
5
5
  from .backoff_strategies import ConstantBackOffStrategy
6
6
 
7
7
  from .backoff_strategy import BackOffStrategy
@@ -2,11 +2,11 @@ import asyncio
2
2
  import functools
3
3
  import os
4
4
  import unittest
5
- import inspect
6
- from inspect import iscoroutine, iscoroutinefunction
5
+ from inspect import iscoroutinefunction
7
6
  from typing import Callable, Type, Coroutine, Union, Any
8
7
 
9
- from danielutils import create_directory, get_current_working_directory, set_current_working_directory, delete_directory
8
+ from ...io_ import create_directory, delete_directory
9
+ from ...path import get_current_working_directory, set_current_working_directory
10
10
 
11
11
 
12
12
  def dispatch_function(func: Union[Callable, Coroutine], *args, **kwargs) -> Any:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: danielutils
3
- Version: 1.0.36
3
+ Version: 1.0.38
4
4
  Summary: A python utils library for things I find useful
5
5
  Author-email: danielnachumdev <danielnachumdev@gmail.com>
6
6
  License: MIT License
@@ -35,6 +35,8 @@ danielutils/abstractions/multiprogramming/multi_id.py
35
35
  danielutils/abstractions/multiprogramming/worker.py
36
36
  danielutils/abstractions/multiprogramming/worker_pool.py
37
37
  danielutils/async_/__init__.py
38
+ danielutils/async_/async_cmd.py
39
+ danielutils/async_/async_layered_command.py
38
40
  danielutils/async_/async_retry_executor.py
39
41
  danielutils/async_/async_worker_pool.py
40
42
  danielutils/async_/time_strategy.py
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "danielutils"
7
- version = "1.0.36"
7
+ version = "1.0.38"
8
8
  authors = [
9
9
  { name = "danielnachumdev", email = "danielnachumdev@gmail.com" },
10
10
  ]
@@ -1,4 +0,0 @@
1
- from .async_worker_pool import *
2
- from .async_worker_pool import *
3
- from .time_strategy import *
4
- from .utils import *
@@ -1,65 +0,0 @@
1
- import asyncio
2
- import json
3
- from typing import Callable, Literal, Optional, Coroutine
4
-
5
- from .async_retry_executor import AsyncRetryExecutor
6
-
7
-
8
- class AsyncWorkerPool:
9
- def __init__(self, num_workers: int, retry_executor: Optional[AsyncRetryExecutor] = None) -> None:
10
- self.num_workers = num_workers
11
- self.queue = asyncio.Queue()
12
- self.workers = []
13
- self.retry_executor = retry_executor
14
-
15
- async def worker(self, worker_id) -> None:
16
- """Worker coroutine that continuously fetches and executes tasks from the queue."""
17
- count = 0
18
- while True:
19
- task = await self.queue.get()
20
- if task is None: # Sentinel value to shut down the worker
21
- break
22
- count += 1
23
- func, args, kwargs = task
24
- self.info(f"Worker {worker_id} started with task {count}")
25
- if self.retry_executor:
26
- await self.retry_executor.execute(func, args=args, kwargs=kwargs)
27
- else:
28
- await func(*args, **kwargs)
29
- self.info(f"Worker {worker_id} finished with task {count}")
30
- self.queue.task_done()
31
- self.info(f"Worker {worker_id} done.")
32
-
33
- async def start(self) -> None:
34
- """Starts the worker pool."""
35
- self.workers = [asyncio.create_task(self.worker(i + 1)) for i in range(self.num_workers)]
36
-
37
- async def submit(self, func: Callable[..., Coroutine[None, None, None]], *args, **kwargs) -> None:
38
- """Submit a new task to the queue."""
39
- await self.queue.put((func, args, kwargs))
40
-
41
- async def join(self) -> None:
42
- """Stops the worker pool by waiting for all tasks to complete and shutting down workers."""
43
- await self.queue.join() # Wait until all tasks are processed
44
- for _ in range(self.num_workers):
45
- await self.queue.put(None) # Send sentinel values to stop workers
46
- await asyncio.gather(*self.workers) # Wait for workers to finish
47
-
48
- def log(self, level: Literal["INFO", "WARNING", "ERROR"], message: str, **kwargs) -> None:
49
- kwargs["level"] = level
50
- kwargs["message"] = message
51
- print(json.dumps(kwargs, default=str))
52
-
53
- def info(self, message: str, **kwargs) -> None:
54
- self.log("INFO", message, **kwargs)
55
-
56
- def warn(self, message: str, **kwargs) -> None:
57
- self.log("WARNING", message, **kwargs)
58
-
59
- def error(self, message: str, **kwargs) -> None:
60
- self.log("ERROR", message, **kwargs)
61
-
62
-
63
- __all__ = [
64
- "AsyncWorkerPool",
65
- ]
File without changes
File without changes
File without changes