danielutils 0.9.80__tar.gz → 0.9.82__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 (186) hide show
  1. {danielutils-0.9.80/danielutils.egg-info → danielutils-0.9.82}/PKG-INFO +2 -2
  2. {danielutils-0.9.80 → danielutils-0.9.82}/README.md +1 -1
  3. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/__init__.py +2 -1
  4. danielutils-0.9.82/danielutils/context_managers/__init__.py +2 -0
  5. danielutils-0.9.82/danielutils/context_managers/attr_context.py +25 -0
  6. danielutils-0.9.82/danielutils/context_managers/temporary_file.py +46 -0
  7. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/system/__init__.py +1 -0
  8. danielutils-0.9.82/danielutils/system/layered_command.py +110 -0
  9. {danielutils-0.9.80 → danielutils-0.9.82/danielutils.egg-info}/PKG-INFO +2 -2
  10. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils.egg-info/SOURCES.txt +4 -0
  11. {danielutils-0.9.80 → danielutils-0.9.82}/pyproject.toml +1 -1
  12. {danielutils-0.9.80 → danielutils-0.9.82}/LICENSE +0 -0
  13. {danielutils-0.9.80 → danielutils-0.9.82}/MANIFEST.in +0 -0
  14. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/abstractions/__init__.py +0 -0
  15. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/abstractions/database/__init__.py +0 -0
  16. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/abstractions/database/cached_database.py +0 -0
  17. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/abstractions/database/database.py +0 -0
  18. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/abstractions/database/redis_database.py +0 -0
  19. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/abstractions/multiprogramming/__init__.py +0 -0
  20. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/abstractions/multiprogramming/multi_id.py +0 -0
  21. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/abstractions/multiprogramming/worker.py +0 -0
  22. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/abstractions/multiprogramming/worker_pool.py +0 -0
  23. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/abstractions/repl.py +0 -0
  24. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/aliases.py +0 -0
  25. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/better_builtins/__init__.py +0 -0
  26. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/better_builtins/counter.py +0 -0
  27. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/better_builtins/frange.py +0 -0
  28. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/better_builtins/typed_builtins/__init__.py +0 -0
  29. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/better_builtins/typed_builtins/factory.py +0 -0
  30. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/better_builtins/typed_builtins/tdict.py +0 -0
  31. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/better_builtins/typed_builtins/tlist.py +0 -0
  32. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/better_builtins/typed_builtins/tset.py +0 -0
  33. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/better_builtins/typed_builtins/ttuple.py +0 -0
  34. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/colors.py +0 -0
  35. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/convenience.py +0 -0
  36. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/conversions/__init__.py +0 -0
  37. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/conversions/main_conversions.py +0 -0
  38. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/conversions/specialized_conversions/__init__.py +0 -0
  39. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/conversions/specialized_conversions/to_hex.py +0 -0
  40. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/conversions/specialized_conversions/to_int.py +0 -0
  41. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/data_structures/__init__.py +0 -0
  42. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/data_structures/comparer.py +0 -0
  43. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/data_structures/default_dict.py +0 -0
  44. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/data_structures/functions.py +0 -0
  45. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/data_structures/graph/__init__.py +0 -0
  46. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/data_structures/graph/binary_node.py +0 -0
  47. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/data_structures/graph/graph.py +0 -0
  48. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/data_structures/graph/multinode.py +0 -0
  49. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/data_structures/graph/node.py +0 -0
  50. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/data_structures/heap/__init__.py +0 -0
  51. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/data_structures/heap/heap.py +0 -0
  52. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/data_structures/heap/max_heap.py +0 -0
  53. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/data_structures/heap/min_heap.py +0 -0
  54. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/data_structures/queue/__init__.py +0 -0
  55. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/data_structures/queue/atomic_queue.py +0 -0
  56. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/data_structures/queue/priority_queue.py +0 -0
  57. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/data_structures/queue/queue.py +0 -0
  58. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/data_structures/stack.py +0 -0
  59. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/data_structures/trees/__init__.py +0 -0
  60. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/data_structures/trees/binary_syntax_tree.py +0 -0
  61. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/data_structures/trees/binary_tree.py +0 -0
  62. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/date.py +0 -0
  63. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/date_time.py +0 -0
  64. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/decorators/__init__.py +0 -0
  65. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/decorators/atomic.py +0 -0
  66. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/decorators/attach.py +0 -0
  67. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/decorators/chain_decorators.py +0 -0
  68. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/decorators/decorate_conditionally.py +0 -0
  69. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/decorators/delay_call.py +0 -0
  70. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/decorators/deprecate.py +0 -0
  71. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/decorators/final.py +0 -0
  72. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/decorators/limit_recursion.py +0 -0
  73. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/decorators/memo.py +0 -0
  74. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/decorators/overload.py +0 -0
  75. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/decorators/partially_implemented.py +0 -0
  76. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/decorators/processify.py +0 -0
  77. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/decorators/property.py +0 -0
  78. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/decorators/singleton.py +0 -0
  79. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/decorators/threadify.py +0 -0
  80. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/decorators/timeout.py +0 -0
  81. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/decorators/total_ordering.py +0 -0
  82. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/decorators/validate.py +0 -0
  83. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/exceptions.py +0 -0
  84. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/functions/__init__.py +0 -0
  85. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/functions/areoneof.py +0 -0
  86. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/functions/check_foreach.py +0 -0
  87. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/functions/flatten.py +0 -0
  88. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/functions/isoftype.py +0 -0
  89. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/functions/isoneof.py +0 -0
  90. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/functions/multiloop.py +0 -0
  91. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/functions/powerset.py +0 -0
  92. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/functions/subseteq.py +0 -0
  93. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/functions/types_subseteq.py +0 -0
  94. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/generators/__init__.py +0 -0
  95. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/generators/conditional_generator.py +0 -0
  96. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/generators/generator_from_stream.py +0 -0
  97. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/generators/join_generators.py +0 -0
  98. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/internet.py +0 -0
  99. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/io_.py +0 -0
  100. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/math_/__init__.py +0 -0
  101. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/math_/constants.py +0 -0
  102. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/math_/functions.py +0 -0
  103. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/math_/math_print.py +0 -0
  104. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/math_/math_symbols.py +0 -0
  105. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/math_/polynomial/__init__.py +0 -0
  106. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/math_/polynomial/polinomial.py +0 -0
  107. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/metaclasses/__init__.py +0 -0
  108. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/metaclasses/atomic_class_meta.py +0 -0
  109. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/metaclasses/implicit_data_deleter_meta.py +0 -0
  110. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/metaclasses/instance_cache_meta.py +0 -0
  111. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/metaclasses/interface.py +0 -0
  112. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/metaclasses/overload_meta.py +0 -0
  113. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/mock_/__init__.py +0 -0
  114. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/mock_/mock_database.py +0 -0
  115. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/mock_/mock_module.py +0 -0
  116. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/path.py +0 -0
  117. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/print_.py +0 -0
  118. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/protocols/__init__.py +0 -0
  119. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/protocols/dictable.py +0 -0
  120. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/protocols/evaluable.py +0 -0
  121. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/py.typed +0 -0
  122. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/reflection/__init__.py +0 -0
  123. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/reflection/class_/__init__.py +0 -0
  124. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/reflection/class_/class_reflection.py +0 -0
  125. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/reflection/file/__init__.py +0 -0
  126. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/reflection/file/file_reflection.py +0 -0
  127. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/reflection/function/__init__.py +0 -0
  128. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/reflection/function/function_reflections.py +0 -0
  129. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/reflection/interpreter/__init__.py +0 -0
  130. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/reflection/interpreter/callstack.py +0 -0
  131. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/reflection/interpreter/get_traceback.py +0 -0
  132. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/reflection/interpreter/os_.py +0 -0
  133. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/reflection/interpreter/packages.py +0 -0
  134. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/reflection/interpreter/python_version.py +0 -0
  135. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/reflection/interpreter/signals.py +0 -0
  136. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/reflection/interpreter/tracer.py +0 -0
  137. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/reflection/module/__init__.py +0 -0
  138. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/reflection/module/module_reflections.py +0 -0
  139. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/reflection/module/package_reflection.py +0 -0
  140. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/snippets/__init__.py +0 -0
  141. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/snippets/try_get.py +0 -0
  142. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/system/independent.py +0 -0
  143. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/system/windows/__init__.py +0 -0
  144. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/system/windows/utils/__init__.py +0 -0
  145. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/system/windows/utils/filetime.py +0 -0
  146. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/system/windows/win32_ctime.py +0 -0
  147. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/system/windows/windows.py +0 -0
  148. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/text.py +0 -0
  149. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/time.py +0 -0
  150. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/tqdm_.py +0 -0
  151. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/university/__init__.py +0 -0
  152. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/university/databases/__init__.py +0 -0
  153. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/university/databases/all.py +0 -0
  154. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/university/oop/__init__.py +0 -0
  155. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/university/oop/observer.py +0 -0
  156. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/university/oop/strategy.py +0 -0
  157. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/university/probability/__init__.py +0 -0
  158. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/university/probability/conditional_variable/__init__.py +0 -0
  159. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/university/probability/conditional_variable/conditional_variable.py +0 -0
  160. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/university/probability/conditional_variable/continuous/__init__.py +0 -0
  161. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/university/probability/conditional_variable/discrete/__init__.py +0 -0
  162. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/university/probability/conditional_variable/discrete/bernoulli.py +0 -0
  163. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/university/probability/conditional_variable/discrete/binomial.py +0 -0
  164. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/university/probability/conditional_variable/discrete/conditional_from_discrete_probability_func.py +0 -0
  165. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/university/probability/conditional_variable/discrete/discrete.py +0 -0
  166. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/university/probability/conditional_variable/discrete/geometric.py +0 -0
  167. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/university/probability/conditional_variable/discrete/poisson.py +0 -0
  168. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/university/probability/conditional_variable/discrete/uniform.py +0 -0
  169. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/university/probability/distributions.py +0 -0
  170. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/university/probability/expressions/__init__.py +0 -0
  171. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/university/probability/expressions/accumulation_expression.py +0 -0
  172. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/university/probability/expressions/probability_expression.py +0 -0
  173. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/university/probability/funcs/__init__.py +0 -0
  174. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/university/probability/funcs/covariance.py +0 -0
  175. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/university/probability/funcs/expected_value.py +0 -0
  176. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/university/probability/funcs/probability_function.py +0 -0
  177. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/university/probability/funcs/variance.py +0 -0
  178. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/university/probability/operator.py +0 -0
  179. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/university/probability/protocols.py +0 -0
  180. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/university/probability/supp.py +0 -0
  181. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/university/probability/transformation.py +0 -0
  182. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/versioned_imports.py +0 -0
  183. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils.egg-info/dependency_links.txt +0 -0
  184. {danielutils-0.9.80 → danielutils-0.9.82}/danielutils.egg-info/top_level.txt +0 -0
  185. {danielutils-0.9.80 → danielutils-0.9.82}/setup.cfg +0 -0
  186. {danielutils-0.9.80 → danielutils-0.9.82}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: danielutils
3
- Version: 0.9.80
3
+ Version: 0.9.82
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
@@ -41,7 +41,7 @@ License-File: LICENSE
41
41
  [![Python 3.10.11](https://img.shields.io/badge/python-3.10.11-blue.svg)](https://www.python.org/downloads/release/python-31011/)
42
42
  [![gitleaks](https://github.com/danielnachumdev/danielutils/actions/workflows/gitleaks.yml/badge.svg)](https://github.com/danielnachumdev/danielutils/actions/workflows/gitleaks.yml)
43
43
  [![CodeQL](https://github.com/danielnachumdev/danielutils/actions/workflows/github-code-scanning/codeql/badge.svg)](https://github.com/danielnachumdev/danielutils/actions/workflows/github-code-scanning/codeql)
44
- # danielutils v=0.9.80
44
+ # danielutils v=0.9.82
45
45
  A utils library for things that I find useful for my coding workflow.\
46
46
  Feel free to use and / or contribute / improve my code :)
47
47
 
@@ -4,7 +4,7 @@
4
4
  [![Python 3.10.11](https://img.shields.io/badge/python-3.10.11-blue.svg)](https://www.python.org/downloads/release/python-31011/)
5
5
  [![gitleaks](https://github.com/danielnachumdev/danielutils/actions/workflows/gitleaks.yml/badge.svg)](https://github.com/danielnachumdev/danielutils/actions/workflows/gitleaks.yml)
6
6
  [![CodeQL](https://github.com/danielnachumdev/danielutils/actions/workflows/github-code-scanning/codeql/badge.svg)](https://github.com/danielnachumdev/danielutils/actions/workflows/github-code-scanning/codeql)
7
- # danielutils v=0.9.80
7
+ # danielutils v=0.9.82
8
8
  A utils library for things that I find useful for my coding workflow.\
9
9
  Feel free to use and / or contribute / improve my code :)
10
10
 
@@ -39,4 +39,5 @@ from .print_ import *
39
39
  from .metaclasses import *
40
40
  from .generators import *
41
41
  from .university import *
42
- from .mock_ import *
42
+ from .mock_ import *
43
+ from .context_managers import *
@@ -0,0 +1,2 @@
1
+ from .temporary_file import *
2
+ from .attr_context import *
@@ -0,0 +1,25 @@
1
+ class AttrContext:
2
+ def __init__(self, obj: object, attr: str, new_value: object, *, nonexistent_is_error: bool = True) -> None:
3
+ self.obj = obj
4
+ self.attr = attr
5
+ self.new_value = new_value
6
+ self.old_value = None
7
+ self._has_attr: bool = hasattr(self.obj, self.attr)
8
+ if nonexistent_is_error and not self._has_attr:
9
+ raise RuntimeError(f"Nonexistent attribute '{self.attr}' in '{self.obj}'")
10
+
11
+ def __enter__(self) -> 'AttrContext':
12
+ self.old_value = getattr(self.obj, self.attr, None)
13
+ setattr(self.obj, self.attr, self.new_value)
14
+ return self
15
+
16
+ def __exit__(self, exc_type, exc_val, exc_tb):
17
+ if self._has_attr:
18
+ setattr(self.obj, self.attr, self.old_value)
19
+ else:
20
+ delattr(self.obj, self.attr)
21
+
22
+
23
+ __all__ = [
24
+ 'AttrContext'
25
+ ]
@@ -0,0 +1,46 @@
1
+ from ..io_ import file_exists, delete_file
2
+ import atexit
3
+
4
+
5
+ class TemporaryFile:
6
+ _instances: set['TemporaryFile'] = set()
7
+
8
+ def __init__(self, path: str):
9
+ if file_exists(path):
10
+ raise RuntimeError(f"Can't create a temporary file if file '{path}' already exists.")
11
+ self.path = path
12
+ TemporaryFile._instances.add(self)
13
+
14
+ def __enter__(self):
15
+ return self
16
+
17
+ def __exit__(self, exc_type, exc_val, exc_tb):
18
+ self.close()
19
+
20
+ @atexit.register
21
+ @staticmethod
22
+ def _global_close():
23
+ for inst in TemporaryFile._instances:
24
+ inst.close()
25
+
26
+ def close(self) -> None:
27
+ delete_file(self.path)
28
+
29
+ def read(self) -> list[str]:
30
+ if not file_exists(self.path):
31
+ return []
32
+ with open(self.path, 'r') as f:
33
+ return f.readlines()
34
+
35
+ def write(self, lines: list[str]) -> None:
36
+ with open(self.path, 'a') as f:
37
+ f.writelines(lines)
38
+
39
+ def clear(self):
40
+ with open(self.path, 'w') as _:
41
+ pass
42
+
43
+
44
+ __all__ = [
45
+ 'TemporaryFile'
46
+ ]
@@ -1,2 +1,3 @@
1
1
  from .independent import *
2
2
  from .windows import *
3
+ from .layered_command import *
@@ -0,0 +1,110 @@
1
+ import sys, os
2
+ from typing import Optional
3
+ from ..context_managers import TemporaryFile
4
+ import random
5
+
6
+
7
+ class LayeredCommand:
8
+ class_flush_stdout: bool = True
9
+ class_flush_stderr: bool = True
10
+ class_raise_on_fail: bool = True
11
+ class_verbose: bool = False
12
+ _class_prev_instance: Optional['LayeredCommand'] = None
13
+ _id: int = 0
14
+
15
+ def __init__(
16
+ self,
17
+ command: Optional[str] = None,
18
+ *,
19
+ prev_instance: Optional['LayeredCommand'] = None,
20
+ instance_flush_stdout: Optional[bool] = None,
21
+ instance_flush_stderr: Optional[bool] = None,
22
+ instance_raise_on_fail: Optional[bool] = None,
23
+ instance_verbose: Optional[bool] = None
24
+ ):
25
+ self._command = command if command is not None else ""
26
+ self._instance_flush_stdout = instance_flush_stdout
27
+ self._instance_flush_stderr = instance_flush_stderr
28
+ self._instance_raise_on_fail = instance_raise_on_fail
29
+ self._instance_verbose = instance_verbose
30
+ self._prev_instance = prev_instance if prev_instance is not None else LayeredCommand._class_prev_instance
31
+ self._cur_class_prev_instance = LayeredCommand._class_prev_instance
32
+ LayeredCommand._class_prev_instance = self
33
+ self._executor = os.system
34
+ self._has_entered: bool = False
35
+
36
+ def __enter__(self):
37
+ self._open()
38
+ return self
39
+
40
+ def _open(self) -> None:
41
+ self._has_entered = True
42
+
43
+ def __exit__(self, exc_type, exc_val, exc_tb):
44
+ if self._prev_instance is self._cur_class_prev_instance:
45
+ LayeredCommand._class_prev_instance = self._prev_instance
46
+
47
+ def _build_command(self, *commands: str) -> str:
48
+ res = ""
49
+ if self._prev_instance is not None:
50
+ prev = self._prev_instance._build_command()
51
+ res += f"{prev} & " if prev != "" else ""
52
+ if self._command != "":
53
+ return res + " & ".join([self._command, *commands])
54
+ return res + " & ".join(commands)
55
+
56
+ def _error(self, predicate: bool, command: str, code: int, command_verbose: Optional[bool]) -> None:
57
+ if predicate:
58
+ verbose = self._merge_values(command_verbose, self._instance_verbose, LayeredCommand.class_verbose)
59
+ if verbose:
60
+ raise RuntimeError(f"command '{command}' failed with exit code {code}")
61
+ sys.exit(1)
62
+
63
+ @staticmethod
64
+ def _merge_values(command: Optional[bool], instance: Optional[bool], class_: bool) -> bool:
65
+ return command if command is not None else (instance if instance is not None else class_)
66
+
67
+ def execute(
68
+ self,
69
+ *commands: str,
70
+ command_flush_stdout: Optional[bool] = None,
71
+ command_flush_stderr: Optional[bool] = None,
72
+ command_raise_on_fail: Optional[bool] = None,
73
+ command_verbose: Optional[bool] = None
74
+ ) -> tuple[int, list[str], list[str]]:
75
+ if not self._has_entered:
76
+ raise RuntimeError(
77
+ "LayeredCommand must be used with a context manager. Use as: `with LayeredCommand(...) as l1:`")
78
+ flush_stdout = self._merge_values(command_flush_stdout, self._instance_flush_stdout, self.class_flush_stdout)
79
+ flush_stderr = self._merge_values(command_flush_stderr, self._instance_flush_stderr, self.class_flush_stderr)
80
+ raise_on_fail = self._merge_values(command_raise_on_fail, self._instance_raise_on_fail,
81
+ self.class_raise_on_fail)
82
+
83
+ command = self._build_command(*commands)
84
+ if flush_stdout and flush_stderr:
85
+ code = self._executor(command)
86
+ self._error(raise_on_fail and code != 0, command, code, command_verbose)
87
+ return code, [], []
88
+
89
+ letters = "abcdefghijklmnopqrstuvwxyz"
90
+ temp_name = "".join(random.choices(letters, k=50)) + f"_{LayeredCommand._id}"
91
+ stdout_path = f"./{temp_name}_stdout.log"
92
+ stderr_path = f"./{temp_name}_stderr.log"
93
+ LayeredCommand._id += 1
94
+ with TemporaryFile(stdout_path) as stdout:
95
+ with TemporaryFile(stderr_path) as stderr:
96
+ if not flush_stdout:
97
+ command += f" > {stdout_path}"
98
+ if not flush_stderr:
99
+ command += f" 2> {stderr_path}"
100
+ code = self._executor(command)
101
+ self._error(raise_on_fail and code != 0, command, code, command_verbose)
102
+ return code, stdout.read(), stderr.read()
103
+
104
+ def __call__(self, *args, **kwargs) -> tuple[int, list[str], list[str]]:
105
+ return self.execute(*args, **kwargs)
106
+
107
+
108
+ __all__ = [
109
+ 'LayeredCommand'
110
+ ]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: danielutils
3
- Version: 0.9.80
3
+ Version: 0.9.82
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
@@ -41,7 +41,7 @@ License-File: LICENSE
41
41
  [![Python 3.10.11](https://img.shields.io/badge/python-3.10.11-blue.svg)](https://www.python.org/downloads/release/python-31011/)
42
42
  [![gitleaks](https://github.com/danielnachumdev/danielutils/actions/workflows/gitleaks.yml/badge.svg)](https://github.com/danielnachumdev/danielutils/actions/workflows/gitleaks.yml)
43
43
  [![CodeQL](https://github.com/danielnachumdev/danielutils/actions/workflows/github-code-scanning/codeql/badge.svg)](https://github.com/danielnachumdev/danielutils/actions/workflows/github-code-scanning/codeql)
44
- # danielutils v=0.9.80
44
+ # danielutils v=0.9.82
45
45
  A utils library for things that I find useful for my coding workflow.\
46
46
  Feel free to use and / or contribute / improve my code :)
47
47
 
@@ -42,6 +42,9 @@ danielutils/better_builtins/typed_builtins/tdict.py
42
42
  danielutils/better_builtins/typed_builtins/tlist.py
43
43
  danielutils/better_builtins/typed_builtins/tset.py
44
44
  danielutils/better_builtins/typed_builtins/ttuple.py
45
+ danielutils/context_managers/__init__.py
46
+ danielutils/context_managers/attr_context.py
47
+ danielutils/context_managers/temporary_file.py
45
48
  danielutils/conversions/__init__.py
46
49
  danielutils/conversions/main_conversions.py
47
50
  danielutils/conversions/specialized_conversions/__init__.py
@@ -142,6 +145,7 @@ danielutils/snippets/__init__.py
142
145
  danielutils/snippets/try_get.py
143
146
  danielutils/system/__init__.py
144
147
  danielutils/system/independent.py
148
+ danielutils/system/layered_command.py
145
149
  danielutils/system/windows/__init__.py
146
150
  danielutils/system/windows/win32_ctime.py
147
151
  danielutils/system/windows/windows.py
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "danielutils"
7
- version = "0.9.80"
7
+ version = "0.9.82"
8
8
  authors = [
9
9
  { name = "danielnachumdev", email = "danielnachumdev@gmail.com" },
10
10
  ]
File without changes
File without changes
File without changes
File without changes