osbot-utils 2.10.0__tar.gz → 2.12.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/PKG-INFO +3 -3
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/README.md +1 -1
- osbot_utils-2.12.0/osbot_utils/context_managers/capture_duration.py +37 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/CPrint.py +0 -1
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/trace/Trace_Call.py +1 -2
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/trace/Trace_Call__Handler.py +14 -14
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/xml/Xml__File.py +1 -1
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/xml/Xml__File__To_Dict.py +1 -1
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/xml/Xml__File__To_Xml.py +1 -1
- osbot_utils-2.12.0/osbot_utils/testing/performance/Performance_Measure__Session.py +108 -0
- osbot_utils-2.12.0/osbot_utils/testing/performance/models/Model__Performance_Measure__Measurement.py +14 -0
- osbot_utils-2.12.0/osbot_utils/testing/performance/models/Model__Performance_Measure__Result.py +10 -0
- osbot_utils-2.12.0/osbot_utils/type_safe/Type_Safe.py +109 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/type_safe/Type_Safe__Base.py +8 -24
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/type_safe/Type_Safe__Dict.py +9 -8
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/type_safe/methods/type_safe_property.py +1 -1
- osbot_utils-2.12.0/osbot_utils/type_safe/shared/Type_Safe__Annotations.py +29 -0
- osbot_utils-2.12.0/osbot_utils/type_safe/shared/Type_Safe__Cache.py +143 -0
- osbot_utils-2.12.0/osbot_utils/type_safe/shared/Type_Safe__Convert.py +46 -0
- osbot_utils-2.12.0/osbot_utils/type_safe/shared/Type_Safe__Not_Cached.py +24 -0
- osbot_utils-2.12.0/osbot_utils/type_safe/shared/Type_Safe__Raise_Exception.py +14 -0
- osbot_utils-2.12.0/osbot_utils/type_safe/shared/Type_Safe__Shared__Variables.py +4 -0
- osbot_utils-2.12.0/osbot_utils/type_safe/shared/Type_Safe__Validation.py +246 -0
- osbot_utils-2.12.0/osbot_utils/type_safe/shared/__init__.py +0 -0
- osbot_utils-2.12.0/osbot_utils/type_safe/steps/Type_Safe__Step__Class_Kwargs.py +110 -0
- osbot_utils-2.12.0/osbot_utils/type_safe/steps/Type_Safe__Step__Default_Kwargs.py +42 -0
- osbot_utils-2.12.0/osbot_utils/type_safe/steps/Type_Safe__Step__Default_Value.py +74 -0
- osbot_utils-2.12.0/osbot_utils/type_safe/steps/Type_Safe__Step__From_Json.py +138 -0
- osbot_utils-2.12.0/osbot_utils/type_safe/steps/Type_Safe__Step__Init.py +24 -0
- osbot_utils-2.12.0/osbot_utils/type_safe/steps/Type_Safe__Step__Set_Attr.py +92 -0
- osbot_utils-2.12.0/osbot_utils/type_safe/steps/__init__.py +0 -0
- osbot_utils-2.12.0/osbot_utils/type_safe/validators/__init__.py +0 -0
- osbot_utils-2.12.0/osbot_utils/utils/Objects.py +318 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/utils/Status.py +0 -2
- osbot_utils-2.12.0/osbot_utils/utils/__init__.py +0 -0
- osbot_utils-2.12.0/osbot_utils/version +1 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/pyproject.toml +1 -1
- osbot_utils-2.10.0/osbot_utils/context_managers/capture_duration.py +0 -30
- osbot_utils-2.10.0/osbot_utils/type_safe/Type_Safe.py +0 -492
- osbot_utils-2.10.0/osbot_utils/utils/Objects.py +0 -523
- osbot_utils-2.10.0/osbot_utils/version +0 -1
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/LICENSE +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/__init__.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/base_classes/Cache_Pickle.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/base_classes/Kwargs_To_Disk.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/base_classes/Kwargs_To_Self.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/base_classes/__init__.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/context_managers/__init__.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/context_managers/async_invoke.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/context_managers/disable_root_loggers.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/context_managers/print_duration.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/decorators/__init__.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/decorators/classes/__init__.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/decorators/classes/singleton.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/decorators/lists/__init__.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/decorators/lists/filter_list.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/decorators/lists/group_by.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/decorators/lists/index_by.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/decorators/methods/__init__.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/decorators/methods/cache.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/decorators/methods/cache_on_function.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/decorators/methods/cache_on_self.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/decorators/methods/cache_on_tmp.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/decorators/methods/capture_exception.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/decorators/methods/capture_status.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/decorators/methods/catch.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/decorators/methods/context.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/decorators/methods/depreciated.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/decorators/methods/function_type_check.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/decorators/methods/obj_as_context.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/decorators/methods/remove_return_value.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/decorators/methods/required_fields.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/fluent/Fluent_Dict.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/fluent/Fluent_List.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/fluent/__init__.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/CFormat.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/Dependency_Manager.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/Dict_To_Attr.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/Guid.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/Hashicorp_Secrets.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/Local_Cache.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/Local_Caches.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/Print_Table.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/Python_Audit.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/Random_Guid.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/Random_Guid_Short.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/Random_Seed.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/Safe_Id.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/Str_ASCII.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/Timestamp_Now.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/Type_Registry.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/Zip_Bytes.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/__init__.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/Ast.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/Ast_Base.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/Ast_Data.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/Ast_Load.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/Ast_Merge.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/Ast_Node.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/Ast_Visit.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/Call_Tree.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/__init__.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Add.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Alias.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_And.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Argument.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Arguments.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Assert.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Assign.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Attribute.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Aug_Assign.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Bin_Op.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Bool_Op.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Break.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Call.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Class_Def.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Compare.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Comprehension.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Constant.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Continue.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Dict.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Eq.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Except_Handler.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Expr.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_For.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Function_Def.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Generator_Exp.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Gt.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_GtE.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_If.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_If_Exp.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Import.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Import_From.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_In.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Is.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Is_Not.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Keyword.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Lambda.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_List.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_List_Comp.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Load.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Lt.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_LtE.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Mod.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Module.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Mult.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Name.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Not.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Not_Eq.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Not_In.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Or.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Pass.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Pow.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Raise.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Return.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Set.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Slice.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Starred.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Store.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Sub.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Subscript.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Try.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Tuple.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Unary_Op.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_While.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_With.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_With_Item.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/Ast_Yield.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ast/nodes/__init__.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/cache_requests/Cache__Requests__Actions.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/cache_requests/Cache__Requests__Config.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/cache_requests/Cache__Requests__Data.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/cache_requests/Cache__Requests__Invoke.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/cache_requests/Cache__Requests__Row.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/cache_requests/Cache__Requests__Table.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/cache_requests/__init__.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/cache_requests/flows/flow__Cache__Requests.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/flows/Flow.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/flows/Flow__Events.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/flows/Task.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/flows/__init__.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/flows/decorators/__init__.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/flows/decorators/flow.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/flows/decorators/task.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/flows/models/Flow_Run__Config.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/flows/models/Flow_Run__Event.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/flows/models/Flow_Run__Event_Data.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/flows/models/Flow_Run__Event_Type.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/flows/models/__init__.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/generators/Generator_Context_Manager.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/generators/Generator_Manager.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/generators/Model__Generator_State.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/generators/Model__Generator_Target.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/generators/__init__.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/html/Dict_To_Css.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/html/Dict_To_Html.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/html/Dict_To_Tags.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/html/Html_To_Dict.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/html/Html_To_Tag.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/html/Tag__Base.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/html/Tag__Body.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/html/Tag__Div.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/html/Tag__H.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/html/Tag__HR.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/html/Tag__Head.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/html/Tag__Html.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/html/Tag__Link.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/html/Tag__Style.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/html/__init__.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/pubsub/Event__Queue.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/pubsub/PubSub__Client.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/pubsub/PubSub__Room.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/pubsub/PubSub__Server.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/pubsub/PubSub__Sqlite.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/pubsub/__init__.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/pubsub/schemas/Schema__Event.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/pubsub/schemas/Schema__Event__Connect.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/pubsub/schemas/Schema__Event__Disconnect.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/pubsub/schemas/Schema__Event__Execute_Method.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/pubsub/schemas/Schema__Event__Join_Room.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/pubsub/schemas/Schema__Event__Leave_Room.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/pubsub/schemas/Schema__Event__Message.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/pubsub/schemas/Schema__PubSub__Client.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/pubsub/schemas/__init__.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/python_compatibility/__init__.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/python_compatibility/python_3_8.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/sqlite/Capture_Sqlite_Error.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/sqlite/Sqlite__Cursor.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/sqlite/Sqlite__Database.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/sqlite/Sqlite__Field.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/sqlite/Sqlite__Globals.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/sqlite/Sqlite__Table.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/sqlite/Sqlite__Table__Create.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/sqlite/Temp_Sqlite__Database__Disk.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/sqlite/Temp_Sqlite__Table.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/sqlite/__init__.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/sqlite/cache/Schema__Table__Requests.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/sqlite/cache/Sqlite__Cache__Requests.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/sqlite/cache/Sqlite__Cache__Requests__Patch.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/sqlite/cache/Sqlite__Cache__Requests__Sqlite.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/sqlite/cache/Sqlite__Cache__Requests__Table.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/sqlite/cache/Sqlite__DB__Requests.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/sqlite/cache/TestCase__Sqlite__Cache__Requests.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/sqlite/cache/__init__.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/sqlite/domains/Sqlite__DB.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/sqlite/domains/Sqlite__DB__Files.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/sqlite/domains/Sqlite__DB__Graph.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/sqlite/domains/Sqlite__DB__Json.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/sqlite/domains/Sqlite__DB__Local.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/sqlite/domains/__init__.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/sqlite/domains/schemas/__init__.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/sqlite/models/Sqlite__Field__Type.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/sqlite/models/__init__.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/sqlite/sample_data/Sqlite__Sample_Data__Chinook.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/sqlite/sample_data/__init__.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/sqlite/sql_builder/SQL_Builder.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/sqlite/sql_builder/SQL_Builder__Select.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/sqlite/sql_builder/__init__.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/sqlite/tables/Sqlite__Table__Config.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/sqlite/tables/Sqlite__Table__Edges.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/sqlite/tables/Sqlite__Table__Files.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/sqlite/tables/Sqlite__Table__Nodes.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/sqlite/tables/__init__.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ssh/SCP.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ssh/SSH.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ssh/SSH__Cache__Requests.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ssh/SSH__Execute.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ssh/SSH__Health_Check.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ssh/SSH__Linux.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ssh/SSH__Linux__Amazon.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ssh/SSH__Python.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ssh/TestCase__SSH.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/ssh/__init__.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/trace/Trace_Call__Config.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/trace/Trace_Call__Print_Lines.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/trace/Trace_Call__Print_Traces.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/trace/Trace_Call__Stack.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/trace/Trace_Call__Stack_Node.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/trace/Trace_Call__Stats.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/trace/Trace_Call__View_Model.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/trace/Trace_Files.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/trace/__init__.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/xml/Xml__Attribute.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/xml/Xml__Element.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/xml/Xml__File__Load.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/xml/__init__.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/xml/rss/RSS__Channel.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/xml/rss/RSS__Enclosure.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/xml/rss/RSS__Feed.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/xml/rss/RSS__Feed__Parser.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/xml/rss/RSS__Image.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/helpers/xml/rss/RSS__Item.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/testing/Catch.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/testing/Custom_Handler_For_Http_Tests.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/testing/Duration.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/testing/Hook_Method.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/testing/Log_To_Queue.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/testing/Log_To_String.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/testing/Logging.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/testing/Patch_Print.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/testing/Profiler.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/testing/Pytest.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/testing/Stderr.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/testing/Stdout.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/testing/Temp_Env_Vars.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/testing/Temp_File.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/testing/Temp_Folder.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/testing/Temp_Sys_Path.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/testing/Temp_Web_Server.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/testing/Temp_Zip.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/testing/Temp_Zip_In_Memory.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/testing/Unit_Test.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/testing/Unzip_File.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/testing/__init__.py +0 -0
- {osbot_utils-2.10.0/osbot_utils/type_safe → osbot_utils-2.12.0/osbot_utils/testing/performance}/__init__.py +0 -0
- {osbot_utils-2.10.0/osbot_utils/type_safe/decorators → osbot_utils-2.12.0/osbot_utils/testing/performance/models}/__init__.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/type_safe/Type_Safe__List.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/type_safe/Type_Safe__Method.py +0 -0
- {osbot_utils-2.10.0/osbot_utils/type_safe/methods → osbot_utils-2.12.0/osbot_utils/type_safe}/__init__.py +0 -0
- {osbot_utils-2.10.0/osbot_utils/type_safe/validators → osbot_utils-2.12.0/osbot_utils/type_safe/decorators}/__init__.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/type_safe/decorators/type_safe.py +0 -0
- {osbot_utils-2.10.0/osbot_utils/utils → osbot_utils-2.12.0/osbot_utils/type_safe/methods}/__init__.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/type_safe/validators/Type_Safe__Validator.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/type_safe/validators/Validator__Max.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/type_safe/validators/Validator__Min.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/type_safe/validators/Validator__One_Of.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/type_safe/validators/Validator__Regex.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/utils/Assert.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/utils/Call_Stack.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/utils/Csv.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/utils/Dev.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/utils/Env.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/utils/Exceptions.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/utils/Files.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/utils/Functions.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/utils/Http.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/utils/Int.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/utils/Json.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/utils/Json_Cache.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/utils/Lists.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/utils/Misc.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/utils/Png.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/utils/Process.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/utils/Python_Logger.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/utils/Regex.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/utils/Str.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/utils/Threads.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/utils/Toml.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/utils/Version.py +0 -0
- {osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/utils/Zip.py +0 -0
@@ -1,8 +1,7 @@
|
|
1
1
|
Metadata-Version: 2.3
|
2
2
|
Name: osbot_utils
|
3
|
-
Version: 2.
|
3
|
+
Version: 2.12.0
|
4
4
|
Summary: OWASP Security Bot - Utils
|
5
|
-
Home-page: https://github.com/owasp-sbot/OSBot-Utils
|
6
5
|
License: MIT
|
7
6
|
Author: Dinis Cruz
|
8
7
|
Author-email: dinis.cruz@owasp.org
|
@@ -16,6 +15,7 @@ Classifier: Programming Language :: Python :: 3.10
|
|
16
15
|
Classifier: Programming Language :: Python :: 3.11
|
17
16
|
Classifier: Programming Language :: Python :: 3.12
|
18
17
|
Classifier: Programming Language :: Python :: 3.13
|
18
|
+
Project-URL: Homepage, https://github.com/owasp-sbot/OSBot-Utils
|
19
19
|
Project-URL: Repository, https://github.com/owasp-sbot/OSBot-Utils
|
20
20
|
Description-Content-Type: text/markdown
|
21
21
|
|
@@ -23,7 +23,7 @@ Description-Content-Type: text/markdown
|
|
23
23
|
|
24
24
|
Powerful Python util methods and classes that simplify common apis and tasks.
|
25
25
|
|
26
|
-

|
27
27
|
[](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
|
-

|
6
6
|
[](https://codecov.io/gh/owasp-sbot/OSBot-Utils)
|
7
7
|
|
8
8
|
|
@@ -0,0 +1,37 @@
|
|
1
|
+
import time
|
2
|
+
|
3
|
+
from osbot_utils.type_safe.Type_Safe import Type_Safe
|
4
|
+
|
5
|
+
|
6
|
+
class capture_duration(Type_Safe):
|
7
|
+
action_name : str
|
8
|
+
duration : float
|
9
|
+
start_time : float
|
10
|
+
end_time : float
|
11
|
+
seconds : float
|
12
|
+
precision : int = 3 # Default rounding to 3 decimal places
|
13
|
+
|
14
|
+
|
15
|
+
def __enter__(self):
|
16
|
+
self.start_time = time.perf_counter() # Start the performance counter
|
17
|
+
return self
|
18
|
+
|
19
|
+
def __exit__(self, exc_type, exc_val, exc_tb):
|
20
|
+
self.end_time = time.perf_counter() # End the performance counter
|
21
|
+
self.duration = self.end_time - self.start_time
|
22
|
+
self.seconds = round(self.duration, self.precision) # Use configurable precision
|
23
|
+
return False # Ensures that exceptions are rethrown
|
24
|
+
|
25
|
+
def data(self):
|
26
|
+
return {
|
27
|
+
"start": self.start_time,
|
28
|
+
"end": self.end_time,
|
29
|
+
"seconds": self.seconds,
|
30
|
+
}
|
31
|
+
|
32
|
+
def print(self):
|
33
|
+
print()
|
34
|
+
if self.action_name:
|
35
|
+
print(f'action "{self.action_name}" took: {self.seconds} seconds')
|
36
|
+
else:
|
37
|
+
print(f'action took: {self.seconds} seconds')
|
@@ -1,8 +1,7 @@
|
|
1
1
|
import linecache
|
2
2
|
import sys
|
3
3
|
import threading
|
4
|
-
from functools
|
5
|
-
|
4
|
+
from functools import wraps
|
6
5
|
from osbot_utils.base_classes.Kwargs_To_Self import Kwargs_To_Self
|
7
6
|
from osbot_utils.helpers.trace.Trace_Call__Config import Trace_Call__Config, PRINT_MAX_STRING_LENGTH
|
8
7
|
from osbot_utils.helpers.trace.Trace_Call__Handler import Trace_Call__Handler
|
@@ -8,29 +8,29 @@ from osbot_utils.helpers.trace.Trace_Call__Stack_Node import Trace_Call__Stack
|
|
8
8
|
from osbot_utils.helpers.trace.Trace_Call__Stats import Trace_Call__Stats
|
9
9
|
|
10
10
|
DEFAULT_ROOT_NODE_NODE_TITLE = 'Trace Session'
|
11
|
-
GLOBAL_FUNCTIONS_TO_IGNORE = ['value_type_matches_obj_annotation_for_attr' , # these are type safety functions which introduce quite a lot of noise in the traces (and unless one is debugging type safety, they will not be needed)
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
'<module>']
|
11
|
+
# GLOBAL_FUNCTIONS_TO_IGNORE = ['value_type_matches_obj_annotation_for_attr' , # these are type safety functions which introduce quite a lot of noise in the traces (and unless one is debugging type safety, they will not be needed)
|
12
|
+
# 'value_type_matches_obj_annotation_for_union_and_annotated' , # todo: map out and document why exactly these methods are ignore (and what is the side effect)
|
13
|
+
# 'are_types_compatible_for_assigment' ,
|
14
|
+
# 'obj_attribute_annotation' ,
|
15
|
+
# 'all_annotations' ,
|
16
|
+
# 'get_origin' ,
|
17
|
+
# 'getmro' ,
|
18
|
+
# 'default_value' ,
|
19
|
+
# '__cls_kwargs__' ,
|
20
|
+
# '__default__value__' ,
|
21
|
+
# '__setattr__' ,
|
22
|
+
# '<module>']
|
24
23
|
GLOBAL_MODULES_TO_IGNORE = ['osbot_utils.helpers.trace.Trace_Call' , # todo: map out and document why exactly these modules are ignore (and what is the side effect)
|
25
24
|
'osbot_utils.helpers.trace.Trace_Call__Config' ,
|
26
25
|
'osbot_utils.helpers.trace.Trace_Call__View_Model' ,
|
27
26
|
'osbot_utils.helpers.trace.Trace_Call__Print_Traces' ,
|
28
27
|
'osbot_utils.helpers.trace.Trace_Call__Stack' ,
|
29
|
-
|
28
|
+
# 'osbot_utils.base_classes.Type_Safe' ,
|
30
29
|
'osbot_utils.helpers.CPrint' , # also see if this should be done here or at the print/view stage
|
31
30
|
'osbot_utils.helpers.Print_Table' ,
|
32
31
|
'osbot_utils.decorators.methods.cache_on_self' ,
|
33
32
|
'codecs' ]
|
33
|
+
GLOBAL_FUNCTIONS_TO_IGNORE = []
|
34
34
|
|
35
35
|
#GLOBAL_MODULES_TO_IGNORE = []
|
36
36
|
#GLOBAL_FUNCTIONS_TO_IGNORE = []
|
@@ -1,7 +1,7 @@
|
|
1
1
|
from typing import Optional
|
2
2
|
from xml.etree.ElementTree import Element, SubElement, tostring
|
3
3
|
from xml.dom import minidom
|
4
|
-
from osbot_utils.type_safe.Type_Safe
|
4
|
+
from osbot_utils.type_safe.Type_Safe import Type_Safe
|
5
5
|
from osbot_utils.helpers.xml.Xml__Element import XML__Element
|
6
6
|
from osbot_utils.helpers.xml.Xml__File import Xml__File
|
7
7
|
|
@@ -0,0 +1,108 @@
|
|
1
|
+
import time
|
2
|
+
from typing import Callable, List
|
3
|
+
from statistics import mean, median, stdev
|
4
|
+
from osbot_utils.utils.Env import in_github_action
|
5
|
+
from osbot_utils.testing.performance.models.Model__Performance_Measure__Measurement import Model__Performance_Measure__Measurement
|
6
|
+
from osbot_utils.testing.performance.models.Model__Performance_Measure__Result import Model__Performance_Measure__Result
|
7
|
+
from osbot_utils.type_safe.Type_Safe import Type_Safe
|
8
|
+
|
9
|
+
MEASURE__INVOCATION__LOOPS = [1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610] # Fibonacci sequence for measurement loops
|
10
|
+
|
11
|
+
class Performance_Measure__Session(Type_Safe):
|
12
|
+
result : Model__Performance_Measure__Result = None # Current measurement result
|
13
|
+
assert_enabled: bool = True
|
14
|
+
|
15
|
+
def calculate_raw_score(self, times: List[int]) -> int: # Calculate raw performance score
|
16
|
+
if len(times) < 3: # Need at least 3 values for stability
|
17
|
+
return mean(times)
|
18
|
+
|
19
|
+
sorted_times = sorted(times) # Sort times for analysis
|
20
|
+
trim_size = max(1, len(times) // 10) # Remove ~10% from each end
|
21
|
+
|
22
|
+
trimmed = sorted_times[trim_size:-trim_size] # Remove outliers
|
23
|
+
med = median(trimmed) # Get median of trimmed data
|
24
|
+
trimmed_mean = mean (trimmed) # Get mean of trimmed data
|
25
|
+
|
26
|
+
raw_score = int(med * 0.6 + trimmed_mean * 0.4) # Weighted combination favoring median
|
27
|
+
return raw_score
|
28
|
+
|
29
|
+
def calculate_stable_score(self, raw_score: float) -> int: # Calculate stable performance score
|
30
|
+
if raw_score < 1_000: # Dynamic normalization based on score magnitude
|
31
|
+
return int(round(raw_score / 100) * 100) # Under 1µs: nearest 100ns
|
32
|
+
elif raw_score < 10_000:
|
33
|
+
return int(round(raw_score / 1000) * 1000) # Under 10µs: nearest 500ns
|
34
|
+
elif raw_score < 100_000:
|
35
|
+
return int(round(raw_score / 10000) * 10000) # Under 100µs: nearest 1000ns
|
36
|
+
else:
|
37
|
+
return int(round(raw_score / 100000) * 100000) # Above 100µs: nearest 5000ns
|
38
|
+
|
39
|
+
def calculate_metrics(self, times: List[int]) -> Model__Performance_Measure__Measurement: # Calculate statistical metrics
|
40
|
+
if not times:
|
41
|
+
raise ValueError("Cannot calculate metrics from empty time list")
|
42
|
+
raw_score = self.calculate_raw_score (times)
|
43
|
+
score = self.calculate_stable_score(raw_score)
|
44
|
+
return Model__Performance_Measure__Measurement(
|
45
|
+
avg_time = int(mean(times)) ,
|
46
|
+
min_time = min(times) ,
|
47
|
+
max_time = max(times) ,
|
48
|
+
median_time = int(median(times)) ,
|
49
|
+
stddev_time = stdev(times) if len(times) > 1 else 0 ,
|
50
|
+
raw_times = times ,
|
51
|
+
sample_size = len(times) ,
|
52
|
+
raw_score = raw_score ,
|
53
|
+
score = score )
|
54
|
+
|
55
|
+
def measure(self, target: Callable) -> 'Performance_Measure__Session': # Perform measurements
|
56
|
+
name = target.__name__
|
57
|
+
measurements = {}
|
58
|
+
all_times = [] # Collect all times for final score
|
59
|
+
|
60
|
+
for loop_size in MEASURE__INVOCATION__LOOPS: # Measure each loop size
|
61
|
+
loop_times = []
|
62
|
+
for i in range(loop_size):
|
63
|
+
start = time.perf_counter_ns()
|
64
|
+
target()
|
65
|
+
end = time.perf_counter_ns()
|
66
|
+
time_taken = end - start
|
67
|
+
loop_times.append(time_taken)
|
68
|
+
all_times.append(time_taken) # Add to overall collection
|
69
|
+
|
70
|
+
measurements[loop_size] = self.calculate_metrics(loop_times) # Store metrics for this loop size
|
71
|
+
|
72
|
+
raw_score = self.calculate_raw_score (all_times)
|
73
|
+
final_score = self.calculate_stable_score(raw_score) # Calculate final stable score
|
74
|
+
|
75
|
+
self.result = Model__Performance_Measure__Result(
|
76
|
+
measurements = measurements ,
|
77
|
+
name = name ,
|
78
|
+
raw_score = raw_score ,
|
79
|
+
final_score = final_score )
|
80
|
+
|
81
|
+
return self
|
82
|
+
|
83
|
+
def print_measurement(self, measurement: Model__Performance_Measure__Measurement): # Format measurement details
|
84
|
+
print(f"Samples : {measurement.sample_size}")
|
85
|
+
print(f"Score : {measurement.score:,.0f}ns")
|
86
|
+
print(f"Avg : {measurement.avg_time:,}ns")
|
87
|
+
print(f"Min : {measurement.min_time:,}ns")
|
88
|
+
print(f"Max : {measurement.max_time:,}ns")
|
89
|
+
print(f"Median : {measurement.median_time:,}ns")
|
90
|
+
print(f"StdDev : {measurement.stddev_time:,.2f}ns")
|
91
|
+
|
92
|
+
def print(self, padding=12 ): # Print measurement results
|
93
|
+
if not self.result:
|
94
|
+
print("No measurements taken yet")
|
95
|
+
return
|
96
|
+
print(f"{self.result.name:{padding}} | score: {self.result.final_score:7,d} ns | raw: {self.result.raw_score:7,d} ns") # Print name and normalized score
|
97
|
+
|
98
|
+
return self
|
99
|
+
|
100
|
+
def assert_time(self, *expected_time: int): # Assert that the final score matches the expected normalized time"""
|
101
|
+
if self.assert_enabled is False:
|
102
|
+
return
|
103
|
+
if in_github_action():
|
104
|
+
last_expected_time = expected_time[-1] + 100 # +100 in case it is 0
|
105
|
+
new_expected_time = last_expected_time * 5 # using last_expected_time * 5 as the upper limit (since these tests are significantly slowed in GitHUb Actions)
|
106
|
+
assert last_expected_time <= self.result.final_score <= new_expected_time, f"Performance changed for {self.result.name}: expected {last_expected_time} < {self.result.final_score:,d}ns, expected {new_expected_time}"
|
107
|
+
else:
|
108
|
+
assert self.result.final_score in expected_time, f"Performance changed for {self.result.name}: got {self.result.final_score:,d}ns, expected {expected_time}"
|
osbot_utils-2.12.0/osbot_utils/testing/performance/models/Model__Performance_Measure__Measurement.py
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
from typing import List
|
2
|
+
from osbot_utils.type_safe.Type_Safe import Type_Safe
|
3
|
+
|
4
|
+
|
5
|
+
class Model__Performance_Measure__Measurement(Type_Safe): # Pure data container for measurement metrics
|
6
|
+
avg_time : int # Average time in nanoseconds
|
7
|
+
min_time : int # Minimum time observed
|
8
|
+
max_time : int # Maximum time observed
|
9
|
+
median_time : int # Median time
|
10
|
+
stddev_time : float # Standard deviation
|
11
|
+
raw_times : List[int] # Raw measurements for analysis
|
12
|
+
sample_size : int # Number of measurements taken
|
13
|
+
score : float
|
14
|
+
raw_score : float
|
osbot_utils-2.12.0/osbot_utils/testing/performance/models/Model__Performance_Measure__Result.py
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
from typing import Dict
|
2
|
+
from osbot_utils.testing.performance.models.Model__Performance_Measure__Measurement import Model__Performance_Measure__Measurement
|
3
|
+
from osbot_utils.type_safe.Type_Safe import Type_Safe
|
4
|
+
|
5
|
+
class Model__Performance_Measure__Result(Type_Safe): # Pure data container for measurement results
|
6
|
+
measurements : Dict[int, Model__Performance_Measure__Measurement] # Results per loop size
|
7
|
+
name : str # Name of measured target
|
8
|
+
raw_score : float
|
9
|
+
final_score : float
|
10
|
+
|
@@ -0,0 +1,109 @@
|
|
1
|
+
# todo: find a way to add these documentations strings to a separate location so that
|
2
|
+
# the data is available in IDE's code complete
|
3
|
+
from osbot_utils.type_safe.shared.Type_Safe__Validation import type_safe_validation
|
4
|
+
from osbot_utils.type_safe.steps.Type_Safe__Step__Class_Kwargs import type_safe_step_class_kwargs
|
5
|
+
from osbot_utils.type_safe.steps.Type_Safe__Step__Default_Kwargs import type_safe_step_default_kwargs
|
6
|
+
from osbot_utils.type_safe.steps.Type_Safe__Step__Default_Value import type_safe_step_default_value
|
7
|
+
from osbot_utils.type_safe.steps.Type_Safe__Step__Init import type_safe_step_init
|
8
|
+
from osbot_utils.type_safe.steps.Type_Safe__Step__Set_Attr import type_safe_step_set_attr
|
9
|
+
from osbot_utils.utils.Objects import serialize_to_dict
|
10
|
+
|
11
|
+
class Type_Safe:
|
12
|
+
|
13
|
+
def __init__(self, **kwargs):
|
14
|
+
|
15
|
+
class_kwargs = self.__cls_kwargs__()
|
16
|
+
type_safe_step_init.init(self, class_kwargs, **kwargs)
|
17
|
+
|
18
|
+
|
19
|
+
def __enter__(self): return self
|
20
|
+
def __exit__(self, exc_type, exc_val, exc_tb): pass
|
21
|
+
|
22
|
+
def __setattr__(self, name, value):
|
23
|
+
type_safe_step_set_attr.setattr(super(), self, name, value)
|
24
|
+
|
25
|
+
def __attr_names__(self):
|
26
|
+
from osbot_utils.utils.Misc import list_set
|
27
|
+
|
28
|
+
return list_set(self.__locals__())
|
29
|
+
|
30
|
+
@classmethod
|
31
|
+
def __cls_kwargs__(cls): # Return current class dictionary of class level variables and their values
|
32
|
+
return type_safe_step_class_kwargs.get_cls_kwargs(cls)
|
33
|
+
|
34
|
+
@classmethod
|
35
|
+
def __default__value__(cls, var_type):
|
36
|
+
return type_safe_step_default_value.default_value(cls, var_type)
|
37
|
+
|
38
|
+
def __default_kwargs__(self): # Return entire (including base classes) dictionary of class level variables and their values.
|
39
|
+
return type_safe_step_default_kwargs.default_kwargs(self)
|
40
|
+
|
41
|
+
def __kwargs__(self): # Return a dictionary of the current instance's attribute values including inherited class defaults.
|
42
|
+
return type_safe_step_default_kwargs.kwargs(self)
|
43
|
+
|
44
|
+
|
45
|
+
def __locals__(self): # Return a dictionary of the current instance's attribute values.
|
46
|
+
return type_safe_step_default_kwargs.locals(self)
|
47
|
+
|
48
|
+
# global methods added to any class that base classes this
|
49
|
+
# todo: see if there should be a prefix on these methods, to make it easier to spot them
|
50
|
+
# of if these are actually that useful that they should be added like this
|
51
|
+
# todo: these methods should not be here
|
52
|
+
# def bytes(self):
|
53
|
+
# from osbot_utils.utils.Json import json_to_bytes
|
54
|
+
#
|
55
|
+
# return json_to_bytes(self.json())
|
56
|
+
#
|
57
|
+
# def bytes_gz(self):
|
58
|
+
# from osbot_utils.utils.Json import json_to_gz
|
59
|
+
#
|
60
|
+
# return json_to_gz(self.json())
|
61
|
+
|
62
|
+
def json(self):
|
63
|
+
return self.serialize_to_dict()
|
64
|
+
|
65
|
+
# todo: see if we still need this. now that Type_Safe handles base types, there should be no need for this
|
66
|
+
def merge_with(self, target):
|
67
|
+
original_attrs = {k: v for k, v in self.__dict__.items() if k not in target.__dict__} # Store the original attributes of self that should be retained.
|
68
|
+
self.__dict__ = target.__dict__ # Set the target's __dict__ to self, now self and target share the same __dict__.
|
69
|
+
self.__dict__.update(original_attrs) # Reassign the original attributes back to self.
|
70
|
+
return self
|
71
|
+
|
72
|
+
# def locked(self, value=True): # todo: figure out best way to do this (maybe???)
|
73
|
+
# self.__lock_attributes__ = value # : update, with the latest changes were we don't show internals on __locals__() this might be a good way to do this
|
74
|
+
# return self
|
75
|
+
|
76
|
+
def reset(self):
|
77
|
+
for k,v in self.__cls_kwargs__().items():
|
78
|
+
setattr(self, k, v)
|
79
|
+
|
80
|
+
# todo: see if we still need this here in this class
|
81
|
+
def update_from_kwargs(self, **kwargs): # Update instance attributes with values from provided keyword arguments.
|
82
|
+
|
83
|
+
for key, value in kwargs.items():
|
84
|
+
if value is not None:
|
85
|
+
if hasattr(self,'__annotations__'): # can only do type safety checks if the class does not have annotations
|
86
|
+
if type_safe_validation.check_if__type_matches__obj_annotation__for_attr(self, key, value) is False:
|
87
|
+
raise ValueError(f"Invalid type for attribute '{key}'. Expected '{self.__annotations__.get(key)}' but got '{type(value)}'")
|
88
|
+
setattr(self, key, value)
|
89
|
+
return self
|
90
|
+
|
91
|
+
def obj(self):
|
92
|
+
from osbot_utils.utils.Objects import dict_to_obj
|
93
|
+
|
94
|
+
return dict_to_obj(self.json())
|
95
|
+
|
96
|
+
def serialize_to_dict(self): # todo: see if we need this method or if the .json() is enough
|
97
|
+
return serialize_to_dict(self)
|
98
|
+
|
99
|
+
def print(self):
|
100
|
+
from osbot_utils.utils.Dev import pprint
|
101
|
+
|
102
|
+
pprint(serialize_to_dict(self))
|
103
|
+
|
104
|
+
@classmethod
|
105
|
+
def from_json(cls, json_data, raise_on_not_found=False):
|
106
|
+
from osbot_utils.type_safe.steps.Type_Safe__Step__From_Json import type_safe_step_from_json # circular dependency on Type_Safe
|
107
|
+
return type_safe_step_from_json.from_json(cls, json_data, raise_on_not_found)
|
108
|
+
|
109
|
+
|
@@ -1,4 +1,6 @@
|
|
1
|
-
from typing import
|
1
|
+
from typing import get_args, Union, Optional, Any, ForwardRef
|
2
|
+
|
3
|
+
from osbot_utils.type_safe.shared.Type_Safe__Cache import type_safe_cache
|
2
4
|
|
3
5
|
EXACT_TYPE_MATCH = (int, float, str, bytes, bool, complex)
|
4
6
|
|
@@ -8,7 +10,7 @@ class Type_Safe__Base:
|
|
8
10
|
return True
|
9
11
|
if isinstance(expected_type, ForwardRef): # todo: add support for ForwardRef
|
10
12
|
return True
|
11
|
-
origin = get_origin(expected_type)
|
13
|
+
origin = type_safe_cache.get_origin(expected_type)
|
12
14
|
args = get_args(expected_type)
|
13
15
|
if origin is None:
|
14
16
|
if expected_type in EXACT_TYPE_MATCH:
|
@@ -85,12 +87,12 @@ class Type_Safe__Base:
|
|
85
87
|
actual_type_name = type_str(type(item))
|
86
88
|
raise TypeError(f"Expected '{expected_type_name}', but got '{actual_type_name}'")
|
87
89
|
|
88
|
-
def json(self):
|
89
|
-
|
90
|
+
# def json(self):
|
91
|
+
# pass
|
90
92
|
|
91
93
|
# todo: see if we should/can move this to the Objects.py file
|
92
94
|
def type_str(tp):
|
93
|
-
origin = get_origin(tp)
|
95
|
+
origin = type_safe_cache.get_origin(tp)
|
94
96
|
if origin is None:
|
95
97
|
if hasattr(tp, '__name__'):
|
96
98
|
return tp.__name__
|
@@ -99,22 +101,4 @@ def type_str(tp):
|
|
99
101
|
else:
|
100
102
|
args = get_args(tp)
|
101
103
|
args_str = ', '.join(type_str(arg) for arg in args)
|
102
|
-
return f"{origin.__name__}[{args_str}]"
|
103
|
-
|
104
|
-
def get_object_type_str(obj):
|
105
|
-
if isinstance(obj, dict):
|
106
|
-
if not obj:
|
107
|
-
return "Dict[Empty]"
|
108
|
-
key_types = set(type(k).__name__ for k in obj.keys())
|
109
|
-
value_types = set(type(v).__name__ for v in obj.values())
|
110
|
-
key_type_str = ', '.join(sorted(key_types))
|
111
|
-
value_type_str = ', '.join(sorted(value_types))
|
112
|
-
return f"Dict[{key_type_str}, {value_type_str}]"
|
113
|
-
elif isinstance(obj, list):
|
114
|
-
if not obj:
|
115
|
-
return "List[Empty]"
|
116
|
-
elem_types = set(type(e).__name__ for e in obj)
|
117
|
-
elem_type_str = ', '.join(sorted(elem_types))
|
118
|
-
return f"List[{elem_type_str}]"
|
119
|
-
else:
|
120
|
-
return type(obj).__name__
|
104
|
+
return f"{origin.__name__}[{args_str}]"
|
@@ -1,4 +1,4 @@
|
|
1
|
-
from osbot_utils.type_safe.Type_Safe__Base import
|
1
|
+
from osbot_utils.type_safe.Type_Safe__Base import Type_Safe__Base
|
2
2
|
|
3
3
|
class Type_Safe__Dict(Type_Safe__Base, dict):
|
4
4
|
def __init__(self, expected_key_type, expected_value_type, *args, **kwargs):
|
@@ -7,19 +7,20 @@ class Type_Safe__Dict(Type_Safe__Base, dict):
|
|
7
7
|
self.expected_key_type = expected_key_type
|
8
8
|
self.expected_value_type = expected_value_type
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
|
10
|
+
# todo: see if we need to do this, since there was not code coverage hitting it
|
11
|
+
# for k, v in self.items(): # check type-safety of ctor arguments
|
12
|
+
# self.is_instance_of_type(k, self.expected_key_type )
|
13
|
+
# self.is_instance_of_type(v, self.expected_value_type)
|
13
14
|
|
14
15
|
def __setitem__(self, key, value): # Check type-safety before allowing assignment.
|
15
16
|
self.is_instance_of_type(key, self.expected_key_type)
|
16
17
|
self.is_instance_of_type(value, self.expected_value_type)
|
17
18
|
super().__setitem__(key, value)
|
18
19
|
|
19
|
-
def __repr__(self):
|
20
|
-
|
21
|
-
|
22
|
-
|
20
|
+
# def __repr__(self):
|
21
|
+
# key_type_name = type_str(self.expected_key_type)
|
22
|
+
# value_type_name = type_str(self.expected_value_type)
|
23
|
+
# return f"dict[{key_type_name}, {value_type_name}] with {len(self)} entries"
|
23
24
|
|
24
25
|
def json(self): # Convert the dictionary to a JSON-serializable format.
|
25
26
|
from osbot_utils.type_safe.Type_Safe import Type_Safe # can only import this here to avoid circular imports
|
{osbot_utils-2.10.0 → osbot_utils-2.12.0}/osbot_utils/type_safe/methods/type_safe_property.py
RENAMED
@@ -2,7 +2,7 @@ from typing import TypeVar, Type, Optional
|
|
2
2
|
|
3
3
|
T = TypeVar('T')
|
4
4
|
|
5
|
-
def type_safe_property(target_path: str, target_name: str, expected_type: Optional[Type[T]] = None) ->
|
5
|
+
def type_safe_property(target_path: str, target_name: str, expected_type: Optional[Type[T]] = None) -> T: # Creates a type-safe property that delegates get/set operations to a nested data object
|
6
6
|
|
7
7
|
def getter(self) -> T:
|
8
8
|
target = self
|
@@ -0,0 +1,29 @@
|
|
1
|
+
from osbot_utils.type_safe.shared.Type_Safe__Cache import type_safe_cache
|
2
|
+
|
3
|
+
|
4
|
+
class Type_Safe__Annotations:
|
5
|
+
|
6
|
+
def all_annotations(self, target):
|
7
|
+
return type_safe_cache.get_obj_annotations(target) # use cache
|
8
|
+
|
9
|
+
def all_annotations__in_class(self, cls):
|
10
|
+
return type_safe_cache.get_class_annotations(cls)
|
11
|
+
|
12
|
+
def obj_attribute_annotation(self, target, attr_name):
|
13
|
+
return self.all_annotations(target).get(attr_name) # use cache
|
14
|
+
|
15
|
+
def obj_is_attribute_annotation_of_type(self, target, attr_name, expected_type):
|
16
|
+
attribute_annotation = self.obj_attribute_annotation(target, attr_name)
|
17
|
+
if expected_type is attribute_annotation:
|
18
|
+
return True
|
19
|
+
if expected_type is type(attribute_annotation):
|
20
|
+
return True
|
21
|
+
if expected_type is type_safe_cache.get_origin(attribute_annotation): # handle genericAlias
|
22
|
+
return True
|
23
|
+
return False
|
24
|
+
|
25
|
+
def get_origin(self, var_type):
|
26
|
+
return type_safe_cache.get_origin(var_type)
|
27
|
+
|
28
|
+
type_safe_annotations = Type_Safe__Annotations()
|
29
|
+
|