danielutils 1.0.1__tar.gz → 1.0.3__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 (265) hide show
  1. {danielutils-1.0.1/danielutils.egg-info → danielutils-1.0.3}/PKG-INFO +1 -1
  2. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/__init__.py +1 -0
  3. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/context_managers/temporary_file.py +10 -0
  4. {danielutils-1.0.1/danielutils/Functions → danielutils-1.0.3/danielutils/functions}/isoftype.py +1 -5
  5. danielutils-1.0.3/danielutils/java/interfaces/comparable.py +31 -0
  6. danielutils-1.0.3/danielutils/java/java_interface.py +41 -0
  7. danielutils-1.0.3/danielutils/logging_/__init__.py +4 -0
  8. danielutils-1.0.3/danielutils/logging_/builtin_impls/__init__.py +2 -0
  9. danielutils-1.0.3/danielutils/logging_/builtin_impls/file_logger.py +25 -0
  10. danielutils-1.0.3/danielutils/logging_/builtin_impls/print_logger.py +11 -0
  11. danielutils-1.0.3/danielutils/logging_/log_level.py +13 -0
  12. danielutils-1.0.3/danielutils/logging_/logger.py +99 -0
  13. danielutils-1.0.3/danielutils/logging_/logger_strategy_impl_base.py +29 -0
  14. danielutils-1.0.3/danielutils/lombok/__init__.py +1 -0
  15. danielutils-1.0.3/danielutils/lombok/builder.py +49 -0
  16. {danielutils-1.0.1/danielutils/Reflection → danielutils-1.0.3/danielutils/reflection}/class_info.py +25 -3
  17. {danielutils-1.0.1/danielutils/Reflection → danielutils-1.0.3/danielutils/reflection}/decoration_info.py +1 -1
  18. {danielutils-1.0.1/danielutils/Reflection → danielutils-1.0.3/danielutils/reflection}/function_info.py +2 -2
  19. danielutils-1.0.3/danielutils/testing/unittest_/always_teardown_testcase.py +67 -0
  20. danielutils-1.0.3/danielutils/testing/unittest_/auto_cwd_testcase.py +92 -0
  21. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/versioned_imports.py +3 -1
  22. {danielutils-1.0.1 → danielutils-1.0.3/danielutils.egg-info}/PKG-INFO +1 -1
  23. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils.egg-info/SOURCES.txt +11 -42
  24. {danielutils-1.0.1 → danielutils-1.0.3}/pyproject.toml +1 -1
  25. danielutils-1.0.1/danielutils/java/interfaces/comparable.py +0 -31
  26. danielutils-1.0.1/danielutils/java/java_interface.py +0 -33
  27. danielutils-1.0.1/danielutils/testing/unittest_/always_teardown_testcase.py +0 -37
  28. danielutils-1.0.1/danielutils/testing/unittest_/auto_cwd_testcase.py +0 -49
  29. {danielutils-1.0.1 → danielutils-1.0.3}/LICENSE +0 -0
  30. {danielutils-1.0.1 → danielutils-1.0.3}/MANIFEST.in +0 -0
  31. {danielutils-1.0.1 → danielutils-1.0.3}/README.md +0 -0
  32. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/abstractions/__init__.py +0 -0
  33. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/abstractions/database/__init__.py +0 -0
  34. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/abstractions/database/cached_database.py +0 -0
  35. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/abstractions/database/database.py +0 -0
  36. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/abstractions/database/redis_database.py +0 -0
  37. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/abstractions/multiprogramming/__init__.py +0 -0
  38. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/abstractions/multiprogramming/multi_id.py +0 -0
  39. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/abstractions/multiprogramming/worker.py +0 -0
  40. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/abstractions/multiprogramming/worker_pool.py +0 -0
  41. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/abstractions/repl.py +0 -0
  42. /danielutils-1.0.1/danielutils/Aliases.py → /danielutils-1.0.3/danielutils/aliases.py +0 -0
  43. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/better_builtins/__init__.py +0 -0
  44. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/better_builtins/counter.py +0 -0
  45. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/better_builtins/frange.py +0 -0
  46. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/better_builtins/typed_builtins/__init__.py +0 -0
  47. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/better_builtins/typed_builtins/factory.py +0 -0
  48. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/better_builtins/typed_builtins/tdict.py +0 -0
  49. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/better_builtins/typed_builtins/tlist.py +0 -0
  50. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/better_builtins/typed_builtins/tset.py +0 -0
  51. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/better_builtins/typed_builtins/ttuple.py +0 -0
  52. /danielutils-1.0.1/danielutils/Colors.py → /danielutils-1.0.3/danielutils/colors.py +0 -0
  53. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/context_managers/__init__.py +0 -0
  54. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/context_managers/attr_context.py +0 -0
  55. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/context_managers/multi_context.py +0 -0
  56. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/context_managers/optional_context.py +0 -0
  57. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/context_managers/state_context.py +0 -0
  58. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/convenience.py +0 -0
  59. {danielutils-1.0.1/danielutils/Conversions → danielutils-1.0.3/danielutils/conversions}/__init__.py +0 -0
  60. {danielutils-1.0.1/danielutils/Conversions → danielutils-1.0.3/danielutils/conversions}/main_conversions.py +0 -0
  61. {danielutils-1.0.1/danielutils/Conversions → danielutils-1.0.3/danielutils/conversions}/specialized_conversions/__init__.py +0 -0
  62. {danielutils-1.0.1/danielutils/Conversions → danielutils-1.0.3/danielutils/conversions}/specialized_conversions/to_hex.py +0 -0
  63. {danielutils-1.0.1/danielutils/Conversions → danielutils-1.0.3/danielutils/conversions}/specialized_conversions/to_int.py +0 -0
  64. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/custom_types.py +0 -0
  65. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/data_structures/__init__.py +0 -0
  66. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/data_structures/algorithms.py +0 -0
  67. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/data_structures/comparer.py +0 -0
  68. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/data_structures/default_dict.py +0 -0
  69. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/data_structures/functions.py +0 -0
  70. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/data_structures/graph/__init__.py +0 -0
  71. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/data_structures/graph/binary_node.py +0 -0
  72. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/data_structures/graph/graph.py +0 -0
  73. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/data_structures/graph/multinode.py +0 -0
  74. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/data_structures/graph/node.py +0 -0
  75. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/data_structures/heap/__init__.py +0 -0
  76. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/data_structures/heap/heap.py +0 -0
  77. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/data_structures/heap/max_heap.py +0 -0
  78. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/data_structures/heap/min_heap.py +0 -0
  79. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/data_structures/queue/__init__.py +0 -0
  80. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/data_structures/queue/atomic_queue.py +0 -0
  81. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/data_structures/queue/priority_queue.py +0 -0
  82. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/data_structures/queue/queue.py +0 -0
  83. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/data_structures/stack.py +0 -0
  84. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/data_structures/trees/__init__.py +0 -0
  85. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/data_structures/trees/binary_syntax_tree.py +0 -0
  86. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/data_structures/trees/binary_tree.py +0 -0
  87. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/date.py +0 -0
  88. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/date_time.py +0 -0
  89. {danielutils-1.0.1/danielutils/Decorators → danielutils-1.0.3/danielutils/decorators}/__init__.py +0 -0
  90. {danielutils-1.0.1/danielutils/Decorators → danielutils-1.0.3/danielutils/decorators}/atomic.py +0 -0
  91. {danielutils-1.0.1/danielutils/Decorators → danielutils-1.0.3/danielutils/decorators}/attach.py +0 -0
  92. {danielutils-1.0.1/danielutils/Decorators → danielutils-1.0.3/danielutils/decorators}/chain_decorators.py +0 -0
  93. {danielutils-1.0.1/danielutils/Decorators → danielutils-1.0.3/danielutils/decorators}/decorate_conditionally.py +0 -0
  94. {danielutils-1.0.1/danielutils/Decorators → danielutils-1.0.3/danielutils/decorators}/delay_call.py +0 -0
  95. {danielutils-1.0.1/danielutils/Decorators → danielutils-1.0.3/danielutils/decorators}/deprecate.py +0 -0
  96. {danielutils-1.0.1/danielutils/Decorators → danielutils-1.0.3/danielutils/decorators}/final.py +0 -0
  97. {danielutils-1.0.1/danielutils/Decorators → danielutils-1.0.3/danielutils/decorators}/limit_recursion.py +0 -0
  98. {danielutils-1.0.1/danielutils/Decorators → danielutils-1.0.3/danielutils/decorators}/memo.py +0 -0
  99. {danielutils-1.0.1/danielutils/Decorators → danielutils-1.0.3/danielutils/decorators}/overload.py +0 -0
  100. {danielutils-1.0.1/danielutils/Decorators → danielutils-1.0.3/danielutils/decorators}/partially_implemented.py +0 -0
  101. {danielutils-1.0.1/danielutils/Decorators → danielutils-1.0.3/danielutils/decorators}/processify.py +0 -0
  102. {danielutils-1.0.1/danielutils/Decorators → danielutils-1.0.3/danielutils/decorators}/property.py +0 -0
  103. {danielutils-1.0.1/danielutils/Decorators → danielutils-1.0.3/danielutils/decorators}/singleton.py +0 -0
  104. {danielutils-1.0.1/danielutils/Decorators → danielutils-1.0.3/danielutils/decorators}/threadify.py +0 -0
  105. {danielutils-1.0.1/danielutils/Decorators → danielutils-1.0.3/danielutils/decorators}/timeout.py +0 -0
  106. {danielutils-1.0.1/danielutils/Decorators → danielutils-1.0.3/danielutils/decorators}/total_ordering.py +0 -0
  107. {danielutils-1.0.1/danielutils/Decorators → danielutils-1.0.3/danielutils/decorators}/validate.py +0 -0
  108. /danielutils-1.0.1/danielutils/Exceptions.py → /danielutils-1.0.3/danielutils/exceptions.py +0 -0
  109. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/file_specifications/__init__.py +0 -0
  110. {danielutils-1.0.1/danielutils/Functions → danielutils-1.0.3/danielutils/functions}/__init__.py +0 -0
  111. {danielutils-1.0.1/danielutils/Functions → danielutils-1.0.3/danielutils/functions}/areoneof.py +0 -0
  112. {danielutils-1.0.1/danielutils/Functions → danielutils-1.0.3/danielutils/functions}/check_foreach.py +0 -0
  113. {danielutils-1.0.1/danielutils/Functions → danielutils-1.0.3/danielutils/functions}/factorial.py +0 -0
  114. {danielutils-1.0.1/danielutils/Functions → danielutils-1.0.3/danielutils/functions}/flatten.py +0 -0
  115. {danielutils-1.0.1/danielutils/Functions → danielutils-1.0.3/danielutils/functions}/foreach.py +0 -0
  116. {danielutils-1.0.1/danielutils/Functions → danielutils-1.0.3/danielutils/functions}/isoneof.py +0 -0
  117. {danielutils-1.0.1/danielutils/Functions → danielutils-1.0.3/danielutils/functions}/multiloop.py +0 -0
  118. {danielutils-1.0.1/danielutils/Functions → danielutils-1.0.3/danielutils/functions}/parallel_for.py +0 -0
  119. {danielutils-1.0.1/danielutils/Functions → danielutils-1.0.3/danielutils/functions}/partition.py +0 -0
  120. {danielutils-1.0.1/danielutils/Functions → danielutils-1.0.3/danielutils/functions}/powerset.py +0 -0
  121. {danielutils-1.0.1/danielutils/Functions → danielutils-1.0.3/danielutils/functions}/subseteq.py +0 -0
  122. {danielutils-1.0.1/danielutils/Functions → danielutils-1.0.3/danielutils/functions}/types_subseteq.py +0 -0
  123. {danielutils-1.0.1/danielutils/Generators → danielutils-1.0.3/danielutils/generators}/__init__.py +0 -0
  124. {danielutils-1.0.1/danielutils/Generators → danielutils-1.0.3/danielutils/generators}/conditional_generator.py +0 -0
  125. {danielutils-1.0.1/danielutils/Generators → danielutils-1.0.3/danielutils/generators}/generator_from_stream.py +0 -0
  126. {danielutils-1.0.1/danielutils/Generators → danielutils-1.0.3/danielutils/generators}/join_generators.py +0 -0
  127. /danielutils-1.0.1/danielutils/Internet.py → /danielutils-1.0.3/danielutils/internet.py +0 -0
  128. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/io_.py +0 -0
  129. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/java/__init__.py +0 -0
  130. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/java/interfaces/__init__.py +0 -0
  131. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/math_/__init__.py +0 -0
  132. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/math_/constants.py +0 -0
  133. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/math_/functions.py +0 -0
  134. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/math_/math_print.py +0 -0
  135. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/math_/math_symbols.py +0 -0
  136. {danielutils-1.0.1/danielutils/MetaClasses → danielutils-1.0.3/danielutils/metaclasses}/__init__.py +0 -0
  137. {danielutils-1.0.1/danielutils/MetaClasses → danielutils-1.0.3/danielutils/metaclasses}/atomic_class_meta.py +0 -0
  138. {danielutils-1.0.1/danielutils/MetaClasses → danielutils-1.0.3/danielutils/metaclasses}/implicit_data_deleter_meta.py +0 -0
  139. {danielutils-1.0.1/danielutils/MetaClasses → danielutils-1.0.3/danielutils/metaclasses}/instance_cache_meta.py +0 -0
  140. /danielutils-1.0.1/danielutils/MetaClasses/Interface.py → /danielutils-1.0.3/danielutils/metaclasses/interface.py +0 -0
  141. {danielutils-1.0.1/danielutils/MetaClasses → danielutils-1.0.3/danielutils/metaclasses}/overload_meta.py +0 -0
  142. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/mock_/__init__.py +0 -0
  143. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/mock_/mock_database.py +0 -0
  144. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/mock_/mock_module.py +0 -0
  145. /danielutils-1.0.1/danielutils/Path.py → /danielutils-1.0.3/danielutils/path.py +0 -0
  146. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/print_.py +0 -0
  147. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/progress_bar/__init__.py +0 -0
  148. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/progress_bar/ascii_progress_bar.py +0 -0
  149. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/progress_bar/progress_bar.py +0 -0
  150. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/progress_bar/progress_bar_pool.py +0 -0
  151. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/protocols/__init__.py +0 -0
  152. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/protocols/dictable.py +0 -0
  153. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/protocols/evaluable.py +0 -0
  154. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/protocols/serializable.py +0 -0
  155. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/py.typed +0 -0
  156. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/random_.py +0 -0
  157. {danielutils-1.0.1/danielutils/Reflection → danielutils-1.0.3/danielutils/reflection}/__init__.py +0 -0
  158. {danielutils-1.0.1/danielutils/Reflection → danielutils-1.0.3/danielutils/reflection}/argument_info.py +0 -0
  159. {danielutils-1.0.1/danielutils/Reflection → danielutils-1.0.3/danielutils/reflection}/class_/__init__.py +0 -0
  160. {danielutils-1.0.1/danielutils/Reflection → danielutils-1.0.3/danielutils/reflection}/class_/class_reflection.py +0 -0
  161. {danielutils-1.0.1/danielutils/Reflection → danielutils-1.0.3/danielutils/reflection}/file/__init__.py +0 -0
  162. {danielutils-1.0.1/danielutils/Reflection → danielutils-1.0.3/danielutils/reflection}/file/file_reflection.py +0 -0
  163. {danielutils-1.0.1/danielutils/Reflection → danielutils-1.0.3/danielutils/reflection}/function/__init__.py +0 -0
  164. {danielutils-1.0.1/danielutils/Reflection → danielutils-1.0.3/danielutils/reflection}/function/function_reflections.py +0 -0
  165. {danielutils-1.0.1/danielutils/Reflection → danielutils-1.0.3/danielutils/reflection}/interpreter/__init__.py +0 -0
  166. {danielutils-1.0.1/danielutils/Reflection → danielutils-1.0.3/danielutils/reflection}/interpreter/callstack.py +0 -0
  167. {danielutils-1.0.1/danielutils/Reflection → danielutils-1.0.3/danielutils/reflection}/interpreter/get_traceback.py +0 -0
  168. {danielutils-1.0.1/danielutils/Reflection → danielutils-1.0.3/danielutils/reflection}/interpreter/interpreter.py +0 -0
  169. {danielutils-1.0.1/danielutils/Reflection → danielutils-1.0.3/danielutils/reflection}/interpreter/is_debugging.py +0 -0
  170. {danielutils-1.0.1/danielutils/Reflection → danielutils-1.0.3/danielutils/reflection}/interpreter/os_.py +0 -0
  171. {danielutils-1.0.1/danielutils/Reflection → danielutils-1.0.3/danielutils/reflection}/interpreter/packages.py +0 -0
  172. {danielutils-1.0.1/danielutils/Reflection → danielutils-1.0.3/danielutils/reflection}/interpreter/python_version.py +0 -0
  173. {danielutils-1.0.1/danielutils/Reflection → danielutils-1.0.3/danielutils/reflection}/interpreter/signals.py +0 -0
  174. {danielutils-1.0.1/danielutils/Reflection → danielutils-1.0.3/danielutils/reflection}/interpreter/tracer.py +0 -0
  175. {danielutils-1.0.1/danielutils/Reflection → danielutils-1.0.3/danielutils/reflection}/module/__init__.py +0 -0
  176. {danielutils-1.0.1/danielutils/Reflection → danielutils-1.0.3/danielutils/reflection}/module/module_reflections.py +0 -0
  177. {danielutils-1.0.1/danielutils/Reflection → danielutils-1.0.3/danielutils/reflection}/module/package_reflection.py +0 -0
  178. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/retry_executor/__init__.py +0 -0
  179. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/retry_executor/backoff_strategies/__init__.py +0 -0
  180. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/retry_executor/backoff_strategies/constant_backoff.py +0 -0
  181. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/retry_executor/backoff_strategies/exponential_backoff.py +0 -0
  182. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/retry_executor/backoff_strategies/functional_backoff.py +0 -0
  183. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/retry_executor/backoff_strategies/linear_backoff.py +0 -0
  184. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/retry_executor/backoff_strategies/multiplicative_backoff.py +0 -0
  185. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/retry_executor/backoff_strategies/no_backoff.py +0 -0
  186. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/retry_executor/backoff_strategy.py +0 -0
  187. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/retry_executor/retry_executor.py +0 -0
  188. {danielutils-1.0.1/danielutils/Snippets → danielutils-1.0.3/danielutils/snippets}/__init__.py +0 -0
  189. {danielutils-1.0.1/danielutils/Snippets → danielutils-1.0.3/danielutils/snippets}/try_get.py +0 -0
  190. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/system/__init__.py +0 -0
  191. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/system/independent.py +0 -0
  192. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/system/layered_command.py +0 -0
  193. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/system/windows/__init__.py +0 -0
  194. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/system/windows/utils/__init__.py +0 -0
  195. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/system/windows/utils/filetime.py +0 -0
  196. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/system/windows/win32_ctime.py +0 -0
  197. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/system/windows/windows.py +0 -0
  198. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/testing/__init__.py +0 -0
  199. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils/testing/unittest_/__init__.py +0 -0
  200. /danielutils-1.0.1/danielutils/Text.py → /danielutils-1.0.3/danielutils/text.py +0 -0
  201. /danielutils-1.0.1/danielutils/Time.py → /danielutils-1.0.3/danielutils/time.py +0 -0
  202. {danielutils-1.0.1/danielutils/University → danielutils-1.0.3/danielutils/university}/__init__.py +0 -0
  203. {danielutils-1.0.1/danielutils/University → danielutils-1.0.3/danielutils/university}/computability_and_complexity/__init__.py +0 -0
  204. {danielutils-1.0.1/danielutils/University → danielutils-1.0.3/danielutils/university}/computability_and_complexity/discreate_finite_automaton.py +0 -0
  205. {danielutils-1.0.1/danielutils/University → danielutils-1.0.3/danielutils/university}/computability_and_complexity/languages/__init__.py +0 -0
  206. {danielutils-1.0.1/danielutils/University → danielutils-1.0.3/danielutils/university}/computability_and_complexity/languages/language.py +0 -0
  207. {danielutils-1.0.1/danielutils/University → danielutils-1.0.3/danielutils/university}/computability_and_complexity/languages/sat.py +0 -0
  208. {danielutils-1.0.1/danielutils/University → danielutils-1.0.3/danielutils/university}/computability_and_complexity/turing_machine.py +0 -0
  209. {danielutils-1.0.1/danielutils/University/Databases → danielutils-1.0.3/danielutils/university/databases}/__init__.py +0 -0
  210. {danielutils-1.0.1/danielutils/University/Databases → danielutils-1.0.3/danielutils/university/databases}/all.py +0 -0
  211. {danielutils-1.0.1/danielutils/University → danielutils-1.0.3/danielutils/university}/image_proccesing/__init__.py +0 -0
  212. {danielutils-1.0.1/danielutils/University → danielutils-1.0.3/danielutils/university}/image_proccesing/encoding/__init__.py +0 -0
  213. {danielutils-1.0.1/danielutils/University → danielutils-1.0.3/danielutils/university}/image_proccesing/encoding/encoding.py +0 -0
  214. {danielutils-1.0.1/danielutils/University → danielutils-1.0.3/danielutils/university}/image_proccesing/encoding/lossless/__init__.py +0 -0
  215. {danielutils-1.0.1/danielutils/University → danielutils-1.0.3/danielutils/university}/image_proccesing/encoding/lossless/huffman.py +0 -0
  216. {danielutils-1.0.1/danielutils/University → danielutils-1.0.3/danielutils/university}/image_proccesing/encoding/lossless/lossless_encoding.py +0 -0
  217. {danielutils-1.0.1/danielutils/University → danielutils-1.0.3/danielutils/university}/image_proccesing/encoding/lossless/lzw.py +0 -0
  218. {danielutils-1.0.1/danielutils/University → danielutils-1.0.3/danielutils/university}/image_proccesing/encoding/lossless/run_length.py +0 -0
  219. {danielutils-1.0.1/danielutils/University → danielutils-1.0.3/danielutils/university}/image_proccesing/encoding/lossy/__init__.py +0 -0
  220. {danielutils-1.0.1/danielutils/University → danielutils-1.0.3/danielutils/university}/image_proccesing/encoding/lossy/lossy_encoding.py +0 -0
  221. {danielutils-1.0.1/danielutils/University → danielutils-1.0.3/danielutils/university}/image_proccesing/tansformations/__init__.py +0 -0
  222. {danielutils-1.0.1/danielutils/University → danielutils-1.0.3/danielutils/university}/image_proccesing/tansformations/gaussian.py +0 -0
  223. {danielutils-1.0.1/danielutils/University → danielutils-1.0.3/danielutils/university}/image_proccesing/tansformations/gradient.py +0 -0
  224. {danielutils-1.0.1/danielutils/University → danielutils-1.0.3/danielutils/university}/image_proccesing/tansformations/hough.py +0 -0
  225. {danielutils-1.0.1/danielutils/University → danielutils-1.0.3/danielutils/university}/image_proccesing/tansformations/laplacian.py +0 -0
  226. {danielutils-1.0.1/danielutils/University → danielutils-1.0.3/danielutils/university}/image_proccesing/tansformations/transformation.py +0 -0
  227. {danielutils-1.0.1/danielutils/University → danielutils-1.0.3/danielutils/university}/linear_algebra/__init__.py +0 -0
  228. {danielutils-1.0.1/danielutils/University → danielutils-1.0.3/danielutils/university}/linear_algebra/matrix.py +0 -0
  229. {danielutils-1.0.1/danielutils/University → danielutils-1.0.3/danielutils/university}/machine_learning/__init__.py +0 -0
  230. {danielutils-1.0.1/danielutils/University → danielutils-1.0.3/danielutils/university}/machine_learning/activation_functions/__init__.py +0 -0
  231. {danielutils-1.0.1/danielutils/University → danielutils-1.0.3/danielutils/university}/machine_learning/activation_functions/activation_function.py +0 -0
  232. {danielutils-1.0.1/danielutils/University → danielutils-1.0.3/danielutils/university}/machine_learning/activation_functions/relu.py +0 -0
  233. {danielutils-1.0.1/danielutils/University → danielutils-1.0.3/danielutils/university}/machine_learning/neuron.py +0 -0
  234. {danielutils-1.0.1/danielutils/University → danielutils-1.0.3/danielutils/university}/oop/__init__.py +0 -0
  235. {danielutils-1.0.1/danielutils/University → danielutils-1.0.3/danielutils/university}/oop/observer.py +0 -0
  236. {danielutils-1.0.1/danielutils/University → danielutils-1.0.3/danielutils/university}/oop/strategy.py +0 -0
  237. {danielutils-1.0.1/danielutils/University → danielutils-1.0.3/danielutils/university}/probability/__init__.py +0 -0
  238. {danielutils-1.0.1/danielutils/University → danielutils-1.0.3/danielutils/university}/probability/conditional_variable/__init__.py +0 -0
  239. {danielutils-1.0.1/danielutils/University → danielutils-1.0.3/danielutils/university}/probability/conditional_variable/conditional_variable.py +0 -0
  240. {danielutils-1.0.1/danielutils/University → danielutils-1.0.3/danielutils/university}/probability/conditional_variable/continuous/__init__.py +0 -0
  241. {danielutils-1.0.1/danielutils/University → danielutils-1.0.3/danielutils/university}/probability/conditional_variable/discrete/__init__.py +0 -0
  242. {danielutils-1.0.1/danielutils/University → danielutils-1.0.3/danielutils/university}/probability/conditional_variable/discrete/bernoulli.py +0 -0
  243. {danielutils-1.0.1/danielutils/University → danielutils-1.0.3/danielutils/university}/probability/conditional_variable/discrete/binomial.py +0 -0
  244. {danielutils-1.0.1/danielutils/University → danielutils-1.0.3/danielutils/university}/probability/conditional_variable/discrete/conditional_from_discrete_probability_func.py +0 -0
  245. {danielutils-1.0.1/danielutils/University → danielutils-1.0.3/danielutils/university}/probability/conditional_variable/discrete/discrete.py +0 -0
  246. {danielutils-1.0.1/danielutils/University → danielutils-1.0.3/danielutils/university}/probability/conditional_variable/discrete/geometric.py +0 -0
  247. {danielutils-1.0.1/danielutils/University → danielutils-1.0.3/danielutils/university}/probability/conditional_variable/discrete/poisson.py +0 -0
  248. {danielutils-1.0.1/danielutils/University → danielutils-1.0.3/danielutils/university}/probability/conditional_variable/discrete/uniform.py +0 -0
  249. {danielutils-1.0.1/danielutils/University → danielutils-1.0.3/danielutils/university}/probability/distributions.py +0 -0
  250. {danielutils-1.0.1/danielutils/University → danielutils-1.0.3/danielutils/university}/probability/expressions/__init__.py +0 -0
  251. {danielutils-1.0.1/danielutils/University → danielutils-1.0.3/danielutils/university}/probability/expressions/accumulation_expression.py +0 -0
  252. {danielutils-1.0.1/danielutils/University → danielutils-1.0.3/danielutils/university}/probability/expressions/probability_expression.py +0 -0
  253. {danielutils-1.0.1/danielutils/University → danielutils-1.0.3/danielutils/university}/probability/funcs/__init__.py +0 -0
  254. {danielutils-1.0.1/danielutils/University → danielutils-1.0.3/danielutils/university}/probability/funcs/covariance.py +0 -0
  255. {danielutils-1.0.1/danielutils/University → danielutils-1.0.3/danielutils/university}/probability/funcs/expected_value.py +0 -0
  256. {danielutils-1.0.1/danielutils/University → danielutils-1.0.3/danielutils/university}/probability/funcs/probability_function.py +0 -0
  257. {danielutils-1.0.1/danielutils/University → danielutils-1.0.3/danielutils/university}/probability/funcs/variance.py +0 -0
  258. {danielutils-1.0.1/danielutils/University → danielutils-1.0.3/danielutils/university}/probability/operator.py +0 -0
  259. {danielutils-1.0.1/danielutils/University → danielutils-1.0.3/danielutils/university}/probability/protocols.py +0 -0
  260. {danielutils-1.0.1/danielutils/University → danielutils-1.0.3/danielutils/university}/probability/supp.py +0 -0
  261. {danielutils-1.0.1/danielutils/University → danielutils-1.0.3/danielutils/university}/probability/transformation.py +0 -0
  262. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils.egg-info/dependency_links.txt +0 -0
  263. {danielutils-1.0.1 → danielutils-1.0.3}/danielutils.egg-info/top_level.txt +0 -0
  264. {danielutils-1.0.1 → danielutils-1.0.3}/setup.cfg +0 -0
  265. {danielutils-1.0.1 → danielutils-1.0.3}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: danielutils
3
- Version: 1.0.1
3
+ Version: 1.0.3
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
@@ -45,3 +45,4 @@ from .testing import *
45
45
  from .retry_executor import *
46
46
  from .java import *
47
47
  from .random_ import *
48
+ from .lombok import *
@@ -44,6 +44,12 @@ class TemporaryFile(ContextManager):
44
44
  with open(self.path, 'r') as f:
45
45
  return f.read()
46
46
 
47
+ def readbinary(self) -> bytes:
48
+ if not file_exists(self.path):
49
+ return b""
50
+ with open(self.path, 'rb') as f:
51
+ return f.read()
52
+
47
53
  def readlines(self) -> List[str]:
48
54
  if not file_exists(self.path):
49
55
  return []
@@ -54,6 +60,10 @@ class TemporaryFile(ContextManager):
54
60
  with open(self.path, 'a') as f:
55
61
  f.write(s)
56
62
 
63
+ def writebinary(self, s: bytes) -> None:
64
+ with open(self.path, 'ab') as f:
65
+ f.write(s)
66
+
57
67
  def writelines(self, lines: List[str]) -> None:
58
68
  with open(self.path, 'a') as f:
59
69
  f.writelines(lines)
@@ -431,8 +431,4 @@ def isoftype(V: Any, T: Any, /, strict: bool = True) -> bool:
431
431
 
432
432
  __all__ = [
433
433
  "isoftype"
434
- ]
435
-
436
- __all__ = [
437
- "isoftype"
438
- ]
434
+ ]
@@ -0,0 +1,31 @@
1
+ # from abc import abstractmethod
2
+ # from typing import TypeVar, Generic
3
+ #
4
+ # from ..java_interface import JavaInterface
5
+ #
6
+ # T = TypeVar('T')
7
+ #
8
+ #
9
+ # class Comparable(JavaInterface, Generic[T]):
10
+ # @abstractmethod
11
+ # def __lt__(self, other: T) -> bool: ...
12
+ #
13
+ # @abstractmethod
14
+ # def __gt__(self, other: T) -> bool: ...
15
+ #
16
+ # @abstractmethod
17
+ # def __eq__(self, other: T) -> bool: ...
18
+ #
19
+ # @abstractmethod
20
+ # def __le__(self, other: T) -> bool: ...
21
+ #
22
+ # @abstractmethod
23
+ # def __ge__(self, other: T) -> bool: ...
24
+ #
25
+ # @abstractmethod
26
+ # def __ne__(self, other: T) -> bool: ...
27
+ #
28
+ #
29
+ # __all__ = [
30
+ # "Comparable",
31
+ # ]
@@ -0,0 +1,41 @@
1
+
2
+ from abc import abstractmethod, ABC
3
+ from typing import Protocol, runtime_checkable, Any, Callable, ParamSpec, Generic
4
+ from ..reflection import ClassInfo
5
+
6
+
7
+ class InterfaceError(Exception):
8
+ ...
9
+
10
+
11
+ # @runtime_checkable
12
+ class JavaInterface(ABC):
13
+ InterfaceError = InterfaceError
14
+
15
+ @classmethod
16
+ def __init_subclass__(cls, **kwargs) -> None:
17
+ info = ClassInfo(cls)
18
+ for base in info.bases:
19
+ if base.name == JavaInterface.__name__:
20
+ setattr(cls, "__is_interface__", True)
21
+ break
22
+ else:
23
+ setattr(cls, "__is_interface__", False)
24
+ info = ClassInfo(cls)
25
+ print(set(info.functions))
26
+ print(set(info.inherited_methods))
27
+ actual_func_names = set(f.name for f in info.functions)
28
+ for to_remove in {"__class_getitem__", "__init_subclass__"}:
29
+ if getattr(cls, to_remove, None) is getattr(JavaInterface, to_remove, None):
30
+ actual_func_names.remove(to_remove)
31
+ for interface in (base for base in cls.__mro__ if getattr(base, "__is_interface__", False)):
32
+ expected_func_names = set(f.name for f in ClassInfo(interface).abstract_methods)
33
+ if subtraction := expected_func_names.difference(actual_func_names):
34
+ raise InterfaceError(
35
+ f"class '{cls.__name__}' does not implement required methods {subtraction}")
36
+ super().__init_subclass__(**kwargs)
37
+
38
+
39
+ __all__ = [
40
+ "JavaInterface",
41
+ ]
@@ -0,0 +1,4 @@
1
+ from .builtin_impls import *
2
+ from .log_level import *
3
+ from .logger import *
4
+ from .logger_strategy_impl_base import *
@@ -0,0 +1,2 @@
1
+ from .print_logger import *
2
+ from .file_logger import *
@@ -0,0 +1,25 @@
1
+ from pathlib import Path
2
+
3
+ from danielutils import delete_file, directory_exists, create_directory
4
+
5
+ from ..logger_strategy_impl_base import LoggerStrategyImplBase
6
+
7
+
8
+ class FIleLogger(LoggerStrategyImplBase):
9
+ def __init__(self, output_path: str, logger_id: str, delete_if_already_exists: bool = True, channel: str = "all"):
10
+ if delete_if_already_exists:
11
+ delete_file(output_path)
12
+ if not directory_exists(parent := str(Path(output_path).parent.absolute().resolve())):
13
+ create_directory(parent)
14
+ self.output_path: str = str(Path(output_path).absolute().resolve())
15
+
16
+ def foo(s: str):
17
+ with open(self.output_path, "a+") as f:
18
+ f.write(s)
19
+
20
+ super().__init__(foo, logger_id, channel)
21
+
22
+
23
+ __all__ = [
24
+ "FIleLogger"
25
+ ]
@@ -0,0 +1,11 @@
1
+ from ..logger_strategy_impl_base import LoggerStrategyImplBase
2
+
3
+
4
+ class PrintLogger(LoggerStrategyImplBase):
5
+ def __init__(self, logger_id: str, channel: str = "all"):
6
+ super().__init__(lambda s: print(s, end=""), logger_id, channel)
7
+
8
+
9
+ __all__ = [
10
+ "PrintLogger"
11
+ ]
@@ -0,0 +1,13 @@
1
+ from enum import IntEnum
2
+
3
+
4
+ class LogLevel(IntEnum):
5
+ DEBUG = 0
6
+ INFO = 1
7
+ WARNING = 2
8
+ ERROR = 3
9
+
10
+
11
+ __all__ = [
12
+ "LogLevel"
13
+ ]
@@ -0,0 +1,99 @@
1
+ import json
2
+ from datetime import datetime
3
+ from typing import Type, Optional, Dict, List
4
+
5
+ from .log_level import LogLevel
6
+ from .logger_strategy_impl_base import LoggerStrategyImplBase
7
+
8
+
9
+ class _LoggerImpl:
10
+ def __init__(self, origin: Type):
11
+ self.origin = origin
12
+
13
+ @classmethod
14
+ def parse_message(
15
+ cls,
16
+ origin: Type,
17
+ logger_id: Optional,
18
+ channel: str,
19
+ level: LogLevel,
20
+ message: str,
21
+ module: Optional[str] = None,
22
+ cls_name: Optional[str] = None,
23
+ metadata: Optional[Dict] = None
24
+ ) -> str:
25
+ d = dict(
26
+ timestamp=str(datetime.now()),
27
+ origin=origin.__qualname__,
28
+ logger_id=logger_id,
29
+ channel=channel,
30
+ level=level.name,
31
+ message=message
32
+ )
33
+ if module:
34
+ d.update({'module': module})
35
+
36
+ if cls_name:
37
+ d.update({'cls': cls_name})
38
+
39
+ if metadata:
40
+ d.update({'metadata': metadata})
41
+ s = json.dumps(d)
42
+ return f"{s}\n"
43
+
44
+ def _log(self, level: LogLevel, message: str, channel: str, **metadata):
45
+ message = str(message)
46
+ for logger in LoggerStrategyImplBase._loggers[channel]:
47
+ logger(self.parse_message(
48
+ self.origin,
49
+ logger.logger_id,
50
+ channel,
51
+ level,
52
+ message,
53
+ metadata.get("cls", {}).get("__module__", None),
54
+ metadata.pop("cls", {}).get("__qualname__", None),
55
+ metadata
56
+ ))
57
+
58
+ def debug(self, message: str, channel: str = "all", **metadata):
59
+ self._log(LogLevel.DEBUG, message, channel, **metadata)
60
+
61
+ def info(self, message: str, channel: str = "all", **metadata):
62
+ self._log(LogLevel.INFO, message, channel, **metadata)
63
+
64
+ def warning(self, message: str, channel: str = "all", **metadata):
65
+ self._log(LogLevel.WARNING, message, channel, **metadata)
66
+
67
+ def error(self, message: str, channel: str = "all", **metadata):
68
+ self._log(LogLevel.ERROR, message, channel, **metadata)
69
+
70
+
71
+ class Logger:
72
+ @classmethod
73
+ def __init_subclass__(cls, **kwargs):
74
+ cls._logger = _LoggerImpl(cls)
75
+ cls._registered_loggers: List[LoggerStrategyImplBase] = []
76
+ cls.init_subscribers()
77
+
78
+ @classmethod
79
+ @property
80
+ def logger(cls) -> _LoggerImpl:
81
+ return cls._logger
82
+
83
+ @classmethod
84
+ def init_subscribers(cls):
85
+ pass
86
+
87
+ @classmethod
88
+ def register_logger(cls, logger: LoggerStrategyImplBase) -> None:
89
+ cls._registered_loggers.append(logger)
90
+
91
+
92
+ class GlobalLogger(Logger):
93
+ pass
94
+
95
+
96
+ __all__ = [
97
+ "Logger",
98
+ "GlobalLogger"
99
+ ]
@@ -0,0 +1,29 @@
1
+ from collections import defaultdict
2
+ from typing import Dict, List, Callable
3
+
4
+
5
+ class LoggerStrategyImplBase:
6
+ _loggers: Dict[str, List['LoggerStrategyImplBase']] = defaultdict(list)
7
+
8
+ def __init__(self, output_func: Callable[[str], None], logger_id: str, channel: str = "all"):
9
+ self.output_func: Callable[[str], None] = output_func
10
+ self.channel: str = channel
11
+ self.logger_id: str = logger_id
12
+ LoggerStrategyImplBase._loggers[channel].append(self)
13
+
14
+ def __call__(self, s: str) -> None:
15
+ self.output_func(s)
16
+
17
+ def delete(self) -> None:
18
+ LoggerStrategyImplBase._loggers[self.channel].remove(self)
19
+
20
+ def __enter__(self):
21
+ return self
22
+
23
+ def __exit__(self, exc_type, exc_val, exc_tb):
24
+ self.delete()
25
+
26
+
27
+ __all__ = [
28
+ "LoggerStrategyImplBase"
29
+ ]
@@ -0,0 +1 @@
1
+ from .builder import *
@@ -0,0 +1,49 @@
1
+ from typing import Type, Generic, TypeVar
2
+
3
+ T = TypeVar("T", bound=Type)
4
+
5
+
6
+ class Builder(Generic[T]):
7
+ PREFIX: str = "foo"
8
+
9
+ def __init__(self, dcls: T):
10
+ setattr(self, f"{Builder.PREFIX}_dcls", dcls)
11
+ setattr(self, f"{Builder.PREFIX}_kwargs", {})
12
+
13
+ def __getattribute__(self, item: str):
14
+ if item.startswith(Builder.PREFIX) or item == "build":
15
+ return super().__getattribute__(item)
16
+ cls = super().__getattribute__(f"{Builder.PREFIX}_dcls")
17
+ if item not in cls.__dataclass_fields__:
18
+ raise AttributeError(f"'{cls.__qualname__}' object has no attribute '{item}'")
19
+
20
+ def inner(o) -> Builder:
21
+ getattr(self, f"{Builder.PREFIX}_kwargs")[item] = o
22
+ return self
23
+
24
+ return inner
25
+
26
+ def build(self) -> T:
27
+ dcls = getattr(self, f"{Builder.PREFIX}_dcls")
28
+ kwargs = getattr(self, f"{Builder.PREFIX}_kwargs")
29
+ return dcls(**kwargs)
30
+
31
+
32
+ def builder(dcls: T):
33
+ if not hasattr(dcls, "__dataclass_fields__"):
34
+ raise RuntimeError("Can only create builders out of @dataclass classes")
35
+ for name in dcls.__dataclass_fields__.keys():
36
+ if name.startswith("build"):
37
+ raise AttributeError(f"@builder reserves attributes that has 'build' prefix. Invalid attribute: '{name}'")
38
+
39
+ @classmethod # type: ignore
40
+ def builder_impl(cls) -> Builder[T]:
41
+ return Builder[T](cls)
42
+
43
+ setattr(dcls, "builder", builder_impl)
44
+ return dcls
45
+
46
+
47
+ __all__ = [
48
+ "builder"
49
+ ]
@@ -1,9 +1,20 @@
1
1
  import inspect
2
2
  import re
3
- from typing import Optional, List, Iterable, Type
3
+ from typing import Optional, List, Iterable, Type, TypeVar, Generic, get_origin
4
4
  from .function_info import FunctionInfo
5
5
  from .decoration_info import DecorationInfo
6
6
  from .argument_info import ArgumentInfo
7
+ from danielutils.functions import isoftype
8
+
9
+ T = TypeVar("T")
10
+
11
+
12
+ class _A(Generic[T]): ...
13
+
14
+
15
+ _GenericAlias = type(_A[int])
16
+
17
+ del T, _A
7
18
 
8
19
 
9
20
  class ClassInfo:
@@ -13,6 +24,8 @@ class ClassInfo:
13
24
  # r"(?P<decorations>[\s\S]*)?^class (?P<name>\w[\w\d]*)(?:\((?P<bases>.*)\))?:(?P<body>[\s\S]+)"
14
25
 
15
26
  def __init__(self, cls: Type) -> None:
27
+ if isoftype(cls, _GenericAlias): # type:ignore
28
+ cls = get_origin(cls) # type:ignore
16
29
  if not inspect.isclass(cls):
17
30
  raise TypeError(f"'{cls.__name__}' is not a class")
18
31
  self._cls = cls
@@ -40,14 +53,15 @@ class ClassInfo:
40
53
  def _parse_body(self) -> None:
41
54
  for attr in dir(self._cls):
42
55
  obj = getattr(self._cls, attr, None)
43
- if inspect.isbuiltin(obj): continue
56
+ if inspect.isbuiltin(obj):
57
+ continue
44
58
  try:
45
59
  if inspect.isroutine(obj):
46
60
  inspect.getsource(obj)
47
61
  elif inspect.isdatadescriptor(obj):
48
62
  inspect.getsource(obj.fget) # type:ignore
49
63
  else:
50
- raise 1
64
+ raise Exception()
51
65
  except:
52
66
  continue
53
67
  self._functions.append(FunctionInfo(obj, self._cls))
@@ -82,6 +96,14 @@ class ClassInfo:
82
96
  def instance_methods(self) -> Iterable[FunctionInfo]:
83
97
  return sorted(filter(lambda f: f.is_instance_method, self._functions), key=lambda f: f.name)
84
98
 
99
+ @property
100
+ def inherited_methods(self)->Iterable[FunctionInfo]:
101
+ return sorted(filter(lambda f: f.is_inherited, self._functions), key=lambda f: f.name)
102
+
103
+ @property
104
+ def abstract_methods(self) -> Iterable[FunctionInfo]:
105
+ return sorted(filter(lambda f: f.is_abstract, self._functions), key=lambda f: f.name)
106
+
85
107
  @property
86
108
  def functions(self) -> List[FunctionInfo]:
87
109
  return self._functions
@@ -6,7 +6,7 @@ from .argument_info import ArgumentInfo
6
6
 
7
7
 
8
8
  class DecorationInfo:
9
- DECORATOR_INFO_REGEX: re.Pattern = re.compile(r"^@?(?P<name>\w[\w\d]*)(?P<arguments>\(.*\))?")
9
+ DECORATOR_INFO_REGEX: re.Pattern = re.compile(r"^@?(?P<name>\w[\w\d]*)(?:\((?P<arguments>.*)\))?")
10
10
 
11
11
  def __init__(self, name: str, arguments: List[ArgumentInfo]):
12
12
  self._name = name
@@ -13,7 +13,7 @@ class FunctionInfo:
13
13
  def __init__(self, func: Callable, owner: Type) -> None:
14
14
  try:
15
15
  if inspect.isdatadescriptor(func):
16
- inspect.getsource(func.fget)
16
+ inspect.getsource(func.fget) # type: ignore
17
17
  self._is_property = True
18
18
  else:
19
19
  inspect.getsource(func)
@@ -53,7 +53,7 @@ class FunctionInfo:
53
53
 
54
54
  @property
55
55
  def is_inherited(self) -> bool:
56
- return self._func in self._owner.__dict__
56
+ return self._func in set(self._owner.__dict__.keys())
57
57
 
58
58
  @property
59
59
  def is_class_method(self) -> bool:
@@ -0,0 +1,67 @@
1
+ import functools
2
+ import unittest
3
+ from _collections_abc import Coroutine
4
+ from typing import Optional, Callable, Type
5
+ from unittest import TestResult
6
+
7
+
8
+ class AlwaysTeardownTestCase(unittest.TestCase):
9
+ """
10
+ SafeTestCase makes sure that tearDown / cleanup methods are always run when
11
+ They should be.
12
+ """
13
+
14
+ def run(self, result=None) -> Optional[TestResult]:
15
+ test_method = getattr(self, self._testMethodName)
16
+ wrapped_test = self._cleanup_wrapper(test_method, KeyboardInterrupt)
17
+ setattr(self, self._testMethodName, wrapped_test)
18
+
19
+ self.setUp = self._cleanup_wrapper(self.setUp, BaseException)
20
+
21
+ return super().run(result)
22
+
23
+ def _cleanup_wrapper(self, method: Callable, exception: Type[BaseException]) -> Callable:
24
+ @functools.wraps(method)
25
+ def wrapper(*args, **kwargs):
26
+ try:
27
+ return method(*args, **kwargs)
28
+ except exception:
29
+ self.tearDown()
30
+ self.doCleanups()
31
+ raise
32
+
33
+ return wrapper
34
+
35
+
36
+ class AsyncAlwaysTeardownTestCase(unittest.IsolatedAsyncioTestCase):
37
+ """
38
+ SafeTestCase makes sure that tearDown / cleanup methods are always run when
39
+ They should be.
40
+ """
41
+
42
+ def run(self, result=None) -> Optional[TestResult]:
43
+ test_method = getattr(self, self._testMethodName)
44
+ wrapped_test = self._cleanup_wrapper(test_method, KeyboardInterrupt)
45
+ setattr(self, self._testMethodName, wrapped_test)
46
+
47
+ self.asyncSetUp = self._cleanup_wrapper(self.asyncSetUp, BaseException)
48
+
49
+ return super().run(result)
50
+
51
+ def _cleanup_wrapper(self, method: Coroutine, exception: Type[BaseException]) -> Callable:
52
+ @functools.wraps(method)
53
+ async def wrapper(*args, **kwargs):
54
+ try:
55
+ return await method(*args, **kwargs)
56
+ except exception:
57
+ self.tearDown()
58
+ self.doCleanups()
59
+ raise
60
+
61
+ return wrapper
62
+
63
+
64
+ __all__ = [
65
+ "AlwaysTeardownTestCase",
66
+ "AsyncAlwaysTeardownTestCase",
67
+ ]
@@ -0,0 +1,92 @@
1
+ import asyncio
2
+ import functools
3
+ import os
4
+ import unittest
5
+ import inspect
6
+ from inspect import iscoroutine, iscoroutinefunction
7
+ from typing import Callable, Type, Coroutine, Union, Any
8
+
9
+ from danielutils import create_directory, get_current_working_directory, set_current_working_directory, delete_directory
10
+
11
+
12
+ def dispatch_function(func: Union[Callable, Coroutine], *args, **kwargs) -> Any:
13
+ if asyncio.iscoroutinefunction(func):
14
+ return asyncio.run(func(*args, **kwargs))
15
+ elif asyncio.iscoroutine(func):
16
+ return asyncio.run(func)
17
+ else:
18
+ return func(*args, **kwargs)
19
+
20
+
21
+ def improved_setup(func: Callable) -> Callable:
22
+ @functools.wraps(func)
23
+ def wrapper(self):
24
+ self.cwd = f"./{self.__class__.__name__}_test_folder"
25
+ create_directory(self.cwd)
26
+ self.prev_cwd = get_current_working_directory()
27
+ set_current_working_directory(os.path.join(self.prev_cwd, self.cwd))
28
+ if func is not None:
29
+ func(self)
30
+
31
+ @functools.wraps(func)
32
+ async def async_wrapper(self):
33
+ self.cwd = f"./{self.__class__.__name__}_test_folder"
34
+ create_directory(self.cwd)
35
+ self.prev_cwd = get_current_working_directory()
36
+ set_current_working_directory(os.path.join(self.prev_cwd, self.cwd))
37
+ if func is not None:
38
+ await func(self)
39
+
40
+ return async_wrapper if iscoroutinefunction(func) else wrapper
41
+
42
+
43
+ def improved_teardown(func: Callable) -> Callable:
44
+ @functools.wraps(func)
45
+ def wrapper(self):
46
+ if func is not None:
47
+ func(self)
48
+ set_current_working_directory(self.prev_cwd)
49
+ delete_directory(self.cwd)
50
+
51
+ @functools.wraps(func)
52
+ async def async_wrapper(self):
53
+ if func is not None:
54
+ await func(self)
55
+ set_current_working_directory(self.prev_cwd)
56
+ delete_directory(self.cwd)
57
+
58
+ return async_wrapper if iscoroutinefunction(func) else wrapper
59
+
60
+
61
+ class AutoCWDTestCase(unittest.TestCase):
62
+ @staticmethod
63
+ def _dummy(*args, **kwargs) -> None:
64
+ pass
65
+
66
+ @classmethod
67
+ def __init_subclass__(cls: Type, **kwargs) -> None:
68
+ dct = dict(cls.__dict__)
69
+ impl_setUp = dct.get("setUp", cls._dummy)
70
+ impl_tearDown = dct.get("tearDown", cls._dummy)
71
+ setattr(cls, "setUp", improved_setup(impl_setUp))
72
+ setattr(cls, "tearDown", improved_teardown(impl_tearDown))
73
+
74
+
75
+ class AsyncAutoCWDTestCase(unittest.IsolatedAsyncioTestCase):
76
+ @staticmethod
77
+ async def _async_dummy(*args, **kwargs) -> None:
78
+ pass
79
+
80
+ @classmethod
81
+ def __init_subclass__(cls: Type, **kwargs) -> None:
82
+ dct = dict(cls.__dict__)
83
+ async_impl_setUp = dct.get("asyncSetUp", cls._async_dummy)
84
+ async_impl_tearDown = dct.get("asyncTearDown", cls._async_dummy)
85
+ setattr(cls, "asyncSetUp", improved_setup(async_impl_setUp))
86
+ setattr(cls, "asyncTearDown", improved_teardown(async_impl_tearDown))
87
+
88
+
89
+ __all__ = [
90
+ 'AutoCWDTestCase',
91
+ "AsyncAutoCWDTestCase"
92
+ ]
@@ -1,10 +1,12 @@
1
+ from typing import Tuple
2
+
1
3
  try:
2
4
  from typing import ParamSpec
3
5
  except ImportError:
4
6
  from .reflection import get_python_version
5
7
 
6
8
  if get_python_version() >= (3, 9):
7
- ParamSpec = lambda name: [...]
9
+ ParamSpec = lambda name: [Any]
8
10
  else:
9
11
  from typing import Any
10
12
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: danielutils
3
- Version: 1.0.1
3
+ Version: 1.0.3
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