danielutils 1.0.46__tar.gz → 1.0.50__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 (281) hide show
  1. {danielutils-1.0.46/danielutils.egg-info → danielutils-1.0.50}/PKG-INFO +3 -4
  2. {danielutils-1.0.46 → danielutils-1.0.50}/README.md +1 -1
  3. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/abstractions/db/database_initializer.py +1 -1
  4. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/logging_/logger.py +1 -1
  5. danielutils-1.0.50/danielutils/reflection/__init__.py +6 -0
  6. danielutils-1.0.50/danielutils/reflection/info_classes/__init__.py +6 -0
  7. {danielutils-1.0.46/danielutils/reflection → danielutils-1.0.50/danielutils/reflection/info_classes}/argument_info.py +8 -2
  8. {danielutils-1.0.46/danielutils/reflection → danielutils-1.0.50/danielutils/reflection/info_classes}/class_info.py +8 -4
  9. danielutils-1.0.50/danielutils/reflection/info_classes/file_info.py +267 -0
  10. {danielutils-1.0.46/danielutils/reflection → danielutils-1.0.50/danielutils/reflection/info_classes}/function_info.py +10 -3
  11. danielutils-1.0.50/danielutils/reflection/info_classes/import_info.py +100 -0
  12. {danielutils-1.0.46 → danielutils-1.0.50/danielutils.egg-info}/PKG-INFO +3 -4
  13. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils.egg-info/SOURCES.txt +7 -4
  14. {danielutils-1.0.46 → danielutils-1.0.50}/pyproject.toml +1 -1
  15. danielutils-1.0.46/danielutils/reflection/__init__.py +0 -53
  16. {danielutils-1.0.46 → danielutils-1.0.50}/LICENSE +0 -0
  17. {danielutils-1.0.46 → danielutils-1.0.50}/MANIFEST.in +0 -0
  18. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/__init__.py +0 -0
  19. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/abstractions/__init__.py +0 -0
  20. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/abstractions/db/__init__.py +0 -0
  21. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/abstractions/db/database.py +0 -0
  22. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/abstractions/db/database_definitions.py +0 -0
  23. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/abstractions/db/database_exceptions.py +0 -0
  24. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/abstractions/db/database_factory.py +0 -0
  25. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/abstractions/db/database_models.py +0 -0
  26. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/abstractions/db/dependencies.py +0 -0
  27. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/abstractions/db/implementations/__init__.py +0 -0
  28. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/abstractions/db/implementations/in_memory_database.py +0 -0
  29. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/abstractions/db/implementations/persistent_in_memory_database.py +0 -0
  30. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/abstractions/db/implementations/redis_database.py +0 -0
  31. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/abstractions/db/implementations/sqlite_database.py +0 -0
  32. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/abstractions/multiprogramming/__init__.py +0 -0
  33. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/abstractions/multiprogramming/multi_id.py +0 -0
  34. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/abstractions/multiprogramming/worker.py +0 -0
  35. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/abstractions/multiprogramming/worker_pool.py +0 -0
  36. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/abstractions/repl.py +0 -0
  37. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/aliases.py +0 -0
  38. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/async_/__init__.py +0 -0
  39. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/async_/async_cmd.py +0 -0
  40. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/async_/async_layered_command.py +0 -0
  41. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/async_/async_retry_executor.py +0 -0
  42. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/async_/async_worker_pool.py +0 -0
  43. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/async_/time_strategy.py +0 -0
  44. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/async_/utils.py +0 -0
  45. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/better_builtins/__init__.py +0 -0
  46. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/better_builtins/counter.py +0 -0
  47. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/better_builtins/frange.py +0 -0
  48. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/better_builtins/typed_builtins/__init__.py +0 -0
  49. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/better_builtins/typed_builtins/factory.py +0 -0
  50. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/better_builtins/typed_builtins/tdict.py +0 -0
  51. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/better_builtins/typed_builtins/tlist.py +0 -0
  52. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/better_builtins/typed_builtins/tset.py +0 -0
  53. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/better_builtins/typed_builtins/ttuple.py +0 -0
  54. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/colors.py +0 -0
  55. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/context_managers/__init__.py +0 -0
  56. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/context_managers/attr_context.py +0 -0
  57. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/context_managers/multi_context.py +0 -0
  58. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/context_managers/optional_context.py +0 -0
  59. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/context_managers/state_context.py +0 -0
  60. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/context_managers/temporary_file.py +0 -0
  61. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/convenience.py +0 -0
  62. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/conversions/__init__.py +0 -0
  63. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/conversions/main_conversions.py +0 -0
  64. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/conversions/specialized_conversions/__init__.py +0 -0
  65. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/conversions/specialized_conversions/to_hex.py +0 -0
  66. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/conversions/specialized_conversions/to_int.py +0 -0
  67. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/custom_types.py +0 -0
  68. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/data_structures/__init__.py +0 -0
  69. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/data_structures/algorithms.py +0 -0
  70. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/data_structures/comparer.py +0 -0
  71. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/data_structures/default_dict.py +0 -0
  72. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/data_structures/functions.py +0 -0
  73. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/data_structures/graph/__init__.py +0 -0
  74. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/data_structures/graph/binary_node.py +0 -0
  75. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/data_structures/graph/graph.py +0 -0
  76. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/data_structures/graph/multinode.py +0 -0
  77. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/data_structures/graph/node.py +0 -0
  78. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/data_structures/heap/__init__.py +0 -0
  79. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/data_structures/heap/heap.py +0 -0
  80. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/data_structures/heap/max_heap.py +0 -0
  81. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/data_structures/heap/min_heap.py +0 -0
  82. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/data_structures/queue/__init__.py +0 -0
  83. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/data_structures/queue/atomic_queue.py +0 -0
  84. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/data_structures/queue/priority_queue.py +0 -0
  85. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/data_structures/queue/queue.py +0 -0
  86. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/data_structures/stack.py +0 -0
  87. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/data_structures/trees/__init__.py +0 -0
  88. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/data_structures/trees/binary_syntax_tree.py +0 -0
  89. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/data_structures/trees/binary_tree.py +0 -0
  90. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/date.py +0 -0
  91. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/date_time.py +0 -0
  92. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/decorators/__init__.py +0 -0
  93. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/decorators/atomic.py +0 -0
  94. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/decorators/attach.py +0 -0
  95. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/decorators/chain_decorators.py +0 -0
  96. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/decorators/decorate_conditionally.py +0 -0
  97. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/decorators/delay_call.py +0 -0
  98. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/decorators/deprecate.py +0 -0
  99. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/decorators/final.py +0 -0
  100. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/decorators/limit_recursion.py +0 -0
  101. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/decorators/memo.py +0 -0
  102. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/decorators/normalize_decorator.py +0 -0
  103. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/decorators/overload.py +0 -0
  104. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/decorators/partially_implemented.py +0 -0
  105. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/decorators/processify.py +0 -0
  106. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/decorators/property.py +0 -0
  107. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/decorators/singleton.py +0 -0
  108. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/decorators/threadify.py +0 -0
  109. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/decorators/timeout.py +0 -0
  110. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/decorators/total_ordering.py +0 -0
  111. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/decorators/validate.py +0 -0
  112. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/exceptions.py +0 -0
  113. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/file_specifications/__init__.py +0 -0
  114. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/functions/__init__.py +0 -0
  115. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/functions/areoneof.py +0 -0
  116. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/functions/check_foreach.py +0 -0
  117. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/functions/factorial.py +0 -0
  118. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/functions/flatten.py +0 -0
  119. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/functions/foreach.py +0 -0
  120. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/functions/isoftype.py +0 -0
  121. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/functions/isoneof.py +0 -0
  122. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/functions/multiloop.py +0 -0
  123. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/functions/parallel_for.py +0 -0
  124. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/functions/partition.py +0 -0
  125. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/functions/powerset.py +0 -0
  126. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/functions/subseteq.py +0 -0
  127. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/functions/types_subseteq.py +0 -0
  128. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/generators/__init__.py +0 -0
  129. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/generators/conditional_generator.py +0 -0
  130. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/generators/generator_from_stream.py +0 -0
  131. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/generators/join_generators.py +0 -0
  132. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/internet.py +0 -0
  133. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/io_.py +0 -0
  134. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/java/__init__.py +0 -0
  135. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/java/interfaces/__init__.py +0 -0
  136. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/java/interfaces/comparable.py +0 -0
  137. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/java/java_interface.py +0 -0
  138. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/logging_/__init__.py +0 -0
  139. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/logging_/builtin_impls/__init__.py +0 -0
  140. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/logging_/builtin_impls/file_logger.py +0 -0
  141. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/logging_/builtin_impls/print_logger.py +0 -0
  142. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/logging_/log_level.py +0 -0
  143. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/logging_/logger_strategy_impl_base.py +0 -0
  144. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/lombok/__init__.py +0 -0
  145. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/lombok/builder.py +0 -0
  146. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/math_/__init__.py +0 -0
  147. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/math_/constants.py +0 -0
  148. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/math_/functions.py +0 -0
  149. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/math_/math_print.py +0 -0
  150. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/math_/math_symbols.py +0 -0
  151. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/metaclasses/__init__.py +0 -0
  152. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/metaclasses/atomic_class_meta.py +0 -0
  153. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/metaclasses/implicit_data_deleter_meta.py +0 -0
  154. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/metaclasses/instance_cache_meta.py +0 -0
  155. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/metaclasses/interface.py +0 -0
  156. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/metaclasses/overload_meta.py +0 -0
  157. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/mock_/__init__.py +0 -0
  158. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/mock_/mock_module.py +0 -0
  159. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/path.py +0 -0
  160. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/print_.py +0 -0
  161. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/progress_bar/__init__.py +0 -0
  162. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/progress_bar/ascii_progress_bar.py +0 -0
  163. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/progress_bar/progress_bar.py +0 -0
  164. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/progress_bar/progress_bar_pool.py +0 -0
  165. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/protocols/__init__.py +0 -0
  166. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/protocols/dictable.py +0 -0
  167. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/protocols/evaluable.py +0 -0
  168. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/protocols/serializable.py +0 -0
  169. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/py.typed +0 -0
  170. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/random_.py +0 -0
  171. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/reflection/class_/__init__.py +0 -0
  172. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/reflection/class_/class_reflection.py +0 -0
  173. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/reflection/file/__init__.py +0 -0
  174. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/reflection/file/file_reflection.py +0 -0
  175. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/reflection/function/__init__.py +0 -0
  176. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/reflection/function/function_reflections.py +0 -0
  177. {danielutils-1.0.46/danielutils/reflection → danielutils-1.0.50/danielutils/reflection/info_classes}/decoration_info.py +0 -0
  178. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/reflection/interpreter/__init__.py +0 -0
  179. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/reflection/interpreter/callstack.py +0 -0
  180. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/reflection/interpreter/get_traceback.py +0 -0
  181. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/reflection/interpreter/interpreter.py +0 -0
  182. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/reflection/interpreter/is_debugging.py +0 -0
  183. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/reflection/interpreter/os_.py +0 -0
  184. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/reflection/interpreter/packages.py +0 -0
  185. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/reflection/interpreter/python_version.py +0 -0
  186. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/reflection/interpreter/signals.py +0 -0
  187. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/reflection/interpreter/tracer.py +0 -0
  188. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/reflection/module/__init__.py +0 -0
  189. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/reflection/module/module_reflections.py +0 -0
  190. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/reflection/module/package_reflection.py +0 -0
  191. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/retry_executor/__init__.py +0 -0
  192. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/retry_executor/backoff_strategies/__init__.py +0 -0
  193. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/retry_executor/backoff_strategies/constant_backoff.py +0 -0
  194. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/retry_executor/backoff_strategies/exponential_backoff.py +0 -0
  195. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/retry_executor/backoff_strategies/functional_backoff.py +0 -0
  196. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/retry_executor/backoff_strategies/linear_backoff.py +0 -0
  197. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/retry_executor/backoff_strategies/multiplicative_backoff.py +0 -0
  198. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/retry_executor/backoff_strategies/no_backoff.py +0 -0
  199. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/retry_executor/backoff_strategy.py +0 -0
  200. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/retry_executor/retry_executor.py +0 -0
  201. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/snippets/__init__.py +0 -0
  202. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/snippets/try_get.py +0 -0
  203. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/system/__init__.py +0 -0
  204. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/system/independent.py +0 -0
  205. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/system/layered_command.py +0 -0
  206. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/system/windows/__init__.py +0 -0
  207. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/system/windows/utils/__init__.py +0 -0
  208. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/system/windows/utils/filetime.py +0 -0
  209. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/system/windows/win32_ctime.py +0 -0
  210. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/system/windows/windows.py +0 -0
  211. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/testing/__init__.py +0 -0
  212. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/testing/unittest_/__init__.py +0 -0
  213. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/testing/unittest_/always_teardown_testcase.py +0 -0
  214. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/testing/unittest_/auto_cwd_testcase.py +0 -0
  215. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/text.py +0 -0
  216. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/time.py +0 -0
  217. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/university/__init__.py +0 -0
  218. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/university/computability_and_complexity/__init__.py +0 -0
  219. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/university/computability_and_complexity/discreate_finite_automaton.py +0 -0
  220. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/university/computability_and_complexity/languages/__init__.py +0 -0
  221. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/university/computability_and_complexity/languages/language.py +0 -0
  222. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/university/computability_and_complexity/languages/sat.py +0 -0
  223. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/university/computability_and_complexity/turing_machine.py +0 -0
  224. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/university/databases/__init__.py +0 -0
  225. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/university/databases/all.py +0 -0
  226. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/university/image_proccesing/__init__.py +0 -0
  227. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/university/image_proccesing/encoding/__init__.py +0 -0
  228. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/university/image_proccesing/encoding/encoding.py +0 -0
  229. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/university/image_proccesing/encoding/lossless/__init__.py +0 -0
  230. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/university/image_proccesing/encoding/lossless/huffman.py +0 -0
  231. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/university/image_proccesing/encoding/lossless/lossless_encoding.py +0 -0
  232. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/university/image_proccesing/encoding/lossless/lzw.py +0 -0
  233. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/university/image_proccesing/encoding/lossless/run_length.py +0 -0
  234. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/university/image_proccesing/encoding/lossy/__init__.py +0 -0
  235. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/university/image_proccesing/encoding/lossy/lossy_encoding.py +0 -0
  236. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/university/image_proccesing/tansformations/__init__.py +0 -0
  237. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/university/image_proccesing/tansformations/gaussian.py +0 -0
  238. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/university/image_proccesing/tansformations/gradient.py +0 -0
  239. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/university/image_proccesing/tansformations/hough.py +0 -0
  240. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/university/image_proccesing/tansformations/laplacian.py +0 -0
  241. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/university/image_proccesing/tansformations/transformation.py +0 -0
  242. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/university/linear_algebra/__init__.py +0 -0
  243. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/university/linear_algebra/matrix.py +0 -0
  244. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/university/machine_learning/__init__.py +0 -0
  245. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/university/machine_learning/activation_functions/__init__.py +0 -0
  246. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/university/machine_learning/activation_functions/activation_function.py +0 -0
  247. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/university/machine_learning/activation_functions/relu.py +0 -0
  248. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/university/machine_learning/neuron.py +0 -0
  249. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/university/oop/__init__.py +0 -0
  250. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/university/oop/observer.py +0 -0
  251. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/university/oop/strategy.py +0 -0
  252. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/university/probability/__init__.py +0 -0
  253. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/university/probability/conditional_variable/__init__.py +0 -0
  254. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/university/probability/conditional_variable/conditional_variable.py +0 -0
  255. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/university/probability/conditional_variable/continuous/__init__.py +0 -0
  256. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/university/probability/conditional_variable/discrete/__init__.py +0 -0
  257. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/university/probability/conditional_variable/discrete/bernoulli.py +0 -0
  258. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/university/probability/conditional_variable/discrete/binomial.py +0 -0
  259. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/university/probability/conditional_variable/discrete/conditional_from_discrete_probability_func.py +0 -0
  260. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/university/probability/conditional_variable/discrete/discrete.py +0 -0
  261. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/university/probability/conditional_variable/discrete/geometric.py +0 -0
  262. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/university/probability/conditional_variable/discrete/poisson.py +0 -0
  263. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/university/probability/conditional_variable/discrete/uniform.py +0 -0
  264. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/university/probability/distributions.py +0 -0
  265. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/university/probability/expressions/__init__.py +0 -0
  266. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/university/probability/expressions/accumulation_expression.py +0 -0
  267. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/university/probability/expressions/probability_expression.py +0 -0
  268. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/university/probability/funcs/__init__.py +0 -0
  269. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/university/probability/funcs/covariance.py +0 -0
  270. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/university/probability/funcs/expected_value.py +0 -0
  271. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/university/probability/funcs/probability_function.py +0 -0
  272. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/university/probability/funcs/variance.py +0 -0
  273. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/university/probability/operator.py +0 -0
  274. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/university/probability/protocols.py +0 -0
  275. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/university/probability/supp.py +0 -0
  276. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/university/probability/transformation.py +0 -0
  277. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils/versioned_imports.py +0 -0
  278. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils.egg-info/dependency_links.txt +0 -0
  279. {danielutils-1.0.46 → danielutils-1.0.50}/danielutils.egg-info/top_level.txt +0 -0
  280. {danielutils-1.0.46 → danielutils-1.0.50}/setup.cfg +0 -0
  281. {danielutils-1.0.46 → danielutils-1.0.50}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.4
1
+ Metadata-Version: 2.1
2
2
  Name: danielutils
3
- Version: 1.0.46
3
+ Version: 1.0.50
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
@@ -33,7 +33,6 @@ Classifier: Operating System :: Microsoft :: Windows
33
33
  Requires-Python: >=3.8.0
34
34
  Description-Content-Type: text/markdown
35
35
  License-File: LICENSE
36
- Dynamic: license-file
37
36
 
38
37
  [![Python package](https://github.com/danielnachumdev/danielutils/actions/workflows/python-package.yml/badge.svg)](https://github.com/danielnachumdev/danielutils/actions/workflows/python-package.yml)
39
38
  [![Pylint](https://github.com/danielnachumdev/danielutils/actions/workflows/pylint.yml/badge.svg)](https://github.com/danielnachumdev/danielutils/actions/workflows/pylint.yml)
@@ -41,7 +40,7 @@ Dynamic: license-file
41
40
  [![gitleaks](https://github.com/danielnachumdev/danielutils/actions/workflows/gitleaks.yml/badge.svg)](https://github.com/danielnachumdev/danielutils/actions/workflows/gitleaks.yml)
42
41
  [![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)
43
42
 
44
- # danielutils v1.0.46
43
+ # danielutils v1.0.50
45
44
 
46
45
  A comprehensive Python utilities library designed to enhance your development workflow with powerful tools for type safety, async programming, database operations, and much more.
47
46
 
@@ -4,7 +4,7 @@
4
4
  [![gitleaks](https://github.com/danielnachumdev/danielutils/actions/workflows/gitleaks.yml/badge.svg)](https://github.com/danielnachumdev/danielutils/actions/workflows/gitleaks.yml)
5
5
  [![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)
6
6
 
7
- # danielutils v1.0.46
7
+ # danielutils v1.0.50
8
8
 
9
9
  A comprehensive Python utilities library designed to enhance your development workflow with powerful tools for type safety, async programming, database operations, and much more.
10
10
 
@@ -238,7 +238,7 @@ class DatabaseInitializer(ABC):
238
238
  await db.create_table(expected_schema)
239
239
  else:
240
240
  logger.info(f"Validating table '{table_name}'")
241
- if not validate_schema(db, table_name, expected_schema):
241
+ if not await validate_schema(db, table_name, expected_schema):
242
242
  raise ValueError(
243
243
  f"Schema validation failed for table '{table_name}'. "
244
244
  "Please check the logs for details."
@@ -70,7 +70,7 @@ class _LoggerImpl:
70
70
 
71
71
  class Logger:
72
72
  @classmethod
73
- def __init_subclass__(cls, **kwargs):
73
+ def __init_subclass__(cls, **kwargs) -> None:
74
74
  cls._logger = _LoggerImpl(cls)
75
75
  cls._registered_loggers: List[LoggerStrategyImplBase] = []
76
76
  cls.init_subscribers()
@@ -0,0 +1,6 @@
1
+ from .interpreter import * # this has to be first, the order matters!
2
+ from .file import *
3
+ from .function import *
4
+ from .info_classes import *
5
+ from .class_ import *
6
+ from .module import *
@@ -0,0 +1,6 @@
1
+ from .argument_info import *
2
+ from .class_info import *
3
+ from .decoration_info import *
4
+ from .file_info import *
5
+ from .function_info import *
6
+ from .import_info import *
@@ -62,7 +62,7 @@ class ArgumentInfo:
62
62
  if self.default is not None:
63
63
  res += f", default={self.default}"
64
64
  if self.is_parameterized:
65
- res+=f", parameters={self.parameters}"
65
+ res += f", parameters={self.parameters}"
66
66
  return res + ")"
67
67
 
68
68
  def __str__(self) -> str:
@@ -75,8 +75,11 @@ class ArgumentInfo:
75
75
  raise ValueError(f"Invalid argument info string: {string}")
76
76
 
77
77
  kwargs, args, kwarg_only, pname, parameters, name, type, default_value = m.groups()
78
+ type = None if type is None else type.strip()
79
+ default_value = None if default_value is None else default_value.strip()
78
80
  return ArgumentInfo(
79
- name=name or pname,
81
+ name=name or pname or (args.strip("*") if args else None) or (
82
+ kwargs.strip("*") if kwargs else None) or (kwarg_only.strip("/") if kwarg_only else None) or None,
80
83
  type=type,
81
84
  default=default_value,
82
85
  is_kwargs=kwargs is not None,
@@ -90,6 +93,9 @@ class ArgumentInfo:
90
93
  if string is None:
91
94
  return []
92
95
  string = string.strip()
96
+ if not string:
97
+ return []
98
+ string = string.strip()
93
99
  indices = [-1]
94
100
  stack: List[str] = []
95
101
  for i, c in enumerate(string):
@@ -1,11 +1,11 @@
1
1
  import inspect
2
2
  import json
3
3
  import re
4
- from typing import Optional, List, Iterable, Type, TypeVar, Generic, get_origin
4
+ from typing import List, Iterable, Type, TypeVar, Generic, get_origin
5
5
  from .function_info import FunctionInfo
6
6
  from .decoration_info import DecorationInfo
7
7
  from .argument_info import ArgumentInfo
8
- from ..functions import isoftype
8
+ from ...functions import isoftype
9
9
 
10
10
  T = TypeVar("T")
11
11
 
@@ -62,10 +62,14 @@ class ClassInfo:
62
62
  elif inspect.isdatadescriptor(obj):
63
63
  inspect.getsource(obj.fget) # type:ignore
64
64
  else:
65
- raise Exception()
65
+ continue
66
66
  except:
67
67
  continue
68
- self._functions.append(FunctionInfo(obj, self._cls))
68
+
69
+ try:
70
+ self._functions.append(FunctionInfo(obj, self._cls)) # type: ignore
71
+ except Exception as e:
72
+ raise Exception(f"Error parsing function '{attr}' of class '{self._name}': {e}", e) from e
69
73
 
70
74
  def __str__(self) -> str:
71
75
  body = json.dumps({
@@ -0,0 +1,267 @@
1
+ import ast
2
+ import tokenize
3
+ import io
4
+ import importlib.util
5
+ import inspect
6
+ from collections import Counter
7
+ from pathlib import Path
8
+ from typing import List, Set, Dict, Any
9
+
10
+ from .import_info import ImportInfo
11
+ from .class_info import ClassInfo
12
+ from .function_info import FunctionInfo
13
+
14
+
15
+ class FileInfo:
16
+ """
17
+ A class for static analysis of a Python source file.
18
+
19
+ Analysis includes:
20
+ • Tokenization: token count and token frequency distribution.
21
+ • Extraction of comments.
22
+ • Listing names of classes and functions.
23
+ • Identification of import statements, now represented by ImportInfo objects.
24
+ • Basic import usage analysis (which imports appear to be used).
25
+ • (Dynamic) loading of the file to create detailed ClassInfo and FunctionInfo objects.
26
+ """
27
+
28
+ def __init__(self, file_path: str) -> None:
29
+ self.file_path = str(Path(file_path).resolve())
30
+ self._content: str = self._read_file()
31
+ self._tree: ast.AST = self._parse_content()
32
+ self._tokens: List[tokenize.TokenInfo] = None
33
+
34
+ def _read_file(self) -> str:
35
+ """Reads and returns the file content as UTF-8 text."""
36
+ try:
37
+ with open(self.file_path, "r", encoding="utf-8") as f:
38
+ return f.read()
39
+ except Exception as e:
40
+ raise Exception(f"Error reading {self.file_path}: {e}")
41
+
42
+ def _parse_content(self) -> ast.AST:
43
+ """Parses the file content into an AST."""
44
+ try:
45
+ return ast.parse(self._content, filename=self.file_path)
46
+ except Exception as e:
47
+ raise Exception(f"Error parsing {self.file_path}: {e}")
48
+
49
+ def _tokenize(self) -> None:
50
+ """Tokenizes the file content using tokenize.tokenize()."""
51
+ self._tokens = []
52
+ stream = io.BytesIO(self._content.encode("utf-8"))
53
+ try:
54
+ for tok in tokenize.tokenize(stream.readline):
55
+ if tok.type == tokenize.ENCODING:
56
+ continue
57
+ self._tokens.append(tok)
58
+ except tokenize.TokenError as te:
59
+ print(f"Tokenize error: {te}")
60
+
61
+ @property
62
+ def tokens(self) -> List[tokenize.TokenInfo]:
63
+ """Returns the list of tokens from the file."""
64
+ if self._tokens is None:
65
+ self._tokenize()
66
+ return self._tokens
67
+
68
+ @property
69
+ def token_count(self) -> int:
70
+ """Total number of tokens in the file."""
71
+ return len(self.tokens)
72
+
73
+ @property
74
+ def token_distribution(self) -> Dict[str, int]:
75
+ """A dictionary mapping token strings to their frequency."""
76
+ return dict(Counter(tok.string for tok in self.tokens))
77
+
78
+ @property
79
+ def comments(self) -> List[str]:
80
+ """A list of all comment strings in the file."""
81
+ return [tok.string for tok in self.tokens if tok.type == tokenize.COMMENT]
82
+
83
+ @property
84
+ def class_names(self) -> List[str]:
85
+ """Names of all classes defined in the file."""
86
+ return [node.name for node in ast.walk(self._tree) if isinstance(node, ast.ClassDef)]
87
+
88
+ @property
89
+ def function_names(self) -> List[str]:
90
+ """Names of all functions (including async) defined in the file."""
91
+ return [
92
+ node.name
93
+ for node in ast.walk(self._tree)
94
+ if isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef))
95
+ ]
96
+
97
+ @property
98
+ def imports(self) -> List[Any]:
99
+ """
100
+ Returns a list of ImportInfo objects representing all import statements.
101
+ Each AST node of type ast.Import or ast.ImportFrom is transformed via
102
+ ImportInfo.from_ast().
103
+ """
104
+ results = []
105
+ if ImportInfo is None:
106
+ return results
107
+ for node in ast.walk(self._tree):
108
+ if isinstance(node, (ast.Import, ast.ImportFrom)):
109
+ results.extend(ImportInfo.from_ast(node))
110
+ return results
111
+
112
+ @property
113
+ def used_names(self) -> Set[str]:
114
+ """
115
+ A set of all names (identifiers) used in the file,
116
+ based on ast.Name nodes.
117
+ """
118
+ names = set()
119
+ for node in ast.walk(self._tree):
120
+ if isinstance(node, ast.Name):
121
+ names.add(node.id)
122
+ return names
123
+
124
+ @property
125
+ def import_usage(self) -> Dict[str, List[Any]]:
126
+ """
127
+ Returns a dictionary with two keys:
128
+ • 'used' : list of ImportInfo objects for which the alias is found in the file,
129
+ • 'unused' : list of ImportInfo objects whose alias is never referenced.
130
+ Wildcard imports (alias "*") are assumed to be used.
131
+ """
132
+ used, unused = [], []
133
+ for imp in self.imports:
134
+ if imp.alias == "*" or imp.alias is None or imp.alias in self.used_names:
135
+ used.append(imp)
136
+ else:
137
+ unused.append(imp)
138
+ return {"used": used, "unused": unused}
139
+
140
+ def _load_module(self) -> Any:
141
+ """
142
+ Dynamically loads the file as a module and returns the module object.
143
+ Returns None if the loading fails.
144
+
145
+ Warning: This executes the file's top-level code.
146
+ """
147
+ try:
148
+ module_name = "_temp_module_" + str(abs(hash(self.file_path)))
149
+ spec = importlib.util.spec_from_file_location(module_name, self.file_path)
150
+ module = importlib.util.module_from_spec(spec)
151
+ spec.loader.exec_module(module)
152
+ return module
153
+ except Exception as e:
154
+ print(f"Error loading module from {self.file_path}: {e}")
155
+ return None
156
+
157
+ def get_dynamic_class_info(self) -> List[Any]:
158
+ """
159
+ Dynamically imports the file as a module and returns a list of ClassInfo objects,
160
+ one per class defined at module level.
161
+
162
+ Warning: This executes the file's top-level code.
163
+ """
164
+ if ClassInfo is None:
165
+ print("ClassInfo unavailable; skipping dynamic class analysis.")
166
+ return []
167
+ module = self._load_module()
168
+ if module is None:
169
+ return []
170
+ infos = []
171
+ for name, obj in inspect.getmembers(module, inspect.isclass):
172
+ if inspect.getmodule(obj) == module:
173
+ try:
174
+ infos.append(ClassInfo(obj))
175
+ except Exception as e:
176
+ print(f"Error processing class {name}: {e}")
177
+ return infos
178
+
179
+ def get_dynamic_function_info(self) -> List[Any]:
180
+ """
181
+ Dynamically imports the file as a module and returns a list of FunctionInfo objects,
182
+ one per function defined at module level.
183
+
184
+ Warning: This executes the file's top-level code.
185
+ """
186
+ if FunctionInfo is None:
187
+ print("FunctionInfo unavailable; skipping dynamic function analysis.")
188
+ return []
189
+ module = self._load_module()
190
+ if module is None:
191
+ return []
192
+ infos = []
193
+ for name, obj in inspect.getmembers(module, inspect.isfunction):
194
+ if inspect.getmodule(obj) == module:
195
+ try:
196
+ infos.append(FunctionInfo(obj))
197
+ except Exception as e:
198
+ print(f"Error processing function {name}: {e}")
199
+ return infos
200
+
201
+ def print_summary(self) -> None:
202
+ """Prints a detailed summary of all analyses of the file."""
203
+ print(f"===== Analysis of {self.file_path} =====")
204
+
205
+ print(f"\nToken Count: {self.token_count}")
206
+ print("\nToken Distribution (Top 10):")
207
+ for token, count in sorted(self.token_distribution.items(), key=lambda x: -x[1])[:10]:
208
+ print(f" {repr(token)}: {count}")
209
+
210
+ print("\nComments Found:")
211
+ if self.comments:
212
+ for comment in self.comments:
213
+ print(" ", comment)
214
+ else:
215
+ print(" (None)")
216
+
217
+ print("\nClasses Defined:")
218
+ if self.class_names:
219
+ for cls in self.class_names:
220
+ print(" ", cls)
221
+ else:
222
+ print(" (None)")
223
+
224
+ print("\nFunctions Defined:")
225
+ if self.function_names:
226
+ for fn in self.function_names:
227
+ print(" ", fn)
228
+ else:
229
+ print(" (None)")
230
+
231
+ print("\nImports Found:")
232
+ for imp in self.imports:
233
+ print(f" {imp.alias} from {imp.module} ({imp.kind})")
234
+
235
+ usage = self.import_usage
236
+ print("\nUsed Imports:")
237
+ for imp in usage["used"]:
238
+ print(f" {imp.alias} from {imp.module} ({imp.kind})")
239
+
240
+ print("\nUnused Imports:")
241
+ if usage["unused"]:
242
+ for imp in usage["unused"]:
243
+ print(f" {imp.alias} from {imp.module} ({imp.kind})")
244
+ else:
245
+ print(" (None)")
246
+
247
+ print("\nDetailed Class Info:")
248
+ dynamic_class_infos = self.get_dynamic_class_info()
249
+ if dynamic_class_infos:
250
+ for info in dynamic_class_infos:
251
+ print(info)
252
+ else:
253
+ print(" (None)")
254
+
255
+ print("\nDetailed Function Info:")
256
+ dynamic_function_infos = self.get_dynamic_function_info()
257
+ if dynamic_function_infos:
258
+ for info in dynamic_function_infos:
259
+ print(info)
260
+ else:
261
+ print(" (None)")
262
+ print("========================================")
263
+
264
+
265
+ __all__ = [
266
+ "FileInfo"
267
+ ]
@@ -8,7 +8,7 @@ from .argument_info import ArgumentInfo
8
8
 
9
9
  class FunctionInfo:
10
10
  FUNCTION_DEFINITION_REGEX: re.Pattern = re.compile(
11
- r"(?P<decorators>[\s\S]+)?\s*def (?P<name>\w[\w\d]*)\s*\((?P<arguments>.+)?\)\s*(?:\s*\-\>\s*(?P<return_type>[\s\S]+?)\s*)?:(?P<body>[\s\S]+)",
11
+ r"(?P<decorators>(?:@[\s\S]+?)+?)?\s*(?P<async>async )?def (?P<name>\w[\w\d]*)\s*\((?P<arguments>[\s\S]+?)?\)\s*(?:\s*\-\>\s*(?P<return_type>[\s\S]+?)\s*)?:(?P<body>[\s\S]+)",
12
12
  re.MULTILINE)
13
13
 
14
14
  def __init__(self, func: Callable, owner: Type) -> None:
@@ -18,7 +18,7 @@ class FunctionInfo:
18
18
  self._is_property = True
19
19
  else:
20
20
  inspect.getsource(func)
21
- self._is_property = False
21
+ self._is_property = False # type: ignore
22
22
  except:
23
23
  raise TypeError(f"'{func.__name__}' is not a user defined function")
24
24
  self._func = func
@@ -34,10 +34,13 @@ class FunctionInfo:
34
34
  m = FunctionInfo.FUNCTION_DEFINITION_REGEX.match(code)
35
35
  if m is None:
36
36
  raise ValueError("Invalid function source code")
37
- decorators, name, arguments, return_type, body = m.groups()
37
+ decorators, async_, name, arguments, return_type, body = m.groups()
38
38
  if decorators is not None:
39
39
  for substr in decorators.strip().splitlines():
40
40
  self._decorators.append(DecorationInfo.from_str(substr.strip()))
41
+
42
+ self._is_async = async_ is not None
43
+
41
44
  self._name = name
42
45
  if arguments is not None:
43
46
  self._arguments = ArgumentInfo.from_str(arguments)
@@ -57,6 +60,10 @@ class FunctionInfo:
57
60
  def __repr__(self) -> str:
58
61
  return f"{self.__class__.__name__}(name=\"{self.name}\")"
59
62
 
63
+ @property
64
+ def is_async(self) -> bool:
65
+ return self._is_async
66
+
60
67
  @property
61
68
  def is_inherited(self) -> bool:
62
69
  return self._func in set(self._owner.__dict__.keys())
@@ -0,0 +1,100 @@
1
+ import ast
2
+ from typing import List, Union
3
+
4
+
5
+ class ImportInfo:
6
+ """
7
+ A class that encapsulates information about a single import statement element.
8
+
9
+ Depending on how the import appears in the source code, this may represent:
10
+ - a regular import (e.g., "import os" or "import os.path as osp"),
11
+ - a from-import (e.g., "from sys import version_info"), or
12
+ - a wildcard import (e.g., "from math import *").
13
+
14
+ The exposed properties are:
15
+ • alias: The accessible name in the file.
16
+ • module: The imported module or package.
17
+ • kind: A short string indicating the type. It will be one of:
18
+ "import", "from_import", or "from_import_all".
19
+ """
20
+
21
+ def __init__(self, alias: str, module: str, kind: str) -> None:
22
+ """
23
+ :param alias: The name used in the current file. For example, in
24
+ "import os as myos", the alias is 'myos'; if no alias is given,
25
+ a default is provided (e.g., the top-level module name).
26
+ :param module: The full module or package name (e.g., "os", or "os.path").
27
+ :param kind: A descriptor of the import kind: "import", "from_import", or "from_import_all".
28
+ """
29
+ self._alias = alias
30
+ self._module = module
31
+ self._kind = kind
32
+
33
+ @property
34
+ def alias(self) -> str:
35
+ """Returns the alias (or name) used for the import in the file."""
36
+ return self._alias
37
+
38
+ @property
39
+ def module(self) -> str:
40
+ """Returns the module or package name as imported."""
41
+ return self._module
42
+
43
+ @property
44
+ def kind(self) -> str:
45
+ """
46
+ Returns the type of import:
47
+ - "import" for a standard import statement,
48
+ - "from_import" for a 'from X import Y' statement,
49
+ - "from_import_all" for a wildcard import (e.g., 'from X import *').
50
+ """
51
+ return self._kind
52
+
53
+ def to_dict(self) -> dict:
54
+ """Returns a dictionary representation of the import information."""
55
+ return {"alias": self.alias, "module": self.module, "kind": self.kind}
56
+
57
+ def __str__(self) -> str:
58
+ return f"ImportInfo(alias={self.alias!r}, module={self.module!r}, kind={self.kind!r})"
59
+
60
+ def __repr__(self) -> str:
61
+ return self.__str__()
62
+
63
+ @classmethod
64
+ def from_ast(cls, node: Union[ast.Import, ast.ImportFrom]) -> List["ImportInfo"]:
65
+ """
66
+ Given an AST node of type ast.Import or ast.ImportFrom, returns a list
67
+ of ImportInfo instances representing each imported alias in that node.
68
+
69
+ For an ast.Import node:
70
+ • Each alias in node.names is processed.
71
+ • If an alias is not provided (using the as keyword), then the first
72
+ part of the module name (split by '.') is used as the alias.
73
+
74
+ For an ast.ImportFrom node:
75
+ • The module attribute (which can be None for relative imports) is used.
76
+ • Each alias is processed. If alias.name equals "*", the import is considered a wildcard.
77
+
78
+ :param node: An ast.Import or ast.ImportFrom node.
79
+ :return: A list of ImportInfo objects.
80
+ """
81
+ imports = []
82
+ if isinstance(node, ast.Import):
83
+ for alias in node.names:
84
+ # Use asname if available; otherwise use the top-level name.
85
+ local_alias = alias.asname if alias.asname else alias.name.split(".")[0]
86
+ imports.append(cls(local_alias, alias.name, "import"))
87
+ elif isinstance(node, ast.ImportFrom):
88
+ modname = node.module if node.module is not None else ""
89
+ for alias in node.names:
90
+ if alias.name == "*":
91
+ imports.append(cls("*", modname, "from_import_all"))
92
+ else:
93
+ local_alias = alias.asname if alias.asname else alias.name
94
+ imports.append(cls(local_alias, modname, "from_import"))
95
+ return imports
96
+
97
+
98
+ __all__ = [
99
+ "ImportInfo"
100
+ ]
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.4
1
+ Metadata-Version: 2.1
2
2
  Name: danielutils
3
- Version: 1.0.46
3
+ Version: 1.0.50
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
@@ -33,7 +33,6 @@ Classifier: Operating System :: Microsoft :: Windows
33
33
  Requires-Python: >=3.8.0
34
34
  Description-Content-Type: text/markdown
35
35
  License-File: LICENSE
36
- Dynamic: license-file
37
36
 
38
37
  [![Python package](https://github.com/danielnachumdev/danielutils/actions/workflows/python-package.yml/badge.svg)](https://github.com/danielnachumdev/danielutils/actions/workflows/python-package.yml)
39
38
  [![Pylint](https://github.com/danielnachumdev/danielutils/actions/workflows/pylint.yml/badge.svg)](https://github.com/danielnachumdev/danielutils/actions/workflows/pylint.yml)
@@ -41,7 +40,7 @@ Dynamic: license-file
41
40
  [![gitleaks](https://github.com/danielnachumdev/danielutils/actions/workflows/gitleaks.yml/badge.svg)](https://github.com/danielnachumdev/danielutils/actions/workflows/gitleaks.yml)
42
41
  [![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)
43
42
 
44
- # danielutils v1.0.46
43
+ # danielutils v1.0.50
45
44
 
46
45
  A comprehensive Python utilities library designed to enhance your development workflow with powerful tools for type safety, async programming, database operations, and much more.
47
46
 
@@ -168,16 +168,19 @@ danielutils/protocols/dictable.py
168
168
  danielutils/protocols/evaluable.py
169
169
  danielutils/protocols/serializable.py
170
170
  danielutils/reflection/__init__.py
171
- danielutils/reflection/argument_info.py
172
- danielutils/reflection/class_info.py
173
- danielutils/reflection/decoration_info.py
174
- danielutils/reflection/function_info.py
175
171
  danielutils/reflection/class_/__init__.py
176
172
  danielutils/reflection/class_/class_reflection.py
177
173
  danielutils/reflection/file/__init__.py
178
174
  danielutils/reflection/file/file_reflection.py
179
175
  danielutils/reflection/function/__init__.py
180
176
  danielutils/reflection/function/function_reflections.py
177
+ danielutils/reflection/info_classes/__init__.py
178
+ danielutils/reflection/info_classes/argument_info.py
179
+ danielutils/reflection/info_classes/class_info.py
180
+ danielutils/reflection/info_classes/decoration_info.py
181
+ danielutils/reflection/info_classes/file_info.py
182
+ danielutils/reflection/info_classes/function_info.py
183
+ danielutils/reflection/info_classes/import_info.py
181
184
  danielutils/reflection/interpreter/__init__.py
182
185
  danielutils/reflection/interpreter/callstack.py
183
186
  danielutils/reflection/interpreter/get_traceback.py
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "danielutils"
7
- version = "1.0.46"
7
+ version = "1.0.50"
8
8
  authors = [
9
9
  { name = "danielnachumdev", email = "danielnachumdev@gmail.com" },
10
10
  ]
@@ -1,53 +0,0 @@
1
- from .interpreter import * # this has to be first, the order matters!
2
- from .file import *
3
- from .function import *
4
- from .class_ import *
5
- from .module import *
6
- from .argument_info import *
7
- from .decoration_info import *
8
- from .function_info import *
9
- from .class_info import *
10
- # def get_class(module_name: str, class_name: str) -> type:
11
- # """dynammically loads the module and returns the class from this file
12
-
13
- # Args:
14
- # module_name (str): name of python module, (typically a file name without extention)
15
- # class_name (str): the name of the wanted class
16
-
17
- # Returns:
18
- # type (type): The class
19
- # """
20
- # return dynamically_load(module_name, class_name)
21
-
22
-
23
- # def get_function(module_name: str, func_name: str) -> Callable:
24
- # """dynammically loads the module and returns the function from this file
25
-
26
- # Args:
27
- # module_name (str): name of python module, (typically a file name without extention)
28
- # func_name (str): the name of the wanted function
29
-
30
- # Returns:
31
- # Callable: the function
32
- # """
33
- # return dynamically_load(module_name, func_name)
34
-
35
-
36
- # def get_current_function() -> Callable:
37
- # """return the function that is calling this file
38
-
39
- # Returns:
40
- # Callable: function
41
- # """
42
- # return get_caller()
43
-
44
-
45
- # def get_caller() -> Callable:
46
- # """returns the caller of the function thats using this function
47
-
48
- # Returns:
49
- # Callable: caller
50
- # """
51
- # name = get_caller_name(1)
52
- # module = get_caller_filename().removesuffix(".py")
53
- # return get_function(module, name)
File without changes
File without changes