osbot-utils 2.10.0__tar.gz → 2.12.0__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 (350) hide show
  1. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/PKG-INFO +3 -3
  2. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/README.md +1 -1
  3. osbot_utils-2.12.0/osbot_utils/context_managers/capture_duration.py +37 -0
  4. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/CPrint.py +0 -1
  5. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/trace/Trace_Call.py +1 -2
  6. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/trace/Trace_Call__Handler.py +14 -14
  7. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/xml/Xml__File.py +1 -1
  8. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/xml/Xml__File__To_Dict.py +1 -1
  9. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/xml/Xml__File__To_Xml.py +1 -1
  10. osbot_utils-2.12.0/osbot_utils/testing/performance/Performance_Measure__Session.py +108 -0
  11. osbot_utils-2.12.0/osbot_utils/testing/performance/models/Model__Performance_Measure__Measurement.py +14 -0
  12. osbot_utils-2.12.0/osbot_utils/testing/performance/models/Model__Performance_Measure__Result.py +10 -0
  13. osbot_utils-2.12.0/osbot_utils/type_safe/Type_Safe.py +109 -0
  14. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/type_safe/Type_Safe__Base.py +8 -24
  15. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/type_safe/Type_Safe__Dict.py +9 -8
  16. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/type_safe/methods/type_safe_property.py +1 -1
  17. osbot_utils-2.12.0/osbot_utils/type_safe/shared/Type_Safe__Annotations.py +29 -0
  18. osbot_utils-2.12.0/osbot_utils/type_safe/shared/Type_Safe__Cache.py +143 -0
  19. osbot_utils-2.12.0/osbot_utils/type_safe/shared/Type_Safe__Convert.py +46 -0
  20. osbot_utils-2.12.0/osbot_utils/type_safe/shared/Type_Safe__Not_Cached.py +24 -0
  21. osbot_utils-2.12.0/osbot_utils/type_safe/shared/Type_Safe__Raise_Exception.py +14 -0
  22. osbot_utils-2.12.0/osbot_utils/type_safe/shared/Type_Safe__Shared__Variables.py +4 -0
  23. osbot_utils-2.12.0/osbot_utils/type_safe/shared/Type_Safe__Validation.py +246 -0
  24. osbot_utils-2.12.0/osbot_utils/type_safe/shared/__init__.py +0 -0
  25. osbot_utils-2.12.0/osbot_utils/type_safe/steps/Type_Safe__Step__Class_Kwargs.py +110 -0
  26. osbot_utils-2.12.0/osbot_utils/type_safe/steps/Type_Safe__Step__Default_Kwargs.py +42 -0
  27. osbot_utils-2.12.0/osbot_utils/type_safe/steps/Type_Safe__Step__Default_Value.py +74 -0
  28. osbot_utils-2.12.0/osbot_utils/type_safe/steps/Type_Safe__Step__From_Json.py +138 -0
  29. osbot_utils-2.12.0/osbot_utils/type_safe/steps/Type_Safe__Step__Init.py +24 -0
  30. osbot_utils-2.12.0/osbot_utils/type_safe/steps/Type_Safe__Step__Set_Attr.py +92 -0
  31. osbot_utils-2.12.0/osbot_utils/type_safe/steps/__init__.py +0 -0
  32. osbot_utils-2.12.0/osbot_utils/type_safe/validators/__init__.py +0 -0
  33. osbot_utils-2.12.0/osbot_utils/utils/Objects.py +318 -0
  34. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/utils/Status.py +0 -2
  35. osbot_utils-2.12.0/osbot_utils/utils/__init__.py +0 -0
  36. osbot_utils-2.12.0/osbot_utils/version +1 -0
  37. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/pyproject.toml +1 -1
  38. osbot_utils-2.10.0/osbot_utils/context_managers/capture_duration.py +0 -30
  39. osbot_utils-2.10.0/osbot_utils/type_safe/Type_Safe.py +0 -492
  40. osbot_utils-2.10.0/osbot_utils/utils/Objects.py +0 -523
  41. osbot_utils-2.10.0/osbot_utils/version +0 -1
  42. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/LICENSE +0 -0
  43. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/__init__.py +0 -0
  44. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/base_classes/Cache_Pickle.py +0 -0
  45. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/base_classes/Kwargs_To_Disk.py +0 -0
  46. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/base_classes/Kwargs_To_Self.py +0 -0
  47. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/base_classes/__init__.py +0 -0
  48. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/context_managers/__init__.py +0 -0
  49. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/context_managers/async_invoke.py +0 -0
  50. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/context_managers/disable_root_loggers.py +0 -0
  51. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/context_managers/print_duration.py +0 -0
  52. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/decorators/__init__.py +0 -0
  53. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/decorators/classes/__init__.py +0 -0
  54. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/decorators/classes/singleton.py +0 -0
  55. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/decorators/lists/__init__.py +0 -0
  56. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/decorators/lists/filter_list.py +0 -0
  57. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/decorators/lists/group_by.py +0 -0
  58. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/decorators/lists/index_by.py +0 -0
  59. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/decorators/methods/__init__.py +0 -0
  60. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/decorators/methods/cache.py +0 -0
  61. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/decorators/methods/cache_on_function.py +0 -0
  62. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/decorators/methods/cache_on_self.py +0 -0
  63. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/decorators/methods/cache_on_tmp.py +0 -0
  64. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/decorators/methods/capture_exception.py +0 -0
  65. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/decorators/methods/capture_status.py +0 -0
  66. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/decorators/methods/catch.py +0 -0
  67. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/decorators/methods/context.py +0 -0
  68. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/decorators/methods/depreciated.py +0 -0
  69. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/decorators/methods/function_type_check.py +0 -0
  70. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/decorators/methods/obj_as_context.py +0 -0
  71. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/decorators/methods/remove_return_value.py +0 -0
  72. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/decorators/methods/required_fields.py +0 -0
  73. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/fluent/Fluent_Dict.py +0 -0
  74. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/fluent/Fluent_List.py +0 -0
  75. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/fluent/__init__.py +0 -0
  76. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/CFormat.py +0 -0
  77. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/Dependency_Manager.py +0 -0
  78. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/Dict_To_Attr.py +0 -0
  79. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/Guid.py +0 -0
  80. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/Hashicorp_Secrets.py +0 -0
  81. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/Local_Cache.py +0 -0
  82. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/Local_Caches.py +0 -0
  83. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/Print_Table.py +0 -0
  84. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/Python_Audit.py +0 -0
  85. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/Random_Guid.py +0 -0
  86. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/Random_Guid_Short.py +0 -0
  87. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/Random_Seed.py +0 -0
  88. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/Safe_Id.py +0 -0
  89. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/Str_ASCII.py +0 -0
  90. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/Timestamp_Now.py +0 -0
  91. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/Type_Registry.py +0 -0
  92. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/Zip_Bytes.py +0 -0
  93. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/__init__.py +0 -0
  94. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/Ast.py +0 -0
  95. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/Ast_Base.py +0 -0
  96. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/Ast_Data.py +0 -0
  97. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/Ast_Load.py +0 -0
  98. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/Ast_Merge.py +0 -0
  99. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/Ast_Node.py +0 -0
  100. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/Ast_Visit.py +0 -0
  101. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/Call_Tree.py +0 -0
  102. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/__init__.py +0 -0
  103. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Add.py +0 -0
  104. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Alias.py +0 -0
  105. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_And.py +0 -0
  106. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Argument.py +0 -0
  107. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Arguments.py +0 -0
  108. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Assert.py +0 -0
  109. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Assign.py +0 -0
  110. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Attribute.py +0 -0
  111. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Aug_Assign.py +0 -0
  112. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Bin_Op.py +0 -0
  113. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Bool_Op.py +0 -0
  114. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Break.py +0 -0
  115. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Call.py +0 -0
  116. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Class_Def.py +0 -0
  117. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Compare.py +0 -0
  118. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Comprehension.py +0 -0
  119. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Constant.py +0 -0
  120. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Continue.py +0 -0
  121. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Dict.py +0 -0
  122. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Eq.py +0 -0
  123. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Except_Handler.py +0 -0
  124. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Expr.py +0 -0
  125. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_For.py +0 -0
  126. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Function_Def.py +0 -0
  127. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Generator_Exp.py +0 -0
  128. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Gt.py +0 -0
  129. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_GtE.py +0 -0
  130. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_If.py +0 -0
  131. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_If_Exp.py +0 -0
  132. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Import.py +0 -0
  133. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Import_From.py +0 -0
  134. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_In.py +0 -0
  135. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Is.py +0 -0
  136. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Is_Not.py +0 -0
  137. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Keyword.py +0 -0
  138. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Lambda.py +0 -0
  139. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_List.py +0 -0
  140. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_List_Comp.py +0 -0
  141. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Load.py +0 -0
  142. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Lt.py +0 -0
  143. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_LtE.py +0 -0
  144. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Mod.py +0 -0
  145. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Module.py +0 -0
  146. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Mult.py +0 -0
  147. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Name.py +0 -0
  148. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Not.py +0 -0
  149. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Not_Eq.py +0 -0
  150. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Not_In.py +0 -0
  151. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Or.py +0 -0
  152. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Pass.py +0 -0
  153. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Pow.py +0 -0
  154. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Raise.py +0 -0
  155. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Return.py +0 -0
  156. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Set.py +0 -0
  157. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Slice.py +0 -0
  158. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Starred.py +0 -0
  159. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Store.py +0 -0
  160. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Sub.py +0 -0
  161. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Subscript.py +0 -0
  162. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Try.py +0 -0
  163. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Tuple.py +0 -0
  164. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Unary_Op.py +0 -0
  165. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_While.py +0 -0
  166. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_With.py +0 -0
  167. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_With_Item.py +0 -0
  168. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Yield.py +0 -0
  169. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/__init__.py +0 -0
  170. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/cache_requests/Cache__Requests__Actions.py +0 -0
  171. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/cache_requests/Cache__Requests__Config.py +0 -0
  172. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/cache_requests/Cache__Requests__Data.py +0 -0
  173. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/cache_requests/Cache__Requests__Invoke.py +0 -0
  174. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/cache_requests/Cache__Requests__Row.py +0 -0
  175. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/cache_requests/Cache__Requests__Table.py +0 -0
  176. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/cache_requests/__init__.py +0 -0
  177. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/cache_requests/flows/flow__Cache__Requests.py +0 -0
  178. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/flows/Flow.py +0 -0
  179. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/flows/Flow__Events.py +0 -0
  180. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/flows/Task.py +0 -0
  181. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/flows/__init__.py +0 -0
  182. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/flows/decorators/__init__.py +0 -0
  183. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/flows/decorators/flow.py +0 -0
  184. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/flows/decorators/task.py +0 -0
  185. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/flows/models/Flow_Run__Config.py +0 -0
  186. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/flows/models/Flow_Run__Event.py +0 -0
  187. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/flows/models/Flow_Run__Event_Data.py +0 -0
  188. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/flows/models/Flow_Run__Event_Type.py +0 -0
  189. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/flows/models/__init__.py +0 -0
  190. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/generators/Generator_Context_Manager.py +0 -0
  191. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/generators/Generator_Manager.py +0 -0
  192. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/generators/Model__Generator_State.py +0 -0
  193. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/generators/Model__Generator_Target.py +0 -0
  194. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/generators/__init__.py +0 -0
  195. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/html/Dict_To_Css.py +0 -0
  196. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/html/Dict_To_Html.py +0 -0
  197. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/html/Dict_To_Tags.py +0 -0
  198. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/html/Html_To_Dict.py +0 -0
  199. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/html/Html_To_Tag.py +0 -0
  200. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/html/Tag__Base.py +0 -0
  201. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/html/Tag__Body.py +0 -0
  202. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/html/Tag__Div.py +0 -0
  203. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/html/Tag__H.py +0 -0
  204. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/html/Tag__HR.py +0 -0
  205. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/html/Tag__Head.py +0 -0
  206. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/html/Tag__Html.py +0 -0
  207. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/html/Tag__Link.py +0 -0
  208. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/html/Tag__Style.py +0 -0
  209. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/html/__init__.py +0 -0
  210. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/pubsub/Event__Queue.py +0 -0
  211. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/pubsub/PubSub__Client.py +0 -0
  212. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/pubsub/PubSub__Room.py +0 -0
  213. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/pubsub/PubSub__Server.py +0 -0
  214. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/pubsub/PubSub__Sqlite.py +0 -0
  215. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/pubsub/__init__.py +0 -0
  216. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/pubsub/schemas/Schema__Event.py +0 -0
  217. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/pubsub/schemas/Schema__Event__Connect.py +0 -0
  218. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/pubsub/schemas/Schema__Event__Disconnect.py +0 -0
  219. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/pubsub/schemas/Schema__Event__Execute_Method.py +0 -0
  220. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/pubsub/schemas/Schema__Event__Join_Room.py +0 -0
  221. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/pubsub/schemas/Schema__Event__Leave_Room.py +0 -0
  222. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/pubsub/schemas/Schema__Event__Message.py +0 -0
  223. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/pubsub/schemas/Schema__PubSub__Client.py +0 -0
  224. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/pubsub/schemas/__init__.py +0 -0
  225. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/python_compatibility/__init__.py +0 -0
  226. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/python_compatibility/python_3_8.py +0 -0
  227. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/sqlite/Capture_Sqlite_Error.py +0 -0
  228. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/sqlite/Sqlite__Cursor.py +0 -0
  229. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/sqlite/Sqlite__Database.py +0 -0
  230. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/sqlite/Sqlite__Field.py +0 -0
  231. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/sqlite/Sqlite__Globals.py +0 -0
  232. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/sqlite/Sqlite__Table.py +0 -0
  233. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/sqlite/Sqlite__Table__Create.py +0 -0
  234. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/sqlite/Temp_Sqlite__Database__Disk.py +0 -0
  235. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/sqlite/Temp_Sqlite__Table.py +0 -0
  236. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/sqlite/__init__.py +0 -0
  237. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/sqlite/cache/Schema__Table__Requests.py +0 -0
  238. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/sqlite/cache/Sqlite__Cache__Requests.py +0 -0
  239. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/sqlite/cache/Sqlite__Cache__Requests__Patch.py +0 -0
  240. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/sqlite/cache/Sqlite__Cache__Requests__Sqlite.py +0 -0
  241. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/sqlite/cache/Sqlite__Cache__Requests__Table.py +0 -0
  242. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/sqlite/cache/Sqlite__DB__Requests.py +0 -0
  243. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/sqlite/cache/TestCase__Sqlite__Cache__Requests.py +0 -0
  244. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/sqlite/cache/__init__.py +0 -0
  245. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/sqlite/domains/Sqlite__DB.py +0 -0
  246. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/sqlite/domains/Sqlite__DB__Files.py +0 -0
  247. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/sqlite/domains/Sqlite__DB__Graph.py +0 -0
  248. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/sqlite/domains/Sqlite__DB__Json.py +0 -0
  249. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/sqlite/domains/Sqlite__DB__Local.py +0 -0
  250. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/sqlite/domains/__init__.py +0 -0
  251. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/sqlite/domains/schemas/__init__.py +0 -0
  252. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/sqlite/models/Sqlite__Field__Type.py +0 -0
  253. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/sqlite/models/__init__.py +0 -0
  254. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/sqlite/sample_data/Sqlite__Sample_Data__Chinook.py +0 -0
  255. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/sqlite/sample_data/__init__.py +0 -0
  256. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/sqlite/sql_builder/SQL_Builder.py +0 -0
  257. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/sqlite/sql_builder/SQL_Builder__Select.py +0 -0
  258. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/sqlite/sql_builder/__init__.py +0 -0
  259. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/sqlite/tables/Sqlite__Table__Config.py +0 -0
  260. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/sqlite/tables/Sqlite__Table__Edges.py +0 -0
  261. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/sqlite/tables/Sqlite__Table__Files.py +0 -0
  262. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/sqlite/tables/Sqlite__Table__Nodes.py +0 -0
  263. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/sqlite/tables/__init__.py +0 -0
  264. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ssh/SCP.py +0 -0
  265. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ssh/SSH.py +0 -0
  266. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ssh/SSH__Cache__Requests.py +0 -0
  267. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ssh/SSH__Execute.py +0 -0
  268. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ssh/SSH__Health_Check.py +0 -0
  269. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ssh/SSH__Linux.py +0 -0
  270. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ssh/SSH__Linux__Amazon.py +0 -0
  271. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ssh/SSH__Python.py +0 -0
  272. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ssh/TestCase__SSH.py +0 -0
  273. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ssh/__init__.py +0 -0
  274. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/trace/Trace_Call__Config.py +0 -0
  275. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/trace/Trace_Call__Print_Lines.py +0 -0
  276. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/trace/Trace_Call__Print_Traces.py +0 -0
  277. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/trace/Trace_Call__Stack.py +0 -0
  278. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/trace/Trace_Call__Stack_Node.py +0 -0
  279. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/trace/Trace_Call__Stats.py +0 -0
  280. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/trace/Trace_Call__View_Model.py +0 -0
  281. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/trace/Trace_Files.py +0 -0
  282. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/trace/__init__.py +0 -0
  283. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/xml/Xml__Attribute.py +0 -0
  284. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/xml/Xml__Element.py +0 -0
  285. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/xml/Xml__File__Load.py +0 -0
  286. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/xml/__init__.py +0 -0
  287. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/xml/rss/RSS__Channel.py +0 -0
  288. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/xml/rss/RSS__Enclosure.py +0 -0
  289. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/xml/rss/RSS__Feed.py +0 -0
  290. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/xml/rss/RSS__Feed__Parser.py +0 -0
  291. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/xml/rss/RSS__Image.py +0 -0
  292. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/xml/rss/RSS__Item.py +0 -0
  293. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/testing/Catch.py +0 -0
  294. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/testing/Custom_Handler_For_Http_Tests.py +0 -0
  295. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/testing/Duration.py +0 -0
  296. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/testing/Hook_Method.py +0 -0
  297. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/testing/Log_To_Queue.py +0 -0
  298. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/testing/Log_To_String.py +0 -0
  299. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/testing/Logging.py +0 -0
  300. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/testing/Patch_Print.py +0 -0
  301. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/testing/Profiler.py +0 -0
  302. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/testing/Pytest.py +0 -0
  303. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/testing/Stderr.py +0 -0
  304. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/testing/Stdout.py +0 -0
  305. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/testing/Temp_Env_Vars.py +0 -0
  306. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/testing/Temp_File.py +0 -0
  307. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/testing/Temp_Folder.py +0 -0
  308. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/testing/Temp_Sys_Path.py +0 -0
  309. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/testing/Temp_Web_Server.py +0 -0
  310. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/testing/Temp_Zip.py +0 -0
  311. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/testing/Temp_Zip_In_Memory.py +0 -0
  312. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/testing/Unit_Test.py +0 -0
  313. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/testing/Unzip_File.py +0 -0
  314. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/testing/__init__.py +0 -0
  315. {osbot_utils-2.10.0/osbot_utils/type_safe → osbot_utils-2.12.0/osbot_utils/testing/performance}/__init__.py +0 -0
  316. {osbot_utils-2.10.0/osbot_utils/type_safe/decorators → osbot_utils-2.12.0/osbot_utils/testing/performance/models}/__init__.py +0 -0
  317. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/type_safe/Type_Safe__List.py +0 -0
  318. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/type_safe/Type_Safe__Method.py +0 -0
  319. {osbot_utils-2.10.0/osbot_utils/type_safe/methods → osbot_utils-2.12.0/osbot_utils/type_safe}/__init__.py +0 -0
  320. {osbot_utils-2.10.0/osbot_utils/type_safe/validators → osbot_utils-2.12.0/osbot_utils/type_safe/decorators}/__init__.py +0 -0
  321. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/type_safe/decorators/type_safe.py +0 -0
  322. {osbot_utils-2.10.0/osbot_utils/utils → osbot_utils-2.12.0/osbot_utils/type_safe/methods}/__init__.py +0 -0
  323. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/type_safe/validators/Type_Safe__Validator.py +0 -0
  324. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/type_safe/validators/Validator__Max.py +0 -0
  325. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/type_safe/validators/Validator__Min.py +0 -0
  326. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/type_safe/validators/Validator__One_Of.py +0 -0
  327. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/type_safe/validators/Validator__Regex.py +0 -0
  328. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/utils/Assert.py +0 -0
  329. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/utils/Call_Stack.py +0 -0
  330. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/utils/Csv.py +0 -0
  331. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/utils/Dev.py +0 -0
  332. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/utils/Env.py +0 -0
  333. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/utils/Exceptions.py +0 -0
  334. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/utils/Files.py +0 -0
  335. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/utils/Functions.py +0 -0
  336. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/utils/Http.py +0 -0
  337. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/utils/Int.py +0 -0
  338. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/utils/Json.py +0 -0
  339. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/utils/Json_Cache.py +0 -0
  340. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/utils/Lists.py +0 -0
  341. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/utils/Misc.py +0 -0
  342. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/utils/Png.py +0 -0
  343. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/utils/Process.py +0 -0
  344. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/utils/Python_Logger.py +0 -0
  345. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/utils/Regex.py +0 -0
  346. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/utils/Str.py +0 -0
  347. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/utils/Threads.py +0 -0
  348. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/utils/Toml.py +0 -0
  349. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/utils/Version.py +0 -0
  350. {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/utils/Zip.py +0 -0
@@ -1,8 +1,7 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: osbot_utils
3
- Version: 2.10.0
3
+ Version: 2.12.0
4
4
  Summary: OWASP Security Bot - Utils
5
- Home-page: https://github.com/owasp-sbot/OSBot-Utils
6
5
  License: MIT
7
6
  Author: Dinis Cruz
8
7
  Author-email: dinis.cruz@owasp.org
@@ -16,6 +15,7 @@ Classifier: Programming Language :: Python :: 3.10
16
15
  Classifier: Programming Language :: Python :: 3.11
17
16
  Classifier: Programming Language :: Python :: 3.12
18
17
  Classifier: Programming Language :: Python :: 3.13
18
+ Project-URL: Homepage, https://github.com/owasp-sbot/OSBot-Utils
19
19
  Project-URL: Repository, https://github.com/owasp-sbot/OSBot-Utils
20
20
  Description-Content-Type: text/markdown
21
21
 
@@ -23,7 +23,7 @@ Description-Content-Type: text/markdown
23
23
 
24
24
  Powerful Python util methods and classes that simplify common apis and tasks.
25
25
 
26
- ![Current Release](https://img.shields.io/badge/release-v2.10.0-blue)
26
+ ![Current Release](https://img.shields.io/badge/release-v2.12.0-blue)
27
27
  [![codecov](https://codecov.io/gh/owasp-sbot/OSBot-Utils/graph/badge.svg?token=GNVW0COX1N)](https://codecov.io/gh/owasp-sbot/OSBot-Utils)
28
28
 
29
29
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  Powerful Python util methods and classes that simplify common apis and tasks.
4
4
 
5
- ![Current Release](https://img.shields.io/badge/release-v2.10.0-blue)
5
+ ![Current Release](https://img.shields.io/badge/release-v2.12.0-blue)
6
6
  [![codecov](https://codecov.io/gh/owasp-sbot/OSBot-Utils/graph/badge.svg?token=GNVW0COX1N)](https://codecov.io/gh/owasp-sbot/OSBot-Utils)
7
7
 
8
8
 
@@ -0,0 +1,37 @@
1
+ import time
2
+
3
+ from osbot_utils.type_safe.Type_Safe import Type_Safe
4
+
5
+
6
+ class capture_duration(Type_Safe):
7
+ action_name : str
8
+ duration : float
9
+ start_time : float
10
+ end_time : float
11
+ seconds : float
12
+ precision : int = 3 # Default rounding to 3 decimal places
13
+
14
+
15
+ def __enter__(self):
16
+ self.start_time = time.perf_counter() # Start the performance counter
17
+ return self
18
+
19
+ def __exit__(self, exc_type, exc_val, exc_tb):
20
+ self.end_time = time.perf_counter() # End the performance counter
21
+ self.duration = self.end_time - self.start_time
22
+ self.seconds = round(self.duration, self.precision) # Use configurable precision
23
+ return False # Ensures that exceptions are rethrown
24
+
25
+ def data(self):
26
+ return {
27
+ "start": self.start_time,
28
+ "end": self.end_time,
29
+ "seconds": self.seconds,
30
+ }
31
+
32
+ def print(self):
33
+ print()
34
+ if self.action_name:
35
+ print(f'action "{self.action_name}" took: {self.seconds} seconds')
36
+ else:
37
+ print(f'action took: {self.seconds} seconds')
@@ -1,4 +1,3 @@
1
- from osbot_utils.base_classes.Kwargs_To_Self import Kwargs_To_Self
2
1
  from osbot_utils.helpers.CFormat import CFormat, CFormat_Colors
3
2
 
4
3
 
@@ -1,8 +1,7 @@
1
1
  import linecache
2
2
  import sys
3
3
  import threading
4
- from functools import wraps
5
-
4
+ from functools import wraps
6
5
  from osbot_utils.base_classes.Kwargs_To_Self import Kwargs_To_Self
7
6
  from osbot_utils.helpers.trace.Trace_Call__Config import Trace_Call__Config, PRINT_MAX_STRING_LENGTH
8
7
  from osbot_utils.helpers.trace.Trace_Call__Handler import Trace_Call__Handler
@@ -8,29 +8,29 @@ from osbot_utils.helpers.trace.Trace_Call__Stack_Node import Trace_Call__Stack
8
8
  from osbot_utils.helpers.trace.Trace_Call__Stats import Trace_Call__Stats
9
9
 
10
10
  DEFAULT_ROOT_NODE_NODE_TITLE = 'Trace Session'
11
- GLOBAL_FUNCTIONS_TO_IGNORE = ['value_type_matches_obj_annotation_for_attr' , # these are type safety functions which introduce quite a lot of noise in the traces (and unless one is debugging type safety, they will not be needed)
12
- 'value_type_matches_obj_annotation_for_union_and_annotated' , # todo: map out and document why exactly these methods are ignore (and what is the side effect)
13
- 'are_types_compatible_for_assigment' ,
14
- 'obj_attribute_annotation' ,
15
- 'all_annotations' ,
16
- 'get_origin' ,
17
- 'getmro' ,
18
- 'default_value' ,
19
- 'raise_exception_on_obj_type_annotation_mismatch' ,
20
- '__cls_kwargs__' ,
21
- '__default__value__' ,
22
- '__setattr__' ,
23
- '<module>']
11
+ # GLOBAL_FUNCTIONS_TO_IGNORE = ['value_type_matches_obj_annotation_for_attr' , # these are type safety functions which introduce quite a lot of noise in the traces (and unless one is debugging type safety, they will not be needed)
12
+ # 'value_type_matches_obj_annotation_for_union_and_annotated' , # todo: map out and document why exactly these methods are ignore (and what is the side effect)
13
+ # 'are_types_compatible_for_assigment' ,
14
+ # 'obj_attribute_annotation' ,
15
+ # 'all_annotations' ,
16
+ # 'get_origin' ,
17
+ # 'getmro' ,
18
+ # 'default_value' ,
19
+ # '__cls_kwargs__' ,
20
+ # '__default__value__' ,
21
+ # '__setattr__' ,
22
+ # '<module>']
24
23
  GLOBAL_MODULES_TO_IGNORE = ['osbot_utils.helpers.trace.Trace_Call' , # todo: map out and document why exactly these modules are ignore (and what is the side effect)
25
24
  'osbot_utils.helpers.trace.Trace_Call__Config' ,
26
25
  'osbot_utils.helpers.trace.Trace_Call__View_Model' ,
27
26
  'osbot_utils.helpers.trace.Trace_Call__Print_Traces' ,
28
27
  'osbot_utils.helpers.trace.Trace_Call__Stack' ,
29
- 'osbot_utils.base_classes.Type_Safe' ,
28
+ # 'osbot_utils.base_classes.Type_Safe' ,
30
29
  'osbot_utils.helpers.CPrint' , # also see if this should be done here or at the print/view stage
31
30
  'osbot_utils.helpers.Print_Table' ,
32
31
  'osbot_utils.decorators.methods.cache_on_self' ,
33
32
  'codecs' ]
33
+ GLOBAL_FUNCTIONS_TO_IGNORE = []
34
34
 
35
35
  #GLOBAL_MODULES_TO_IGNORE = []
36
36
  #GLOBAL_FUNCTIONS_TO_IGNORE = []
@@ -1,5 +1,5 @@
1
1
  from typing import Dict
2
- from osbot_utils.type_safe.Type_Safe import Type_Safe
2
+ from osbot_utils.type_safe.Type_Safe import Type_Safe
3
3
  from osbot_utils.helpers.xml.Xml__Element import XML__Element
4
4
 
5
5
  class Xml__File(Type_Safe):
@@ -1,5 +1,5 @@
1
1
  from typing import Dict, Any
2
- from osbot_utils.type_safe.Type_Safe import Type_Safe
2
+ from osbot_utils.type_safe.Type_Safe import Type_Safe
3
3
  from osbot_utils.helpers.xml.Xml__Element import XML__Element
4
4
  from osbot_utils.helpers.xml.Xml__File import Xml__File
5
5
 
@@ -1,7 +1,7 @@
1
1
  from typing import Optional
2
2
  from xml.etree.ElementTree import Element, SubElement, tostring
3
3
  from xml.dom import minidom
4
- from osbot_utils.type_safe.Type_Safe import Type_Safe
4
+ from osbot_utils.type_safe.Type_Safe import Type_Safe
5
5
  from osbot_utils.helpers.xml.Xml__Element import XML__Element
6
6
  from osbot_utils.helpers.xml.Xml__File import Xml__File
7
7
 
@@ -0,0 +1,108 @@
1
+ import time
2
+ from typing import Callable, List
3
+ from statistics import mean, median, stdev
4
+ from osbot_utils.utils.Env import in_github_action
5
+ from osbot_utils.testing.performance.models.Model__Performance_Measure__Measurement import Model__Performance_Measure__Measurement
6
+ from osbot_utils.testing.performance.models.Model__Performance_Measure__Result import Model__Performance_Measure__Result
7
+ from osbot_utils.type_safe.Type_Safe import Type_Safe
8
+
9
+ MEASURE__INVOCATION__LOOPS = [1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610] # Fibonacci sequence for measurement loops
10
+
11
+ class Performance_Measure__Session(Type_Safe):
12
+ result : Model__Performance_Measure__Result = None # Current measurement result
13
+ assert_enabled: bool = True
14
+
15
+ def calculate_raw_score(self, times: List[int]) -> int: # Calculate raw performance score
16
+ if len(times) < 3: # Need at least 3 values for stability
17
+ return mean(times)
18
+
19
+ sorted_times = sorted(times) # Sort times for analysis
20
+ trim_size = max(1, len(times) // 10) # Remove ~10% from each end
21
+
22
+ trimmed = sorted_times[trim_size:-trim_size] # Remove outliers
23
+ med = median(trimmed) # Get median of trimmed data
24
+ trimmed_mean = mean (trimmed) # Get mean of trimmed data
25
+
26
+ raw_score = int(med * 0.6 + trimmed_mean * 0.4) # Weighted combination favoring median
27
+ return raw_score
28
+
29
+ def calculate_stable_score(self, raw_score: float) -> int: # Calculate stable performance score
30
+ if raw_score < 1_000: # Dynamic normalization based on score magnitude
31
+ return int(round(raw_score / 100) * 100) # Under 1µs: nearest 100ns
32
+ elif raw_score < 10_000:
33
+ return int(round(raw_score / 1000) * 1000) # Under 10µs: nearest 500ns
34
+ elif raw_score < 100_000:
35
+ return int(round(raw_score / 10000) * 10000) # Under 100µs: nearest 1000ns
36
+ else:
37
+ return int(round(raw_score / 100000) * 100000) # Above 100µs: nearest 5000ns
38
+
39
+ def calculate_metrics(self, times: List[int]) -> Model__Performance_Measure__Measurement: # Calculate statistical metrics
40
+ if not times:
41
+ raise ValueError("Cannot calculate metrics from empty time list")
42
+ raw_score = self.calculate_raw_score (times)
43
+ score = self.calculate_stable_score(raw_score)
44
+ return Model__Performance_Measure__Measurement(
45
+ avg_time = int(mean(times)) ,
46
+ min_time = min(times) ,
47
+ max_time = max(times) ,
48
+ median_time = int(median(times)) ,
49
+ stddev_time = stdev(times) if len(times) > 1 else 0 ,
50
+ raw_times = times ,
51
+ sample_size = len(times) ,
52
+ raw_score = raw_score ,
53
+ score = score )
54
+
55
+ def measure(self, target: Callable) -> 'Performance_Measure__Session': # Perform measurements
56
+ name = target.__name__
57
+ measurements = {}
58
+ all_times = [] # Collect all times for final score
59
+
60
+ for loop_size in MEASURE__INVOCATION__LOOPS: # Measure each loop size
61
+ loop_times = []
62
+ for i in range(loop_size):
63
+ start = time.perf_counter_ns()
64
+ target()
65
+ end = time.perf_counter_ns()
66
+ time_taken = end - start
67
+ loop_times.append(time_taken)
68
+ all_times.append(time_taken) # Add to overall collection
69
+
70
+ measurements[loop_size] = self.calculate_metrics(loop_times) # Store metrics for this loop size
71
+
72
+ raw_score = self.calculate_raw_score (all_times)
73
+ final_score = self.calculate_stable_score(raw_score) # Calculate final stable score
74
+
75
+ self.result = Model__Performance_Measure__Result(
76
+ measurements = measurements ,
77
+ name = name ,
78
+ raw_score = raw_score ,
79
+ final_score = final_score )
80
+
81
+ return self
82
+
83
+ def print_measurement(self, measurement: Model__Performance_Measure__Measurement): # Format measurement details
84
+ print(f"Samples : {measurement.sample_size}")
85
+ print(f"Score : {measurement.score:,.0f}ns")
86
+ print(f"Avg : {measurement.avg_time:,}ns")
87
+ print(f"Min : {measurement.min_time:,}ns")
88
+ print(f"Max : {measurement.max_time:,}ns")
89
+ print(f"Median : {measurement.median_time:,}ns")
90
+ print(f"StdDev : {measurement.stddev_time:,.2f}ns")
91
+
92
+ def print(self, padding=12 ): # Print measurement results
93
+ if not self.result:
94
+ print("No measurements taken yet")
95
+ return
96
+ print(f"{self.result.name:{padding}} | score: {self.result.final_score:7,d} ns | raw: {self.result.raw_score:7,d} ns") # Print name and normalized score
97
+
98
+ return self
99
+
100
+ def assert_time(self, *expected_time: int): # Assert that the final score matches the expected normalized time"""
101
+ if self.assert_enabled is False:
102
+ return
103
+ if in_github_action():
104
+ last_expected_time = expected_time[-1] + 100 # +100 in case it is 0
105
+ new_expected_time = last_expected_time * 5 # using last_expected_time * 5 as the upper limit (since these tests are significantly slowed in GitHUb Actions)
106
+ assert last_expected_time <= self.result.final_score <= new_expected_time, f"Performance changed for {self.result.name}: expected {last_expected_time} < {self.result.final_score:,d}ns, expected {new_expected_time}"
107
+ else:
108
+ assert self.result.final_score in expected_time, f"Performance changed for {self.result.name}: got {self.result.final_score:,d}ns, expected {expected_time}"
@@ -0,0 +1,14 @@
1
+ from typing import List
2
+ from osbot_utils.type_safe.Type_Safe import Type_Safe
3
+
4
+
5
+ class Model__Performance_Measure__Measurement(Type_Safe): # Pure data container for measurement metrics
6
+ avg_time : int # Average time in nanoseconds
7
+ min_time : int # Minimum time observed
8
+ max_time : int # Maximum time observed
9
+ median_time : int # Median time
10
+ stddev_time : float # Standard deviation
11
+ raw_times : List[int] # Raw measurements for analysis
12
+ sample_size : int # Number of measurements taken
13
+ score : float
14
+ raw_score : float
@@ -0,0 +1,10 @@
1
+ from typing import Dict
2
+ from osbot_utils.testing.performance.models.Model__Performance_Measure__Measurement import Model__Performance_Measure__Measurement
3
+ from osbot_utils.type_safe.Type_Safe import Type_Safe
4
+
5
+ class Model__Performance_Measure__Result(Type_Safe): # Pure data container for measurement results
6
+ measurements : Dict[int, Model__Performance_Measure__Measurement] # Results per loop size
7
+ name : str # Name of measured target
8
+ raw_score : float
9
+ final_score : float
10
+
@@ -0,0 +1,109 @@
1
+ # todo: find a way to add these documentations strings to a separate location so that
2
+ # the data is available in IDE's code complete
3
+ from osbot_utils.type_safe.shared.Type_Safe__Validation import type_safe_validation
4
+ from osbot_utils.type_safe.steps.Type_Safe__Step__Class_Kwargs import type_safe_step_class_kwargs
5
+ from osbot_utils.type_safe.steps.Type_Safe__Step__Default_Kwargs import type_safe_step_default_kwargs
6
+ from osbot_utils.type_safe.steps.Type_Safe__Step__Default_Value import type_safe_step_default_value
7
+ from osbot_utils.type_safe.steps.Type_Safe__Step__Init import type_safe_step_init
8
+ from osbot_utils.type_safe.steps.Type_Safe__Step__Set_Attr import type_safe_step_set_attr
9
+ from osbot_utils.utils.Objects import serialize_to_dict
10
+
11
+ class Type_Safe:
12
+
13
+ def __init__(self, **kwargs):
14
+
15
+ class_kwargs = self.__cls_kwargs__()
16
+ type_safe_step_init.init(self, class_kwargs, **kwargs)
17
+
18
+
19
+ def __enter__(self): return self
20
+ def __exit__(self, exc_type, exc_val, exc_tb): pass
21
+
22
+ def __setattr__(self, name, value):
23
+ type_safe_step_set_attr.setattr(super(), self, name, value)
24
+
25
+ def __attr_names__(self):
26
+ from osbot_utils.utils.Misc import list_set
27
+
28
+ return list_set(self.__locals__())
29
+
30
+ @classmethod
31
+ def __cls_kwargs__(cls): # Return current class dictionary of class level variables and their values
32
+ return type_safe_step_class_kwargs.get_cls_kwargs(cls)
33
+
34
+ @classmethod
35
+ def __default__value__(cls, var_type):
36
+ return type_safe_step_default_value.default_value(cls, var_type)
37
+
38
+ def __default_kwargs__(self): # Return entire (including base classes) dictionary of class level variables and their values.
39
+ return type_safe_step_default_kwargs.default_kwargs(self)
40
+
41
+ def __kwargs__(self): # Return a dictionary of the current instance's attribute values including inherited class defaults.
42
+ return type_safe_step_default_kwargs.kwargs(self)
43
+
44
+
45
+ def __locals__(self): # Return a dictionary of the current instance's attribute values.
46
+ return type_safe_step_default_kwargs.locals(self)
47
+
48
+ # global methods added to any class that base classes this
49
+ # todo: see if there should be a prefix on these methods, to make it easier to spot them
50
+ # of if these are actually that useful that they should be added like this
51
+ # todo: these methods should not be here
52
+ # def bytes(self):
53
+ # from osbot_utils.utils.Json import json_to_bytes
54
+ #
55
+ # return json_to_bytes(self.json())
56
+ #
57
+ # def bytes_gz(self):
58
+ # from osbot_utils.utils.Json import json_to_gz
59
+ #
60
+ # return json_to_gz(self.json())
61
+
62
+ def json(self):
63
+ return self.serialize_to_dict()
64
+
65
+ # todo: see if we still need this. now that Type_Safe handles base types, there should be no need for this
66
+ def merge_with(self, target):
67
+ original_attrs = {k: v for k, v in self.__dict__.items() if k not in target.__dict__} # Store the original attributes of self that should be retained.
68
+ self.__dict__ = target.__dict__ # Set the target's __dict__ to self, now self and target share the same __dict__.
69
+ self.__dict__.update(original_attrs) # Reassign the original attributes back to self.
70
+ return self
71
+
72
+ # def locked(self, value=True): # todo: figure out best way to do this (maybe???)
73
+ # self.__lock_attributes__ = value # : update, with the latest changes were we don't show internals on __locals__() this might be a good way to do this
74
+ # return self
75
+
76
+ def reset(self):
77
+ for k,v in self.__cls_kwargs__().items():
78
+ setattr(self, k, v)
79
+
80
+ # todo: see if we still need this here in this class
81
+ def update_from_kwargs(self, **kwargs): # Update instance attributes with values from provided keyword arguments.
82
+
83
+ for key, value in kwargs.items():
84
+ if value is not None:
85
+ if hasattr(self,'__annotations__'): # can only do type safety checks if the class does not have annotations
86
+ if type_safe_validation.check_if__type_matches__obj_annotation__for_attr(self, key, value) is False:
87
+ raise ValueError(f"Invalid type for attribute '{key}'. Expected '{self.__annotations__.get(key)}' but got '{type(value)}'")
88
+ setattr(self, key, value)
89
+ return self
90
+
91
+ def obj(self):
92
+ from osbot_utils.utils.Objects import dict_to_obj
93
+
94
+ return dict_to_obj(self.json())
95
+
96
+ def serialize_to_dict(self): # todo: see if we need this method or if the .json() is enough
97
+ return serialize_to_dict(self)
98
+
99
+ def print(self):
100
+ from osbot_utils.utils.Dev import pprint
101
+
102
+ pprint(serialize_to_dict(self))
103
+
104
+ @classmethod
105
+ def from_json(cls, json_data, raise_on_not_found=False):
106
+ from osbot_utils.type_safe.steps.Type_Safe__Step__From_Json import type_safe_step_from_json # circular dependency on Type_Safe
107
+ return type_safe_step_from_json.from_json(cls, json_data, raise_on_not_found)
108
+
109
+
@@ -1,4 +1,6 @@
1
- from typing import get_origin, get_args, Union, Optional, Any, ForwardRef
1
+ from typing import get_args, Union, Optional, Any, ForwardRef
2
+
3
+ from osbot_utils.type_safe.shared.Type_Safe__Cache import type_safe_cache
2
4
 
3
5
  EXACT_TYPE_MATCH = (int, float, str, bytes, bool, complex)
4
6
 
@@ -8,7 +10,7 @@ class Type_Safe__Base:
8
10
  return True
9
11
  if isinstance(expected_type, ForwardRef): # todo: add support for ForwardRef
10
12
  return True
11
- origin = get_origin(expected_type)
13
+ origin = type_safe_cache.get_origin(expected_type)
12
14
  args = get_args(expected_type)
13
15
  if origin is None:
14
16
  if expected_type in EXACT_TYPE_MATCH:
@@ -85,12 +87,12 @@ class Type_Safe__Base:
85
87
  actual_type_name = type_str(type(item))
86
88
  raise TypeError(f"Expected '{expected_type_name}', but got '{actual_type_name}'")
87
89
 
88
- def json(self):
89
- raise NotImplemented
90
+ # def json(self):
91
+ # pass
90
92
 
91
93
  # todo: see if we should/can move this to the Objects.py file
92
94
  def type_str(tp):
93
- origin = get_origin(tp)
95
+ origin = type_safe_cache.get_origin(tp)
94
96
  if origin is None:
95
97
  if hasattr(tp, '__name__'):
96
98
  return tp.__name__
@@ -99,22 +101,4 @@ def type_str(tp):
99
101
  else:
100
102
  args = get_args(tp)
101
103
  args_str = ', '.join(type_str(arg) for arg in args)
102
- return f"{origin.__name__}[{args_str}]"
103
-
104
- def get_object_type_str(obj):
105
- if isinstance(obj, dict):
106
- if not obj:
107
- return "Dict[Empty]"
108
- key_types = set(type(k).__name__ for k in obj.keys())
109
- value_types = set(type(v).__name__ for v in obj.values())
110
- key_type_str = ', '.join(sorted(key_types))
111
- value_type_str = ', '.join(sorted(value_types))
112
- return f"Dict[{key_type_str}, {value_type_str}]"
113
- elif isinstance(obj, list):
114
- if not obj:
115
- return "List[Empty]"
116
- elem_types = set(type(e).__name__ for e in obj)
117
- elem_type_str = ', '.join(sorted(elem_types))
118
- return f"List[{elem_type_str}]"
119
- else:
120
- return type(obj).__name__
104
+ return f"{origin.__name__}[{args_str}]"
@@ -1,4 +1,4 @@
1
- from osbot_utils.type_safe.Type_Safe__Base import type_str, Type_Safe__Base
1
+ from osbot_utils.type_safe.Type_Safe__Base import Type_Safe__Base
2
2
 
3
3
  class Type_Safe__Dict(Type_Safe__Base, dict):
4
4
  def __init__(self, expected_key_type, expected_value_type, *args, **kwargs):
@@ -7,19 +7,20 @@ class Type_Safe__Dict(Type_Safe__Base, dict):
7
7
  self.expected_key_type = expected_key_type
8
8
  self.expected_value_type = expected_value_type
9
9
 
10
- for k, v in self.items(): # check type-safety of ctor arguments
11
- self.is_instance_of_type(k, self.expected_key_type )
12
- self.is_instance_of_type(v, self.expected_value_type)
10
+ # todo: see if we need to do this, since there was not code coverage hitting it
11
+ # for k, v in self.items(): # check type-safety of ctor arguments
12
+ # self.is_instance_of_type(k, self.expected_key_type )
13
+ # self.is_instance_of_type(v, self.expected_value_type)
13
14
 
14
15
  def __setitem__(self, key, value): # Check type-safety before allowing assignment.
15
16
  self.is_instance_of_type(key, self.expected_key_type)
16
17
  self.is_instance_of_type(value, self.expected_value_type)
17
18
  super().__setitem__(key, value)
18
19
 
19
- def __repr__(self):
20
- key_type_name = type_str(self.expected_key_type)
21
- value_type_name = type_str(self.expected_value_type)
22
- return f"dict[{key_type_name}, {value_type_name}] with {len(self)} entries"
20
+ # def __repr__(self):
21
+ # key_type_name = type_str(self.expected_key_type)
22
+ # value_type_name = type_str(self.expected_value_type)
23
+ # return f"dict[{key_type_name}, {value_type_name}] with {len(self)} entries"
23
24
 
24
25
  def json(self): # Convert the dictionary to a JSON-serializable format.
25
26
  from osbot_utils.type_safe.Type_Safe import Type_Safe # can only import this here to avoid circular imports
@@ -2,7 +2,7 @@ from typing import TypeVar, Type, Optional
2
2
 
3
3
  T = TypeVar('T')
4
4
 
5
- def type_safe_property(target_path: str, target_name: str, expected_type: Optional[Type[T]] = None) -> property: # Creates a type-safe property that delegates get/set operations to a nested data object
5
+ def type_safe_property(target_path: str, target_name: str, expected_type: Optional[Type[T]] = None) -> T: # Creates a type-safe property that delegates get/set operations to a nested data object
6
6
 
7
7
  def getter(self) -> T:
8
8
  target = self
@@ -0,0 +1,29 @@
1
+ from osbot_utils.type_safe.shared.Type_Safe__Cache import type_safe_cache
2
+
3
+
4
+ class Type_Safe__Annotations:
5
+
6
+ def all_annotations(self, target):
7
+ return type_safe_cache.get_obj_annotations(target) # use cache
8
+
9
+ def all_annotations__in_class(self, cls):
10
+ return type_safe_cache.get_class_annotations(cls)
11
+
12
+ def obj_attribute_annotation(self, target, attr_name):
13
+ return self.all_annotations(target).get(attr_name) # use cache
14
+
15
+ def obj_is_attribute_annotation_of_type(self, target, attr_name, expected_type):
16
+ attribute_annotation = self.obj_attribute_annotation(target, attr_name)
17
+ if expected_type is attribute_annotation:
18
+ return True
19
+ if expected_type is type(attribute_annotation):
20
+ return True
21
+ if expected_type is type_safe_cache.get_origin(attribute_annotation): # handle genericAlias
22
+ return True
23
+ return False
24
+
25
+ def get_origin(self, var_type):
26
+ return type_safe_cache.get_origin(var_type)
27
+
28
+ type_safe_annotations = Type_Safe__Annotations()
29
+