danielutils 0.9.76__tar.gz → 0.9.77__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 (184) hide show
  1. {danielutils-0.9.76/danielutils.egg-info → danielutils-0.9.77}/PKG-INFO +4 -1
  2. {danielutils-0.9.76 → danielutils-0.9.77}/README.md +3 -0
  3. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/abstractions/database/redis_database.py +2 -2
  4. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/data_structures/trees/binary_syntax_tree.py +6 -4
  5. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/decorators/__init__.py +1 -0
  6. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/decorators/atomic.py +4 -6
  7. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/decorators/attach.py +4 -5
  8. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/decorators/delay_call.py +4 -5
  9. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/decorators/deprecate.py +7 -5
  10. danielutils-0.9.77/danielutils/decorators/final.py +37 -0
  11. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/decorators/limit_recursion.py +6 -8
  12. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/decorators/memo.py +3 -7
  13. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/decorators/overload.py +1 -6
  14. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/decorators/partially_implemented.py +3 -6
  15. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/decorators/threadify.py +3 -5
  16. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/decorators/timeout.py +1 -5
  17. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/decorators/validate.py +89 -90
  18. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/functions/isoftype.py +3 -9
  19. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/math_/polynomial/polinomial.py +12 -6
  20. danielutils-0.9.77/danielutils/protocols/dictable.py +20 -0
  21. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/reflection/class_/class_reflection.py +16 -12
  22. danielutils-0.9.77/danielutils/reflection/file/file_reflection.py +58 -0
  23. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/reflection/interpreter/callstack.py +13 -2
  24. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/reflection/interpreter/tracer.py +7 -3
  25. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/time.py +1 -5
  26. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/tqdm_.py +1 -1
  27. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/university/probability/__init__.py +1 -1
  28. {danielutils-0.9.76/danielutils/university/probability/conditional_variables → danielutils-0.9.77/danielutils/university/probability/conditional_variable}/conditional_variable.py +43 -21
  29. {danielutils-0.9.76/danielutils/university/probability/conditional_variables → danielutils-0.9.77/danielutils/university/probability/conditional_variable}/discrete/bernoulli.py +14 -6
  30. {danielutils-0.9.76/danielutils/university/probability/conditional_variables → danielutils-0.9.77/danielutils/university/probability/conditional_variable}/discrete/binomial.py +2 -2
  31. {danielutils-0.9.76/danielutils/university/probability/conditional_variables → danielutils-0.9.77/danielutils/university/probability/conditional_variable}/discrete/conditional_from_discrete_probability_func.py +2 -2
  32. {danielutils-0.9.76/danielutils/university/probability/conditional_variables → danielutils-0.9.77/danielutils/university/probability/conditional_variable}/discrete/discrete.py +4 -4
  33. {danielutils-0.9.76/danielutils/university/probability/conditional_variables → danielutils-0.9.77/danielutils/university/probability/conditional_variable}/discrete/geometric.py +9 -4
  34. {danielutils-0.9.76/danielutils/university/probability/conditional_variables → danielutils-0.9.77/danielutils/university/probability/conditional_variable}/discrete/poisson.py +2 -2
  35. {danielutils-0.9.76/danielutils/university/probability/conditional_variables → danielutils-0.9.77/danielutils/university/probability/conditional_variable}/discrete/uniform.py +4 -4
  36. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/university/probability/distributions.py +2 -2
  37. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/university/probability/expressions/accumulation_expression.py +8 -9
  38. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/university/probability/expressions/probability_expression.py +28 -29
  39. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/university/probability/funcs/covariance.py +2 -2
  40. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/university/probability/funcs/expected_value.py +1 -1
  41. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/university/probability/funcs/variance.py +2 -1
  42. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/university/probability/operator.py +12 -7
  43. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/university/probability/supp.py +36 -7
  44. danielutils-0.9.77/danielutils/university/probability/transformation.py +40 -0
  45. danielutils-0.9.77/danielutils/versioned_imports.py +21 -0
  46. {danielutils-0.9.76 → danielutils-0.9.77/danielutils.egg-info}/PKG-INFO +4 -1
  47. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils.egg-info/SOURCES.txt +14 -11
  48. {danielutils-0.9.76 → danielutils-0.9.77}/pyproject.toml +3 -3
  49. danielutils-0.9.76/danielutils/protocols/dictable.py +0 -16
  50. danielutils-0.9.76/danielutils/reflection/file/file_reflection.py +0 -44
  51. {danielutils-0.9.76 → danielutils-0.9.77}/LICENSE +0 -0
  52. {danielutils-0.9.76 → danielutils-0.9.77}/MANIFEST.in +0 -0
  53. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/__init__.py +0 -0
  54. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/abstractions/__init__.py +0 -0
  55. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/abstractions/database/__init__.py +0 -0
  56. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/abstractions/database/cached_database.py +0 -0
  57. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/abstractions/database/database.py +0 -0
  58. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/abstractions/multiprogramming/__init__.py +0 -0
  59. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/abstractions/multiprogramming/multi_id.py +0 -0
  60. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/abstractions/multiprogramming/worker.py +0 -0
  61. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/abstractions/multiprogramming/worker_pool.py +0 -0
  62. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/abstractions/repl.py +0 -0
  63. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/aliases.py +0 -0
  64. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/better_builtins/__init__.py +0 -0
  65. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/better_builtins/counter.py +0 -0
  66. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/better_builtins/frange.py +0 -0
  67. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/better_builtins/typed_builtins/__init__.py +0 -0
  68. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/better_builtins/typed_builtins/factory.py +0 -0
  69. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/better_builtins/typed_builtins/tdict.py +0 -0
  70. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/better_builtins/typed_builtins/tlist.py +0 -0
  71. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/better_builtins/typed_builtins/tset.py +0 -0
  72. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/better_builtins/typed_builtins/ttuple.py +0 -0
  73. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/colors.py +0 -0
  74. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/convenience.py +0 -0
  75. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/conversions/__init__.py +0 -0
  76. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/conversions/main_conversions.py +0 -0
  77. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/conversions/specialized_conversions/__init__.py +0 -0
  78. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/conversions/specialized_conversions/to_hex.py +0 -0
  79. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/conversions/specialized_conversions/to_int.py +0 -0
  80. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/data_structures/__init__.py +0 -0
  81. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/data_structures/comparer.py +0 -0
  82. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/data_structures/default_dict.py +0 -0
  83. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/data_structures/functions.py +0 -0
  84. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/data_structures/graph/__init__.py +0 -0
  85. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/data_structures/graph/binary_node.py +0 -0
  86. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/data_structures/graph/graph.py +0 -0
  87. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/data_structures/graph/multinode.py +0 -0
  88. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/data_structures/graph/node.py +0 -0
  89. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/data_structures/heap/__init__.py +0 -0
  90. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/data_structures/heap/heap.py +0 -0
  91. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/data_structures/heap/max_heap.py +0 -0
  92. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/data_structures/heap/min_heap.py +0 -0
  93. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/data_structures/queue/__init__.py +0 -0
  94. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/data_structures/queue/atomic_queue.py +0 -0
  95. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/data_structures/queue/priority_queue.py +0 -0
  96. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/data_structures/queue/queue.py +0 -0
  97. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/data_structures/stack.py +0 -0
  98. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/data_structures/trees/__init__.py +0 -0
  99. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/data_structures/trees/binary_tree.py +0 -0
  100. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/date.py +0 -0
  101. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/date_time.py +0 -0
  102. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/decorators/chain_decorators.py +0 -0
  103. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/decorators/decorate_conditionally.py +0 -0
  104. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/decorators/processify.py +0 -0
  105. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/decorators/property.py +0 -0
  106. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/decorators/singleton.py +0 -0
  107. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/decorators/total_ordering.py +0 -0
  108. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/exceptions.py +0 -0
  109. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/functions/__init__.py +0 -0
  110. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/functions/areoneof.py +0 -0
  111. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/functions/check_foreach.py +0 -0
  112. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/functions/flatten.py +0 -0
  113. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/functions/isoneof.py +0 -0
  114. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/functions/multiloop.py +0 -0
  115. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/functions/powerset.py +0 -0
  116. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/functions/subseteq.py +0 -0
  117. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/functions/types_subseteq.py +0 -0
  118. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/generators/__init__.py +0 -0
  119. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/generators/conditional_generator.py +0 -0
  120. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/generators/generator_from_stream.py +0 -0
  121. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/generators/join_generators.py +0 -0
  122. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/internet.py +0 -0
  123. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/io_.py +0 -0
  124. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/math_/__init__.py +0 -0
  125. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/math_/constants.py +0 -0
  126. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/math_/functions.py +0 -0
  127. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/math_/math_print.py +0 -0
  128. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/math_/math_symbols.py +0 -0
  129. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/math_/polynomial/__init__.py +0 -0
  130. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/metaclasses/__init__.py +0 -0
  131. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/metaclasses/atomic_class_meta.py +0 -0
  132. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/metaclasses/implicit_data_deleter_meta.py +0 -0
  133. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/metaclasses/instance_cache_meta.py +0 -0
  134. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/metaclasses/interface.py +0 -0
  135. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/metaclasses/overload_meta.py +0 -0
  136. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/mock_/__init__.py +0 -0
  137. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/mock_/mock_database.py +0 -0
  138. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/mock_/mock_module.py +0 -0
  139. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/path.py +0 -0
  140. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/print_.py +0 -0
  141. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/protocols/__init__.py +0 -0
  142. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/protocols/evaluable.py +0 -0
  143. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/py.typed +0 -0
  144. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/reflection/__init__.py +0 -0
  145. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/reflection/class_/__init__.py +0 -0
  146. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/reflection/file/__init__.py +0 -0
  147. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/reflection/function/__init__.py +0 -0
  148. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/reflection/function/function_reflections.py +0 -0
  149. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/reflection/interpreter/__init__.py +0 -0
  150. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/reflection/interpreter/get_traceback.py +0 -0
  151. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/reflection/interpreter/os_.py +0 -0
  152. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/reflection/interpreter/packages.py +0 -0
  153. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/reflection/interpreter/python_version.py +0 -0
  154. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/reflection/interpreter/signals.py +0 -0
  155. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/reflection/module/__init__.py +0 -0
  156. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/reflection/module/module_reflections.py +0 -0
  157. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/reflection/module/package_reflection.py +0 -0
  158. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/snippets/__init__.py +0 -0
  159. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/snippets/try_get.py +0 -0
  160. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/system/__init__.py +0 -0
  161. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/system/independent.py +0 -0
  162. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/system/windows/__init__.py +0 -0
  163. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/system/windows/utils/__init__.py +0 -0
  164. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/system/windows/utils/filetime.py +0 -0
  165. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/system/windows/win32_ctime.py +0 -0
  166. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/system/windows/windows.py +0 -0
  167. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/text.py +0 -0
  168. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/university/__init__.py +0 -0
  169. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/university/databases/__init__.py +0 -0
  170. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/university/databases/all.py +0 -0
  171. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/university/oop/__init__.py +0 -0
  172. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/university/oop/observer.py +0 -0
  173. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/university/oop/strategy.py +0 -0
  174. {danielutils-0.9.76/danielutils/university/probability/conditional_variables → danielutils-0.9.77/danielutils/university/probability/conditional_variable}/__init__.py +0 -0
  175. {danielutils-0.9.76/danielutils/university/probability/conditional_variables → danielutils-0.9.77/danielutils/university/probability/conditional_variable}/continuous/__init__.py +0 -0
  176. {danielutils-0.9.76/danielutils/university/probability/conditional_variables → danielutils-0.9.77/danielutils/university/probability/conditional_variable}/discrete/__init__.py +0 -0
  177. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/university/probability/expressions/__init__.py +0 -0
  178. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/university/probability/funcs/__init__.py +0 -0
  179. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/university/probability/funcs/probability_function.py +0 -0
  180. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils/university/probability/protocols.py +0 -0
  181. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils.egg-info/dependency_links.txt +0 -0
  182. {danielutils-0.9.76 → danielutils-0.9.77}/danielutils.egg-info/top_level.txt +0 -0
  183. {danielutils-0.9.76 → danielutils-0.9.77}/setup.cfg +0 -0
  184. {danielutils-0.9.76 → danielutils-0.9.77}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: danielutils
3
- Version: 0.9.76
3
+ Version: 0.9.77
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
@@ -47,6 +47,9 @@ Feel free to use and / or contribute / improve my code :)
47
47
 
48
48
  THIS PACKAGE IS IN DEVELOPMENT AND SUBJECT TO CHANGE, USE AT YOUR OWN RISK!
49
49
 
50
+ **Tested python versions**: `3.8.0`*, `3.9.0`, `3.10.13`
51
+
52
+ Versions marked with * are partially working
50
53
  # Showcase
51
54
  In [this](./READMES/) folder you can check out some more in depth showcase of some of the topics I have covered in this package
52
55
 
@@ -10,6 +10,9 @@ Feel free to use and / or contribute / improve my code :)
10
10
 
11
11
  THIS PACKAGE IS IN DEVELOPMENT AND SUBJECT TO CHANGE, USE AT YOUR OWN RISK!
12
12
 
13
+ **Tested python versions**: `3.8.0`*, `3.9.0`, `3.10.13`
14
+
15
+ Versions marked with * are partially working
13
16
  # Showcase
14
17
  In [this](./READMES/) folder you can check out some more in depth showcase of some of the topics I have covered in this package
15
18
 
@@ -3,10 +3,10 @@ from typing import Any, Optional, TypeVar
3
3
  try:
4
4
  import redis
5
5
  except ImportError:
6
- from mock_ import MockImportObject
6
+ from ...mock_ import MockImportObject
7
7
 
8
8
  redis = MockImportObject("`redis` is not installed")
9
- from abstractions.database.database import Database
9
+ from .database import Database
10
10
 
11
11
  K = TypeVar('K')
12
12
  V = TypeVar('V')
@@ -1,7 +1,9 @@
1
- from typing import Union, Any, Callable
1
+ from typing import Union, Any, Callable,Dict as t_dict
2
2
  from .binary_tree import BinaryTree
3
3
  from ..graph import BinaryNode
4
-
4
+ from ...reflection import get_python_version
5
+ if get_python_version()>=(3,9):
6
+ from builtins import dict as t_dict
5
7
 
6
8
  class BinarySyntaxTree(BinaryTree):
7
9
  """
@@ -9,7 +11,7 @@ class BinarySyntaxTree(BinaryTree):
9
11
  """
10
12
 
11
13
  @staticmethod
12
- def _evaluate_node(v: BinaryNode, operator_func_dict: dict[Any, Callable[[Any, Any], Any]]):
14
+ def _evaluate_node(v: BinaryNode, operator_func_dict: t_dict[Any, Callable[[Any, Any], Any]]):
13
15
  if not isinstance(v, BinaryNode) or v.left is None and v.right is None:
14
16
  return v
15
17
 
@@ -72,7 +74,7 @@ class BinarySyntaxTree(BinaryTree):
72
74
  def __reversed__(self) -> "BinarySyntaxTree":
73
75
  return self.reverse()
74
76
 
75
- def evaluate(self, operator_func_dict: dict[Any, Callable[[Any, Any], Any]]) -> Any:
77
+ def evaluate(self, operator_func_dict: t_dict[Any, Callable[[Any, Any], Any]]) -> Any:
76
78
  return BinarySyntaxTree._evaluate_node(self.root, operator_func_dict)
77
79
 
78
80
 
@@ -14,3 +14,4 @@ from .deprecate import *
14
14
  from .processify import *
15
15
  from .singleton import *
16
16
  from .total_ordering import *
17
+ from .final import *
@@ -3,11 +3,8 @@ from typing import Callable, Any, TypeVar
3
3
  import threading
4
4
  from .validate import validate
5
5
 
6
- from ..reflection import get_python_version
7
- if get_python_version() < (3, 9):
8
- from typing_extensions import ParamSpec
9
- else:
10
- from typing import ParamSpec # type:ignore # pylint: disable=ungrouped-imports
6
+ from ..versioned_imports import ParamSpec
7
+
11
8
  T = TypeVar("T")
12
9
  P = ParamSpec("P")
13
10
  FuncT = Callable[P, T] # type:ignore
@@ -26,10 +23,11 @@ def atomic(func: FuncT) -> FuncT:
26
23
  """
27
24
  lock = threading.Lock()
28
25
 
29
- @ functools.wraps(func)
26
+ @functools.wraps(func)
30
27
  def wrapper(*args, **kwargs) -> Any:
31
28
  with lock:
32
29
  return func(*args, **kwargs)
30
+
33
31
  return wrapper
34
32
 
35
33
 
@@ -1,11 +1,8 @@
1
1
  import functools
2
2
  from typing import Callable, Optional, TypeVar
3
3
  from .validate import validate
4
- from ..reflection import get_python_version
5
- if get_python_version() < (3, 9):
6
- from typing_extensions import ParamSpec
7
- else:
8
- from typing import ParamSpec # type:ignore # pylint: disable=ungrouped-imports
4
+ from ..versioned_imports import ParamSpec
5
+
9
6
  T = TypeVar("T")
10
7
  P = ParamSpec("P")
11
8
  FuncT = Callable[P, T] # type:ignore
@@ -41,7 +38,9 @@ def attach(before: Optional[Callable] = None, after: Optional[Callable] = None)
41
38
  if after is not None:
42
39
  after()
43
40
  return res
41
+
44
42
  return wrapper
43
+
45
44
  return attach_deco
46
45
 
47
46
 
@@ -3,12 +3,8 @@ import time
3
3
  import functools
4
4
  from .decorate_conditionally import decorate_conditionally
5
5
  from .threadify import threadify
6
+ from ..versioned_imports import ParamSpec
6
7
 
7
- from ..reflection import get_python_version
8
- if get_python_version() < (3, 9):
9
- from typing_extensions import ParamSpec
10
- else:
11
- from typing import ParamSpec # type:ignore# pylint: disable=ungrouped-imports
12
8
  T = TypeVar("T")
13
9
  P = ParamSpec("P")
14
10
  FuncT = Callable[P, T] # type:ignore
@@ -22,13 +18,16 @@ def delay_call(seconds: Union[float, int], blocking: bool = True) -> Callable[[F
22
18
  blocking (bool, optional): whether to block the main thread
23
19
  when waiting or to wait in a different thread. Defaults to True.
24
20
  """
21
+
25
22
  def deco(func: FuncT) -> FuncT:
26
23
  @decorate_conditionally(threadify, not blocking)
27
24
  @functools.wraps(func)
28
25
  def wrapper(*args, **kwargs):
29
26
  time.sleep(seconds)
30
27
  func(*args, **kwargs)
28
+
31
29
  return wrapper
30
+
32
31
  return deco
33
32
 
34
33
 
@@ -1,11 +1,7 @@
1
1
  from typing import Callable, TypeVar
2
2
  from ..colors import warning, ColoredText
3
+ from ..versioned_imports import ParamSpec
3
4
 
4
- from ..reflection import get_python_version
5
- if get_python_version() < (3, 9):
6
- from typing_extensions import ParamSpec
7
- else:
8
- from typing import ParamSpec # type:ignore # pylint: disable=ungrouped-imports
9
5
  T = TypeVar("T")
10
6
  P = ParamSpec("P")
11
7
  FuncT = Callable[P, T] # type:ignore
@@ -13,13 +9,16 @@ FuncT = Callable[P, T] # type:ignore
13
9
 
14
10
  def deprecate_with(replacement_func) -> Callable[[FuncT], FuncT]:
15
11
  """will replace a deprecated function with the replacement func and will print a warning"""
12
+
16
13
  def deco(func: FuncT) -> FuncT:
17
14
  warning(f"{func.__module__}.{func.__qualname__} is deprecated,"
18
15
  f" using {replacement_func.__module__}.{replacement_func.__qualname__} instead")
19
16
 
20
17
  def wrapper(*args, **kwargs):
21
18
  return replacement_func(*args, **kwargs)
19
+
22
20
  return wrapper
21
+
23
22
  return deco
24
23
 
25
24
 
@@ -29,12 +28,15 @@ def deprecate(deprecation_message: str) -> Callable[[FuncT], FuncT]:
29
28
  Args:
30
29
  deprecation_message (str): deprecation message
31
30
  """
31
+
32
32
  def deco(func: FuncT) -> FuncT:
33
33
  def wrapper(*args, **kwargs):
34
34
  print(ColoredText.orange("Deprecation Warning") +
35
35
  ":", deprecation_message)
36
36
  return func(*args, **kwargs)
37
+
37
38
  return wrapper
39
+
38
40
  return deco
39
41
 
40
42
 
@@ -0,0 +1,37 @@
1
+ def final(cls: type) -> type:
2
+ """
3
+ A class Decorator to mark a class as final and add expected behavior
4
+ Args:
5
+ cls: the class to mark
6
+
7
+ Returns:
8
+ marked class
9
+ """
10
+ def __init__subclass__(*args, **kwargs):
11
+ raise TypeError(f"'{cls.__qualname__}' is final. Can't create subclasses")
12
+
13
+ setattr(cls, "__init_subclass__", __init__subclass__)
14
+ return cls
15
+
16
+
17
+ class Final:
18
+ """
19
+ A parent class to make direct child a Final class. will add expected behaviour.
20
+ """
21
+ def __new__(cls, *args, **kwargs):
22
+ if cls is Final:
23
+ raise TypeError("Can't instantiate 'Final'")
24
+ return super().__new__(cls, *args, **kwargs)
25
+
26
+ @classmethod
27
+ def __init_subclass__(cls, **kwargs):
28
+ def __init__subclass__(*args, **kwargs):
29
+ raise TypeError(f"'{cls.__qualname__}' is final. Can't create subclasses")
30
+
31
+ setattr(cls, "__init_subclass__", __init__subclass__)
32
+
33
+
34
+ __all__ = [
35
+ "final",
36
+ "Final"
37
+ ]
@@ -4,12 +4,8 @@ import traceback
4
4
  from typing import Any, Callable, TypeVar
5
5
  from .validate import validate
6
6
  from ..colors import warning
7
+ from ..versioned_imports import ParamSpec
7
8
 
8
- from ..reflection import get_python_version
9
- if get_python_version() < (3, 9):
10
- from typing_extensions import ParamSpec
11
- else:
12
- from typing import ParamSpec # type:ignore # pylint: disable=ungrouped-imports
13
9
  T = TypeVar("T")
14
10
  P = ParamSpec("P")
15
11
  FuncT = Callable[P, T] # type:ignore
@@ -27,12 +23,12 @@ def limit_recursion(max_depth: int, return_value: Any = None, quiet: bool = True
27
23
  """
28
24
 
29
25
  def deco(func: FuncT) -> FuncT:
30
- @ functools.wraps(func)
26
+ @functools.wraps(func)
31
27
  def wrapper(*args, **kwargs):
32
28
  depth = functools.reduce(
33
29
  lambda count, line:
34
- count + 1 if re.search(rf"{func.__name__}\(.*\)$", line)
35
- else count,
30
+ count + 1 if re.search(rf"{func.__name__}\(.*\)$", line)
31
+ else count,
36
32
  traceback.format_stack(), 0
37
33
  )
38
34
  if depth >= max_depth:
@@ -44,7 +40,9 @@ def limit_recursion(max_depth: int, return_value: Any = None, quiet: bool = True
44
40
  return return_value
45
41
  return args, kwargs
46
42
  return func(*args, **kwargs)
43
+
47
44
  return wrapper
45
+
48
46
  return deco
49
47
 
50
48
 
@@ -2,13 +2,8 @@ import functools
2
2
  from typing import Callable, Any, TypeVar, Dict as t_dict
3
3
  from copy import deepcopy
4
4
  from .validate import validate
5
+ from ..versioned_imports import ParamSpec, t_dict
5
6
 
6
- from ..reflection import get_python_version
7
- if get_python_version() < (3, 9):
8
- from typing_extensions import ParamSpec
9
- else:
10
- from builtins import dict as t_dict
11
- from typing import ParamSpec # type:ignore # pylint: disable=ungrouped-imports
12
7
  T = TypeVar("T")
13
8
  P = ParamSpec("P")
14
9
  FuncT = Callable[P, T] # type:ignore
@@ -23,11 +18,12 @@ def memo(func: FuncT) -> FuncT:
23
18
  """
24
19
  cache: t_dict[tuple, Any] = {}
25
20
 
26
- @ functools.wraps(func)
21
+ @functools.wraps(func)
27
22
  def wrapper(*args, **kwargs):
28
23
  if (args, *kwargs.items()) not in cache:
29
24
  cache[(args, *kwargs.items())] = func(*args, **kwargs)
30
25
  return deepcopy(cache[(args, *kwargs.items())])
26
+
31
27
  return wrapper
32
28
 
33
29
 
@@ -5,13 +5,8 @@ from ..reflection import is_function_annotated_properly
5
5
  from ..functions import isoftype, isoneof, isoneof_strict
6
6
  from ..exceptions import OverloadDuplication, OverloadNotFound
7
7
  from .deprecate import deprecate
8
- from ..reflection import get_python_version
8
+ from ..versioned_imports import ParamSpec, t_dict, t_list
9
9
 
10
- if get_python_version() < (3, 9):
11
- from typing_extensions import ParamSpec
12
- else:
13
- from typing import ParamSpec # type:ignore# pylint: disable=ungrouped-imports
14
- from builtins import dict as t_dict, list as t_list
15
10
  T = TypeVar("T")
16
11
  P = ParamSpec("P")
17
12
  FuncT = Callable[P, T] # type:ignore
@@ -2,12 +2,8 @@ from typing import Callable, Any, TypeVar
2
2
  import functools
3
3
  from .validate import validate
4
4
  from ..colors import warning
5
+ from ..versioned_imports import ParamSpec
5
6
 
6
- from ..reflection import get_python_version
7
- if get_python_version() < (3, 9):
8
- from typing_extensions import ParamSpec
9
- else:
10
- from typing import ParamSpec # type:ignore # pylint: disable=ungrouped-imports
11
7
  T = TypeVar("T")
12
8
  P = ParamSpec("P")
13
9
  FuncT = Callable[P, T] # type:ignore
@@ -21,12 +17,13 @@ def PartiallyImplemented(func: FuncT) -> FuncT:
21
17
  func (Callable): the function to decorate
22
18
  """
23
19
 
24
- @ functools.wraps(func)
20
+ @functools.wraps(func)
25
21
  def wrapper(*args, **kwargs) -> Any:
26
22
  warning(
27
23
  f"As marked by the developer, {func.__module__}.{func.__qualname__} "
28
24
  "may not be fully implemented and might not work properly.")
29
25
  return func(*args, **kwargs)
26
+
30
27
  return wrapper
31
28
 
32
29
 
@@ -1,12 +1,8 @@
1
1
  from typing import Callable, TypeVar
2
2
  import functools
3
3
  import threading
4
+ from ..versioned_imports import ParamSpec
4
5
 
5
- from ..reflection import get_python_version
6
- if get_python_version() < (3, 9):
7
- from typing_extensions import ParamSpec
8
- else:
9
- from typing import ParamSpec # type:ignore # pylint: disable=ungrouped-imports
10
6
  T = TypeVar("T")
11
7
  P = ParamSpec("P")
12
8
  FuncT = Callable[P, T] # type:ignore
@@ -22,9 +18,11 @@ def threadify(func: FuncT) -> FuncT:
22
18
  Returns:
23
19
  Callable: the modified function
24
20
  """
21
+
25
22
  @functools.wraps(func)
26
23
  def wrapper(*args, **kwargs):
27
24
  threading.Thread(target=func, args=args, kwargs=kwargs).start()
25
+
28
26
  return wrapper
29
27
 
30
28
 
@@ -2,12 +2,8 @@ import threading
2
2
  import functools
3
3
  from typing import Callable, TypeVar, Union
4
4
  from .validate import validate
5
- from ..reflection import get_python_version
5
+ from ..versioned_imports import ParamSpec
6
6
 
7
- if get_python_version() < (3, 9):
8
- from typing_extensions import ParamSpec
9
- else:
10
- from typing import ParamSpec # type:ignore # pylint: disable=ungrouped-imports
11
7
  T = TypeVar("T")
12
8
  P = ParamSpec("P")
13
9
  FuncT = Callable[P, T] # type:ignore
@@ -3,13 +3,10 @@ import inspect
3
3
  from typing import Callable, get_type_hints, cast, TypeVar, Union
4
4
  from ..functions.isoftype import isoftype
5
5
  from ..reflection import get_function_return_type
6
- from ..exceptions import EmptyAnnotationException,\
6
+ from ..exceptions import EmptyAnnotationException, \
7
7
  InvalidDefaultValueException, ValidationException, InvalidReturnValueException
8
- from ..reflection import get_python_version
9
- if get_python_version() < (3, 9):
10
- from typing_extensions import ParamSpec
11
- else:
12
- from typing import ParamSpec # type:ignore # pylint: disable=ungrouped-imports
8
+ from ..versioned_imports import ParamSpec
9
+
13
10
  T = TypeVar("T")
14
11
  P = ParamSpec("P")
15
12
  FuncT = Callable[P, T] # type:ignore
@@ -106,7 +103,9 @@ def validate(strict: Union[FuncT, bool] = True) -> FuncT:
106
103
  f"In function {func_name}, the return type is annotated as "
107
104
  f"{return_type} but got '{result}' which is {type(result)}")
108
105
  return result
106
+
109
107
  return wrapper
108
+
110
109
  if callable(strict):
111
110
  func = strict
112
111
  strict = True
@@ -115,90 +114,90 @@ def validate(strict: Union[FuncT, bool] = True) -> FuncT:
115
114
 
116
115
 
117
116
  # def validate(func: Callable) -> Callable:
118
- # """A decorator that validates the annotations and types of the arguments and return
119
- # value of a function.
120
-
121
- # * 'None' is allowed as default value for everything
122
- # * Because of their use in better_builtins, the generally accepted keywords 'self' and 'cls'
123
- # are not validated to not break intellisense when using 'Any'
124
-
125
- # Args:
126
- # func (Callable): The function to be decorated.
127
-
128
- # Raises:
129
- # TypeError: if the decorated object is nto a Callable
130
- # EmptyAnnotationException: If an argument is not annotated.
131
- # InvalidDefaultValueException: If an argument's default value is not of the annotated type.
132
- # ValidationException: If an argument's value is not of the expected type.
133
- # InvalidReturnValueException: If the return value is not of the expected type.
134
-
135
- # Returns:
136
- # Callable: A wrapper function that performs the validation and calls the original function.
137
- # """
138
- # SKIP_SET = {"self", "cls"}
139
- # if not isinstance(func, Callable):
140
- # raise TypeError("The validate decorator must only decorate a function")
141
- # func_name = f"{func.__module__}.{func.__qualname__}"
142
- # # get the signature of the function
143
- # signature = inspect.signature(func)
144
- # for arg_name, arg_param in signature.parameters.items():
145
- # if arg_name not in SKIP_SET:
146
- # arg_type = arg_param.annotation
147
- # # check if an annotation is missing
148
- # if arg_type == inspect.Parameter.empty:
149
- # raise EmptyAnnotationException(
150
- # f"In {func_name}, argument '{arg_name}' is not annotated")
151
-
152
- # # check if the argument has a default value
153
- # default_value = signature.parameters[arg_name].default
154
- # if default_value != inspect.Parameter.empty:
155
- # # allow everything to be set to None as default
156
- # if default_value is None:
157
- # continue
158
- # # if it does, check the type of the default value
159
- # if not isoftype(default_value, arg_type):
160
- # raise InvalidDefaultValueException(
161
- # f"In {func_name}, argument '{arg_name}'s default value is annotated \
162
- # as {arg_type} but got '{default_value}' which is {type(default_value)}")
163
-
164
- # @functools.wraps(func)
165
- # def wrapper(*args, **kwargs):
166
- # """wrapper function for the type validating - will run on each call independently
167
- # """
168
- # hints = None
169
- # # check all arguments
170
- # bound = signature.bind(*args, **kwargs)
171
- # for variable_name, variable_value in bound.arguments.items():
172
- # if variable_name in SKIP_SET:
173
- # continue
174
- # expected_type = func.__annotations__[variable_name]
175
-
176
- # if isinstance(expected_type, str):
177
- # # why does this even happen?
178
- # if hints is None:
179
- # hints = get_type_hints(func)
180
- # expected_type = hints[variable_name]
181
-
182
- # if not isoftype(variable_value, expected_type):
183
- # raise ValidationException(
184
- # f"In {func_name}, argument '{variable_name}' is annotated as \
185
- # {expected_type} but got '{variable_value}' which is {type(variable_value)}")
186
-
187
- # # call the function
188
- # result = func(*args, **kwargs)
189
-
190
- # # check the return type
191
- # return_type = type(None) if ("inspect._empty" in str(signature.return_annotation)
192
- # or signature.return_annotation is None) else signature.return_annotation
193
- # if isinstance(return_type, str):
194
- # # why does this even happen?
195
- # return_type = get_type_hints(func)["return"]
196
- # if return_type is not type(None) and not isoftype(result, return_type):
197
- # raise InvalidReturnValueException(
198
- # f"In function {func_name}, the return type is annotated as "
199
- # f"{return_type} but got '{result}' which is {type(result)}")
200
- # return result
201
- # return wrapper
117
+ # """A decorator that validates the annotations and types of the arguments and return
118
+ # value of a function.
119
+
120
+ # * 'None' is allowed as default value for everything
121
+ # * Because of their use in better_builtins, the generally accepted keywords 'self' and 'cls'
122
+ # are not validated to not break intellisense when using 'Any'
123
+
124
+ # Args:
125
+ # func (Callable): The function to be decorated.
126
+
127
+ # Raises:
128
+ # TypeError: if the decorated object is nto a Callable
129
+ # EmptyAnnotationException: If an argument is not annotated.
130
+ # InvalidDefaultValueException: If an argument's default value is not of the annotated type.
131
+ # ValidationException: If an argument's value is not of the expected type.
132
+ # InvalidReturnValueException: If the return value is not of the expected type.
133
+
134
+ # Returns:
135
+ # Callable: A wrapper function that performs the validation and calls the original function.
136
+ # """
137
+ # SKIP_SET = {"self", "cls"}
138
+ # if not isinstance(func, Callable):
139
+ # raise TypeError("The validate decorator must only decorate a function")
140
+ # func_name = f"{func.__module__}.{func.__qualname__}"
141
+ # # get the signature of the function
142
+ # signature = inspect.signature(func)
143
+ # for arg_name, arg_param in signature.parameters.items():
144
+ # if arg_name not in SKIP_SET:
145
+ # arg_type = arg_param.annotation
146
+ # # check if an annotation is missing
147
+ # if arg_type == inspect.Parameter.empty:
148
+ # raise EmptyAnnotationException(
149
+ # f"In {func_name}, argument '{arg_name}' is not annotated")
150
+
151
+ # # check if the argument has a default value
152
+ # default_value = signature.parameters[arg_name].default
153
+ # if default_value != inspect.Parameter.empty:
154
+ # # allow everything to be set to None as default
155
+ # if default_value is None:
156
+ # continue
157
+ # # if it does, check the type of the default value
158
+ # if not isoftype(default_value, arg_type):
159
+ # raise InvalidDefaultValueException(
160
+ # f"In {func_name}, argument '{arg_name}'s default value is annotated \
161
+ # as {arg_type} but got '{default_value}' which is {type(default_value)}")
162
+
163
+ # @functools.wraps(func)
164
+ # def wrapper(*args, **kwargs):
165
+ # """wrapper function for the type validating - will run on each call independently
166
+ # """
167
+ # hints = None
168
+ # # check all arguments
169
+ # bound = signature.bind(*args, **kwargs)
170
+ # for variable_name, variable_value in bound.arguments.items():
171
+ # if variable_name in SKIP_SET:
172
+ # continue
173
+ # expected_type = func.__annotations__[variable_name]
174
+
175
+ # if isinstance(expected_type, str):
176
+ # # why does this even happen?
177
+ # if hints is None:
178
+ # hints = get_type_hints(func)
179
+ # expected_type = hints[variable_name]
180
+
181
+ # if not isoftype(variable_value, expected_type):
182
+ # raise ValidationException(
183
+ # f"In {func_name}, argument '{variable_name}' is annotated as \
184
+ # {expected_type} but got '{variable_value}' which is {type(variable_value)}")
185
+
186
+ # # call the function
187
+ # result = func(*args, **kwargs)
188
+
189
+ # # check the return type
190
+ # return_type = type(None) if ("inspect._empty" in str(signature.return_annotation)
191
+ # or signature.return_annotation is None) else signature.return_annotation
192
+ # if isinstance(return_type, str):
193
+ # # why does this even happen?
194
+ # return_type = get_type_hints(func)["return"]
195
+ # if return_type is not type(None) and not isoftype(result, return_type):
196
+ # raise InvalidReturnValueException(
197
+ # f"In function {func_name}, the return type is annotated as "
198
+ # f"{return_type} but got '{result}' which is {type(result)}")
199
+ # return result
200
+ # return wrapper
202
201
 
203
202
  # @validate
204
203
  # def NotImplemented(func: Callable) -> Callable:
@@ -1,15 +1,9 @@
1
1
  from typing import get_args, get_origin, get_type_hints, Any, Union, TypeVar, \
2
- ForwardRef, Literal, Optional, Tuple as t_tuple, Protocol
2
+ ForwardRef, Literal, Optional, Protocol
3
3
  from collections.abc import Callable, Generator, Iterable
4
4
  from ..reflection import get_python_version
5
+ from ..versioned_imports import ParamSpec, Concatenate, t_tuple
5
6
 
6
- if get_python_version() < (3, 9):
7
- from typing_extensions import ParamSpec, Concatenate
8
- else:
9
-
10
- # pylint: disable=ungrouped-imports
11
- from typing import ParamSpec, Concatenate # type:ignore
12
- from builtins import tuple as t_tuple # type:ignore
13
7
  # implicit_union_type = type(int | str)
14
8
  concatenate_t = type(Concatenate[str, ParamSpec("P_")])
15
9
  ellipsis_ = ...
@@ -174,7 +168,7 @@ def __handle_callable(params: tuple) -> bool:
174
168
  if len(t_args) == 0:
175
169
  return True
176
170
 
177
- if get_python_version() < (3, 9):
171
+ if get_python_version() < (3, 10):
178
172
  if isoftype(t_args[0][0], [ParamSpec, concatenate_t]):
179
173
  return True
180
174
  else: