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