danielutils 1.1.28__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (287) hide show
  1. danielutils/__init__.py +50 -0
  2. danielutils/abstractions/__init__.py +3 -0
  3. danielutils/abstractions/db/__init__.py +10 -0
  4. danielutils/abstractions/db/database.py +206 -0
  5. danielutils/abstractions/db/database_definitions.py +219 -0
  6. danielutils/abstractions/db/database_exceptions.py +34 -0
  7. danielutils/abstractions/db/database_factory.py +70 -0
  8. danielutils/abstractions/db/database_initializer.py +261 -0
  9. danielutils/abstractions/db/database_models.py +213 -0
  10. danielutils/abstractions/db/dependencies.py +6 -0
  11. danielutils/abstractions/db/implementations/__init__.py +4 -0
  12. danielutils/abstractions/db/implementations/in_memory_database.py +365 -0
  13. danielutils/abstractions/db/implementations/persistent_in_memory_database.py +174 -0
  14. danielutils/abstractions/db/implementations/redis_database.py +403 -0
  15. danielutils/abstractions/db/implementations/sqlite_database.py +491 -0
  16. danielutils/abstractions/multiprogramming/__init__.py +3 -0
  17. danielutils/abstractions/multiprogramming/multi_id.py +26 -0
  18. danielutils/abstractions/multiprogramming/worker.py +104 -0
  19. danielutils/abstractions/multiprogramming/worker_pool.py +98 -0
  20. danielutils/abstractions/repl.py +125 -0
  21. danielutils/aliases.py +174 -0
  22. danielutils/async_/__init__.py +7 -0
  23. danielutils/async_/async_cmd.py +28 -0
  24. danielutils/async_/async_command.py +879 -0
  25. danielutils/async_/async_layered_command.py +125 -0
  26. danielutils/async_/async_retry_executor.py +86 -0
  27. danielutils/async_/async_worker_pool.py +110 -0
  28. danielutils/async_/time_strategy.py +73 -0
  29. danielutils/async_/utils.py +57 -0
  30. danielutils/better_builtins/__init__.py +3 -0
  31. danielutils/better_builtins/counter.py +48 -0
  32. danielutils/better_builtins/frange.py +266 -0
  33. danielutils/better_builtins/typed_builtins/__init__.py +4 -0
  34. danielutils/better_builtins/typed_builtins/factory.py +126 -0
  35. danielutils/better_builtins/typed_builtins/tdict.py +36 -0
  36. danielutils/better_builtins/typed_builtins/tlist.py +223 -0
  37. danielutils/better_builtins/typed_builtins/tset.py +67 -0
  38. danielutils/better_builtins/typed_builtins/ttuple.py +15 -0
  39. danielutils/colors.py +203 -0
  40. danielutils/context_managers/__init__.py +5 -0
  41. danielutils/context_managers/attr_context.py +40 -0
  42. danielutils/context_managers/multi_context.py +34 -0
  43. danielutils/context_managers/optional_context.py +33 -0
  44. danielutils/context_managers/state_context.py +25 -0
  45. danielutils/context_managers/temporary_file.py +108 -0
  46. danielutils/convenience.py +12 -0
  47. danielutils/conversions/__init__.py +2 -0
  48. danielutils/conversions/main_conversions.py +131 -0
  49. danielutils/conversions/specialized_conversions/__init__.py +2 -0
  50. danielutils/conversions/specialized_conversions/to_hex.py +25 -0
  51. danielutils/conversions/specialized_conversions/to_int.py +19 -0
  52. danielutils/custom_types.py +18 -0
  53. danielutils/data_structures/__init__.py +8 -0
  54. danielutils/data_structures/algorithms.py +52 -0
  55. danielutils/data_structures/comparer.py +47 -0
  56. danielutils/data_structures/default_dict.py +23 -0
  57. danielutils/data_structures/functions.py +35 -0
  58. danielutils/data_structures/graph/__init__.py +4 -0
  59. danielutils/data_structures/graph/binary_node.py +71 -0
  60. danielutils/data_structures/graph/graph.py +208 -0
  61. danielutils/data_structures/graph/multinode.py +101 -0
  62. danielutils/data_structures/graph/node.py +60 -0
  63. danielutils/data_structures/heap/__init__.py +3 -0
  64. danielutils/data_structures/heap/heap.py +119 -0
  65. danielutils/data_structures/heap/max_heap.py +18 -0
  66. danielutils/data_structures/heap/min_heap.py +18 -0
  67. danielutils/data_structures/queue/__init__.py +3 -0
  68. danielutils/data_structures/queue/atomic_queue.py +15 -0
  69. danielutils/data_structures/queue/priority_queue.py +110 -0
  70. danielutils/data_structures/queue/queue.py +92 -0
  71. danielutils/data_structures/stack.py +102 -0
  72. danielutils/data_structures/trees/__init__.py +2 -0
  73. danielutils/data_structures/trees/binary_syntax_tree.py +84 -0
  74. danielutils/data_structures/trees/binary_tree.py +63 -0
  75. danielutils/date.py +43 -0
  76. danielutils/date_time.py +23 -0
  77. danielutils/decorators/__init__.py +18 -0
  78. danielutils/decorators/atomic.py +45 -0
  79. danielutils/decorators/attach.py +61 -0
  80. danielutils/decorators/chain_decorators.py +39 -0
  81. danielutils/decorators/decorate_conditionally.py +32 -0
  82. danielutils/decorators/delay_call.py +47 -0
  83. danielutils/decorators/deprecate.py +46 -0
  84. danielutils/decorators/final.py +39 -0
  85. danielutils/decorators/limit_recursion.py +63 -0
  86. danielutils/decorators/memo.py +68 -0
  87. danielutils/decorators/normalize_decorator.py +55 -0
  88. danielutils/decorators/overload.py +204 -0
  89. danielutils/decorators/partially_implemented.py +32 -0
  90. danielutils/decorators/processify.py +74 -0
  91. danielutils/decorators/property.py +42 -0
  92. danielutils/decorators/singleton.py +59 -0
  93. danielutils/decorators/threadify.py +40 -0
  94. danielutils/decorators/timeout.py +82 -0
  95. danielutils/decorators/total_ordering.py +82 -0
  96. danielutils/decorators/validate.py +227 -0
  97. danielutils/exceptions.py +90 -0
  98. danielutils/functions/__init__.py +13 -0
  99. danielutils/functions/areoneof.py +47 -0
  100. danielutils/functions/check_foreach.py +39 -0
  101. danielutils/functions/factorial.py +24 -0
  102. danielutils/functions/flatten.py +33 -0
  103. danielutils/functions/foreach.py +20 -0
  104. danielutils/functions/isoftype.py +475 -0
  105. danielutils/functions/isoneof.py +71 -0
  106. danielutils/functions/multiloop.py +51 -0
  107. danielutils/functions/parallel_for.py +47 -0
  108. danielutils/functions/partition.py +45 -0
  109. danielutils/functions/powerset.py +31 -0
  110. danielutils/functions/subseteq.py +25 -0
  111. danielutils/functions/types_subseteq.py +51 -0
  112. danielutils/generators/__init__.py +3 -0
  113. danielutils/generators/conditional_generator.py +59 -0
  114. danielutils/generators/generator_from_stream.py +31 -0
  115. danielutils/generators/join_generators.py +109 -0
  116. danielutils/internet.py +92 -0
  117. danielutils/io_.py +451 -0
  118. danielutils/java/__init__.py +18 -0
  119. danielutils/java/interfaces/__init__.py +1 -0
  120. danielutils/java/interfaces/comparable.py +31 -0
  121. danielutils/java/java_interface.py +59 -0
  122. danielutils/logging_/__init__.py +2 -0
  123. danielutils/logging_/_impl/__init__.py +4 -0
  124. danielutils/logging_/_impl/builtin_impls/__init__.py +2 -0
  125. danielutils/logging_/_impl/builtin_impls/file_logger.py +35 -0
  126. danielutils/logging_/_impl/builtin_impls/print_logger.py +21 -0
  127. danielutils/logging_/_impl/log_level.py +13 -0
  128. danielutils/logging_/_impl/logger.py +109 -0
  129. danielutils/logging_/_impl/logger_strategy_impl_base.py +37 -0
  130. danielutils/logging_/utils.py +199 -0
  131. danielutils/lombok/__init__.py +1 -0
  132. danielutils/lombok/builder.py +68 -0
  133. danielutils/math_/__init__.py +2 -0
  134. danielutils/math_/constants.py +103 -0
  135. danielutils/math_/functions.py +34 -0
  136. danielutils/math_/math_print.py +52 -0
  137. danielutils/math_/math_symbols.py +125 -0
  138. danielutils/metaclasses/__init__.py +5 -0
  139. danielutils/metaclasses/atomic_class_meta.py +36 -0
  140. danielutils/metaclasses/implicit_data_deleter_meta.py +87 -0
  141. danielutils/metaclasses/instance_cache_meta.py +66 -0
  142. danielutils/metaclasses/interface.py +328 -0
  143. danielutils/metaclasses/overload_meta.py +48 -0
  144. danielutils/mock_/__init__.py +1 -0
  145. danielutils/mock_/mock_module.py +27 -0
  146. danielutils/path.py +55 -0
  147. danielutils/print_.py +123 -0
  148. danielutils/progress_bar/__init__.py +3 -0
  149. danielutils/progress_bar/ascii_progress_bar.py +161 -0
  150. danielutils/progress_bar/progress_bar.py +75 -0
  151. danielutils/progress_bar/progress_bar_pool.py +72 -0
  152. danielutils/protocols/__init__.py +3 -0
  153. danielutils/protocols/dictable.py +38 -0
  154. danielutils/protocols/evaluable.py +26 -0
  155. danielutils/protocols/serializable.py +51 -0
  156. danielutils/py.typed +0 -0
  157. danielutils/random_.py +47 -0
  158. danielutils/reflection/__init__.py +6 -0
  159. danielutils/reflection/declarations.py +288 -0
  160. danielutils/reflection/file/__init__.py +1 -0
  161. danielutils/reflection/file/file_reflection.py +85 -0
  162. danielutils/reflection/function/__init__.py +1 -0
  163. danielutils/reflection/function/function_reflections.py +152 -0
  164. danielutils/reflection/info_classes/__init__.py +6 -0
  165. danielutils/reflection/info_classes/argument_info.py +278 -0
  166. danielutils/reflection/info_classes/class_info.py +204 -0
  167. danielutils/reflection/info_classes/decorator_info.py +54 -0
  168. danielutils/reflection/info_classes/file_info.py +1180 -0
  169. danielutils/reflection/info_classes/folder_info.py +592 -0
  170. danielutils/reflection/info_classes/function_info.py +551 -0
  171. danielutils/reflection/info_classes/import_info.py +207 -0
  172. danielutils/reflection/interpreter/__init__.py +9 -0
  173. danielutils/reflection/interpreter/callstack.py +57 -0
  174. danielutils/reflection/interpreter/get_traceback.py +27 -0
  175. danielutils/reflection/interpreter/interpreter.py +41 -0
  176. danielutils/reflection/interpreter/is_debugging.py +13 -0
  177. danielutils/reflection/interpreter/os_.py +33 -0
  178. danielutils/reflection/interpreter/packages.py +33 -0
  179. danielutils/reflection/interpreter/python_version.py +33 -0
  180. danielutils/reflection/interpreter/signals.py +18 -0
  181. danielutils/reflection/interpreter/tracer.py +175 -0
  182. danielutils/reflection/module/__init__.py +3 -0
  183. danielutils/reflection/module/lazy_module.py +104 -0
  184. danielutils/reflection/module/module_reflections.py +34 -0
  185. danielutils/reflection/module/package_reflection.py +161 -0
  186. danielutils/retry_executor/__init__.py +3 -0
  187. danielutils/retry_executor/backoff_strategies/__init__.py +6 -0
  188. danielutils/retry_executor/backoff_strategies/constant_backoff.py +25 -0
  189. danielutils/retry_executor/backoff_strategies/exponential_backoff.py +26 -0
  190. danielutils/retry_executor/backoff_strategies/functional_backoff.py +29 -0
  191. danielutils/retry_executor/backoff_strategies/linear_backoff.py +23 -0
  192. danielutils/retry_executor/backoff_strategies/multiplicative_backoff.py +23 -0
  193. danielutils/retry_executor/backoff_strategies/no_backoff.py +17 -0
  194. danielutils/retry_executor/backoff_strategy.py +28 -0
  195. danielutils/retry_executor/retry_executor.py +55 -0
  196. danielutils/snippets/__init__.py +1 -0
  197. danielutils/snippets/try_get.py +28 -0
  198. danielutils/system/__init__.py +3 -0
  199. danielutils/system/independent.py +197 -0
  200. danielutils/system/layered_command.py +130 -0
  201. danielutils/system/windows/__init__.py +2 -0
  202. danielutils/system/windows/utils/__init__.py +1 -0
  203. danielutils/system/windows/utils/filetime.py +19 -0
  204. danielutils/system/windows/win32_ctime.py +183 -0
  205. danielutils/system/windows/windows.py +78 -0
  206. danielutils/testing/__init__.py +1 -0
  207. danielutils/testing/unittest_/__init__.py +2 -0
  208. danielutils/testing/unittest_/always_teardown_testcase.py +75 -0
  209. danielutils/testing/unittest_/auto_cwd_testcase.py +114 -0
  210. danielutils/text.py +169 -0
  211. danielutils/time.py +64 -0
  212. danielutils/tools/__init__.py +1 -0
  213. danielutils/tools/unittest_test_runner/__init__.py +9 -0
  214. danielutils/tools/unittest_test_runner/cli.py +70 -0
  215. danielutils/tools/unittest_test_runner/core/__init__.py +17 -0
  216. danielutils/tools/unittest_test_runner/core/discovery.py +322 -0
  217. danielutils/tools/unittest_test_runner/core/execution.py +244 -0
  218. danielutils/tools/unittest_test_runner/core/parser.py +163 -0
  219. danielutils/tools/unittest_test_runner/core/runner.py +561 -0
  220. danielutils/tools/unittest_test_runner/models.py +82 -0
  221. danielutils/university/__init__.py +7 -0
  222. danielutils/university/computability_and_complexity/__init__.py +2 -0
  223. danielutils/university/computability_and_complexity/discreate_finite_automaton.py +89 -0
  224. danielutils/university/computability_and_complexity/languages/__init__.py +0 -0
  225. danielutils/university/computability_and_complexity/languages/language.py +17 -0
  226. danielutils/university/computability_and_complexity/languages/sat.py +71 -0
  227. danielutils/university/computability_and_complexity/turing_machine.py +47 -0
  228. danielutils/university/databases/__init__.py +1 -0
  229. danielutils/university/databases/all.py +756 -0
  230. danielutils/university/image_proccesing/__init__.py +1 -0
  231. danielutils/university/image_proccesing/encoding/__init__.py +3 -0
  232. danielutils/university/image_proccesing/encoding/encoding.py +35 -0
  233. danielutils/university/image_proccesing/encoding/lossless/__init__.py +4 -0
  234. danielutils/university/image_proccesing/encoding/lossless/huffman.py +0 -0
  235. danielutils/university/image_proccesing/encoding/lossless/lossless_encoding.py +10 -0
  236. danielutils/university/image_proccesing/encoding/lossless/lzw.py +0 -0
  237. danielutils/university/image_proccesing/encoding/lossless/run_length.py +22 -0
  238. danielutils/university/image_proccesing/encoding/lossy/__init__.py +1 -0
  239. danielutils/university/image_proccesing/encoding/lossy/lossy_encoding.py +10 -0
  240. danielutils/university/image_proccesing/tansformations/__init__.py +0 -0
  241. danielutils/university/image_proccesing/tansformations/gaussian.py +0 -0
  242. danielutils/university/image_proccesing/tansformations/gradient.py +0 -0
  243. danielutils/university/image_proccesing/tansformations/hough.py +0 -0
  244. danielutils/university/image_proccesing/tansformations/laplacian.py +0 -0
  245. danielutils/university/image_proccesing/tansformations/transformation.py +11 -0
  246. danielutils/university/linear_algebra/__init__.py +1 -0
  247. danielutils/university/linear_algebra/matrix.py +404 -0
  248. danielutils/university/machine_learning/__init__.py +0 -0
  249. danielutils/university/machine_learning/activation_functions/__init__.py +2 -0
  250. danielutils/university/machine_learning/activation_functions/activation_function.py +11 -0
  251. danielutils/university/machine_learning/activation_functions/relu.py +11 -0
  252. danielutils/university/machine_learning/neuron.py +15 -0
  253. danielutils/university/oop/__init__.py +1 -0
  254. danielutils/university/oop/observer.py +31 -0
  255. danielutils/university/oop/strategy.py +9 -0
  256. danielutils/university/probability/__init__.py +7 -0
  257. danielutils/university/probability/conditional_variable/__init__.py +3 -0
  258. danielutils/university/probability/conditional_variable/conditional_variable.py +138 -0
  259. danielutils/university/probability/conditional_variable/continuous/__init__.py +0 -0
  260. danielutils/university/probability/conditional_variable/discrete/__init__.py +8 -0
  261. danielutils/university/probability/conditional_variable/discrete/bernoulli.py +38 -0
  262. danielutils/university/probability/conditional_variable/discrete/bernoulli_sum.py +31 -0
  263. danielutils/university/probability/conditional_variable/discrete/binomial.py +40 -0
  264. danielutils/university/probability/conditional_variable/discrete/conditional_from_discrete_probability_func.py +36 -0
  265. danielutils/university/probability/conditional_variable/discrete/discrete.py +42 -0
  266. danielutils/university/probability/conditional_variable/discrete/geometric.py +43 -0
  267. danielutils/university/probability/conditional_variable/discrete/poisson.py +32 -0
  268. danielutils/university/probability/conditional_variable/discrete/uniform.py +33 -0
  269. danielutils/university/probability/distributions.py +35 -0
  270. danielutils/university/probability/expressions/__init__.py +2 -0
  271. danielutils/university/probability/expressions/accumulation_expression.py +291 -0
  272. danielutils/university/probability/expressions/probability_expression.py +110 -0
  273. danielutils/university/probability/funcs/__init__.py +4 -0
  274. danielutils/university/probability/funcs/covariance.py +12 -0
  275. danielutils/university/probability/funcs/expected_value.py +41 -0
  276. danielutils/university/probability/funcs/probability_function.py +14 -0
  277. danielutils/university/probability/funcs/variance.py +17 -0
  278. danielutils/university/probability/operator.py +79 -0
  279. danielutils/university/probability/protocols.py +32 -0
  280. danielutils/university/probability/supp.py +101 -0
  281. danielutils/university/probability/transformation.py +44 -0
  282. danielutils/versioned_imports.py +31 -0
  283. danielutils-1.1.28.dist-info/METADATA +390 -0
  284. danielutils-1.1.28.dist-info/RECORD +287 -0
  285. danielutils-1.1.28.dist-info/WHEEL +5 -0
  286. danielutils-1.1.28.dist-info/licenses/LICENSE +21 -0
  287. danielutils-1.1.28.dist-info/top_level.txt +1 -0
@@ -0,0 +1,67 @@
1
+ from typing import Generic, TypeVar, Iterable
2
+ from .factory import create_typed_class
3
+ from ...functions import isoftype
4
+ T = TypeVar("T")
5
+ parent: type = create_typed_class("tset", set)
6
+
7
+
8
+ class tset(parent, Generic[T]): # type:ignore
9
+ """like 'set' but with runtime type safety
10
+ """
11
+
12
+ def subscribable_init(self, *args, **kwargs): # pylint: disable=unused-argument
13
+ """the "real" __init__ function
14
+ """
15
+ print(self.get_params())
16
+
17
+ def add(self, value: T) -> None:
18
+ """adds an item to the set
19
+
20
+ Args:
21
+ value (T): item
22
+
23
+ Raises:
24
+ TypeError: if item is if the wrong type
25
+ """
26
+ if not isoftype(value, self.get_params()): # type:ignore
27
+ raise TypeError(
28
+ f"Can't add. Expected {self.get_params()} but got '{value}' which is {type(value)}")
29
+ set.add(self, value)
30
+
31
+ def update(self, *s: Iterable[T]) -> None:
32
+ """updates the set with another iterable
33
+ """
34
+ for value in s:
35
+ if isinstance(value, Iterable):
36
+ for subv in value:
37
+ self.update(subv) # type:ignore
38
+ else:
39
+ self.add(value) # type:ignore
40
+
41
+ def union(self, *s: Iterable[T]) -> "tset[T]":
42
+ """creates a union of two sets
43
+
44
+ Returns:
45
+ tset[T]: the resulting set
46
+ """
47
+ type_set = set(self.get_params())
48
+ for value in s:
49
+ if isinstance(value, Iterable):
50
+ for subv in value:
51
+ type_set.add(type(subv))
52
+ else:
53
+ type_set.add(type(value))
54
+ final_type = next(iter(type_set))
55
+ for t in type_set:
56
+ final_type = final_type | t
57
+ res = tset[final_type]() # type:ignore
58
+ # we can skip the type checking because they will be okay
59
+ set.update(res, self)
60
+ for value in s:
61
+ set.update(res, value)
62
+ return res
63
+
64
+
65
+ __all__ = [
66
+ "tset"
67
+ ]
@@ -0,0 +1,15 @@
1
+
2
+ from typing import Generic, TypeVar
3
+ from .factory import create_typed_class
4
+ T = TypeVar("T")
5
+ parent_ttuple: type = create_typed_class("ttuple", tuple)
6
+
7
+
8
+ class ttuple(parent_ttuple, Generic[T]):
9
+ """like tuple but with runtime type safety
10
+ """
11
+
12
+
13
+ __all__ = [
14
+ "ttuple"
15
+ ]
danielutils/colors.py ADDED
@@ -0,0 +1,203 @@
1
+ import logging
2
+ from typing import Optional, IO
3
+ from .decorators import validate
4
+ from .logging_.utils import get_logger
5
+ logger = get_logger(__name__)
6
+
7
+ RESET = "\033[0m"
8
+
9
+
10
+ class ColoredText:
11
+ """static utility class with static functions:\n
12
+ from_rgb,
13
+ green,
14
+ red,
15
+ blue,
16
+ red,
17
+ yellow,
18
+ white,
19
+ black
20
+ """
21
+
22
+ @staticmethod # type:ignore
23
+ @validate # type:ignore
24
+ def from_rgb(red: int, green: int, blue: int, text: str) -> str:
25
+ """Applies an RGB color to the given text.
26
+
27
+ Args:
28
+ red (int): The red component of the color.
29
+ green (int): The green component of the color.
30
+ blue (int): The blue component of the color.
31
+ text (str): The text to apply the color to.
32
+
33
+ Returns:
34
+ str: The given text with an RGB color applied to it.
35
+ """
36
+ logger.debug("Applying RGB color (%s, %s, %s) to text: %s...", red, green, blue, text[:50])
37
+ return f"\033[38;2;{red};{green};{blue}m{text}{RESET}"
38
+
39
+ @staticmethod
40
+ def green(text: str) -> str:
41
+ """Applies green color to the given text.
42
+
43
+ Args:
44
+ text (str): The text to apply the green color to.
45
+
46
+ Returns:
47
+ str: The given text with green color applied to it.
48
+ """
49
+ return ColoredText.from_rgb(0, 255, 0, text)
50
+
51
+ @staticmethod
52
+ def blue(text: str):
53
+ """Applies blue color to the given text.
54
+
55
+ Args:
56
+ text (str): The text to apply the blue color to.
57
+
58
+ Returns:
59
+ str: The given text with blue color applied to it.
60
+ """
61
+ return ColoredText.from_rgb(0, 0, 255, text)
62
+
63
+ @staticmethod
64
+ def red(text: str):
65
+ """Applies red color to the given text.
66
+
67
+ Args:
68
+ text (str): The text to apply the red color to.
69
+
70
+ Returns:
71
+ str: The given text with red color applied to it.
72
+ """
73
+ return ColoredText.from_rgb(255, 0, 0, text)
74
+
75
+ @staticmethod
76
+ def yellow(text: str):
77
+ """Applies yellow color to the given text.
78
+
79
+ Args:
80
+ text (str): The text to apply the yellow color to.
81
+
82
+ Returns:
83
+ str: The given text with yellow color applied to it.
84
+ """
85
+ return ColoredText.from_rgb(255, 255, 0, text)
86
+
87
+ @staticmethod
88
+ def orange(text: str):
89
+ """Applies yellow color to the given text.
90
+
91
+ Args:
92
+ text (str): The text to apply the yellow color to.
93
+
94
+ Returns:
95
+ str: The given text with yellow color applied to it.
96
+ """
97
+ return ColoredText.from_rgb(255, 165, 0, text)
98
+
99
+ @staticmethod
100
+ def white(text: str):
101
+ """Applies white color to the given text.
102
+
103
+ Args:
104
+ text (str): The text to apply the white color to.
105
+
106
+ Returns:
107
+ str: The given text with white color applied to it.
108
+ """
109
+ return ColoredText.from_rgb(255, 255, 255, text)
110
+
111
+ @staticmethod
112
+ def black(text: str):
113
+ """Applies black color to the given text.
114
+
115
+ Args:
116
+ text (str): The text to apply the black color to.
117
+
118
+ Returns:
119
+ str: The given text with black color applied to it.
120
+ """
121
+ return ColoredText.from_rgb(0, 0, 0, text)
122
+
123
+ @staticmethod
124
+ def supports_color(stream: IO) -> bool:
125
+ """return whether a stream will support colored text
126
+
127
+ Args:
128
+ stream (IO): stream to check
129
+
130
+ Returns:
131
+ bool: boolean result
132
+ """
133
+ result = stream.isatty()
134
+ logger.debug("Color support check for stream: %s", result)
135
+ return result
136
+
137
+
138
+ def __special_print(*args, sep: str = " ", end: str = "\n", start_with: Optional[str] = None):
139
+ """inner helper function"""
140
+ if start_with:
141
+ if "\n" not in sep:
142
+ print(f"{start_with}: ", end="")
143
+ print(sep.join([str(arg) for arg in args]), sep="", end=end)
144
+ else:
145
+ print(
146
+ sep.join([f"{start_with}: {str(arg)}" for arg in args]), sep="", end=end)
147
+ else:
148
+ print(*args, sep=sep, end=end)
149
+
150
+
151
+ def success(*args, sep: str = " ", end: str = "\n"):
152
+ """print a success message
153
+
154
+ Args:
155
+ sep (str, optional): print separator. Defaults to " ".
156
+ end (str, optional): print endline. Defaults to "\\n".
157
+ """
158
+
159
+ __special_print(*args, sep=sep, end=end,
160
+ start_with=ColoredText.green("SUCCESS"))
161
+
162
+
163
+ def warning(*args, sep: str = " ", end: str = "\n"):
164
+ """print a warning message
165
+
166
+ Args:
167
+ sep (str, optional): print separator. Defaults to " ".
168
+ end (str, optional): print endline. Defaults to "\\n".
169
+ """
170
+
171
+ __special_print(*args, sep=sep, end=end,
172
+ start_with=ColoredText.orange("WARNING"))
173
+
174
+
175
+ def error(*args, sep: str = " ", end: str = "\n"):
176
+ """print an error message
177
+
178
+ Args:
179
+ sep (str, optional): print separator. Defaults to " ".
180
+ end (str, optional): print endline. Defaults to "\\n".
181
+ """
182
+ __special_print(*args, sep=sep, end=end,
183
+ start_with=ColoredText.red("ERROR"))
184
+
185
+
186
+ def info(*args, sep: str = " ", end: str = "\n"):
187
+ """print an info message
188
+
189
+ Args:
190
+ sep (str, optional): print separator. Defaults to " ".
191
+ end (str, optional): print endline. Defaults to "\\n".
192
+ """
193
+ __special_print(*args, sep=sep, end=end,
194
+ start_with=ColoredText.yellow("INFO"))
195
+
196
+
197
+ __all__ = [
198
+ "ColoredText",
199
+ "success",
200
+ "warning",
201
+ "error",
202
+ "info"
203
+ ]
@@ -0,0 +1,5 @@
1
+ from .attr_context import *
2
+ from .multi_context import *
3
+ from .optional_context import *
4
+ from .state_context import *
5
+ from .temporary_file import *
@@ -0,0 +1,40 @@
1
+ import logging
2
+ from typing import ContextManager
3
+ from ..logging_.utils import get_logger
4
+
5
+ logger = get_logger(__name__)
6
+
7
+
8
+ class AttrContext(ContextManager):
9
+ def __init__(self, obj: object, attr: str, new_value: object, *, nonexistent_is_error: bool = True) -> None:
10
+ logger.debug("Initializing AttrContext for %s.%s = %s", type(obj).__name__, attr, new_value)
11
+ self.obj = obj
12
+ self.attr = attr
13
+ self.new_value = new_value
14
+ self.old_value = None
15
+ self._has_attr: bool = hasattr(self.obj, self.attr)
16
+ if nonexistent_is_error and not self._has_attr:
17
+ logger.error("Attribute '%s' does not exist on %s", self.attr, type(obj).__name__)
18
+ raise RuntimeError(f"Nonexistent attribute '{self.attr}' in '{self.obj}'")
19
+ logger.debug("AttrContext initialized successfully, has_attr=%s", self._has_attr)
20
+
21
+ def __enter__(self) -> 'AttrContext':
22
+ logger.debug("Entering AttrContext for %s.%s", type(self.obj).__name__, self.attr)
23
+ self.old_value = getattr(self.obj, self.attr, None)
24
+ setattr(self.obj, self.attr, self.new_value)
25
+ logger.info("Attribute %s set to %s (was %s)", self.attr, self.new_value, self.old_value)
26
+ return self
27
+
28
+ def __exit__(self, exc_type, exc_val, exc_tb):
29
+ logger.debug("Exiting AttrContext for %s.%s, exc_type=%s", type(self.obj).__name__, self.attr, exc_type)
30
+ if self._has_attr:
31
+ setattr(self.obj, self.attr, self.old_value)
32
+ logger.info("Attribute %s restored to %s", self.attr, self.old_value)
33
+ else:
34
+ delattr(self.obj, self.attr)
35
+ logger.info("Temporary attribute %s removed", self.attr)
36
+
37
+
38
+ __all__ = [
39
+ 'AttrContext'
40
+ ]
@@ -0,0 +1,34 @@
1
+ import logging
2
+ from typing import ContextManager
3
+ from ..logging_.utils import get_logger
4
+
5
+ logger = get_logger(__name__)
6
+
7
+
8
+ class MultiContext(ContextManager):
9
+ def __init__(self, *contexts: ContextManager):
10
+ logger.debug("Initializing MultiContext with %s contexts", len(contexts))
11
+ self.contexts = contexts
12
+
13
+ def __enter__(self):
14
+ logger.info("Entering MultiContext with %s contexts", len(self.contexts))
15
+ for i, context in enumerate(self.contexts):
16
+ logger.debug("Entering context %s/%s: %s", i+1, len(self.contexts), type(context).__name__)
17
+ context.__enter__()
18
+ logger.debug("All contexts entered successfully")
19
+ return self
20
+
21
+ def __exit__(self, exc_type, exc_val, exc_tb):
22
+ logger.debug("Exiting MultiContext with %s contexts, exc_type=%s", len(self.contexts), exc_type)
23
+ for i, context in enumerate(self.contexts):
24
+ logger.debug("Exiting context %s/%s: %s", i+1, len(self.contexts), type(context).__name__)
25
+ context.__exit__(exc_type, exc_val, exc_tb)
26
+ logger.info("All contexts exited")
27
+
28
+ def __getitem__(self, index):
29
+ return self.contexts[index]
30
+
31
+
32
+ __all__ = [
33
+ "MultiContext",
34
+ ]
@@ -0,0 +1,33 @@
1
+ import logging
2
+ from typing import ContextManager
3
+ from ..logging_.utils import get_logger
4
+
5
+ logger = get_logger(__name__)
6
+
7
+
8
+ class OptionalContext(ContextManager):
9
+ def __init__(self, predicate: bool, context: ContextManager):
10
+ logger.debug("Initializing OptionalContext with predicate=%s, context=%s", predicate, type(context).__name__)
11
+ self.predicate = predicate
12
+ self.context = context
13
+
14
+ def __enter__(self):
15
+ logger.debug("Entering OptionalContext with predicate=%s", self.predicate)
16
+ if self.predicate:
17
+ logger.info("Condition met, entering context: %s", type(self.context).__name__)
18
+ self.context.__enter__()
19
+ else:
20
+ logger.debug("Condition not met, skipping context entry")
21
+
22
+ def __exit__(self, __exc_type, __exc_value, __traceback):
23
+ logger.debug("Exiting OptionalContext with predicate=%s, exc_type=%s", self.predicate, __exc_type)
24
+ if self.predicate:
25
+ logger.info("Condition was met, exiting context: %s", type(self.context).__name__)
26
+ self.context.__exit__(__exc_type, __exc_value, __traceback)
27
+ else:
28
+ logger.debug("Condition was not met, no context to exit")
29
+
30
+
31
+ __all__=[
32
+ "OptionalContext"
33
+ ]
@@ -0,0 +1,25 @@
1
+ import logging
2
+ from contextlib import contextmanager
3
+ from ..custom_types import Procedure
4
+ from ..logging_.utils import get_logger
5
+
6
+ logger = get_logger(__name__)
7
+
8
+
9
+ @contextmanager
10
+ def StateContext(set_state: Procedure, restore_state: Procedure):
11
+ logger.debug("Entering StateContext")
12
+ try:
13
+ logger.info("Setting state")
14
+ set_state()
15
+ logger.debug("State set successfully, yielding control")
16
+ yield
17
+ finally:
18
+ logger.info("Restoring state")
19
+ restore_state()
20
+ logger.debug("State restored successfully")
21
+
22
+
23
+ __all__ = [
24
+ 'StateContext'
25
+ ]
@@ -0,0 +1,108 @@
1
+ import atexit
2
+ import logging
3
+ import random
4
+ from typing import ContextManager, Set, List, Literal, Optional
5
+ from ..io_ import file_exists, delete_file
6
+ from ..logging_.utils import get_logger
7
+
8
+ logger = get_logger(__name__)
9
+
10
+
11
+ class TemporaryFile(ContextManager):
12
+ _instances: Set['TemporaryFile'] = set()
13
+
14
+ @classmethod
15
+ def random(cls, length: int = 10, /, type: Literal["file", "folder"] = "file", prefix: Optional[str] = None,
16
+ suffix: Optional[str] = None) -> 'TemporaryFile':
17
+ from danielutils import RandomDataGenerator
18
+ temp_name = f"{type}_"
19
+ if prefix is not None:
20
+ temp_name += f"{prefix}_"
21
+
22
+ temp_name += RandomDataGenerator.name(length)
23
+ if suffix is not None:
24
+ temp_name += f"_{suffix}"
25
+ logger.debug("Creating random temporary file: %s", temp_name)
26
+ return TemporaryFile(temp_name)
27
+
28
+ def __init__(self, path: str):
29
+ if file_exists(path):
30
+ logger.error("Can't create temporary file - file already exists: %s", path)
31
+ raise RuntimeError(f"Can't create a temporary file if file '{path}' already exists.")
32
+ self.path = path
33
+ TemporaryFile._instances.add(self)
34
+ logger.debug("TemporaryFile created: %s", path)
35
+
36
+ def __enter__(self):
37
+ logger.debug("TemporaryFile context entered: %s", self.path)
38
+ return self
39
+
40
+ def __exit__(self, exc_type, exc_val, exc_tb):
41
+ if exc_type is not None:
42
+ logger.warning("TemporaryFile context exited with exception: %s: %s", exc_type.__name__, exc_val)
43
+ else:
44
+ logger.debug("TemporaryFile context exited successfully: %s", self.path)
45
+ self.close()
46
+
47
+ def __str__(self) -> str:
48
+ return self.path
49
+
50
+ def close(self) -> None:
51
+ logger.debug("Closing temporary file: %s", self.path)
52
+ delete_file(self.path)
53
+
54
+ def read(self) -> str:
55
+ if not file_exists(self.path):
56
+ logger.debug("Temporary file does not exist for reading: %s", self.path)
57
+ return ""
58
+ logger.debug("Reading temporary file: %s", self.path)
59
+ with open(self.path, 'r') as f:
60
+ return f.read()
61
+
62
+ def readbinary(self) -> bytes:
63
+ if not file_exists(self.path):
64
+ logger.debug("Temporary file does not exist for binary reading: %s", self.path)
65
+ return b""
66
+ logger.debug("Reading temporary file as binary: %s", self.path)
67
+ with open(self.path, 'rb') as f:
68
+ return f.read()
69
+
70
+ def readlines(self) -> List[str]:
71
+ if not file_exists(self.path):
72
+ logger.debug("Temporary file does not exist for reading lines: %s", self.path)
73
+ return []
74
+ logger.debug("Reading lines from temporary file: %s", self.path)
75
+ with open(self.path, 'r') as f:
76
+ return f.readlines()
77
+
78
+ def write(self, s: str) -> None:
79
+ logger.debug("Writing to temporary file: %s", self.path)
80
+ with open(self.path, 'a') as f:
81
+ f.write(s)
82
+
83
+ def writebinary(self, s: bytes) -> None:
84
+ logger.debug("Writing binary data to temporary file: %s", self.path)
85
+ with open(self.path, 'ab') as f:
86
+ f.write(s)
87
+
88
+ def writelines(self, lines: List[str]) -> None:
89
+ logger.debug("Writing %s lines to temporary file: %s", len(lines), self.path)
90
+ with open(self.path, 'a') as f:
91
+ f.writelines(lines)
92
+
93
+ def clear(self):
94
+ logger.debug("Clearing temporary file: %s", self.path)
95
+ with open(self.path, 'w') as _:
96
+ pass
97
+
98
+
99
+ @atexit.register
100
+ def __close_all():
101
+ logger.debug("Closing %s temporary files at exit", len(TemporaryFile._instances))
102
+ for inst in TemporaryFile._instances: # type:ignore #pylint: disable=all
103
+ inst.close()
104
+
105
+
106
+ __all__ = [
107
+ 'TemporaryFile'
108
+ ]
@@ -0,0 +1,12 @@
1
+ """class for convenience"""
2
+
3
+
4
+ class DisablePytestDiscovery:
5
+ """inheriting from this class will disable pytest discovery
6
+ """
7
+ __test__ = False
8
+
9
+
10
+ __all__ = [
11
+ "DisablePytestDiscovery"
12
+ ]
@@ -0,0 +1,2 @@
1
+ from .main_conversions import *
2
+ from .specialized_conversions import *
@@ -0,0 +1,131 @@
1
+ from ..decorators import validate
2
+
3
+
4
+ @validate # type:ignore
5
+ def char_to_int(c: str) -> int:
6
+ """convert char to its representing int value
7
+
8
+ Args:
9
+ c (str): char to convert
10
+
11
+ Returns:
12
+ int: int value
13
+ """
14
+ return ord(c)
15
+
16
+
17
+ @validate # type:ignore
18
+ def int_to_char(num: int) -> str:
19
+ """convert int to its corresponding char
20
+
21
+ Args:
22
+ num (int): number to convert
23
+
24
+ Returns:
25
+ str: result character
26
+ """
27
+ return chr(num)
28
+
29
+
30
+ @validate # type:ignore
31
+ def hex_to_char(h: str) -> str:
32
+ """convert hex number to char
33
+
34
+ Args:
35
+ h (str): number to convert
36
+
37
+ Returns:
38
+ str: result char
39
+ """
40
+ return int_to_char(hex_to_dec(h))
41
+
42
+
43
+ @validate # type:ignore
44
+ def hex_to_dec(h: str) -> int:
45
+ """convert hex to dec
46
+
47
+ Args:
48
+ h (str): converts base 16 to base 10
49
+
50
+ Returns:
51
+ int: decimal value for hex number
52
+ """
53
+ return int(h, 16)
54
+
55
+
56
+ @validate # type:ignore
57
+ def char_to_hex(c: str) -> str:
58
+ """convert char to hex
59
+
60
+ Args:
61
+ c (str): char to convert
62
+
63
+ Returns:
64
+ str: hex representation
65
+ """
66
+ return int_to_hex(char_to_int(c))
67
+
68
+
69
+ @validate # type:ignore
70
+ def dec_to_hex(num: int) -> str:
71
+ """convert decimal number to hex
72
+
73
+ Args:
74
+ num (int): number to convert
75
+
76
+ Returns:
77
+ str: _description_
78
+ """
79
+ return int_to_hex(num)
80
+
81
+
82
+ @validate # type:ignore
83
+ def int_to_hex(num: int) -> str:
84
+ """converts an int to it's hex representation
85
+
86
+ Args:
87
+ num (int): int to convert
88
+
89
+ Returns:
90
+ str: the hex representation of the int
91
+ """
92
+ return hex(num)
93
+
94
+
95
+ @validate # type:ignore
96
+ def bytes_to_str(b: bytes) -> str:
97
+ """decodes bytes to str
98
+
99
+ Args:
100
+ b (bytes): bytes to decode
101
+
102
+ Returns:
103
+ str: result
104
+ """
105
+ return b.decode("utf-8")
106
+
107
+
108
+ @validate # type:ignore
109
+ def str_to_bytes(s: str) -> bytes:
110
+ """encodes a string to bytes
111
+
112
+ Args:
113
+ s (str): the string to encode
114
+
115
+ Returns:
116
+ bytes: result
117
+ """
118
+ return bytes(s, encoding='utf-8')
119
+
120
+
121
+ __all__ = [
122
+ "char_to_int",
123
+ "int_to_char",
124
+ "hex_to_char",
125
+ "hex_to_dec",
126
+ "char_to_hex",
127
+ "dec_to_hex",
128
+ "int_to_hex",
129
+ "bytes_to_str",
130
+ "str_to_bytes"
131
+ ]
@@ -0,0 +1,2 @@
1
+ from .to_hex import *
2
+ from .to_int import *