danielutils 1.1.2__tar.gz → 1.1.22__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.
- {danielutils-1.1.2/danielutils.egg-info → danielutils-1.1.22}/PKG-INFO +2 -2
- {danielutils-1.1.2 → danielutils-1.1.22}/README.md +1 -1
- danielutils-1.1.22/danielutils/reflection/info_classes/argument_info.py +278 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/reflection/info_classes/class_info.py +12 -3
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/reflection/info_classes/decorator_info.py +11 -2
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/reflection/info_classes/function_info.py +15 -2
- danielutils-1.1.22/danielutils/tools/__init__.py +1 -0
- danielutils-1.1.22/danielutils/tools/unittest_test_runner/__init__.py +9 -0
- danielutils-1.1.22/danielutils/tools/unittest_test_runner/cli.py +70 -0
- danielutils-1.1.22/danielutils/tools/unittest_test_runner/core/__init__.py +17 -0
- danielutils-1.1.22/danielutils/tools/unittest_test_runner/core/discovery.py +322 -0
- danielutils-1.1.22/danielutils/tools/unittest_test_runner/core/execution.py +244 -0
- danielutils-1.1.22/danielutils/tools/unittest_test_runner/core/parser.py +163 -0
- danielutils-1.1.22/danielutils/tools/unittest_test_runner/core/runner.py +561 -0
- danielutils-1.1.22/danielutils/tools/unittest_test_runner/models.py +82 -0
- {danielutils-1.1.2 → danielutils-1.1.22/danielutils.egg-info}/PKG-INFO +2 -2
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils.egg-info/SOURCES.txt +9 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/pyproject.toml +1 -1
- danielutils-1.1.2/danielutils/reflection/info_classes/argument_info.py +0 -124
- {danielutils-1.1.2 → danielutils-1.1.22}/LICENSE +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/MANIFEST.in +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/__init__.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/abstractions/__init__.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/abstractions/db/__init__.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/abstractions/db/database.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/abstractions/db/database_definitions.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/abstractions/db/database_exceptions.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/abstractions/db/database_factory.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/abstractions/db/database_initializer.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/abstractions/db/database_models.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/abstractions/db/dependencies.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/abstractions/db/implementations/__init__.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/abstractions/db/implementations/in_memory_database.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/abstractions/db/implementations/persistent_in_memory_database.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/abstractions/db/implementations/redis_database.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/abstractions/db/implementations/sqlite_database.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/abstractions/multiprogramming/__init__.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/abstractions/multiprogramming/multi_id.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/abstractions/multiprogramming/worker.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/abstractions/multiprogramming/worker_pool.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/abstractions/repl.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/aliases.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/async_/__init__.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/async_/async_cmd.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/async_/async_command.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/async_/async_layered_command.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/async_/async_retry_executor.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/async_/async_worker_pool.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/async_/time_strategy.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/async_/utils.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/better_builtins/__init__.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/better_builtins/counter.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/better_builtins/frange.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/better_builtins/typed_builtins/__init__.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/better_builtins/typed_builtins/factory.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/better_builtins/typed_builtins/tdict.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/better_builtins/typed_builtins/tlist.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/better_builtins/typed_builtins/tset.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/better_builtins/typed_builtins/ttuple.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/colors.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/context_managers/__init__.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/context_managers/attr_context.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/context_managers/multi_context.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/context_managers/optional_context.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/context_managers/state_context.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/context_managers/temporary_file.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/convenience.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/conversions/__init__.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/conversions/main_conversions.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/conversions/specialized_conversions/__init__.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/conversions/specialized_conversions/to_hex.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/conversions/specialized_conversions/to_int.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/custom_types.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/data_structures/__init__.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/data_structures/algorithms.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/data_structures/comparer.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/data_structures/default_dict.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/data_structures/functions.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/data_structures/graph/__init__.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/data_structures/graph/binary_node.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/data_structures/graph/graph.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/data_structures/graph/multinode.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/data_structures/graph/node.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/data_structures/heap/__init__.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/data_structures/heap/heap.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/data_structures/heap/max_heap.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/data_structures/heap/min_heap.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/data_structures/queue/__init__.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/data_structures/queue/atomic_queue.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/data_structures/queue/priority_queue.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/data_structures/queue/queue.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/data_structures/stack.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/data_structures/trees/__init__.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/data_structures/trees/binary_syntax_tree.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/data_structures/trees/binary_tree.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/date.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/date_time.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/decorators/__init__.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/decorators/atomic.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/decorators/attach.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/decorators/chain_decorators.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/decorators/decorate_conditionally.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/decorators/delay_call.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/decorators/deprecate.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/decorators/final.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/decorators/limit_recursion.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/decorators/memo.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/decorators/normalize_decorator.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/decorators/overload.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/decorators/partially_implemented.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/decorators/processify.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/decorators/property.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/decorators/singleton.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/decorators/threadify.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/decorators/timeout.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/decorators/total_ordering.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/decorators/validate.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/exceptions.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/functions/__init__.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/functions/areoneof.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/functions/check_foreach.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/functions/factorial.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/functions/flatten.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/functions/foreach.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/functions/isoftype.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/functions/isoneof.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/functions/multiloop.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/functions/parallel_for.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/functions/partition.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/functions/powerset.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/functions/subseteq.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/functions/types_subseteq.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/generators/__init__.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/generators/conditional_generator.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/generators/generator_from_stream.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/generators/join_generators.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/internet.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/io_.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/java/__init__.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/java/interfaces/__init__.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/java/interfaces/comparable.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/java/java_interface.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/logging_/__init__.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/logging_/_impl/__init__.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/logging_/_impl/builtin_impls/__init__.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/logging_/_impl/builtin_impls/file_logger.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/logging_/_impl/builtin_impls/print_logger.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/logging_/_impl/log_level.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/logging_/_impl/logger.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/logging_/_impl/logger_strategy_impl_base.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/logging_/utils.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/lombok/__init__.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/lombok/builder.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/math_/__init__.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/math_/constants.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/math_/functions.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/math_/math_print.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/math_/math_symbols.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/metaclasses/__init__.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/metaclasses/atomic_class_meta.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/metaclasses/implicit_data_deleter_meta.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/metaclasses/instance_cache_meta.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/metaclasses/interface.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/metaclasses/overload_meta.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/mock_/__init__.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/mock_/mock_module.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/path.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/print_.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/progress_bar/__init__.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/progress_bar/ascii_progress_bar.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/progress_bar/progress_bar.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/progress_bar/progress_bar_pool.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/protocols/__init__.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/protocols/dictable.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/protocols/evaluable.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/protocols/serializable.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/py.typed +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/random_.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/reflection/__init__.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/reflection/file/__init__.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/reflection/file/file_reflection.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/reflection/function/__init__.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/reflection/function/function_reflections.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/reflection/info_classes/__init__.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/reflection/info_classes/file_info.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/reflection/info_classes/folder_info.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/reflection/info_classes/import_info.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/reflection/interpreter/__init__.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/reflection/interpreter/callstack.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/reflection/interpreter/get_traceback.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/reflection/interpreter/interpreter.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/reflection/interpreter/is_debugging.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/reflection/interpreter/os_.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/reflection/interpreter/packages.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/reflection/interpreter/python_version.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/reflection/interpreter/signals.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/reflection/interpreter/tracer.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/reflection/module/__init__.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/reflection/module/lazy_module.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/reflection/module/module_reflections.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/reflection/module/package_reflection.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/retry_executor/__init__.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/retry_executor/backoff_strategies/__init__.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/retry_executor/backoff_strategies/constant_backoff.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/retry_executor/backoff_strategies/exponential_backoff.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/retry_executor/backoff_strategies/functional_backoff.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/retry_executor/backoff_strategies/linear_backoff.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/retry_executor/backoff_strategies/multiplicative_backoff.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/retry_executor/backoff_strategies/no_backoff.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/retry_executor/backoff_strategy.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/retry_executor/retry_executor.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/snippets/__init__.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/snippets/try_get.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/system/__init__.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/system/independent.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/system/layered_command.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/system/windows/__init__.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/system/windows/utils/__init__.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/system/windows/utils/filetime.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/system/windows/win32_ctime.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/system/windows/windows.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/testing/__init__.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/testing/unittest_/__init__.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/testing/unittest_/always_teardown_testcase.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/testing/unittest_/auto_cwd_testcase.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/text.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/time.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/university/__init__.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/university/computability_and_complexity/__init__.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/university/computability_and_complexity/discreate_finite_automaton.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/university/computability_and_complexity/languages/__init__.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/university/computability_and_complexity/languages/language.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/university/computability_and_complexity/languages/sat.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/university/computability_and_complexity/turing_machine.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/university/databases/__init__.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/university/databases/all.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/university/image_proccesing/__init__.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/university/image_proccesing/encoding/__init__.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/university/image_proccesing/encoding/encoding.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/university/image_proccesing/encoding/lossless/__init__.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/university/image_proccesing/encoding/lossless/huffman.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/university/image_proccesing/encoding/lossless/lossless_encoding.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/university/image_proccesing/encoding/lossless/lzw.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/university/image_proccesing/encoding/lossless/run_length.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/university/image_proccesing/encoding/lossy/__init__.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/university/image_proccesing/encoding/lossy/lossy_encoding.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/university/image_proccesing/tansformations/__init__.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/university/image_proccesing/tansformations/gaussian.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/university/image_proccesing/tansformations/gradient.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/university/image_proccesing/tansformations/hough.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/university/image_proccesing/tansformations/laplacian.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/university/image_proccesing/tansformations/transformation.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/university/linear_algebra/__init__.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/university/linear_algebra/matrix.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/university/machine_learning/__init__.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/university/machine_learning/activation_functions/__init__.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/university/machine_learning/activation_functions/activation_function.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/university/machine_learning/activation_functions/relu.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/university/machine_learning/neuron.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/university/oop/__init__.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/university/oop/observer.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/university/oop/strategy.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/university/probability/__init__.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/university/probability/conditional_variable/__init__.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/university/probability/conditional_variable/conditional_variable.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/university/probability/conditional_variable/continuous/__init__.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/university/probability/conditional_variable/discrete/__init__.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/university/probability/conditional_variable/discrete/bernoulli.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/university/probability/conditional_variable/discrete/binomial.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/university/probability/conditional_variable/discrete/conditional_from_discrete_probability_func.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/university/probability/conditional_variable/discrete/discrete.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/university/probability/conditional_variable/discrete/geometric.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/university/probability/conditional_variable/discrete/poisson.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/university/probability/conditional_variable/discrete/uniform.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/university/probability/distributions.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/university/probability/expressions/__init__.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/university/probability/expressions/accumulation_expression.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/university/probability/expressions/probability_expression.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/university/probability/funcs/__init__.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/university/probability/funcs/covariance.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/university/probability/funcs/expected_value.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/university/probability/funcs/probability_function.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/university/probability/funcs/variance.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/university/probability/operator.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/university/probability/protocols.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/university/probability/supp.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/university/probability/transformation.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils/versioned_imports.py +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils.egg-info/dependency_links.txt +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/danielutils.egg-info/top_level.txt +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/setup.cfg +0 -0
- {danielutils-1.1.2 → danielutils-1.1.22}/setup.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: danielutils
|
|
3
|
-
Version: 1.1.
|
|
3
|
+
Version: 1.1.22
|
|
4
4
|
Summary: A python utils library for things I find useful
|
|
5
5
|
Author-email: danielnachumdev <danielnachumdev@gmail.com>
|
|
6
6
|
License: MIT License
|
|
@@ -41,7 +41,7 @@ Dynamic: license-file
|
|
|
41
41
|
[](https://github.com/danielnachumdev/danielutils/actions/workflows/gitleaks.yml)
|
|
42
42
|
[](https://github.com/danielnachumdev/danielutils/actions/workflows/github-code-scanning/codeql)
|
|
43
43
|
|
|
44
|
-
# danielutils v1.
|
|
44
|
+
# danielutils v1.1.21
|
|
45
45
|
|
|
46
46
|
A comprehensive Python utilities library designed to enhance your development workflow with powerful tools for type safety, async programming, database operations, and much more.
|
|
47
47
|
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
[](https://github.com/danielnachumdev/danielutils/actions/workflows/gitleaks.yml)
|
|
5
5
|
[](https://github.com/danielnachumdev/danielutils/actions/workflows/github-code-scanning/codeql)
|
|
6
6
|
|
|
7
|
-
# danielutils v1.
|
|
7
|
+
# danielutils v1.1.21
|
|
8
8
|
|
|
9
9
|
A comprehensive Python utilities library designed to enhance your development workflow with powerful tools for type safety, async programming, database operations, and much more.
|
|
10
10
|
|
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
import re
|
|
2
|
+
from dataclasses import dataclass
|
|
3
|
+
from typing import Optional, List
|
|
4
|
+
|
|
5
|
+
ARGUMENT_INFO_REGEX: re.Pattern = re.compile(
|
|
6
|
+
r"(?P<kwargs>\*\*\w[\w\d]*)|(?P<args>\*(?:\w[\w\d]*)?)|(?P<kwarg_only>\/)|(?P<pname>\w[\w\d]*)\[(?P<parameters>.+)\]|(?P<name>\w[\w\d]*)(?:(?:\s*:(?P<type>[^\=\n]+))?(?:\s*=(?P<default_value>[\s\S]+))?)?")
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class ArgumentInfo:
|
|
10
|
+
def __init__(
|
|
11
|
+
self,
|
|
12
|
+
name: Optional[str],
|
|
13
|
+
type: Optional[str],
|
|
14
|
+
default: Optional[str],
|
|
15
|
+
is_kwargs: bool,
|
|
16
|
+
is_args: bool,
|
|
17
|
+
is_kwargs_only: bool,
|
|
18
|
+
parameters: Optional[List]
|
|
19
|
+
) -> None:
|
|
20
|
+
self._name = name
|
|
21
|
+
self._type = type
|
|
22
|
+
self._default = default
|
|
23
|
+
self._is_kwargs = is_kwargs
|
|
24
|
+
self._is_args = is_args
|
|
25
|
+
self._is_kwargs_only = is_kwargs_only
|
|
26
|
+
self._parameters = parameters
|
|
27
|
+
|
|
28
|
+
@property
|
|
29
|
+
def name(self) -> Optional[str]:
|
|
30
|
+
return self._name
|
|
31
|
+
|
|
32
|
+
@property
|
|
33
|
+
def type(self) -> Optional[str]:
|
|
34
|
+
return self._type
|
|
35
|
+
|
|
36
|
+
@property
|
|
37
|
+
def default(self) -> Optional[str]:
|
|
38
|
+
return self._default
|
|
39
|
+
|
|
40
|
+
@property
|
|
41
|
+
def is_kwargs(self) -> bool:
|
|
42
|
+
return self._is_kwargs
|
|
43
|
+
|
|
44
|
+
@property
|
|
45
|
+
def is_args(self) -> bool:
|
|
46
|
+
return self._is_args
|
|
47
|
+
|
|
48
|
+
@property
|
|
49
|
+
def is_kwargs_only(self) -> bool:
|
|
50
|
+
return self._is_kwargs_only
|
|
51
|
+
|
|
52
|
+
@property
|
|
53
|
+
def parameters(self) -> Optional[List]:
|
|
54
|
+
return self._parameters
|
|
55
|
+
|
|
56
|
+
@property
|
|
57
|
+
def is_parameterized(self) -> bool:
|
|
58
|
+
return self._parameters is not None and len(self._parameters) > 0
|
|
59
|
+
|
|
60
|
+
def __repr__(self) -> str:
|
|
61
|
+
res = f"{self.__class__.__name__}(name=\"{self.name}\""
|
|
62
|
+
if self.type is not None:
|
|
63
|
+
res += f", type={self.type}"
|
|
64
|
+
if self.default is not None:
|
|
65
|
+
res += f", default={self.default}"
|
|
66
|
+
if self.is_parameterized:
|
|
67
|
+
res += f", parameters={self.parameters}"
|
|
68
|
+
return res + ")"
|
|
69
|
+
|
|
70
|
+
def __str__(self) -> str:
|
|
71
|
+
return repr(self)
|
|
72
|
+
|
|
73
|
+
@staticmethod
|
|
74
|
+
def _parse_one(string: str) -> 'ArgumentInfo':
|
|
75
|
+
string = string.strip()
|
|
76
|
+
|
|
77
|
+
# Handle string literals (decorator context)
|
|
78
|
+
if string.startswith('"') or string.startswith("'"):
|
|
79
|
+
# Extract the string literal (handling escaped quotes)
|
|
80
|
+
quote_char = string[0]
|
|
81
|
+
# Find the matching closing quote
|
|
82
|
+
i = 1
|
|
83
|
+
while i < len(string):
|
|
84
|
+
if string[i] == quote_char and (i == 0 or string[i-1] != '\\'):
|
|
85
|
+
# Found matching quote
|
|
86
|
+
literal_value = string[:i+1]
|
|
87
|
+
return ArgumentInfo(
|
|
88
|
+
name=None,
|
|
89
|
+
type=None,
|
|
90
|
+
default=literal_value,
|
|
91
|
+
is_kwargs=False,
|
|
92
|
+
is_args=False,
|
|
93
|
+
is_kwargs_only=False,
|
|
94
|
+
parameters=None
|
|
95
|
+
)
|
|
96
|
+
i += 1
|
|
97
|
+
# If no closing quote found, treat the whole string as the literal
|
|
98
|
+
return ArgumentInfo(
|
|
99
|
+
name=None,
|
|
100
|
+
type=None,
|
|
101
|
+
default=string,
|
|
102
|
+
is_kwargs=False,
|
|
103
|
+
is_args=False,
|
|
104
|
+
is_kwargs_only=False,
|
|
105
|
+
parameters=None
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
# Handle other literals (numbers, booleans, None, etc.) - check BEFORE regex
|
|
109
|
+
# In decorator context, these are always literals, not parameter definitions
|
|
110
|
+
if string:
|
|
111
|
+
# Check for numeric literal (starts with digit, possibly with decimal point or negative)
|
|
112
|
+
if string[0].isdigit() or (len(string) > 1 and string[0] == '-' and string[1].isdigit()):
|
|
113
|
+
return ArgumentInfo(
|
|
114
|
+
name=None,
|
|
115
|
+
type=None,
|
|
116
|
+
default=string,
|
|
117
|
+
is_kwargs=False,
|
|
118
|
+
is_args=False,
|
|
119
|
+
is_kwargs_only=False,
|
|
120
|
+
parameters=None
|
|
121
|
+
)
|
|
122
|
+
# Check for boolean or None literals
|
|
123
|
+
if string in ('True', 'False', 'None'):
|
|
124
|
+
return ArgumentInfo(
|
|
125
|
+
name=None,
|
|
126
|
+
type=None,
|
|
127
|
+
default=string,
|
|
128
|
+
is_kwargs=False,
|
|
129
|
+
is_args=False,
|
|
130
|
+
is_kwargs_only=False,
|
|
131
|
+
parameters=None
|
|
132
|
+
)
|
|
133
|
+
# Check for list/dict literals or function calls (starts with bracket, brace, or identifier followed by paren)
|
|
134
|
+
if string.startswith('[') or string.startswith('{') or string.startswith('('):
|
|
135
|
+
return ArgumentInfo(
|
|
136
|
+
name=None,
|
|
137
|
+
type=None,
|
|
138
|
+
default=string,
|
|
139
|
+
is_kwargs=False,
|
|
140
|
+
is_args=False,
|
|
141
|
+
is_kwargs_only=False,
|
|
142
|
+
parameters=None
|
|
143
|
+
)
|
|
144
|
+
# Check for function call pattern (identifier followed by opening paren)
|
|
145
|
+
# This handles cases like "some_function(1, 2)"
|
|
146
|
+
if '(' in string and not string.startswith('='):
|
|
147
|
+
# Check if it looks like a function call (has identifier before paren)
|
|
148
|
+
parts = string.split('(', 1)
|
|
149
|
+
if len(parts) == 2 and parts[0].strip() and (parts[0].strip()[0].isalpha() or parts[0].strip()[0] == '_'):
|
|
150
|
+
return ArgumentInfo(
|
|
151
|
+
name=None,
|
|
152
|
+
type=None,
|
|
153
|
+
default=string,
|
|
154
|
+
is_kwargs=False,
|
|
155
|
+
is_args=False,
|
|
156
|
+
is_kwargs_only=False,
|
|
157
|
+
parameters=None
|
|
158
|
+
)
|
|
159
|
+
|
|
160
|
+
# Try regex matching for normal argument patterns
|
|
161
|
+
m = ARGUMENT_INFO_REGEX.match(string)
|
|
162
|
+
if m is None:
|
|
163
|
+
raise ValueError(f"Invalid argument info string: {string}")
|
|
164
|
+
|
|
165
|
+
kwargs, args, kwarg_only, pname, parameters, name, type, default_value = m.groups()
|
|
166
|
+
type = None if type is None else type.strip()
|
|
167
|
+
default_value = None if default_value is None else default_value.strip()
|
|
168
|
+
|
|
169
|
+
return ArgumentInfo(
|
|
170
|
+
name=name or pname or (args.strip("*") if args else None) or (
|
|
171
|
+
kwargs.strip("*") if kwargs else None) or (kwarg_only if kwarg_only else None) or None,
|
|
172
|
+
type=type,
|
|
173
|
+
default=default_value,
|
|
174
|
+
is_kwargs=kwargs is not None,
|
|
175
|
+
is_args=args is not None,
|
|
176
|
+
is_kwargs_only=kwarg_only is not None,
|
|
177
|
+
parameters=[parameters]
|
|
178
|
+
)
|
|
179
|
+
|
|
180
|
+
@staticmethod
|
|
181
|
+
def _strip_comments(string: str) -> str:
|
|
182
|
+
"""Strip comments from string while preserving string literals."""
|
|
183
|
+
result = []
|
|
184
|
+
in_string = False
|
|
185
|
+
string_char = None
|
|
186
|
+
i = 0
|
|
187
|
+
while i < len(string):
|
|
188
|
+
c = string[i]
|
|
189
|
+
# Track string literals
|
|
190
|
+
if c in {'"', "'"} and (i == 0 or string[i-1] != '\\'):
|
|
191
|
+
if not in_string:
|
|
192
|
+
in_string = True
|
|
193
|
+
string_char = c
|
|
194
|
+
elif c == string_char:
|
|
195
|
+
in_string = False
|
|
196
|
+
string_char = None
|
|
197
|
+
result.append(c)
|
|
198
|
+
# Handle comments (only when not in string)
|
|
199
|
+
elif not in_string and c == '#':
|
|
200
|
+
# Skip everything from # to end of line (or end of string)
|
|
201
|
+
# Keep the newline if present to preserve line structure
|
|
202
|
+
while i < len(string) and string[i] != '\n':
|
|
203
|
+
i += 1
|
|
204
|
+
# Include the newline if we found one
|
|
205
|
+
if i < len(string) and string[i] == '\n':
|
|
206
|
+
result.append('\n')
|
|
207
|
+
i += 1
|
|
208
|
+
continue
|
|
209
|
+
else:
|
|
210
|
+
# End of string, break
|
|
211
|
+
break
|
|
212
|
+
else:
|
|
213
|
+
result.append(c)
|
|
214
|
+
i += 1
|
|
215
|
+
return ''.join(result)
|
|
216
|
+
|
|
217
|
+
@staticmethod
|
|
218
|
+
def from_str(string: str) -> List['ArgumentInfo']:
|
|
219
|
+
if string is None:
|
|
220
|
+
return []
|
|
221
|
+
string = string.strip()
|
|
222
|
+
if not string:
|
|
223
|
+
return []
|
|
224
|
+
# Strip comments before processing
|
|
225
|
+
string = ArgumentInfo._strip_comments(string).strip()
|
|
226
|
+
indices = [-1]
|
|
227
|
+
stack: List[str] = []
|
|
228
|
+
in_string = False
|
|
229
|
+
string_char = None
|
|
230
|
+
for i, c in enumerate(string):
|
|
231
|
+
# Track string literals
|
|
232
|
+
if c in {'"', "'"} and (i == 0 or string[i-1] != '\\'):
|
|
233
|
+
if not in_string:
|
|
234
|
+
in_string = True
|
|
235
|
+
string_char = c
|
|
236
|
+
elif c == string_char:
|
|
237
|
+
in_string = False
|
|
238
|
+
string_char = None
|
|
239
|
+
# Track brackets, braces, and parentheses only when not in string
|
|
240
|
+
elif not in_string:
|
|
241
|
+
if c in {'[', ']', '{', '}', '(', ')'}:
|
|
242
|
+
if c in {'[', '{', '('}:
|
|
243
|
+
stack.append(c)
|
|
244
|
+
else:
|
|
245
|
+
# Match closing brackets/braces/parens with opening ones
|
|
246
|
+
if stack:
|
|
247
|
+
opening = stack[-1]
|
|
248
|
+
if (c == ']' and opening == '[') or \
|
|
249
|
+
(c == '}' and opening == '{') or \
|
|
250
|
+
(c == ')' and opening == '('):
|
|
251
|
+
stack.pop()
|
|
252
|
+
elif len(stack) == 0:
|
|
253
|
+
if c == ",":
|
|
254
|
+
indices.append(i)
|
|
255
|
+
indices.append(len(string))
|
|
256
|
+
res = []
|
|
257
|
+
for idx, (start, end) in enumerate(zip(indices[:-1], indices[1:])):
|
|
258
|
+
substr = string[start + 1:end].strip()
|
|
259
|
+
# Skip standalone * (keyword-only separator)
|
|
260
|
+
if substr == "*":
|
|
261
|
+
continue
|
|
262
|
+
# Skip empty strings (from comment-only lines)
|
|
263
|
+
if not substr:
|
|
264
|
+
continue
|
|
265
|
+
try:
|
|
266
|
+
res.append(ArgumentInfo._parse_one(substr))
|
|
267
|
+
except ValueError as e:
|
|
268
|
+
raise ValueError(
|
|
269
|
+
f"Failed to parse argument {idx + 1}: {e}\n"
|
|
270
|
+
f"Argument string: {repr(substr)}\n"
|
|
271
|
+
f"Full arguments string: {repr(string)}"
|
|
272
|
+
) from e
|
|
273
|
+
return res
|
|
274
|
+
|
|
275
|
+
|
|
276
|
+
__all__ = [
|
|
277
|
+
"ArgumentInfo",
|
|
278
|
+
]
|
|
@@ -75,7 +75,13 @@ class ClassInfo:
|
|
|
75
75
|
decorators, name, bases, _ = m.groupdict().values()
|
|
76
76
|
logger.debug("Parsed class name: %s, bases: %s", name, bases)
|
|
77
77
|
self._name = name
|
|
78
|
-
|
|
78
|
+
try:
|
|
79
|
+
self._bases = ArgumentInfo.from_str(bases)
|
|
80
|
+
except ValueError as e:
|
|
81
|
+
raise ValueError(
|
|
82
|
+
f"Failed to parse base classes for class '{name}': {e}\n"
|
|
83
|
+
f"Bases string: {repr(bases)}"
|
|
84
|
+
) from e
|
|
79
85
|
logger.debug("Parsed %s base classes", len(self._bases))
|
|
80
86
|
self._parse_body()
|
|
81
87
|
|
|
@@ -87,8 +93,11 @@ class ClassInfo:
|
|
|
87
93
|
self._decorations.append(
|
|
88
94
|
DecoratorInfo.from_str(substr.strip()))
|
|
89
95
|
except ValueError as e:
|
|
90
|
-
|
|
91
|
-
"Failed to parse decorator '
|
|
96
|
+
error_msg = (
|
|
97
|
+
f"Failed to parse decorator for class '{name}': {e}\n"
|
|
98
|
+
f"Decorator string: {repr(substr.strip())}"
|
|
99
|
+
)
|
|
100
|
+
logger.warning(error_msg)
|
|
92
101
|
# Skip invalid decorators
|
|
93
102
|
continue
|
|
94
103
|
logger.debug("Parsed %s decorators", len(self._decorations))
|
{danielutils-1.1.2 → danielutils-1.1.22}/danielutils/reflection/info_classes/decorator_info.py
RENAMED
|
@@ -25,10 +25,19 @@ class DecoratorInfo:
|
|
|
25
25
|
def from_str(string: str) -> 'DecoratorInfo':
|
|
26
26
|
m = DecoratorInfo.DECORATOR_INFO_REGEX.match(string)
|
|
27
27
|
if m is None:
|
|
28
|
-
raise ValueError()
|
|
28
|
+
raise ValueError(f"Invalid decorator format: {repr(string)}")
|
|
29
29
|
|
|
30
30
|
name, arguments = m.groups()
|
|
31
|
-
|
|
31
|
+
if arguments:
|
|
32
|
+
try:
|
|
33
|
+
args = ArgumentInfo.from_str(arguments)
|
|
34
|
+
except ValueError as e:
|
|
35
|
+
raise ValueError(
|
|
36
|
+
f"Failed to parse arguments for decorator '{name}': {e}\n"
|
|
37
|
+
f"Arguments string: {repr(arguments)}"
|
|
38
|
+
) from e
|
|
39
|
+
else:
|
|
40
|
+
args = []
|
|
32
41
|
return DecoratorInfo(name, args)
|
|
33
42
|
|
|
34
43
|
def __str__(self) -> str:
|
{danielutils-1.1.2 → danielutils-1.1.22}/danielutils/reflection/info_classes/function_info.py
RENAMED
|
@@ -166,13 +166,26 @@ class FunctionInfo:
|
|
|
166
166
|
decorators, async_, name, arguments, return_type, body = m.groups()
|
|
167
167
|
if decorators is not None:
|
|
168
168
|
for substr in decorators.strip().splitlines():
|
|
169
|
-
|
|
169
|
+
try:
|
|
170
|
+
self._decorators.append(
|
|
171
|
+
DecoratorInfo.from_str(substr.strip()))
|
|
172
|
+
except ValueError as e:
|
|
173
|
+
raise ValueError(
|
|
174
|
+
f"Failed to parse decorator for function '{name}': {e}\n"
|
|
175
|
+
f"Decorator string: {repr(substr.strip())}"
|
|
176
|
+
) from e
|
|
170
177
|
|
|
171
178
|
self._is_async = async_ is not None
|
|
172
179
|
|
|
173
180
|
self._name = name
|
|
174
181
|
if arguments is not None:
|
|
175
|
-
|
|
182
|
+
try:
|
|
183
|
+
all_args = ArgumentInfo.from_str(arguments)
|
|
184
|
+
except ValueError as e:
|
|
185
|
+
raise ValueError(
|
|
186
|
+
f"Failed to parse arguments for function '{name}': {e}\n"
|
|
187
|
+
f"Arguments string: {repr(arguments)}"
|
|
188
|
+
) from e
|
|
176
189
|
# Filter out separator arguments (/, *) - they are syntax markers, not actual arguments
|
|
177
190
|
self._arguments = [arg for arg in all_args if not (
|
|
178
191
|
arg.is_kwargs_only and arg.name == "/") and not (arg.is_args and arg.name is None)]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .unittest_test_runner import *
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Command-line interface for the test runner using Google Fire.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import logging
|
|
6
|
+
import fire
|
|
7
|
+
from typing import Optional, Literal
|
|
8
|
+
from .core import TestRunner, VerboseLevel
|
|
9
|
+
|
|
10
|
+
logger = logging.getLogger(__name__)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def run_tests(python_path: Optional[str] = None,
|
|
14
|
+
results_file: str = "test_results.json",
|
|
15
|
+
skip_threshold: int = 24,
|
|
16
|
+
force: bool = False,
|
|
17
|
+
test_name: Optional[str] = None,
|
|
18
|
+
target: Optional[str] = None,
|
|
19
|
+
verbose: VerboseLevel = "class",
|
|
20
|
+
show_function_results: bool = False):
|
|
21
|
+
"""
|
|
22
|
+
Run tests with smart skipping and detailed reporting.
|
|
23
|
+
|
|
24
|
+
Args:
|
|
25
|
+
python_path: Path to Python executable to use for running tests (defaults to current Python)
|
|
26
|
+
results_file: JSON file to store/load results (default: test_results.json)
|
|
27
|
+
skip_threshold: Hours after which to re-run previously passing tests (default: 24)
|
|
28
|
+
force: Force run all tests, ignoring previous results
|
|
29
|
+
test_name: Run only a specific test module (e.g., tests.abstractions.db.test_in_memory_database)
|
|
30
|
+
target: unittest dot-notation target (e.g., tests.module.class.function)
|
|
31
|
+
verbose: Verbose level - module/file/class/function (default: class)
|
|
32
|
+
show_function_results: Show pass/fail status for each individual test function within modules
|
|
33
|
+
"""
|
|
34
|
+
logger.info("Starting test run with parameters: python_path=%s, results_file=%s, skip_threshold=%d, force=%s, target=%s, verbose=%s",
|
|
35
|
+
python_path, results_file, skip_threshold, force, target, verbose)
|
|
36
|
+
|
|
37
|
+
runner = TestRunner(
|
|
38
|
+
python_path=python_path,
|
|
39
|
+
results_file=results_file,
|
|
40
|
+
skip_threshold_hours=skip_threshold,
|
|
41
|
+
force_run=force,
|
|
42
|
+
test_name=test_name,
|
|
43
|
+
target=target,
|
|
44
|
+
verbose=verbose,
|
|
45
|
+
show_function_results=show_function_results
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
try:
|
|
49
|
+
logger.info("Executing all tests")
|
|
50
|
+
runner.run_all_tests()
|
|
51
|
+
logger.info("Saving results to JSON file: %s", results_file)
|
|
52
|
+
runner.save_results_json()
|
|
53
|
+
logger.info("Test run completed successfully")
|
|
54
|
+
except KeyboardInterrupt:
|
|
55
|
+
logger.warning("Test run interrupted by user")
|
|
56
|
+
print("\nTest run interrupted by user.")
|
|
57
|
+
except Exception as e:
|
|
58
|
+
logger.error("Error during test run: %s", e)
|
|
59
|
+
print(f"Error during test run: {e}")
|
|
60
|
+
raise
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def main():
|
|
64
|
+
"""Main entry point for the CLI."""
|
|
65
|
+
logger.info("Starting CLI main entry point")
|
|
66
|
+
fire.Fire(run_tests)
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
if __name__ == "__main__":
|
|
70
|
+
main()
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Core test runner modules.
|
|
3
|
+
|
|
4
|
+
This package contains the core functionality split by responsibility:
|
|
5
|
+
- discovery: Test discovery and structure analysis
|
|
6
|
+
- execution: Test execution hierarchy
|
|
7
|
+
- parser: Output parsing and result processing
|
|
8
|
+
- runner: Main TestRunner orchestration
|
|
9
|
+
- types: Type definitions and data structures
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
from .runner import TestRunner
|
|
13
|
+
|
|
14
|
+
# Define VerboseLevel here since it's a simple type alias
|
|
15
|
+
from typing import Literal
|
|
16
|
+
VerboseLevel = Literal["module", "file", "class", "function"]
|
|
17
|
+
|