osbot-utils 1.90.0__tar.gz → 1.92.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 (347) hide show
  1. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/PKG-INFO +2 -2
  2. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/README.md +1 -1
  3. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/base_classes/Type_Safe.py +38 -7
  4. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/graphs/mermaid/Mermaid.py +7 -7
  5. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/graphs/mgraph/MGraph__Edge.py +1 -4
  6. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/graphs/mgraph/MGraph__Node.py +2 -3
  7. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/graphs/mgraph/MGraph__Serializer.py +4 -5
  8. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/graphs/mgraph/MGraphs.py +0 -5
  9. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/Zip_Bytes.py +2 -2
  10. osbot_utils-1.92.0/osbot_utils/helpers/python_compatibility/python_3_8.py +8 -0
  11. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/trace/Trace_Call__Handler.py +21 -21
  12. osbot_utils-1.92.0/osbot_utils/helpers/type_safe/Type_Safe__Validator.py +14 -0
  13. osbot_utils-1.92.0/osbot_utils/helpers/type_safe/validators/Validator__Max.py +28 -0
  14. osbot_utils-1.92.0/osbot_utils/helpers/type_safe/validators/Validator__Min.py +38 -0
  15. osbot_utils-1.92.0/osbot_utils/helpers/type_safe/validators/Validator__One_Of.py +18 -0
  16. osbot_utils-1.92.0/osbot_utils/helpers/type_safe/validators/Validator__Regex.py +26 -0
  17. osbot_utils-1.92.0/osbot_utils/helpers/xml/__init__.py +0 -0
  18. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/xml/rss/RSS__Feed__Parser.py +11 -1
  19. osbot_utils-1.92.0/osbot_utils/testing/__init__.py +0 -0
  20. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/utils/Objects.py +46 -10
  21. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/utils/Regex.py +1 -1
  22. osbot_utils-1.92.0/osbot_utils/utils/__init__.py +0 -0
  23. osbot_utils-1.92.0/osbot_utils/version +1 -0
  24. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/pyproject.toml +1 -1
  25. osbot_utils-1.90.0/osbot_utils/version +0 -1
  26. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/LICENSE +0 -0
  27. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/__init__.py +0 -0
  28. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/base_classes/Cache_Pickle.py +0 -0
  29. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/base_classes/Kwargs_To_Disk.py +0 -0
  30. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/base_classes/Kwargs_To_Self.py +0 -0
  31. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/base_classes/Type_Safe__Base.py +0 -0
  32. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/base_classes/Type_Safe__Dict.py +0 -0
  33. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/base_classes/Type_Safe__List.py +0 -0
  34. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/base_classes/__init__.py +0 -0
  35. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/context_managers/__init__.py +0 -0
  36. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/context_managers/async_invoke.py +0 -0
  37. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/context_managers/capture_duration.py +0 -0
  38. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/context_managers/disable_root_loggers.py +0 -0
  39. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/context_managers/print_duration.py +0 -0
  40. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/decorators/__init__.py +0 -0
  41. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/decorators/classes/__init__.py +0 -0
  42. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/decorators/classes/singleton.py +0 -0
  43. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/decorators/lists/__init__.py +0 -0
  44. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/decorators/lists/filter_list.py +0 -0
  45. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/decorators/lists/group_by.py +0 -0
  46. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/decorators/lists/index_by.py +0 -0
  47. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/decorators/methods/__init__.py +0 -0
  48. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/decorators/methods/cache.py +0 -0
  49. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/decorators/methods/cache_on_function.py +0 -0
  50. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/decorators/methods/cache_on_self.py +0 -0
  51. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/decorators/methods/cache_on_tmp.py +0 -0
  52. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/decorators/methods/capture_exception.py +0 -0
  53. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/decorators/methods/capture_status.py +0 -0
  54. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/decorators/methods/catch.py +0 -0
  55. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/decorators/methods/context.py +0 -0
  56. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/decorators/methods/depreciated.py +0 -0
  57. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/decorators/methods/function_type_check.py +0 -0
  58. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/decorators/methods/obj_as_context.py +0 -0
  59. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/decorators/methods/remove_return_value.py +0 -0
  60. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/decorators/methods/required_fields.py +0 -0
  61. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/decorators/methods/type_safe.py +0 -0
  62. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/fluent/Fluent_Dict.py +0 -0
  63. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/fluent/Fluent_List.py +0 -0
  64. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/fluent/__init__.py +0 -0
  65. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/graphs/__init__.py +0 -0
  66. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/graphs/mermaid/Mermaid__Edge.py +0 -0
  67. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/graphs/mermaid/Mermaid__Graph.py +0 -0
  68. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/graphs/mermaid/Mermaid__Node.py +0 -0
  69. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/graphs/mermaid/Mermaid__Renderer.py +0 -0
  70. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/graphs/mermaid/configs/Mermaid__Edge__Config.py +0 -0
  71. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/graphs/mermaid/configs/Mermaid__Node__Config.py +0 -0
  72. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/graphs/mermaid/configs/Mermaid__Render__Config.py +0 -0
  73. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/graphs/mermaid/examples/Mermaid_Examples__FlowChart.py +0 -0
  74. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/graphs/mermaid/models/Mermaid__Diagram_Direction.py +0 -0
  75. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/graphs/mermaid/models/Mermaid__Diagram__Type.py +0 -0
  76. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/graphs/mermaid/models/Mermaid__Node__Shape.py +0 -0
  77. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/graphs/mgraph/MGraph.py +0 -0
  78. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/graphs/mgraph/MGraph__Config.py +0 -0
  79. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/graphs/mgraph/MGraph__Data.py +0 -0
  80. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/graphs/mgraph/MGraph__Random_Graphs.py +0 -0
  81. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/graphs/mgraph/__init__.py +0 -0
  82. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/CFormat.py +0 -0
  83. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/CPrint.py +0 -0
  84. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/Dependency_Manager.py +0 -0
  85. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/Dict_To_Attr.py +0 -0
  86. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/Guid.py +0 -0
  87. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/Hashicorp_Secrets.py +0 -0
  88. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/Local_Cache.py +0 -0
  89. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/Local_Caches.py +0 -0
  90. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/Print_Table.py +0 -0
  91. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/Python_Audit.py +0 -0
  92. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/Random_Guid.py +0 -0
  93. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/Random_Guid_Short.py +0 -0
  94. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/Random_Seed.py +0 -0
  95. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/Safe_Id.py +0 -0
  96. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/Str_ASCII.py +0 -0
  97. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/Timestamp_Now.py +0 -0
  98. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/Type_Registry.py +0 -0
  99. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/Type_Safe_Method.py +0 -0
  100. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/__init__.py +0 -0
  101. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/ast/Ast.py +0 -0
  102. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/ast/Ast_Base.py +0 -0
  103. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/ast/Ast_Data.py +0 -0
  104. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/ast/Ast_Load.py +0 -0
  105. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/ast/Ast_Merge.py +0 -0
  106. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/ast/Ast_Node.py +0 -0
  107. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/ast/Ast_Visit.py +0 -0
  108. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/ast/Call_Tree.py +0 -0
  109. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/ast/__init__.py +0 -0
  110. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/ast/nodes/Ast_Add.py +0 -0
  111. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/ast/nodes/Ast_Alias.py +0 -0
  112. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/ast/nodes/Ast_And.py +0 -0
  113. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/ast/nodes/Ast_Argument.py +0 -0
  114. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/ast/nodes/Ast_Arguments.py +0 -0
  115. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/ast/nodes/Ast_Assert.py +0 -0
  116. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/ast/nodes/Ast_Assign.py +0 -0
  117. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/ast/nodes/Ast_Attribute.py +0 -0
  118. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/ast/nodes/Ast_Aug_Assign.py +0 -0
  119. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/ast/nodes/Ast_Bin_Op.py +0 -0
  120. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/ast/nodes/Ast_Bool_Op.py +0 -0
  121. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/ast/nodes/Ast_Break.py +0 -0
  122. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/ast/nodes/Ast_Call.py +0 -0
  123. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/ast/nodes/Ast_Class_Def.py +0 -0
  124. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/ast/nodes/Ast_Compare.py +0 -0
  125. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/ast/nodes/Ast_Comprehension.py +0 -0
  126. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/ast/nodes/Ast_Constant.py +0 -0
  127. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/ast/nodes/Ast_Continue.py +0 -0
  128. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/ast/nodes/Ast_Dict.py +0 -0
  129. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/ast/nodes/Ast_Eq.py +0 -0
  130. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/ast/nodes/Ast_Except_Handler.py +0 -0
  131. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/ast/nodes/Ast_Expr.py +0 -0
  132. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/ast/nodes/Ast_For.py +0 -0
  133. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/ast/nodes/Ast_Function_Def.py +0 -0
  134. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/ast/nodes/Ast_Generator_Exp.py +0 -0
  135. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/ast/nodes/Ast_Gt.py +0 -0
  136. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/ast/nodes/Ast_GtE.py +0 -0
  137. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/ast/nodes/Ast_If.py +0 -0
  138. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/ast/nodes/Ast_If_Exp.py +0 -0
  139. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/ast/nodes/Ast_Import.py +0 -0
  140. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/ast/nodes/Ast_Import_From.py +0 -0
  141. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/ast/nodes/Ast_In.py +0 -0
  142. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/ast/nodes/Ast_Is.py +0 -0
  143. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/ast/nodes/Ast_Is_Not.py +0 -0
  144. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/ast/nodes/Ast_Keyword.py +0 -0
  145. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/ast/nodes/Ast_Lambda.py +0 -0
  146. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/ast/nodes/Ast_List.py +0 -0
  147. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/ast/nodes/Ast_List_Comp.py +0 -0
  148. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/ast/nodes/Ast_Load.py +0 -0
  149. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/ast/nodes/Ast_Lt.py +0 -0
  150. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/ast/nodes/Ast_LtE.py +0 -0
  151. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/ast/nodes/Ast_Mod.py +0 -0
  152. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/ast/nodes/Ast_Module.py +0 -0
  153. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/ast/nodes/Ast_Mult.py +0 -0
  154. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/ast/nodes/Ast_Name.py +0 -0
  155. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/ast/nodes/Ast_Not.py +0 -0
  156. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/ast/nodes/Ast_Not_Eq.py +0 -0
  157. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/ast/nodes/Ast_Not_In.py +0 -0
  158. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/ast/nodes/Ast_Or.py +0 -0
  159. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/ast/nodes/Ast_Pass.py +0 -0
  160. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/ast/nodes/Ast_Pow.py +0 -0
  161. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/ast/nodes/Ast_Raise.py +0 -0
  162. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/ast/nodes/Ast_Return.py +0 -0
  163. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/ast/nodes/Ast_Set.py +0 -0
  164. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/ast/nodes/Ast_Slice.py +0 -0
  165. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/ast/nodes/Ast_Starred.py +0 -0
  166. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/ast/nodes/Ast_Store.py +0 -0
  167. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/ast/nodes/Ast_Sub.py +0 -0
  168. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/ast/nodes/Ast_Subscript.py +0 -0
  169. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/ast/nodes/Ast_Try.py +0 -0
  170. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/ast/nodes/Ast_Tuple.py +0 -0
  171. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/ast/nodes/Ast_Unary_Op.py +0 -0
  172. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/ast/nodes/Ast_While.py +0 -0
  173. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/ast/nodes/Ast_With.py +0 -0
  174. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/ast/nodes/Ast_With_Item.py +0 -0
  175. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/ast/nodes/Ast_Yield.py +0 -0
  176. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/ast/nodes/__init__.py +0 -0
  177. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/cache_requests/Cache__Requests__Actions.py +0 -0
  178. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/cache_requests/Cache__Requests__Config.py +0 -0
  179. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/cache_requests/Cache__Requests__Data.py +0 -0
  180. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/cache_requests/Cache__Requests__Invoke.py +0 -0
  181. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/cache_requests/Cache__Requests__Row.py +0 -0
  182. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/cache_requests/Cache__Requests__Table.py +0 -0
  183. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/cache_requests/__init__.py +0 -0
  184. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/cache_requests/flows/flow__Cache__Requests.py +0 -0
  185. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/flows/Flow.py +0 -0
  186. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/flows/Flow__Events.py +0 -0
  187. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/flows/Task.py +0 -0
  188. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/flows/__init__.py +0 -0
  189. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/flows/decorators/__init__.py +0 -0
  190. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/flows/decorators/flow.py +0 -0
  191. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/flows/decorators/task.py +0 -0
  192. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/flows/models/Flow_Run__Config.py +0 -0
  193. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/flows/models/Flow_Run__Event.py +0 -0
  194. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/flows/models/Flow_Run__Event_Data.py +0 -0
  195. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/flows/models/Flow_Run__Event_Type.py +0 -0
  196. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/flows/models/__init__.py +0 -0
  197. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/generators/Generator_Context_Manager.py +0 -0
  198. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/generators/Generator_Manager.py +0 -0
  199. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/generators/Model__Generator_State.py +0 -0
  200. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/generators/Model__Generator_Target.py +0 -0
  201. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/generators/__init__.py +0 -0
  202. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/html/Dict_To_Css.py +0 -0
  203. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/html/Dict_To_Html.py +0 -0
  204. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/html/Dict_To_Tags.py +0 -0
  205. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/html/Html_To_Dict.py +0 -0
  206. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/html/Html_To_Tag.py +0 -0
  207. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/html/Tag__Base.py +0 -0
  208. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/html/Tag__Body.py +0 -0
  209. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/html/Tag__Div.py +0 -0
  210. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/html/Tag__H.py +0 -0
  211. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/html/Tag__HR.py +0 -0
  212. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/html/Tag__Head.py +0 -0
  213. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/html/Tag__Html.py +0 -0
  214. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/html/Tag__Link.py +0 -0
  215. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/html/Tag__Style.py +0 -0
  216. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/html/__init__.py +0 -0
  217. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/pubsub/Event__Queue.py +0 -0
  218. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/pubsub/PubSub__Client.py +0 -0
  219. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/pubsub/PubSub__Room.py +0 -0
  220. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/pubsub/PubSub__Server.py +0 -0
  221. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/pubsub/PubSub__Sqlite.py +0 -0
  222. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/pubsub/__init__.py +0 -0
  223. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/pubsub/schemas/Schema__Event.py +0 -0
  224. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/pubsub/schemas/Schema__Event__Connect.py +0 -0
  225. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/pubsub/schemas/Schema__Event__Disconnect.py +0 -0
  226. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/pubsub/schemas/Schema__Event__Execute_Method.py +0 -0
  227. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/pubsub/schemas/Schema__Event__Join_Room.py +0 -0
  228. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/pubsub/schemas/Schema__Event__Leave_Room.py +0 -0
  229. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/pubsub/schemas/Schema__Event__Message.py +0 -0
  230. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/pubsub/schemas/Schema__PubSub__Client.py +0 -0
  231. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/pubsub/schemas/__init__.py +0 -0
  232. {osbot_utils-1.90.0/osbot_utils/helpers/sqlite → osbot_utils-1.92.0/osbot_utils/helpers/python_compatibility}/__init__.py +0 -0
  233. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/sqlite/Capture_Sqlite_Error.py +0 -0
  234. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/sqlite/Sqlite__Cursor.py +0 -0
  235. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/sqlite/Sqlite__Database.py +0 -0
  236. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/sqlite/Sqlite__Field.py +0 -0
  237. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/sqlite/Sqlite__Globals.py +0 -0
  238. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/sqlite/Sqlite__Table.py +0 -0
  239. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/sqlite/Sqlite__Table__Create.py +0 -0
  240. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/sqlite/Temp_Sqlite__Database__Disk.py +0 -0
  241. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/sqlite/Temp_Sqlite__Table.py +0 -0
  242. {osbot_utils-1.90.0/osbot_utils/helpers/sqlite/cache → osbot_utils-1.92.0/osbot_utils/helpers/sqlite}/__init__.py +0 -0
  243. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/sqlite/cache/Schema__Table__Requests.py +0 -0
  244. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/sqlite/cache/Sqlite__Cache__Requests.py +0 -0
  245. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/sqlite/cache/Sqlite__Cache__Requests__Patch.py +0 -0
  246. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/sqlite/cache/Sqlite__Cache__Requests__Sqlite.py +0 -0
  247. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/sqlite/cache/Sqlite__Cache__Requests__Table.py +0 -0
  248. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/sqlite/cache/Sqlite__DB__Requests.py +0 -0
  249. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/sqlite/cache/TestCase__Sqlite__Cache__Requests.py +0 -0
  250. {osbot_utils-1.90.0/osbot_utils/helpers/sqlite/domains → osbot_utils-1.92.0/osbot_utils/helpers/sqlite/cache}/__init__.py +0 -0
  251. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/sqlite/domains/Sqlite__DB.py +0 -0
  252. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/sqlite/domains/Sqlite__DB__Files.py +0 -0
  253. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/sqlite/domains/Sqlite__DB__Graph.py +0 -0
  254. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/sqlite/domains/Sqlite__DB__Json.py +0 -0
  255. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/sqlite/domains/Sqlite__DB__Local.py +0 -0
  256. {osbot_utils-1.90.0/osbot_utils/helpers/sqlite/domains/schemas → osbot_utils-1.92.0/osbot_utils/helpers/sqlite/domains}/__init__.py +0 -0
  257. {osbot_utils-1.90.0/osbot_utils/helpers/sqlite/models → osbot_utils-1.92.0/osbot_utils/helpers/sqlite/domains/schemas}/__init__.py +0 -0
  258. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/sqlite/models/Sqlite__Field__Type.py +0 -0
  259. {osbot_utils-1.90.0/osbot_utils/helpers/sqlite/sample_data → osbot_utils-1.92.0/osbot_utils/helpers/sqlite/models}/__init__.py +0 -0
  260. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/sqlite/sample_data/Sqlite__Sample_Data__Chinook.py +0 -0
  261. {osbot_utils-1.90.0/osbot_utils/helpers/sqlite/sql_builder → osbot_utils-1.92.0/osbot_utils/helpers/sqlite/sample_data}/__init__.py +0 -0
  262. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/sqlite/sql_builder/SQL_Builder.py +0 -0
  263. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/sqlite/sql_builder/SQL_Builder__Select.py +0 -0
  264. {osbot_utils-1.90.0/osbot_utils/helpers/sqlite/tables → osbot_utils-1.92.0/osbot_utils/helpers/sqlite/sql_builder}/__init__.py +0 -0
  265. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/sqlite/tables/Sqlite__Table__Config.py +0 -0
  266. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/sqlite/tables/Sqlite__Table__Edges.py +0 -0
  267. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/sqlite/tables/Sqlite__Table__Files.py +0 -0
  268. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/sqlite/tables/Sqlite__Table__Nodes.py +0 -0
  269. {osbot_utils-1.90.0/osbot_utils/helpers/ssh → osbot_utils-1.92.0/osbot_utils/helpers/sqlite/tables}/__init__.py +0 -0
  270. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/ssh/SCP.py +0 -0
  271. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/ssh/SSH.py +0 -0
  272. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/ssh/SSH__Cache__Requests.py +0 -0
  273. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/ssh/SSH__Execute.py +0 -0
  274. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/ssh/SSH__Health_Check.py +0 -0
  275. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/ssh/SSH__Linux.py +0 -0
  276. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/ssh/SSH__Linux__Amazon.py +0 -0
  277. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/ssh/SSH__Python.py +0 -0
  278. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/ssh/TestCase__SSH.py +0 -0
  279. {osbot_utils-1.90.0/osbot_utils/helpers/trace → osbot_utils-1.92.0/osbot_utils/helpers/ssh}/__init__.py +0 -0
  280. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/trace/Trace_Call.py +0 -0
  281. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/trace/Trace_Call__Config.py +0 -0
  282. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/trace/Trace_Call__Graph.py +0 -0
  283. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/trace/Trace_Call__Print_Lines.py +0 -0
  284. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/trace/Trace_Call__Print_Traces.py +0 -0
  285. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/trace/Trace_Call__Stack.py +0 -0
  286. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/trace/Trace_Call__Stack_Node.py +0 -0
  287. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/trace/Trace_Call__Stats.py +0 -0
  288. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/trace/Trace_Call__View_Model.py +0 -0
  289. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/trace/Trace_Files.py +0 -0
  290. {osbot_utils-1.90.0/osbot_utils/helpers/xml → osbot_utils-1.92.0/osbot_utils/helpers/trace}/__init__.py +0 -0
  291. {osbot_utils-1.90.0/osbot_utils/testing → osbot_utils-1.92.0/osbot_utils/helpers/type_safe}/__init__.py +0 -0
  292. {osbot_utils-1.90.0/osbot_utils/utils → osbot_utils-1.92.0/osbot_utils/helpers/type_safe/validators}/__init__.py +0 -0
  293. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/xml/Xml__Attribute.py +0 -0
  294. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/xml/Xml__Element.py +0 -0
  295. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/xml/Xml__File.py +0 -0
  296. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/xml/Xml__File__Load.py +0 -0
  297. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/xml/Xml__File__To_Dict.py +0 -0
  298. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/xml/Xml__File__To_Xml.py +0 -0
  299. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/xml/rss/RSS__Channel.py +0 -0
  300. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/xml/rss/RSS__Enclosure.py +0 -0
  301. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/xml/rss/RSS__Feed.py +0 -0
  302. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/xml/rss/RSS__Image.py +0 -0
  303. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/helpers/xml/rss/RSS__Item.py +0 -0
  304. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/testing/Catch.py +0 -0
  305. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/testing/Custom_Handler_For_Http_Tests.py +0 -0
  306. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/testing/Duration.py +0 -0
  307. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/testing/Hook_Method.py +0 -0
  308. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/testing/Log_To_Queue.py +0 -0
  309. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/testing/Log_To_String.py +0 -0
  310. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/testing/Logging.py +0 -0
  311. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/testing/Patch_Print.py +0 -0
  312. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/testing/Profiler.py +0 -0
  313. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/testing/Pytest.py +0 -0
  314. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/testing/Stderr.py +0 -0
  315. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/testing/Stdout.py +0 -0
  316. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/testing/Temp_Env_Vars.py +0 -0
  317. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/testing/Temp_File.py +0 -0
  318. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/testing/Temp_Folder.py +0 -0
  319. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/testing/Temp_Sys_Path.py +0 -0
  320. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/testing/Temp_Web_Server.py +0 -0
  321. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/testing/Temp_Zip.py +0 -0
  322. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/testing/Temp_Zip_In_Memory.py +0 -0
  323. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/testing/Unit_Test.py +0 -0
  324. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/testing/Unzip_File.py +0 -0
  325. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/utils/Assert.py +0 -0
  326. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/utils/Call_Stack.py +0 -0
  327. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/utils/Csv.py +0 -0
  328. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/utils/Dev.py +0 -0
  329. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/utils/Env.py +0 -0
  330. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/utils/Exceptions.py +0 -0
  331. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/utils/Files.py +0 -0
  332. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/utils/Functions.py +0 -0
  333. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/utils/Http.py +0 -0
  334. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/utils/Int.py +0 -0
  335. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/utils/Json.py +0 -0
  336. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/utils/Json_Cache.py +0 -0
  337. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/utils/Lists.py +0 -0
  338. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/utils/Misc.py +0 -0
  339. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/utils/Png.py +0 -0
  340. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/utils/Process.py +0 -0
  341. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/utils/Python_Logger.py +0 -0
  342. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/utils/Status.py +0 -0
  343. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/utils/Str.py +0 -0
  344. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/utils/Threads.py +0 -0
  345. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/utils/Toml.py +0 -0
  346. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/utils/Version.py +0 -0
  347. {osbot_utils-1.90.0 → osbot_utils-1.92.0}/osbot_utils/utils/Zip.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: osbot_utils
3
- Version: 1.90.0
3
+ Version: 1.92.0
4
4
  Summary: OWASP Security Bot - Utils
5
5
  Home-page: https://github.com/owasp-sbot/OSBot-Utils
6
6
  License: MIT
@@ -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-v1.90.0-blue)
26
+ ![Current Release](https://img.shields.io/badge/release-v1.92.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-v1.90.0-blue)
5
+ ![Current Release](https://img.shields.io/badge/release-v1.92.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,7 +3,7 @@
3
3
 
4
4
  import sys
5
5
  import types
6
- from osbot_utils.utils.Objects import default_value # todo: remove test mocking requirement for this to be here (instead of on the respective method)
6
+ from osbot_utils.utils.Objects import default_value # todo: remove test mocking requirement for this to be here (instead of on the respective method)
7
7
 
8
8
  # Backport implementations of get_origin and get_args for Python 3.7
9
9
  if sys.version_info < (3, 8): # pragma: no cover
@@ -24,6 +24,7 @@ if sys.version_info < (3, 8): # pragma
24
24
  return ()
25
25
  else:
26
26
  from typing import get_origin, get_args, ForwardRef
27
+ from osbot_utils.helpers.python_compatibility.python_3_8 import Annotated
27
28
 
28
29
  if sys.version_info >= (3, 10):
29
30
  NoneType = types.NoneType
@@ -44,7 +45,6 @@ class Type_Safe:
44
45
 
45
46
  for (key, value) in self.__cls_kwargs__().items(): # assign all default values to self
46
47
  if value is not None: # when the value is explicitly set to None on the class static vars, we can't check for type safety
47
-
48
48
  raise_exception_on_obj_type_annotation_mismatch(self, key, value)
49
49
  if hasattr(self, key):
50
50
  existing_value = getattr(self, key)
@@ -64,11 +64,30 @@ class Type_Safe:
64
64
  def __enter__(self): return self
65
65
  def __exit__(self, exc_type, exc_val, exc_tb): pass
66
66
 
67
+ def __getattr__(self, name): # Called when an attribute is not found through normal attribute access
68
+ if name.startswith(("set_", "get_")): # Check if the requested attribute is a getter or setter method
69
+ prefix = name[:4] # Extract "set_" or "get_" from the method name
70
+ attr_name = name[4:] # Get the actual attribute name by removing the prefix
71
+
72
+ if hasattr(self, attr_name): # Verify that the target attribute actually exists on the object
73
+ if prefix == "set_": # Handle setter method creation
74
+ def setter(value): # Create a dynamic setter function that takes a value parameter
75
+ setattr(self, attr_name, value) # Set the attribute value using type-safe setattr from Type_Safe
76
+ return self # Return self for method chaining
77
+ return setter # Return the setter function
78
+ else: # get_ # Handle getter method creation
79
+ def getter(): # Create a dynamic getter function with no parameters
80
+ return getattr(self, attr_name) # Return the attribute value using Python's built-in getattr
81
+ return getter # Return the getter function
82
+
83
+ raise AttributeError(f"'{type(self).__name__}' object has no attribute '{name}'") # Raise error if attribute is not a valid getter/setter
84
+
67
85
  def __setattr__(self, name, value):
68
- from osbot_utils.utils.Objects import convert_dict_to_value_from_obj_annotation
69
- from osbot_utils.utils.Objects import convert_to_value_from_obj_annotation
70
- from osbot_utils.utils.Objects import value_type_matches_obj_annotation_for_attr
71
- from osbot_utils.utils.Objects import value_type_matches_obj_annotation_for_union_attr
86
+ from osbot_utils.utils.Objects import convert_dict_to_value_from_obj_annotation
87
+ from osbot_utils.utils.Objects import convert_to_value_from_obj_annotation
88
+ from osbot_utils.utils.Objects import value_type_matches_obj_annotation_for_attr
89
+ from osbot_utils.utils.Objects import value_type_matches_obj_annotation_for_union_and_annotated
90
+ from osbot_utils.helpers.type_safe.Type_Safe__Validator import Type_Safe__Validator
72
91
 
73
92
  if not hasattr(self, '__annotations__'): # can't do type safety checks if the class does not have annotations
74
93
  return super().__setattr__(name, value)
@@ -79,7 +98,7 @@ class Type_Safe:
79
98
  if type(value) in [int, str]: # for now only a small number of str and int classes are supported (until we understand the full implications of this)
80
99
  value = convert_to_value_from_obj_annotation (self, name, value)
81
100
  check_1 = value_type_matches_obj_annotation_for_attr (self, name, value)
82
- check_2 = value_type_matches_obj_annotation_for_union_attr(self, name, value)
101
+ check_2 = value_type_matches_obj_annotation_for_union_and_annotated(self, name, value)
83
102
  if (check_1 is False and check_2 is None or
84
103
  check_1 is None and check_2 is False or
85
104
  check_1 is False and check_2 is False ): # fix for type safety assigment on Union vars
@@ -89,6 +108,16 @@ class Type_Safe:
89
108
  if getattr(self, name) is not None: # unless it is already set to None
90
109
  raise ValueError(f"Can't set None, to a variable that is already set. Invalid type for attribute '{name}'. Expected '{self.__annotations__.get(name)}' but got '{type(value)}'")
91
110
 
111
+ # todo: refactor this to separate method
112
+ if hasattr(self.__annotations__, 'get'):
113
+ annotation = self.__annotations__.get(name)
114
+ if annotation and get_origin(annotation) is Annotated:
115
+ annotation_args = get_args(annotation)
116
+ target_type = annotation_args[0]
117
+ for attribute in annotation_args[1:]:
118
+ if isinstance(attribute, Type_Safe__Validator):
119
+ attribute.validate(value=value, field_name=name, target_type=target_type)
120
+
92
121
  super().__setattr__(name, value)
93
122
 
94
123
  def __attr_names__(self):
@@ -131,6 +160,8 @@ class Type_Safe:
131
160
  else:
132
161
  var_value = getattr(base_cls, var_name)
133
162
  if var_value is not None: # allow None assignments on ctor since that is a valid use case
163
+ if get_origin(var_type) is Annotated:
164
+ continue
134
165
  if var_type and not isinstance(var_value, var_type): # check type
135
166
  exception_message = f"variable '{var_name}' is defined as type '{var_type}' but has value '{var_value}' of type '{type(var_value)}'"
136
167
  raise ValueError(exception_message)
@@ -1,10 +1,10 @@
1
- from osbot_utils.graphs.mermaid.Mermaid__Renderer import Mermaid__Renderer
2
- from osbot_utils.graphs.mermaid.Mermaid__Edge import Mermaid__Edge
3
- from osbot_utils.graphs.mermaid.Mermaid__Graph import Mermaid__Graph
4
- from osbot_utils.graphs.mermaid.models.Mermaid__Diagram_Direction import Diagram__Direction
5
- from osbot_utils.graphs.mermaid.models.Mermaid__Diagram__Type import Diagram__Type
6
- from osbot_utils.utils.Python_Logger import Python_Logger
7
- from osbot_utils.base_classes.Kwargs_To_Self import Kwargs_To_Self
1
+ from osbot_utils.graphs.mermaid.Mermaid__Renderer import Mermaid__Renderer
2
+ from osbot_utils.graphs.mermaid.Mermaid__Edge import Mermaid__Edge
3
+ from osbot_utils.graphs.mermaid.Mermaid__Graph import Mermaid__Graph
4
+ from osbot_utils.graphs.mermaid.models.Mermaid__Diagram_Direction import Diagram__Direction
5
+ from osbot_utils.graphs.mermaid.models.Mermaid__Diagram__Type import Diagram__Type
6
+ from osbot_utils.utils.Python_Logger import Python_Logger
7
+ from osbot_utils.base_classes.Kwargs_To_Self import Kwargs_To_Self
8
8
 
9
9
  class Mermaid(Kwargs_To_Self):
10
10
  graph : Mermaid__Graph
@@ -1,8 +1,5 @@
1
- from osbot_utils.base_classes.Kwargs_To_Self import Kwargs_To_Self
2
- from osbot_utils.graphs.mermaid.Mermaid__Node import LINE_PADDING, Mermaid__Node
1
+ from osbot_utils.base_classes.Kwargs_To_Self import Kwargs_To_Self
3
2
  from osbot_utils.graphs.mgraph.MGraph__Node import MGraph__Node
4
- from osbot_utils.utils.Str import safe_str
5
-
6
3
 
7
4
  class MGraph__Edge(Kwargs_To_Self):
8
5
  attributes : dict
@@ -1,6 +1,5 @@
1
- from osbot_utils.utils.Misc import random_id
2
-
3
- from osbot_utils.base_classes.Kwargs_To_Self import Kwargs_To_Self
1
+ from osbot_utils.utils.Misc import random_id
2
+ from osbot_utils.base_classes.Kwargs_To_Self import Kwargs_To_Self
4
3
 
5
4
 
6
5
  class MGraph__Node(Kwargs_To_Self):
@@ -1,9 +1,8 @@
1
- from enum import Enum, auto
2
- from osbot_utils.utils.Str import safe_str
3
- from osbot_utils.helpers.Local_Cache import Local_Cache
4
-
1
+ from enum import Enum, auto
2
+ from osbot_utils.utils.Str import safe_str
3
+ from osbot_utils.helpers.Local_Cache import Local_Cache
5
4
  from osbot_utils.base_classes.Kwargs_To_Self import Kwargs_To_Self
6
- from osbot_utils.graphs.mgraph.MGraph import MGraph
5
+ from osbot_utils.graphs.mgraph.MGraph import MGraph
7
6
 
8
7
 
9
8
  class Serialization_Mode(Enum):
@@ -1,10 +1,5 @@
1
- import random
2
-
3
- from osbot_utils.utils.Files import file_exists, file_extension, pickle_load_from_file
4
-
5
1
  from osbot_utils.graphs.mgraph.MGraph__Random_Graphs import MGraph__Random_Graphs
6
2
 
7
-
8
3
  class MGraphs:
9
4
 
10
5
  def new__random(self, config=None, graph_key=None, x_nodes=10, y_edges=20):
@@ -2,10 +2,10 @@ from osbot_utils.base_classes.Type_Safe import Type_Safe
2
2
  from osbot_utils.utils.Dev import pprint
3
3
  from osbot_utils.utils.Files import files_list, file_create_from_bytes, temp_file, parent_folder, parent_folder_create
4
4
  from osbot_utils.utils.Misc import random_text
5
- from osbot_utils.utils.Regex import list__match_regex, list__match_regexes
5
+ from osbot_utils.utils.Regex import list__match_regexes
6
6
  from osbot_utils.utils.Zip import zip_bytes_empty, zip_bytes__files, zip_bytes__add_file, zip_bytes__add_files, \
7
7
  zip_bytes__replace_files, zip_bytes__replace_file, zip_bytes__file_list, zip_bytes__file, \
8
- zip_bytes__add_file__from_disk, zip_bytes__add_files__from_disk, zip_files, zip_file__files, zip_bytes__remove_files
8
+ zip_bytes__add_file__from_disk, zip_bytes__add_files__from_disk, zip_file__files, zip_bytes__remove_files
9
9
 
10
10
 
11
11
  class Zip_Bytes(Type_Safe):
@@ -0,0 +1,8 @@
1
+ import sys
2
+
3
+ if sys.version_info < (3, 9):
4
+ class Annotated:
5
+ def __init__(self, *args) -> None:
6
+ pass
7
+ else:
8
+ from typing import Annotated
@@ -8,28 +8,28 @@ 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_attr' , # 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
- 'get_origin' ,
16
- 'getmro' ,
17
- 'default_value' ,
18
- 'raise_exception_on_obj_type_annotation_mismatch' ,
19
- '__cls_kwargs__' ,
20
- '__default__value__' ,
21
- '__setattr__' ,
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
+ 'get_origin' ,
16
+ 'getmro' ,
17
+ 'default_value' ,
18
+ 'raise_exception_on_obj_type_annotation_mismatch' ,
19
+ '__cls_kwargs__' ,
20
+ '__default__value__' ,
21
+ '__setattr__' ,
22
22
  '<module>']
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)
24
- 'osbot_utils.helpers.trace.Trace_Call__Config' ,
25
- 'osbot_utils.helpers.trace.Trace_Call__View_Model' ,
26
- 'osbot_utils.helpers.trace.Trace_Call__Print_Traces' ,
27
- 'osbot_utils.helpers.trace.Trace_Call__Stack' ,
28
- 'osbot_utils.base_classes.Type_Safe' ,
29
- 'osbot_utils.helpers.CPrint' , # also see if this should be done here or at the print/view stage
30
- 'osbot_utils.helpers.Print_Table' ,
31
- 'osbot_utils.decorators.methods.cache_on_self' ,
32
- 'codecs' ]
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)
24
+ 'osbot_utils.helpers.trace.Trace_Call__Config' ,
25
+ 'osbot_utils.helpers.trace.Trace_Call__View_Model' ,
26
+ 'osbot_utils.helpers.trace.Trace_Call__Print_Traces' ,
27
+ 'osbot_utils.helpers.trace.Trace_Call__Stack' ,
28
+ 'osbot_utils.base_classes.Type_Safe' ,
29
+ 'osbot_utils.helpers.CPrint' , # also see if this should be done here or at the print/view stage
30
+ 'osbot_utils.helpers.Print_Table' ,
31
+ 'osbot_utils.decorators.methods.cache_on_self' ,
32
+ 'codecs' ]
33
33
 
34
34
  #GLOBAL_MODULES_TO_IGNORE = []
35
35
  #GLOBAL_FUNCTIONS_TO_IGNORE = []
@@ -0,0 +1,14 @@
1
+ from osbot_utils.helpers.python_compatibility.python_3_8 import Annotated
2
+ from typing import Any
3
+
4
+ class Type_Safe__Validator: # Base class for all Type_Safe validators.
5
+
6
+ def validate(self, value: Any, field_name: str, target_type: type) -> None: # Validate a value against this validator's rules.
7
+ if value and type(value) != target_type:
8
+ raise ValueError(f"{field_name} must be of type {target_type}, got {type(value)}")
9
+
10
+ def describe(self) -> str: # Return a human-readable description of this validator's rules.
11
+ pass
12
+
13
+
14
+ Validate = Annotated
@@ -0,0 +1,28 @@
1
+ from typing import Any
2
+ from osbot_utils.helpers.type_safe.Type_Safe__Validator import Type_Safe__Validator
3
+
4
+
5
+ class Validator__Max(Type_Safe__Validator): # Validates that a numeric value is at most the specified maximum."""
6
+ max_value: float
7
+
8
+ def __init__(self, max_value):
9
+ self.max_value = max_value
10
+
11
+ def validate(self, value: Any, field_name: str, target_type: type) -> None:
12
+ super().validate(value=value, field_name=field_name, target_type=target_type)
13
+ if value is None:
14
+ return
15
+ compare_value = value if isinstance(value, (int, float)) else len(value)
16
+ if compare_value > self.max_value:
17
+ if not isinstance(value, (int, float)):
18
+ msg = f"{field_name} must be at most {self.max_value}, got {compare_value}"
19
+ elif isinstance(value, (list, tuple)):
20
+ msg = f"{field_name} must be at most {self.max_value}, got length {compare_value}"
21
+ else:
22
+ msg = f"{field_name} must be at most {self.max_value}, got size {compare_value}"
23
+ raise ValueError(msg)
24
+
25
+ def describe(self) -> str:
26
+ return f"maximum value: {self.max_value}"
27
+
28
+ Max = Validator__Max
@@ -0,0 +1,38 @@
1
+ from typing import Any
2
+ from osbot_utils.helpers.type_safe.Type_Safe__Validator import Type_Safe__Validator
3
+
4
+ class Validator__Min(Type_Safe__Validator): # Validates that a value is at least the specified minimum. Works with any type that supports the < operator (numbers, strings, lists, etc.)
5
+ min_value: Any
6
+
7
+ def __init__(self, min_value):
8
+ super().__init__()
9
+ self.min_value = min_value
10
+
11
+ def validate(self, value: Any, field_name: str, target_type: type) -> None:
12
+ super().validate(value=value, field_name=field_name, target_type=target_type)
13
+ if value is None: # can't compare if value has been set to None
14
+ return
15
+
16
+ try:
17
+ compare_value = value if isinstance(value, (int, float)) else len(value)
18
+
19
+ if compare_value < self.min_value:
20
+ if isinstance(value, (int, float)):
21
+ msg = f"{field_name} must be at least {self.min_value}, got {compare_value}"
22
+ elif isinstance(value, str):
23
+ msg = f"{field_name} must have length at least {self.min_value}, got length {compare_value}"
24
+ elif isinstance(value, (list, tuple)):
25
+ msg = f"{field_name} must have length at least {self.min_value}, got length {compare_value}"
26
+ else:
27
+ msg = f"{field_name} must have size at least {self.min_value}, got size {compare_value}"
28
+ raise ValueError(msg)
29
+ except TypeError:
30
+ raise ValueError(f"Cannot compare {field_name} of type {type(value)} with minimum value of type {type(self.min_value)}")
31
+
32
+ def describe(self) -> str:
33
+ if isinstance(self.min_value, (int, float)):
34
+ return f"minimum value: {self.min_value}"
35
+ else:
36
+ return f"minimum length: {len(self.min_value)}"
37
+
38
+ Min = Validator__Min
@@ -0,0 +1,18 @@
1
+ from typing import Any
2
+ from osbot_utils.helpers.type_safe.Type_Safe__Validator import Type_Safe__Validator
3
+
4
+
5
+ class Validator__One_Of(Type_Safe__Validator): # Validates that a value is one of a set of allowed values."""
6
+ allowed: list
7
+
8
+ def __init__(self, allowed):
9
+ self.allowed = allowed
10
+
11
+ def validate(self, value: Any, field_name: str, target_type:type) -> None:
12
+ if value not in self.allowed:
13
+ raise ValueError(f"{field_name} must be one of {self.allowed}, got {value}")
14
+
15
+ def describe(self) -> str:
16
+ return f"must be one of: {self.allowed}"
17
+
18
+ One_Of = Validator__One_Of
@@ -0,0 +1,26 @@
1
+ from typing import Any
2
+ from osbot_utils.helpers.type_safe.Type_Safe__Validator import Type_Safe__Validator
3
+
4
+ class Validator__Regex(Type_Safe__Validator): # Validates that a string matches the specified regex pattern.
5
+ pattern : str
6
+ description: str
7
+
8
+ def __init__(self, pattern, description=None):
9
+ self.pattern = pattern
10
+ self.description = description
11
+
12
+ def validate(self, value: Any, field_name: str, target_type:type) -> None:
13
+ import re
14
+ if value is None:
15
+ return
16
+ if not isinstance(value, str):
17
+ raise ValueError(f"{field_name} must be a string, got {type(value)}")
18
+ if not re.match(self.pattern, value):
19
+ raise ValueError(f"{field_name} must match pattern {self.pattern}")
20
+
21
+ def describe(self) -> str:
22
+ if self.description:
23
+ return self.description
24
+ return f"must match pattern: {self.pattern}"
25
+
26
+ Regex = Validator__Regex
File without changes
@@ -25,13 +25,14 @@ class RSS__Feed__Parser:
25
25
  guid = self.extract_guid(item_data.get('guid' ))
26
26
  pubDate = self.element_text(item_data.get('pubDate' ))
27
27
  creator = self.element_text(item_data.get('creator' ))
28
+ categories = self.ensure_is_list(item_data.get('category'))
28
29
  rss_item = RSS__Item(title = title ,
29
30
  link = link ,
30
31
  description = description ,
31
32
  guid = guid ,
32
33
  pubDate = pubDate ,
33
34
  creator = creator ,
34
- categories = item_data.get('category' , []),
35
+ categories = categories ,
35
36
  content = item_data.get('content' , {}),
36
37
  thumbnail = item_data.get('thumbnail' , {}))
37
38
 
@@ -74,6 +75,15 @@ class RSS__Feed__Parser:
74
75
  def extract_guid(self, target):
75
76
  return Guid(self.extract_text(target))
76
77
 
78
+ def ensure_is_list(self, target):
79
+ if type(target) is list:
80
+ return target
81
+ if type(target) is str:
82
+ return [target]
83
+ if target:
84
+ return [f'{target}']
85
+ return []
86
+
77
87
  def element_text(self, target):
78
88
  if isinstance(target, list):
79
89
  for item in target:
File without changes
@@ -23,7 +23,7 @@ if sys.version_info < (3, 8):
23
23
  else:
24
24
  return ()
25
25
  else:
26
- from typing import get_origin, get_args
26
+ from typing import get_origin, get_args, List, Tuple, Dict
27
27
 
28
28
 
29
29
  def are_types_compatible_for_assigment(source_type, target_type):
@@ -343,11 +343,10 @@ def obj_values(target=None):
343
343
  return list(obj_dict(target).values())
344
344
 
345
345
  def raise_exception_on_obj_type_annotation_mismatch(target, attr_name, value):
346
- # todo : check if this is is not causing the type safety issues
347
346
  if value_type_matches_obj_annotation_for_attr(target, attr_name, value) is False: # handle case with normal types
348
- if value_type_matches_obj_annotation_for_union_attr(target, attr_name, value) is True: # handle union cases
347
+ if value_type_matches_obj_annotation_for_union_and_annotated(target, attr_name, value) is True: # handle union cases
349
348
  return # this is done like this because value_type_matches_obj_annotation_for_union_attr will return None when there is no Union objects
350
- raise Exception(f"Invalid type for attribute '{attr_name}'. Expected '{target.__annotations__.get(attr_name)}' but got '{type(value)}'")
349
+ raise TypeError(f"Invalid type for attribute '{attr_name}'. Expected '{target.__annotations__.get(attr_name)}' but got '{type(value)}'")
351
350
 
352
351
  def obj_attribute_annotation(target, attr_name):
353
352
  if target is not None and attr_name is not None:
@@ -382,15 +381,52 @@ def obj_is_type_union_compatible(var_type, compatible_types):
382
381
  return True # If all args are compatible, return True
383
382
  return var_type in compatible_types or var_type is type(None) # Check for direct compatibility or type(None) for non-Union types
384
383
 
385
- def value_type_matches_obj_annotation_for_union_attr(target, attr_name, value):
386
- from typing import Union
384
+
385
+ def value_type_matches_obj_annotation_for_union_and_annotated(target, attr_name, value):
386
+ from osbot_utils.helpers.python_compatibility.python_3_8 import Annotated
387
+ from typing import Union, get_origin, get_args
388
+
387
389
  value_type = type(value)
388
- attribute_annotation = obj_attribute_annotation(target,attr_name)
390
+ attribute_annotation = obj_attribute_annotation(target, attr_name)
389
391
  origin = get_origin(attribute_annotation)
390
- if origin is Union: # For Union types, including Optionals
391
- args = get_args(attribute_annotation) # Get the argument types
392
+
393
+ if origin is Union: # Handle Union types (including Optional)
394
+ args = get_args(attribute_annotation)
392
395
  return value_type in args
393
- return None # if it is not an Union type just return None (to give an indication to the caller that the comparison was not made)
396
+
397
+ # todo: refactor the logic below to a separate method (and check for duplicate code with other get_origin usage)
398
+ if origin is Annotated: # Handle Annotated types
399
+ args = get_args(attribute_annotation)
400
+ base_type = args[0] # First argument is the base type
401
+ base_origin = get_origin(base_type)
402
+
403
+ if base_origin is None: # Non-container types
404
+ return isinstance(value, base_type)
405
+
406
+ if base_origin in (list, List): # Handle List types
407
+ if not isinstance(value, list):
408
+ return False
409
+ item_type = get_args(base_type)[0]
410
+ return all(isinstance(item, item_type) for item in value)
411
+
412
+ if base_origin in (tuple, Tuple): # Handle Tuple types
413
+ if not isinstance(value, tuple):
414
+ return False
415
+ item_types = get_args(base_type)
416
+ return len(value) == len(item_types) and all(
417
+ isinstance(item, item_type)
418
+ for item, item_type in zip(value, item_types)
419
+ )
420
+
421
+ if base_origin in (dict, Dict): # Handle Dict types
422
+ if not isinstance(value, dict):
423
+ return False
424
+ key_type, value_type = get_args(base_type)
425
+ return all(isinstance(k, key_type) and isinstance(v, value_type)
426
+ for k, v in value.items())
427
+
428
+ # todo: add support for for other typing constructs
429
+ return None # if it is not a Union or Annotated types just return None (to give an indication to the caller that the comparison was not made)
394
430
 
395
431
 
396
432
  def pickle_save_to_bytes(target: object) -> bytes:
@@ -1,7 +1,7 @@
1
1
  import re
2
-
3
2
  from osbot_utils.utils.Status import status_error
4
3
 
4
+ # todo: review if we can delete this file (since we now have an Regex class in the validators)
5
5
 
6
6
  def list__match_regex(target, pattern):
7
7
  return list__match_regexes(target, [pattern])
File without changes
@@ -0,0 +1 @@
1
+ v1.92.0
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "osbot_utils"
3
- version = "v1.90.0"
3
+ version = "v1.92.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
- v1.90.0
File without changes