osbot-utils 2.59.0__tar.gz → 2.61.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 (433) hide show
  1. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/PKG-INFO +2 -2
  2. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/README.md +1 -1
  3. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/html/Html__To__Html_Document.py +1 -2
  4. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/html/schemas/Schema__Html_Node.py +2 -2
  5. osbot_utils-2.61.0/osbot_utils/helpers/safe_float/Safe_Float.py +155 -0
  6. osbot_utils-2.61.0/osbot_utils/helpers/safe_float/Safe_Float__Engineering.py +7 -0
  7. osbot_utils-2.61.0/osbot_utils/helpers/safe_float/Safe_Float__Money.py +11 -0
  8. osbot_utils-2.61.0/osbot_utils/helpers/safe_float/Safe_Float__Percentage_Exact.py +9 -0
  9. osbot_utils-2.61.0/osbot_utils/helpers/safe_int/Safe_Int.py +77 -0
  10. osbot_utils-2.61.0/osbot_utils/helpers/safe_int/Safe_UInt.py +7 -0
  11. osbot_utils-2.61.0/osbot_utils/helpers/safe_int/Safe_UInt__Byte.py +10 -0
  12. osbot_utils-2.61.0/osbot_utils/helpers/safe_int/Safe_UInt__FileSize.py +19 -0
  13. osbot_utils-2.61.0/osbot_utils/helpers/safe_int/Safe_UInt__Percentage.py +10 -0
  14. osbot_utils-2.61.0/osbot_utils/helpers/safe_int/Safe_UInt__Port.py +11 -0
  15. osbot_utils-2.61.0/osbot_utils/helpers/safe_int/__init__.py +10 -0
  16. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/safe_str/Safe_Str.py +1 -1
  17. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/type_safe/shared/Type_Safe__Validation.py +1 -1
  18. osbot_utils-2.61.0/osbot_utils/type_safe/validators/__init__.py +0 -0
  19. osbot_utils-2.61.0/osbot_utils/utils/__init__.py +0 -0
  20. osbot_utils-2.61.0/osbot_utils/version +1 -0
  21. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/pyproject.toml +1 -1
  22. osbot_utils-2.59.0/osbot_utils/version +0 -1
  23. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/LICENSE +0 -0
  24. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/__init__.py +0 -0
  25. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/base_classes/Cache_Pickle.py +0 -0
  26. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/base_classes/Kwargs_To_Disk.py +0 -0
  27. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/base_classes/Kwargs_To_Self.py +0 -0
  28. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/base_classes/__init__.py +0 -0
  29. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/context_managers/__init__.py +0 -0
  30. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/context_managers/async_invoke.py +0 -0
  31. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/context_managers/disable_root_loggers.py +0 -0
  32. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/decorators/__init__.py +0 -0
  33. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/decorators/classes/__init__.py +0 -0
  34. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/decorators/classes/singleton.py +0 -0
  35. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/decorators/lists/__init__.py +0 -0
  36. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/decorators/lists/filter_list.py +0 -0
  37. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/decorators/lists/group_by.py +0 -0
  38. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/decorators/lists/index_by.py +0 -0
  39. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/decorators/methods/__init__.py +0 -0
  40. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/decorators/methods/cache.py +0 -0
  41. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/decorators/methods/cache_on_function.py +0 -0
  42. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/decorators/methods/cache_on_self.py +0 -0
  43. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/decorators/methods/cache_on_tmp.py +0 -0
  44. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/decorators/methods/capture_exception.py +0 -0
  45. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/decorators/methods/capture_status.py +0 -0
  46. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/decorators/methods/catch.py +0 -0
  47. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/decorators/methods/context.py +0 -0
  48. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/decorators/methods/depreciated.py +0 -0
  49. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/decorators/methods/function_type_check.py +0 -0
  50. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/decorators/methods/obj_as_context.py +0 -0
  51. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/decorators/methods/remove_return_value.py +0 -0
  52. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/decorators/methods/required_fields.py +0 -0
  53. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/fluent/Fluent_Dict.py +0 -0
  54. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/fluent/Fluent_List.py +0 -0
  55. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/fluent/__init__.py +0 -0
  56. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/CFormat.py +0 -0
  57. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/CPrint.py +0 -0
  58. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/Dependency_Manager.py +0 -0
  59. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/Dict_To_Attr.py +0 -0
  60. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/Guid.py +0 -0
  61. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/Hashicorp_Secrets.py +0 -0
  62. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/Local_Cache.py +0 -0
  63. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/Local_Caches.py +0 -0
  64. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/Obj_Id.py +0 -0
  65. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/Print_Table.py +0 -0
  66. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/Python_Audit.py +0 -0
  67. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/Random_Guid.py +0 -0
  68. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/Random_Guid_Short.py +0 -0
  69. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/Random_Seed.py +0 -0
  70. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/Safe_Id.py +0 -0
  71. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/Str_ASCII.py +0 -0
  72. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/Timestamp_Now.py +0 -0
  73. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/Type_Registry.py +0 -0
  74. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/Zip_Bytes.py +0 -0
  75. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/__init__.py +0 -0
  76. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/ast/Ast.py +0 -0
  77. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/ast/Ast_Base.py +0 -0
  78. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/ast/Ast_Data.py +0 -0
  79. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/ast/Ast_Load.py +0 -0
  80. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/ast/Ast_Merge.py +0 -0
  81. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/ast/Ast_Node.py +0 -0
  82. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/ast/Ast_Visit.py +0 -0
  83. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/ast/Call_Tree.py +0 -0
  84. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/ast/__init__.py +0 -0
  85. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/ast/nodes/Ast_Add.py +0 -0
  86. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/ast/nodes/Ast_Alias.py +0 -0
  87. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/ast/nodes/Ast_And.py +0 -0
  88. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/ast/nodes/Ast_Argument.py +0 -0
  89. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/ast/nodes/Ast_Arguments.py +0 -0
  90. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/ast/nodes/Ast_Assert.py +0 -0
  91. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/ast/nodes/Ast_Assign.py +0 -0
  92. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/ast/nodes/Ast_Attribute.py +0 -0
  93. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/ast/nodes/Ast_Aug_Assign.py +0 -0
  94. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/ast/nodes/Ast_Bin_Op.py +0 -0
  95. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/ast/nodes/Ast_Bool_Op.py +0 -0
  96. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/ast/nodes/Ast_Break.py +0 -0
  97. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/ast/nodes/Ast_Call.py +0 -0
  98. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/ast/nodes/Ast_Class_Def.py +0 -0
  99. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/ast/nodes/Ast_Compare.py +0 -0
  100. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/ast/nodes/Ast_Comprehension.py +0 -0
  101. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/ast/nodes/Ast_Constant.py +0 -0
  102. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/ast/nodes/Ast_Continue.py +0 -0
  103. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/ast/nodes/Ast_Dict.py +0 -0
  104. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/ast/nodes/Ast_Eq.py +0 -0
  105. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/ast/nodes/Ast_Except_Handler.py +0 -0
  106. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/ast/nodes/Ast_Expr.py +0 -0
  107. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/ast/nodes/Ast_For.py +0 -0
  108. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/ast/nodes/Ast_Function_Def.py +0 -0
  109. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/ast/nodes/Ast_Generator_Exp.py +0 -0
  110. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/ast/nodes/Ast_Gt.py +0 -0
  111. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/ast/nodes/Ast_GtE.py +0 -0
  112. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/ast/nodes/Ast_If.py +0 -0
  113. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/ast/nodes/Ast_If_Exp.py +0 -0
  114. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/ast/nodes/Ast_Import.py +0 -0
  115. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/ast/nodes/Ast_Import_From.py +0 -0
  116. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/ast/nodes/Ast_In.py +0 -0
  117. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/ast/nodes/Ast_Is.py +0 -0
  118. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/ast/nodes/Ast_Is_Not.py +0 -0
  119. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/ast/nodes/Ast_Keyword.py +0 -0
  120. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/ast/nodes/Ast_Lambda.py +0 -0
  121. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/ast/nodes/Ast_List.py +0 -0
  122. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/ast/nodes/Ast_List_Comp.py +0 -0
  123. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/ast/nodes/Ast_Load.py +0 -0
  124. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/ast/nodes/Ast_Lt.py +0 -0
  125. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/ast/nodes/Ast_LtE.py +0 -0
  126. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/ast/nodes/Ast_Mod.py +0 -0
  127. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/ast/nodes/Ast_Module.py +0 -0
  128. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/ast/nodes/Ast_Mult.py +0 -0
  129. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/ast/nodes/Ast_Name.py +0 -0
  130. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/ast/nodes/Ast_Not.py +0 -0
  131. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/ast/nodes/Ast_Not_Eq.py +0 -0
  132. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/ast/nodes/Ast_Not_In.py +0 -0
  133. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/ast/nodes/Ast_Or.py +0 -0
  134. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/ast/nodes/Ast_Pass.py +0 -0
  135. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/ast/nodes/Ast_Pow.py +0 -0
  136. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/ast/nodes/Ast_Raise.py +0 -0
  137. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/ast/nodes/Ast_Return.py +0 -0
  138. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/ast/nodes/Ast_Set.py +0 -0
  139. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/ast/nodes/Ast_Slice.py +0 -0
  140. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/ast/nodes/Ast_Starred.py +0 -0
  141. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/ast/nodes/Ast_Store.py +0 -0
  142. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/ast/nodes/Ast_Sub.py +0 -0
  143. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/ast/nodes/Ast_Subscript.py +0 -0
  144. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/ast/nodes/Ast_Try.py +0 -0
  145. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/ast/nodes/Ast_Tuple.py +0 -0
  146. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/ast/nodes/Ast_Unary_Op.py +0 -0
  147. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/ast/nodes/Ast_While.py +0 -0
  148. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/ast/nodes/Ast_With.py +0 -0
  149. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/ast/nodes/Ast_With_Item.py +0 -0
  150. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/ast/nodes/Ast_Yield.py +0 -0
  151. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/ast/nodes/__init__.py +0 -0
  152. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/cache_requests/Cache__Requests__Actions.py +0 -0
  153. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/cache_requests/Cache__Requests__Config.py +0 -0
  154. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/cache_requests/Cache__Requests__Data.py +0 -0
  155. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/cache_requests/Cache__Requests__Invoke.py +0 -0
  156. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/cache_requests/Cache__Requests__Row.py +0 -0
  157. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/cache_requests/Cache__Requests__Table.py +0 -0
  158. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/cache_requests/__init__.py +0 -0
  159. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/duration/Duration.py +0 -0
  160. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/duration/__init__.py +0 -0
  161. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/duration/decorators/__init__.py +0 -0
  162. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/duration/decorators/capture_duration.py +0 -0
  163. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/duration/decorators/duration.py +0 -0
  164. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/duration/decorators/print_duration.py +0 -0
  165. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/duration/schemas/Schema__Duration.py +0 -0
  166. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/duration/schemas/__init__.py +0 -0
  167. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/flows/Flow.py +0 -0
  168. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/flows/Task.py +0 -0
  169. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/flows/__init__.py +0 -0
  170. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/flows/actions/Flow__Data.py +0 -0
  171. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/flows/actions/Flow__Events.py +0 -0
  172. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/flows/actions/Flow__Stats__Collector.py +0 -0
  173. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/flows/actions/Task__Stats__Collector.py +0 -0
  174. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/flows/actions/__init__.py +0 -0
  175. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/flows/decorators/__init__.py +0 -0
  176. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/flows/decorators/flow.py +0 -0
  177. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/flows/decorators/task.py +0 -0
  178. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/flows/models/Flow_Run__Config.py +0 -0
  179. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/flows/models/Flow_Run__Event.py +0 -0
  180. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/flows/models/Flow_Run__Event_Data.py +0 -0
  181. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/flows/models/Flow_Run__Event_Type.py +0 -0
  182. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/flows/models/Schema__Flow__Artifact.py +0 -0
  183. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/flows/models/Schema__Flow__Result.py +0 -0
  184. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/flows/models/__init__.py +0 -0
  185. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/flows/schemas/Schema__Flow.py +0 -0
  186. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/flows/schemas/Schema__Flow__Data.py +0 -0
  187. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/flows/schemas/Schema__Flow__Event.py +0 -0
  188. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/flows/schemas/Schema__Flow__Event__Data.py +0 -0
  189. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/flows/schemas/Schema__Flow__Log.py +0 -0
  190. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/flows/schemas/Schema__Flow__Stats.py +0 -0
  191. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/flows/schemas/Schema__Flow__Status.py +0 -0
  192. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/flows/schemas/Schema__Flow__Task__Data.py +0 -0
  193. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/flows/schemas/Schema__Task__Stats.py +0 -0
  194. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/flows/schemas/__init__.py +0 -0
  195. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/generators/Generator_Context_Manager.py +0 -0
  196. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/generators/Generator_Manager.py +0 -0
  197. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/generators/Model__Generator_State.py +0 -0
  198. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/generators/Model__Generator_Target.py +0 -0
  199. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/generators/__init__.py +0 -0
  200. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/html/CSS_Dict__To__Css.py +0 -0
  201. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/html/Html_Dict__To__Html.py +0 -0
  202. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/html/Html_Dict__To__Html_Document.py +0 -0
  203. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/html/Html_Dict__To__Html_Tags.py +0 -0
  204. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/html/Html__To__Html_Dict.py +0 -0
  205. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/html/Html__To__Html_Tag.py +0 -0
  206. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/html/Tag__Base.py +0 -0
  207. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/html/Tag__Body.py +0 -0
  208. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/html/Tag__Div.py +0 -0
  209. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/html/Tag__H.py +0 -0
  210. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/html/Tag__HR.py +0 -0
  211. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/html/Tag__Head.py +0 -0
  212. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/html/Tag__Html.py +0 -0
  213. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/html/Tag__Link.py +0 -0
  214. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/html/Tag__Style.py +0 -0
  215. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/html/Tag__Text.py +0 -0
  216. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/html/__init__.py +0 -0
  217. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/html/schemas/Schema__Html_Document.py +0 -0
  218. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/html/schemas/Schema__Html_Node__Data.py +0 -0
  219. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/html/schemas/Schema__Html_Node__Data__Type.py +0 -0
  220. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/html/schemas/__init__.py +0 -0
  221. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/llms/__init__.py +0 -0
  222. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/llms/actions/LLM_Request__Execute.py +0 -0
  223. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/llms/actions/Type_Safe__Schema_For__LLMs.py +0 -0
  224. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/llms/actions/__init__.py +0 -0
  225. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/llms/builders/LLM_Request__Builder.py +0 -0
  226. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/llms/builders/LLM_Request__Builder__Open_AI.py +0 -0
  227. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/llms/builders/LLM_Request__Factory.py +0 -0
  228. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/llms/builders/__init__.py +0 -0
  229. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/llms/cache/LLM_Cache__Path_Generator.py +0 -0
  230. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/llms/cache/LLM_Request__Cache.py +0 -0
  231. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/llms/cache/LLM_Request__Cache__File_System.py +0 -0
  232. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/llms/cache/LLM_Request__Cache__Storage.py +0 -0
  233. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/llms/cache/Virtual_Storage__Local__Folder.py +0 -0
  234. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/llms/cache/Virtual_Storage__Sqlite.py +0 -0
  235. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/llms/cache/__init__.py +0 -0
  236. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/llms/platforms/__init__.py +0 -0
  237. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/llms/platforms/open_ai/API__LLM__Open_AI.py +0 -0
  238. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/llms/platforms/open_ai/__init__.py +0 -0
  239. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/llms/schemas/Schema__LLM_Cache__Index.py +0 -0
  240. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/llms/schemas/Schema__LLM_Request.py +0 -0
  241. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/llms/schemas/Schema__LLM_Request__Data.py +0 -0
  242. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/llms/schemas/Schema__LLM_Request__Function_Call.py +0 -0
  243. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/llms/schemas/Schema__LLM_Request__Message__Content.py +0 -0
  244. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/llms/schemas/Schema__LLM_Request__Message__Role.py +0 -0
  245. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/llms/schemas/Schema__LLM_Response.py +0 -0
  246. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/llms/schemas/Schema__LLM_Response__Cache.py +0 -0
  247. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/llms/schemas/__init__.py +0 -0
  248. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/pubsub/Event__Queue.py +0 -0
  249. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/pubsub/PubSub__Client.py +0 -0
  250. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/pubsub/PubSub__Room.py +0 -0
  251. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/pubsub/PubSub__Server.py +0 -0
  252. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/pubsub/PubSub__Sqlite.py +0 -0
  253. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/pubsub/__init__.py +0 -0
  254. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/pubsub/schemas/Schema__Event.py +0 -0
  255. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/pubsub/schemas/Schema__Event__Connect.py +0 -0
  256. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/pubsub/schemas/Schema__Event__Disconnect.py +0 -0
  257. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/pubsub/schemas/Schema__Event__Execute_Method.py +0 -0
  258. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/pubsub/schemas/Schema__Event__Join_Room.py +0 -0
  259. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/pubsub/schemas/Schema__Event__Leave_Room.py +0 -0
  260. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/pubsub/schemas/Schema__Event__Message.py +0 -0
  261. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/pubsub/schemas/Schema__PubSub__Client.py +0 -0
  262. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/pubsub/schemas/__init__.py +0 -0
  263. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/python_compatibility/__init__.py +0 -0
  264. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/python_compatibility/python_3_8.py +0 -0
  265. {osbot_utils-2.59.0/osbot_utils/helpers/safe_str → osbot_utils-2.61.0/osbot_utils/helpers/safe_float}/__init__.py +0 -0
  266. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/safe_str/Safe_Str__File__Name.py +0 -0
  267. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/safe_str/Safe_Str__File__Path.py +0 -0
  268. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/safe_str/Safe_Str__Hash.py +0 -0
  269. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/safe_str/Safe_Str__Text.py +0 -0
  270. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/safe_str/Safe_Str__Text__Dangerous.py +0 -0
  271. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/safe_str/Safe_Str__Url.py +0 -0
  272. {osbot_utils-2.59.0/osbot_utils/helpers/sqlite → osbot_utils-2.61.0/osbot_utils/helpers/safe_str}/__init__.py +0 -0
  273. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/safe_str/http/Safe_Str__Html.py +0 -0
  274. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/safe_str/http/Safe_Str__Http__Content_Type.py +0 -0
  275. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/safe_str/http/Safe_Str__Http__ETag.py +0 -0
  276. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/safe_str/http/Safe_Str__Http__Last_Modified.py +0 -0
  277. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/safe_str/http/Safe_Str__Http__Text.py +0 -0
  278. {osbot_utils-2.59.0/osbot_utils/helpers/sqlite/cache → osbot_utils-2.61.0/osbot_utils/helpers/safe_str/http}/__init__.py +0 -0
  279. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/sqlite/Capture_Sqlite_Error.py +0 -0
  280. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/sqlite/Sqlite__Cursor.py +0 -0
  281. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/sqlite/Sqlite__Database.py +0 -0
  282. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/sqlite/Sqlite__Field.py +0 -0
  283. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/sqlite/Sqlite__Globals.py +0 -0
  284. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/sqlite/Sqlite__Table.py +0 -0
  285. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/sqlite/Sqlite__Table__Create.py +0 -0
  286. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/sqlite/Temp_Sqlite__Database__Disk.py +0 -0
  287. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/sqlite/Temp_Sqlite__Table.py +0 -0
  288. {osbot_utils-2.59.0/osbot_utils/helpers/sqlite/domains → osbot_utils-2.61.0/osbot_utils/helpers/sqlite}/__init__.py +0 -0
  289. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/sqlite/cache/Schema__Table__Requests.py +0 -0
  290. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/sqlite/cache/Sqlite__Cache__Requests.py +0 -0
  291. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/sqlite/cache/Sqlite__Cache__Requests__Patch.py +0 -0
  292. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/sqlite/cache/Sqlite__Cache__Requests__Sqlite.py +0 -0
  293. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/sqlite/cache/Sqlite__Cache__Requests__Table.py +0 -0
  294. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/sqlite/cache/Sqlite__DB__Requests.py +0 -0
  295. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/sqlite/cache/TestCase__Sqlite__Cache__Requests.py +0 -0
  296. {osbot_utils-2.59.0/osbot_utils/helpers/sqlite/domains/schemas → osbot_utils-2.61.0/osbot_utils/helpers/sqlite/cache}/__init__.py +0 -0
  297. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/sqlite/domains/Sqlite__DB.py +0 -0
  298. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/sqlite/domains/Sqlite__DB__Files.py +0 -0
  299. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/sqlite/domains/Sqlite__DB__Graph.py +0 -0
  300. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/sqlite/domains/Sqlite__DB__Json.py +0 -0
  301. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/sqlite/domains/Sqlite__DB__Local.py +0 -0
  302. {osbot_utils-2.59.0/osbot_utils/helpers/sqlite/models → osbot_utils-2.61.0/osbot_utils/helpers/sqlite/domains}/__init__.py +0 -0
  303. {osbot_utils-2.59.0/osbot_utils/helpers/sqlite/sample_data → osbot_utils-2.61.0/osbot_utils/helpers/sqlite/domains/schemas}/__init__.py +0 -0
  304. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/sqlite/models/Sqlite__Field__Type.py +0 -0
  305. {osbot_utils-2.59.0/osbot_utils/helpers/sqlite/sql_builder → osbot_utils-2.61.0/osbot_utils/helpers/sqlite/models}/__init__.py +0 -0
  306. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/sqlite/sample_data/Sqlite__Sample_Data__Chinook.py +0 -0
  307. {osbot_utils-2.59.0/osbot_utils/helpers/sqlite/tables → osbot_utils-2.61.0/osbot_utils/helpers/sqlite/sample_data}/__init__.py +0 -0
  308. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/sqlite/sql_builder/SQL_Builder.py +0 -0
  309. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/sqlite/sql_builder/SQL_Builder__Select.py +0 -0
  310. {osbot_utils-2.59.0/osbot_utils/helpers/ssh → osbot_utils-2.61.0/osbot_utils/helpers/sqlite/sql_builder}/__init__.py +0 -0
  311. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/sqlite/tables/Sqlite__Table__Config.py +0 -0
  312. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/sqlite/tables/Sqlite__Table__Edges.py +0 -0
  313. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/sqlite/tables/Sqlite__Table__Files.py +0 -0
  314. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/sqlite/tables/Sqlite__Table__Nodes.py +0 -0
  315. {osbot_utils-2.59.0/osbot_utils/helpers/trace → osbot_utils-2.61.0/osbot_utils/helpers/sqlite/tables}/__init__.py +0 -0
  316. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/ssh/SCP.py +0 -0
  317. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/ssh/SSH.py +0 -0
  318. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/ssh/SSH__Cache__Requests.py +0 -0
  319. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/ssh/SSH__Execute.py +0 -0
  320. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/ssh/SSH__Health_Check.py +0 -0
  321. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/ssh/SSH__Linux.py +0 -0
  322. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/ssh/SSH__Linux__Amazon.py +0 -0
  323. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/ssh/SSH__Python.py +0 -0
  324. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/ssh/TestCase__SSH.py +0 -0
  325. {osbot_utils-2.59.0/osbot_utils/helpers/xml → osbot_utils-2.61.0/osbot_utils/helpers/ssh}/__init__.py +0 -0
  326. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/trace/Trace_Call.py +0 -0
  327. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/trace/Trace_Call__Config.py +0 -0
  328. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/trace/Trace_Call__Handler.py +0 -0
  329. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/trace/Trace_Call__Print_Lines.py +0 -0
  330. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/trace/Trace_Call__Print_Traces.py +0 -0
  331. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/trace/Trace_Call__Stack.py +0 -0
  332. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/trace/Trace_Call__Stack_Node.py +0 -0
  333. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/trace/Trace_Call__Stats.py +0 -0
  334. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/trace/Trace_Call__View_Model.py +0 -0
  335. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/trace/Trace_Files.py +0 -0
  336. {osbot_utils-2.59.0/osbot_utils/testing → osbot_utils-2.61.0/osbot_utils/helpers/trace}/__init__.py +0 -0
  337. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/xml/Xml__Attribute.py +0 -0
  338. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/xml/Xml__Element.py +0 -0
  339. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/xml/Xml__File.py +0 -0
  340. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/xml/Xml__File__Load.py +0 -0
  341. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/xml/Xml__File__To_Dict.py +0 -0
  342. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/xml/Xml__File__To_Xml.py +0 -0
  343. {osbot_utils-2.59.0/osbot_utils/testing/performance → osbot_utils-2.61.0/osbot_utils/helpers/xml}/__init__.py +0 -0
  344. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/xml/rss/RSS__Channel.py +0 -0
  345. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/xml/rss/RSS__Enclosure.py +0 -0
  346. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/xml/rss/RSS__Feed.py +0 -0
  347. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/xml/rss/RSS__Feed__Parser.py +0 -0
  348. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/xml/rss/RSS__Image.py +0 -0
  349. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/helpers/xml/rss/RSS__Item.py +0 -0
  350. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/testing/Catch.py +0 -0
  351. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/testing/Custom_Handler_For_Http_Tests.py +0 -0
  352. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/testing/Hook_Method.py +0 -0
  353. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/testing/Log_To_Queue.py +0 -0
  354. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/testing/Log_To_String.py +0 -0
  355. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/testing/Logging.py +0 -0
  356. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/testing/Patch_Print.py +0 -0
  357. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/testing/Profiler.py +0 -0
  358. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/testing/Pytest.py +0 -0
  359. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/testing/Stderr.py +0 -0
  360. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/testing/Stdout.py +0 -0
  361. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/testing/Temp_Env_Vars.py +0 -0
  362. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/testing/Temp_File.py +0 -0
  363. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/testing/Temp_Folder.py +0 -0
  364. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/testing/Temp_Sys_Path.py +0 -0
  365. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/testing/Temp_Web_Server.py +0 -0
  366. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/testing/Temp_Zip.py +0 -0
  367. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/testing/Temp_Zip_In_Memory.py +0 -0
  368. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/testing/Unit_Test.py +0 -0
  369. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/testing/Unzip_File.py +0 -0
  370. {osbot_utils-2.59.0/osbot_utils/testing/performance/models → osbot_utils-2.61.0/osbot_utils/testing}/__init__.py +0 -0
  371. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/testing/performance/Performance_Measure__Session.py +0 -0
  372. {osbot_utils-2.59.0/osbot_utils/type_safe → osbot_utils-2.61.0/osbot_utils/testing/performance}/__init__.py +0 -0
  373. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/testing/performance/models/Model__Performance_Measure__Measurement.py +0 -0
  374. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/testing/performance/models/Model__Performance_Measure__Result.py +0 -0
  375. {osbot_utils-2.59.0/osbot_utils/type_safe/decorators → osbot_utils-2.61.0/osbot_utils/testing/performance/models}/__init__.py +0 -0
  376. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/type_safe/Type_Safe.py +0 -0
  377. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/type_safe/Type_Safe__Base.py +0 -0
  378. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/type_safe/Type_Safe__Dict.py +0 -0
  379. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/type_safe/Type_Safe__List.py +0 -0
  380. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/type_safe/Type_Safe__Method.py +0 -0
  381. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/type_safe/Type_Safe__Set.py +0 -0
  382. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/type_safe/Type_Safe__Tuple.py +0 -0
  383. {osbot_utils-2.59.0/osbot_utils/type_safe/methods → osbot_utils-2.61.0/osbot_utils/type_safe}/__init__.py +0 -0
  384. {osbot_utils-2.59.0/osbot_utils/type_safe/shared → osbot_utils-2.61.0/osbot_utils/type_safe/decorators}/__init__.py +0 -0
  385. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/type_safe/decorators/type_safe.py +0 -0
  386. {osbot_utils-2.59.0/osbot_utils/type_safe/steps → osbot_utils-2.61.0/osbot_utils/type_safe/methods}/__init__.py +0 -0
  387. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/type_safe/methods/type_safe_property.py +0 -0
  388. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/type_safe/shared/Type_Safe__Annotations.py +0 -0
  389. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/type_safe/shared/Type_Safe__Cache.py +0 -0
  390. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/type_safe/shared/Type_Safe__Convert.py +0 -0
  391. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/type_safe/shared/Type_Safe__Json_Compressor.py +0 -0
  392. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/type_safe/shared/Type_Safe__Json_Compressor__Type_Registry.py +0 -0
  393. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/type_safe/shared/Type_Safe__Not_Cached.py +0 -0
  394. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/type_safe/shared/Type_Safe__Raise_Exception.py +0 -0
  395. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/type_safe/shared/Type_Safe__Shared__Variables.py +0 -0
  396. {osbot_utils-2.59.0/osbot_utils/type_safe/validators → osbot_utils-2.61.0/osbot_utils/type_safe/shared}/__init__.py +0 -0
  397. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/type_safe/steps/Type_Safe__Step__Class_Kwargs.py +0 -0
  398. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/type_safe/steps/Type_Safe__Step__Default_Kwargs.py +0 -0
  399. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/type_safe/steps/Type_Safe__Step__Default_Value.py +0 -0
  400. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/type_safe/steps/Type_Safe__Step__From_Json.py +0 -0
  401. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/type_safe/steps/Type_Safe__Step__Init.py +0 -0
  402. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/type_safe/steps/Type_Safe__Step__Set_Attr.py +0 -0
  403. {osbot_utils-2.59.0/osbot_utils/utils → osbot_utils-2.61.0/osbot_utils/type_safe/steps}/__init__.py +0 -0
  404. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/type_safe/validators/Type_Safe__Validator.py +0 -0
  405. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/type_safe/validators/Validator__Max.py +0 -0
  406. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/type_safe/validators/Validator__Min.py +0 -0
  407. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/type_safe/validators/Validator__One_Of.py +0 -0
  408. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/type_safe/validators/Validator__Regex.py +0 -0
  409. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/utils/Assert.py +0 -0
  410. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/utils/Call_Stack.py +0 -0
  411. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/utils/Csv.py +0 -0
  412. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/utils/Dev.py +0 -0
  413. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/utils/Env.py +0 -0
  414. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/utils/Exceptions.py +0 -0
  415. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/utils/Files.py +0 -0
  416. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/utils/Functions.py +0 -0
  417. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/utils/Http.py +0 -0
  418. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/utils/Int.py +0 -0
  419. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/utils/Json.py +0 -0
  420. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/utils/Json_Cache.py +0 -0
  421. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/utils/Lists.py +0 -0
  422. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/utils/Misc.py +0 -0
  423. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/utils/Objects.py +0 -0
  424. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/utils/Png.py +0 -0
  425. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/utils/Process.py +0 -0
  426. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/utils/Python_Logger.py +0 -0
  427. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/utils/Regex.py +0 -0
  428. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/utils/Status.py +0 -0
  429. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/utils/Str.py +0 -0
  430. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/utils/Threads.py +0 -0
  431. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/utils/Toml.py +0 -0
  432. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/utils/Version.py +0 -0
  433. {osbot_utils-2.59.0 → osbot_utils-2.61.0}/osbot_utils/utils/Zip.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: osbot_utils
3
- Version: 2.59.0
3
+ Version: 2.61.0
4
4
  Summary: OWASP Security Bot - Utils
5
5
  License: MIT
6
6
  Author: Dinis Cruz
@@ -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.59.0-blue)
26
+ ![Current Release](https://img.shields.io/badge/release-v2.61.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.59.0-blue)
5
+ ![Current Release](https://img.shields.io/badge/release-v2.61.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
 
@@ -3,13 +3,12 @@ from osbot_utils.helpers.html.Html__To__Html_Dict import Html__To__Htm
3
3
  from osbot_utils.helpers.html.schemas.Schema__Html_Document import Schema__Html_Document
4
4
  from osbot_utils.type_safe.Type_Safe import Type_Safe
5
5
 
6
-
7
6
  class Html__To__Html_Document(Type_Safe):
8
7
  html: str
9
8
  html__dict : dict
10
9
  html__document: Schema__Html_Document
11
10
 
12
- def convert(self):
11
+ def convert(self) -> Schema__Html_Document:
13
12
  if self.html:
14
13
  html__dict = Html__To__Html_Dict(self.html).convert()
15
14
  if html__dict:
@@ -4,7 +4,7 @@ from osbot_utils.type_safe.Type_Safe import Type_Safe
4
4
 
5
5
 
6
6
  class Schema__Html_Node(Type_Safe):
7
- attrs : Dict[str, Optional[str]] # HTML attributes (e.g., {'class': 'container'})
7
+ attrs : Dict[str, Optional[str]] # HTML attributes (e.g., {'class': 'container'}) # todo: see what Safe_Ster we can use for these name attrs
8
8
  nodes : List[Union['Schema__Html_Node', Schema__Html_Node__Data]] # Child nodes (recursive structure)
9
- tag : str # HTML tag name (e.g., 'div', 'meta', 'title')
9
+ tag : str # HTML tag name (e.g., 'div', 'meta', 'title') # todo: see what Safe_Ster we can use for the tag
10
10
 
@@ -0,0 +1,155 @@
1
+ import math
2
+ from decimal import Decimal, ROUND_HALF_UP, InvalidOperation
3
+ from typing import Optional, Union
4
+
5
+ class Safe_Float(float): # Base class for type-safe floats with validation rules
6
+
7
+ min_value : Optional[float] = None
8
+ max_value : Optional[float] = None
9
+ allow_none : bool = True
10
+ allow_bool : bool = False
11
+ allow_str : bool = True
12
+ allow_int : bool = True
13
+ strict_type : bool = False
14
+ decimal_places : Optional[int] = None
15
+
16
+ # Precision handling options
17
+ use_decimal : bool = False
18
+ epsilon : float = 1e-9
19
+ round_output : bool = True
20
+ clamp_to_range : bool = False
21
+
22
+ def __new__(cls, value: Optional[Union[float, int, str]] = None) -> 'Safe_Float':
23
+ if value is None:
24
+ if cls.allow_none:
25
+ return super().__new__(cls, 0.0)
26
+ else:
27
+ raise ValueError(f"{cls.__name__} does not allow None values")
28
+
29
+ # Store original value for range checking
30
+ original_value = value
31
+
32
+ # Convert to float
33
+ if isinstance(value, str):
34
+ if not cls.allow_str:
35
+ raise TypeError(f"{cls.__name__} does not allow string conversion")
36
+ try:
37
+ if cls.use_decimal:
38
+ value = Decimal(value)
39
+ else:
40
+ value = float(value)
41
+ except (ValueError, InvalidOperation):
42
+ raise ValueError(f"Cannot convert '{value}' to float")
43
+ elif isinstance(value, bool):
44
+ if not cls.allow_bool:
45
+ raise TypeError(f"{cls.__name__} does not allow boolean values")
46
+ value = float(value)
47
+ elif isinstance(value, int):
48
+ if not cls.allow_int:
49
+ raise TypeError(f"{cls.__name__} does not allow integer conversion")
50
+ if cls.use_decimal:
51
+ value = Decimal(value)
52
+ else:
53
+ value = float(value)
54
+ elif isinstance(value, float):
55
+ if math.isinf(value):
56
+ raise ValueError(f"{cls.__name__} does not allow infinite values")
57
+ if math.isnan(value):
58
+ raise ValueError(f"{cls.__name__} does not allow NaN values")
59
+
60
+ if cls.use_decimal:
61
+ value = Decimal(str(value))
62
+ elif not isinstance(value, (float, Decimal)):
63
+ raise TypeError(f"{cls.__name__} requires a float value, got {type(value).__name__}")
64
+
65
+ # Get numeric value for range checking (before rounding)
66
+ check_value = float(value) if isinstance(value, Decimal) else value
67
+
68
+ # Range validation BEFORE rounding (unless clamping)
69
+ if not cls.clamp_to_range:
70
+ if cls.min_value is not None and check_value < cls.min_value:
71
+ raise ValueError(f"{cls.__name__} must be >= {cls.min_value}, got {check_value}")
72
+ if cls.max_value is not None and check_value > cls.max_value:
73
+ raise ValueError(f"{cls.__name__} must be <= {cls.max_value}, got {check_value}")
74
+
75
+ # NOW do rounding
76
+ if isinstance(value, Decimal) and cls.decimal_places is not None:
77
+ value = value.quantize(Decimal(f'0.{"0" * cls.decimal_places}'), rounding=ROUND_HALF_UP)
78
+
79
+ if isinstance(value, Decimal):
80
+ value = float(value)
81
+
82
+ # Check again for special values
83
+ if math.isinf(value):
84
+ raise ValueError(f"{cls.__name__} does not allow infinite values")
85
+ if math.isnan(value):
86
+ raise ValueError(f"{cls.__name__} does not allow NaN values")
87
+
88
+ # Clean up floating point errors (only if not already handled by Decimal)
89
+ if cls.round_output and cls.decimal_places is not None and not cls.use_decimal:
90
+ value = cls.__clean_float(value, cls.decimal_places)
91
+
92
+ # Handle clamping AFTER rounding
93
+ if cls.clamp_to_range:
94
+ if cls.min_value is not None and value < cls.min_value:
95
+ value = cls.min_value
96
+ if cls.max_value is not None and value > cls.max_value:
97
+ value = cls.max_value
98
+
99
+ return super().__new__(cls, value)
100
+
101
+ def __truediv__(self, other):
102
+ # Simple and safe - no special handling for infinity
103
+ if float(other) == 0:
104
+ raise ZeroDivisionError(f"{self.__class__.__name__} division by zero")
105
+
106
+ if self.use_decimal:
107
+ result = float(Decimal(str(float(self))) / Decimal(str(float(other))))
108
+ else:
109
+ result = float(self) / float(other)
110
+
111
+ # Check for overflow/underflow
112
+ if math.isinf(result) or math.isnan(result):
113
+ raise OverflowError(f"Division resulted in {result}")
114
+
115
+ if self.round_output and self.decimal_places is not None:
116
+ result = self.__clean_float(result, self.decimal_places)
117
+
118
+ try:
119
+ return self.__class__(result)
120
+ except (ValueError, TypeError):
121
+ return result
122
+
123
+ @classmethod
124
+ def __clean_float(cls, value: float, decimal_places: int) -> float: # Clean up floating point representation errors
125
+ rounded = round(value, decimal_places + 2) # First, round to eliminate tiny errors
126
+
127
+ # Check if very close to a clean decimal
128
+ str_val = f"{rounded:.{decimal_places + 2}f}"
129
+ if str_val.endswith('999999') or str_val.endswith('000001'):
130
+ # Use Decimal for exact rounding
131
+ d = Decimal(str(value))
132
+ return float(d.quantize(Decimal(f'0.{"0" * decimal_places}'), rounding=ROUND_HALF_UP))
133
+
134
+ return round(value, decimal_places) if decimal_places else value
135
+
136
+ def __mul__(self, other):
137
+ if self.use_decimal:
138
+ result = float(Decimal(str(float(self))) * Decimal(str(float(other))))
139
+ else:
140
+ result = float(self) * float(other)
141
+
142
+ if self.round_output and self.decimal_places is not None:
143
+ if not (math.isinf(result) or math.isnan(result)):
144
+ result = self.__clean_float(result, self.decimal_places)
145
+
146
+ try:
147
+ return self.__class__(result)
148
+ except (ValueError, TypeError):
149
+ return result
150
+
151
+ def __eq__(self, other):
152
+ """Equality with epsilon tolerance"""
153
+ if isinstance(other, (int, float)):
154
+ return abs(float(self) - float(other)) < self.epsilon
155
+ return super().__eq__(other)
@@ -0,0 +1,7 @@
1
+ from osbot_utils.helpers.safe_float.Safe_Float import Safe_Float
2
+
3
+ class Safe_Float__Engineering(Safe_Float): # Engineering calculations with controlled precision
4
+ #decimal_places = 6
5
+ epsilon = 1e-6
6
+ round_output = True
7
+ use_decimal = False # Performance over exactness
@@ -0,0 +1,11 @@
1
+ # Safe_Float__Money.py
2
+ from osbot_utils.helpers.safe_float.Safe_Float import Safe_Float
3
+
4
+
5
+ class Safe_Float__Money(Safe_Float): # Money calculations with exact decimal arithmetic
6
+ decimal_places = 2
7
+ use_decimal = True # Use Decimal internally
8
+ allow_inf = False
9
+ allow_nan = False
10
+ min_value = 0.0
11
+ round_output = True
@@ -0,0 +1,9 @@
1
+ from osbot_utils.helpers.safe_float.Safe_Float import Safe_Float
2
+
3
+
4
+ class Safe_Float__Percentage_Exact(Safe_Float): # Exact percentage calculations
5
+ min_value = 0.0
6
+ max_value = 100.0
7
+ decimal_places = 2
8
+ use_decimal = True
9
+ round_output = True
@@ -0,0 +1,77 @@
1
+ from typing import Optional, Union
2
+
3
+ from osbot_utils.helpers.safe_float.Safe_Float import Safe_Float
4
+
5
+
6
+ class Safe_Int(int): # Base class for type-safe integers with validation rules
7
+
8
+ min_value : Optional[int] = None # Minimum allowed value (inclusive)
9
+ max_value : Optional[int] = None # Maximum allowed value (inclusive)
10
+ allow_none : bool = True # Whether None is allowed as input
11
+ allow_bool : bool = False # Whether bool is allowed as input
12
+ allow_str : bool = True # Whether string conversion is allowed
13
+ strict_type : bool = False # If True, only accept int type (no conversions)
14
+
15
+ def __new__(cls, value: Optional[Union[int, str]] = None) -> 'Safe_Int':
16
+ # Handle None input
17
+ if value is None:
18
+ if cls.allow_none:
19
+ return super().__new__(cls, 0) # Default to 0 for None
20
+ else:
21
+ raise ValueError(f"{cls.__name__} does not allow None values")
22
+
23
+ # Strict type checking
24
+ if cls.strict_type and not isinstance(value, int):
25
+ raise TypeError(f"{cls.__name__} requires int type, got {type(value).__name__}")
26
+
27
+ # Type conversion
28
+ if isinstance(value, str):
29
+ if not cls.allow_str:
30
+ raise TypeError(f"{cls.__name__} does not allow string conversion")
31
+ try:
32
+ value = int(value)
33
+ except ValueError:
34
+ raise ValueError(f"Cannot convert '{value}' to integer")
35
+
36
+ elif isinstance(value, bool):
37
+ if not cls.allow_bool:
38
+ raise TypeError(f"{cls.__name__} does not allow boolean values")
39
+ value = int(value)
40
+
41
+ elif not isinstance(value, int):
42
+ raise TypeError(f"{cls.__name__} requires an integer value, got {type(value).__name__}")
43
+
44
+ # Range validation
45
+ if cls.min_value is not None and value < cls.min_value:
46
+ raise ValueError(f"{cls.__name__} must be >= {cls.min_value}, got {value}")
47
+
48
+ if cls.max_value is not None and value > cls.max_value:
49
+ raise ValueError(f"{cls.__name__} must be <= {cls.max_value}, got {value}")
50
+
51
+ return super().__new__(cls, value)
52
+
53
+ # Arithmetic operations that maintain type safety
54
+ def __add__(self, other):
55
+ result = super().__add__(other)
56
+ try:
57
+ return self.__class__(result)
58
+ except (ValueError, TypeError):
59
+ return result # Return plain int if validation fails
60
+
61
+ def __sub__(self, other):
62
+ result = super().__sub__(other)
63
+ try:
64
+ return self.__class__(result)
65
+ except (ValueError, TypeError):
66
+ return result
67
+
68
+ def __mul__(self, other):
69
+ result = super().__mul__(other)
70
+ try:
71
+ return self.__class__(result)
72
+ except (ValueError, TypeError):
73
+ return result
74
+
75
+ def __truediv__(self, other):
76
+ result = super().__truediv__(other)
77
+ return Safe_Float(result)
@@ -0,0 +1,7 @@
1
+ from osbot_utils.helpers.safe_int.Safe_Int import Safe_Int
2
+
3
+ class Safe_UInt(Safe_Int): # Unsigned Integer - only accepts non-negative integer values
4
+
5
+ min_value = 0 # Unsigned means >= 0
6
+ max_value = None # No upper limit by default
7
+ allow_bool = False # Don't allow True/False as 1/0
@@ -0,0 +1,10 @@
1
+ from osbot_utils.helpers.safe_int.Safe_UInt import Safe_UInt
2
+
3
+ TYPE_SAFE_UINT__BYTE__MIN_VALUE = 0
4
+ TYPE_SAFE_UINT__BYTE__MAX_VALUE = 255
5
+
6
+ class Safe_UInt__Byte(Safe_UInt): # Single byte value (0-255)
7
+
8
+ min_value = TYPE_SAFE_UINT__BYTE__MIN_VALUE
9
+ max_value = TYPE_SAFE_UINT__BYTE__MAX_VALUE
10
+ allow_bool = False
@@ -0,0 +1,19 @@
1
+ from osbot_utils.helpers.safe_int.Safe_UInt import Safe_UInt
2
+
3
+ TYPE_SAFE_UINT__FILE_SIZE__MIN_VALUE = 0
4
+ TYPE_SAFE_UINT__FILE_SIZE__MAX_VALUE = 2 ** 63 - 1 # Max file size on most systems
5
+
6
+ class Safe_UInt__FileSize(Safe_UInt): # File size in bytes
7
+
8
+ min_value = TYPE_SAFE_UINT__FILE_SIZE__MIN_VALUE
9
+ max_value = TYPE_SAFE_UINT__FILE_SIZE__MAX_VALUE
10
+ allow_bool = False
11
+
12
+ def to_kb(self) -> float:
13
+ return self / 1024
14
+
15
+ def to_mb(self) -> float:
16
+ return self / (1024 * 1024)
17
+
18
+ def to_gb(self) -> float:
19
+ return self / (1024 * 1024 * 1024)
@@ -0,0 +1,10 @@
1
+ from osbot_utils.helpers.safe_int.Safe_UInt import Safe_UInt
2
+
3
+ TYPE_SAFE_UINT__PERCENTAGE__MIN_VALUE = 0
4
+ TYPE_SAFE_UINT__PERCENTAGE__MAX_VALUE = 100
5
+
6
+ class Safe_UInt__Percentage(Safe_UInt): # Percentage value (0-100)
7
+
8
+ min_value = TYPE_SAFE_UINT__PERCENTAGE__MIN_VALUE
9
+ max_value = TYPE_SAFE_UINT__PERCENTAGE__MAX_VALUE
10
+ allow_bool = False
@@ -0,0 +1,11 @@
1
+ from osbot_utils.helpers.safe_int.Safe_UInt import Safe_UInt
2
+
3
+ TYPE_SAFE_UINT__PORT__MIN_VALUE = 0
4
+ TYPE_SAFE_UINT__PORT__MAX_VALUE = 65535
5
+
6
+ class Safe_UInt__Port(Safe_UInt): # Network port number (0-65535)
7
+
8
+ min_value = TYPE_SAFE_UINT__PORT__MIN_VALUE
9
+ max_value = TYPE_SAFE_UINT__PORT__MAX_VALUE
10
+ allow_bool = False
11
+ allow_none = False # don't allow 0 as port value since that is a really weird value for a port
@@ -0,0 +1,10 @@
1
+ from osbot_utils.helpers.safe_int.Safe_Int import Safe_Int
2
+
3
+ TYPE_SAFE_INT__BYTE__MIN_VALUE = 0
4
+ TYPE_SAFE_INT__BYTE__MAX_VALUE = 255
5
+
6
+ class Safe_Int__Byte(Safe_Int): # Single byte value (0-255)
7
+
8
+ min_value = TYPE_SAFE_INT__BYTE__MIN_VALUE
9
+ max_value = TYPE_SAFE_INT__BYTE__MAX_VALUE
10
+ allow_bool = False
@@ -21,7 +21,7 @@ class Safe_Str(str):
21
21
  if cls.allow_empty:
22
22
  value = ""
23
23
  else:
24
- raise ValueError("Value cannot be None when allow_empty is False")
24
+ raise ValueError(f"in {cls.__name__}, value cannot be None when allow_empty is False") from None
25
25
 
26
26
  if not isinstance(value, str): # Convert to string if not already
27
27
  value = str(value)
@@ -285,7 +285,7 @@ class Type_Safe__Validation:
285
285
  if self.obj_is_type_union_compatible(var_type, IMMUTABLE_TYPES) is False: # if var_type is not something like Optional[Union[int, str]]
286
286
  if var_type not in IMMUTABLE_TYPES or type(var_type) not in IMMUTABLE_TYPES:
287
287
  if not isinstance(var_type, EnumMeta):
288
- if not issubclass(var_type, str):
288
+ if not issubclass(var_type, (int,str, float)):
289
289
  type_safe_raise_exception.immutable_type_error(var_name, var_type)
290
290
 
291
291
  def validate_variable_type(self, var_name, var_type, var_value): # Validate type compatibility
File without changes
@@ -0,0 +1 @@
1
+ v2.61.0
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "osbot_utils"
3
- version = "v2.59.0"
3
+ version = "v2.61.0"
4
4
  description = "OWASP Security Bot - Utils"
5
5
  authors = ["Dinis Cruz <dinis.cruz@owasp.org>"]
6
6
  license = "MIT"
@@ -1 +0,0 @@
1
- v2.59.0
File without changes