haiway 0.14.0__tar.gz → 0.15.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. {haiway-0.14.0 → haiway-0.15.1}/PKG-INFO +1 -1
  2. {haiway-0.14.0 → haiway-0.15.1}/junit/test-results.xml +1 -1
  3. {haiway-0.14.0 → haiway-0.15.1}/pyproject.toml +4 -1
  4. {haiway-0.14.0 → haiway-0.15.1}/src/haiway/context/access.py +34 -18
  5. {haiway-0.14.0 → haiway-0.15.1}/src/haiway/context/state.py +42 -2
  6. {haiway-0.14.0 → haiway-0.15.1}/src/haiway/context/tasks.py +2 -1
  7. {haiway-0.14.0 → haiway-0.15.1}/src/haiway/helpers/asynchrony.py +4 -6
  8. {haiway-0.14.0 → haiway-0.15.1}/src/haiway/helpers/caching.py +1 -1
  9. {haiway-0.14.0 → haiway-0.15.1}/src/haiway/utils/queue.py +4 -0
  10. {haiway-0.14.0 → haiway-0.15.1}/uv.lock +46 -46
  11. {haiway-0.14.0 → haiway-0.15.1}/.github/workflows/ci.yml +0 -0
  12. {haiway-0.14.0 → haiway-0.15.1}/.github/workflows/publish.yml +0 -0
  13. {haiway-0.14.0 → haiway-0.15.1}/.gitignore +0 -0
  14. {haiway-0.14.0 → haiway-0.15.1}/LICENSE +0 -0
  15. {haiway-0.14.0 → haiway-0.15.1}/Makefile +0 -0
  16. {haiway-0.14.0 → haiway-0.15.1}/README.md +0 -0
  17. {haiway-0.14.0 → haiway-0.15.1}/config/pre-push +0 -0
  18. {haiway-0.14.0 → haiway-0.15.1}/examples/fastAPI/.dockerignore +0 -0
  19. {haiway-0.14.0 → haiway-0.15.1}/examples/fastAPI/Dockerfile +0 -0
  20. {haiway-0.14.0 → haiway-0.15.1}/examples/fastAPI/Makefile +0 -0
  21. {haiway-0.14.0 → haiway-0.15.1}/examples/fastAPI/README.md +0 -0
  22. {haiway-0.14.0 → haiway-0.15.1}/examples/fastAPI/config/.env.example +0 -0
  23. {haiway-0.14.0 → haiway-0.15.1}/examples/fastAPI/config/unit.json +0 -0
  24. {haiway-0.14.0 → haiway-0.15.1}/examples/fastAPI/docker-compose.yml +0 -0
  25. {haiway-0.14.0 → haiway-0.15.1}/examples/fastAPI/pyproject.toml +0 -0
  26. {haiway-0.14.0 → haiway-0.15.1}/examples/fastAPI/src/features/__int__.py +0 -0
  27. {haiway-0.14.0 → haiway-0.15.1}/examples/fastAPI/src/features/todos/__init__.py +0 -0
  28. {haiway-0.14.0 → haiway-0.15.1}/examples/fastAPI/src/features/todos/config.py +0 -0
  29. {haiway-0.14.0 → haiway-0.15.1}/examples/fastAPI/src/features/todos/state.py +0 -0
  30. {haiway-0.14.0 → haiway-0.15.1}/examples/fastAPI/src/features/todos/types.py +0 -0
  31. {haiway-0.14.0 → haiway-0.15.1}/examples/fastAPI/src/features/todos/user_tasks.py +0 -0
  32. {haiway-0.14.0 → haiway-0.15.1}/examples/fastAPI/src/integrations/__init__.py +0 -0
  33. {haiway-0.14.0 → haiway-0.15.1}/examples/fastAPI/src/integrations/postgres/__init__.py +0 -0
  34. {haiway-0.14.0 → haiway-0.15.1}/examples/fastAPI/src/integrations/postgres/client.py +0 -0
  35. {haiway-0.14.0 → haiway-0.15.1}/examples/fastAPI/src/integrations/postgres/config.py +0 -0
  36. {haiway-0.14.0 → haiway-0.15.1}/examples/fastAPI/src/integrations/postgres/state.py +0 -0
  37. {haiway-0.14.0 → haiway-0.15.1}/examples/fastAPI/src/integrations/postgres/types.py +0 -0
  38. {haiway-0.14.0 → haiway-0.15.1}/examples/fastAPI/src/migrations/__init__.py +0 -0
  39. {haiway-0.14.0 → haiway-0.15.1}/examples/fastAPI/src/migrations/__main__.py +0 -0
  40. {haiway-0.14.0 → haiway-0.15.1}/examples/fastAPI/src/migrations/postgres/__init__.py +0 -0
  41. {haiway-0.14.0 → haiway-0.15.1}/examples/fastAPI/src/migrations/postgres/execution.py +0 -0
  42. {haiway-0.14.0 → haiway-0.15.1}/examples/fastAPI/src/migrations/postgres/migration_0.py +0 -0
  43. {haiway-0.14.0 → haiway-0.15.1}/examples/fastAPI/src/migrations/postgres/types.py +0 -0
  44. {haiway-0.14.0 → haiway-0.15.1}/examples/fastAPI/src/server/__init__.py +0 -0
  45. {haiway-0.14.0 → haiway-0.15.1}/examples/fastAPI/src/server/__main__.py +0 -0
  46. {haiway-0.14.0 → haiway-0.15.1}/examples/fastAPI/src/server/application.py +0 -0
  47. {haiway-0.14.0 → haiway-0.15.1}/examples/fastAPI/src/server/config.py +0 -0
  48. {haiway-0.14.0 → haiway-0.15.1}/examples/fastAPI/src/server/middlewares/__init__.py +0 -0
  49. {haiway-0.14.0 → haiway-0.15.1}/examples/fastAPI/src/server/middlewares/context.py +0 -0
  50. {haiway-0.14.0 → haiway-0.15.1}/examples/fastAPI/src/server/routes/__init__.py +0 -0
  51. {haiway-0.14.0 → haiway-0.15.1}/examples/fastAPI/src/server/routes/technical.py +0 -0
  52. {haiway-0.14.0 → haiway-0.15.1}/examples/fastAPI/src/server/routes/todos.py +0 -0
  53. {haiway-0.14.0 → haiway-0.15.1}/examples/fastAPI/src/solutions/__init__.py +0 -0
  54. {haiway-0.14.0 → haiway-0.15.1}/examples/fastAPI/src/solutions/user_tasks/__init__.py +0 -0
  55. {haiway-0.14.0 → haiway-0.15.1}/examples/fastAPI/src/solutions/user_tasks/config.py +0 -0
  56. {haiway-0.14.0 → haiway-0.15.1}/examples/fastAPI/src/solutions/user_tasks/postgres.py +0 -0
  57. {haiway-0.14.0 → haiway-0.15.1}/examples/fastAPI/src/solutions/user_tasks/state.py +0 -0
  58. {haiway-0.14.0 → haiway-0.15.1}/examples/fastAPI/src/solutions/user_tasks/types.py +0 -0
  59. {haiway-0.14.0 → haiway-0.15.1}/examples/fastAPI/uv.lock +0 -0
  60. {haiway-0.14.0 → haiway-0.15.1}/guidelines/functionalities.md +0 -0
  61. {haiway-0.14.0 → haiway-0.15.1}/guidelines/packages.md +0 -0
  62. {haiway-0.14.0 → haiway-0.15.1}/src/haiway/__init__.py +0 -0
  63. {haiway-0.14.0 → haiway-0.15.1}/src/haiway/context/__init__.py +0 -0
  64. {haiway-0.14.0 → haiway-0.15.1}/src/haiway/context/disposables.py +0 -0
  65. {haiway-0.14.0 → haiway-0.15.1}/src/haiway/context/identifier.py +0 -0
  66. {haiway-0.14.0 → haiway-0.15.1}/src/haiway/context/logging.py +0 -0
  67. {haiway-0.14.0 → haiway-0.15.1}/src/haiway/context/metrics.py +0 -0
  68. {haiway-0.14.0 → haiway-0.15.1}/src/haiway/context/types.py +0 -0
  69. {haiway-0.14.0 → haiway-0.15.1}/src/haiway/helpers/__init__.py +0 -0
  70. {haiway-0.14.0 → haiway-0.15.1}/src/haiway/helpers/metrics.py +0 -0
  71. {haiway-0.14.0 → haiway-0.15.1}/src/haiway/helpers/retries.py +0 -0
  72. {haiway-0.14.0 → haiway-0.15.1}/src/haiway/helpers/throttling.py +0 -0
  73. {haiway-0.14.0 → haiway-0.15.1}/src/haiway/helpers/timeouted.py +0 -0
  74. {haiway-0.14.0 → haiway-0.15.1}/src/haiway/helpers/tracing.py +0 -0
  75. {haiway-0.14.0 → haiway-0.15.1}/src/haiway/py.typed +0 -0
  76. {haiway-0.14.0 → haiway-0.15.1}/src/haiway/state/__init__.py +0 -0
  77. {haiway-0.14.0 → haiway-0.15.1}/src/haiway/state/attributes.py +0 -0
  78. {haiway-0.14.0 → haiway-0.15.1}/src/haiway/state/path.py +0 -0
  79. {haiway-0.14.0 → haiway-0.15.1}/src/haiway/state/requirement.py +0 -0
  80. {haiway-0.14.0 → haiway-0.15.1}/src/haiway/state/structure.py +0 -0
  81. {haiway-0.14.0 → haiway-0.15.1}/src/haiway/state/validation.py +0 -0
  82. {haiway-0.14.0 → haiway-0.15.1}/src/haiway/types/__init__.py +0 -0
  83. {haiway-0.14.0 → haiway-0.15.1}/src/haiway/types/default.py +0 -0
  84. {haiway-0.14.0 → haiway-0.15.1}/src/haiway/types/frozen.py +0 -0
  85. {haiway-0.14.0 → haiway-0.15.1}/src/haiway/types/missing.py +0 -0
  86. {haiway-0.14.0 → haiway-0.15.1}/src/haiway/utils/__init__.py +0 -0
  87. {haiway-0.14.0 → haiway-0.15.1}/src/haiway/utils/always.py +0 -0
  88. {haiway-0.14.0 → haiway-0.15.1}/src/haiway/utils/collections.py +0 -0
  89. {haiway-0.14.0 → haiway-0.15.1}/src/haiway/utils/env.py +0 -0
  90. {haiway-0.14.0 → haiway-0.15.1}/src/haiway/utils/freezing.py +0 -0
  91. {haiway-0.14.0 → haiway-0.15.1}/src/haiway/utils/logs.py +0 -0
  92. {haiway-0.14.0 → haiway-0.15.1}/src/haiway/utils/mimic.py +0 -0
  93. {haiway-0.14.0 → haiway-0.15.1}/src/haiway/utils/noop.py +0 -0
  94. {haiway-0.14.0 → haiway-0.15.1}/src/haiway/utils/stream.py +0 -0
  95. {haiway-0.14.0 → haiway-0.15.1}/tests/__init__.py +0 -0
  96. {haiway-0.14.0 → haiway-0.15.1}/tests/test_async_queue.py +0 -0
  97. {haiway-0.14.0 → haiway-0.15.1}/tests/test_async_stream.py +0 -0
  98. {haiway-0.14.0 → haiway-0.15.1}/tests/test_attribute_path.py +0 -0
  99. {haiway-0.14.0 → haiway-0.15.1}/tests/test_auto_retry.py +0 -0
  100. {haiway-0.14.0 → haiway-0.15.1}/tests/test_cache.py +0 -0
  101. {haiway-0.14.0 → haiway-0.15.1}/tests/test_context.py +0 -0
  102. {haiway-0.14.0 → haiway-0.15.1}/tests/test_state.py +0 -0
  103. {haiway-0.14.0 → haiway-0.15.1}/tests/test_streaming.py +0 -0
  104. {haiway-0.14.0 → haiway-0.15.1}/tests/test_timeout.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: haiway
3
- Version: 0.14.0
3
+ Version: 0.15.1
4
4
  Summary: Framework for dependency injection and state management within structured concurrency model.
5
5
  Project-URL: Homepage, https://miquido.com
6
6
  Project-URL: Repository, https://github.com/miquido/haiway.git
@@ -1 +1 @@
1
- <?xml version="1.0" encoding="utf-8"?><testsuites><testsuite name="pytest" errors="0" failures="0" skipped="0" tests="88" time="1.127" timestamp="2025-04-01T10:53:25.573207" hostname="fv-az1786-487"><testcase classname="tests.test_async_queue" name="test_fails_when_stream_fails" time="0.002" /><testcase classname="tests.test_async_queue" name="test_cancels_when_iteration_cancels" time="0.001" /><testcase classname="tests.test_async_queue" name="test_ends_when_stream_ends" time="0.001" /><testcase classname="tests.test_async_queue" name="test_buffers_values_when_not_reading" time="0.001" /><testcase classname="tests.test_async_queue" name="test_delivers_buffer_when_streaming_fails" time="0.001" /><testcase classname="tests.test_async_queue" name="test_delivers_updates_when_sending" time="0.001" /><testcase classname="tests.test_async_queue" name="test_fails_when_sending_to_finished" time="0.001" /><testcase classname="tests.test_async_queue" name="test_ignores_when_finishing_when_finished" time="0.001" /><testcase classname="tests.test_async_stream" name="test_fails_when_stream_fails" time="0.001" /><testcase classname="tests.test_async_stream" name="test_cancels_when_iteration_cancels" time="0.001" /><testcase classname="tests.test_async_stream" name="test_ends_when_stream_ends" time="0.001" /><testcase classname="tests.test_async_stream" name="test_finishes_without_buffer" time="0.001" /><testcase classname="tests.test_async_stream" name="test_fails_without_buffer" time="0.001" /><testcase classname="tests.test_async_stream" name="test_delivers_updates_when_sending" time="0.001" /><testcase classname="tests.test_async_stream" name="test_ignores_when_sending_to_finished" time="0.001" /><testcase classname="tests.test_async_stream" name="test_ignores_when_sending_to_failed" time="0.001" /><testcase classname="tests.test_async_stream" name="test_ignores_when_finishing_when_finished" time="0.001" /><testcase classname="tests.test_async_stream" name="test_delivers_all_when_sending_async" time="0.001" /><testcase classname="tests.test_attribute_path" name="test_id_path_points_to_self" time="0.000" /><testcase classname="tests.test_attribute_path" name="test_attribute_path_points_to_attribute" time="0.000" /><testcase classname="tests.test_attribute_path" name="test_nested_attribute_path_points_to_nested_attribute" time="0.000" /><testcase classname="tests.test_attribute_path" name="test_recursive_attribute_path_points_to_attribute" time="0.000" /><testcase classname="tests.test_attribute_path" name="test_list_item_path_points_to_item" time="0.000" /><testcase classname="tests.test_attribute_path" name="test_tuple_item_path_points_to_item" time="0.000" /><testcase classname="tests.test_attribute_path" name="test_mixed_tuple_item_path_points_to_item" time="0.000" /><testcase classname="tests.test_attribute_path" name="test_dict_item_path_points_to_item" time="0.000" /><testcase classname="tests.test_attribute_path" name="test_id_path_set_updates_self" time="0.000" /><testcase classname="tests.test_attribute_path" name="test_attribute_path_set_updates_attribute" time="0.000" /><testcase classname="tests.test_attribute_path" name="test_nested_attribute_path_set_updates_nested_attribute" time="0.000" /><testcase classname="tests.test_attribute_path" name="test_recursive_attribute_set_updates_attribute" time="0.000" /><testcase classname="tests.test_attribute_path" name="test_list_item_path_set_updates_item" time="0.001" /><testcase classname="tests.test_attribute_path" name="test_tuple_item_path_set_updates_item" time="0.000" /><testcase classname="tests.test_attribute_path" name="test_mixed_tuple_item_set_updates_item" time="0.000" /><testcase classname="tests.test_attribute_path" name="test_dict_item_path_set_updates_item" time="0.000" /><testcase classname="tests.test_auto_retry" name="test_returns_value_without_errors" time="0.001" /><testcase classname="tests.test_auto_retry" name="test_retries_with_errors" time="0.001" /><testcase classname="tests.test_auto_retry" name="test_logs_issue_with_errors" time="0.001" /><testcase classname="tests.test_auto_retry" name="test_fails_with_exceeding_errors" time="0.001" /><testcase classname="tests.test_auto_retry" name="test_fails_with_cancellation" time="0.001" /><testcase classname="tests.test_auto_retry" name="test_retries_with_selected_errors" time="0.001" /><testcase classname="tests.test_auto_retry" name="test_fails_with_not_selected_errors" time="0.001" /><testcase classname="tests.test_auto_retry" name="test_async_returns_value_without_errors" time="0.001" /><testcase classname="tests.test_auto_retry" name="test_async_retries_with_errors" time="0.001" /><testcase classname="tests.test_auto_retry" name="test_async_fails_with_exceeding_errors" time="0.001" /><testcase classname="tests.test_auto_retry" name="test_async_fails_with_cancellation" time="0.001" /><testcase classname="tests.test_auto_retry" name="test_async_fails_when_cancelled" time="0.021" /><testcase classname="tests.test_auto_retry" name="test_async_uses_delay_with_errors" time="0.102" /><testcase classname="tests.test_auto_retry" name="test_async_uses_computed_delay_with_errors" time="0.107" /><testcase classname="tests.test_auto_retry" name="test_async_logs_issue_with_errors" time="0.001" /><testcase classname="tests.test_auto_retry" name="test_async_retries_with_selected_errors" time="0.001" /><testcase classname="tests.test_auto_retry" name="test_async_fails_with_not_selected_errors" time="0.001" /><testcase classname="tests.test_cache" name="test_returns_cache_value_with_same_argument" time="0.001" /><testcase classname="tests.test_cache" name="test_returns_fresh_value_with_different_argument" time="0.000" /><testcase classname="tests.test_cache" name="test_returns_fresh_value_with_limit_exceed" time="0.000" /><testcase classname="tests.test_cache" name="test_returns_same_value_with_repeating_argument" time="0.000" /><testcase classname="tests.test_cache" name="test_fails_with_error" time="0.000" /><testcase classname="tests.test_cache" name="test_returns_fresh_value_with_expiration_time_exceed" time="0.021" /><testcase classname="tests.test_cache" name="test_async_returns_cache_value_with_same_argument" time="0.001" /><testcase classname="tests.test_cache" name="test_async_returns_fresh_value_with_different_argument" time="0.001" /><testcase classname="tests.test_cache" name="test_async_returns_fresh_value_with_limit_exceed" time="0.001" /><testcase classname="tests.test_cache" name="test_async_returns_same_value_with_repeating_argument" time="0.001" /><testcase classname="tests.test_cache" name="test_async_returns_fresh_value_with_expiration_time_exceed" time="0.021" /><testcase classname="tests.test_cache" name="test_async_cancel_waiting_does_not_cancel_task" time="0.502" /><testcase classname="tests.test_cache" name="test_async_expiration_does_not_cancel_task" time="0.021" /><testcase classname="tests.test_cache" name="test_async_fails_with_error" time="0.001" /><testcase classname="tests.test_context" name="test_state_is_available_according_to_context" time="0.001" /><testcase classname="tests.test_context" name="test_state_update_updates_local_context" time="0.001" /><testcase classname="tests.test_context" name="test_exceptions_are_propagated" time="0.001" /><testcase classname="tests.test_state" name="test_basic_initializes_with_arguments" time="0.002" /><testcase classname="tests.test_state" name="test_basic_initializes_with_defaults" time="0.001" /><testcase classname="tests.test_state" name="test_basic_equals_checks_properties" time="0.000" /><testcase classname="tests.test_state" name="test_basic_initializes_with_arguments_and_defaults" time="0.000" /><testcase classname="tests.test_state" name="test_parametrized_initializes_with_proper_parameters" time="0.000" /><testcase classname="tests.test_state" name="test_nested_initializes_with_proper_arguments" time="0.001" /><testcase classname="tests.test_state" name="test_dict_skips_missing_properties" time="0.001" /><testcase classname="tests.test_state" name="test_initialization_allows_missing_properties" time="0.001" /><testcase classname="tests.test_state" name="test_generic_subtypes_validation" time="0.002" /><testcase classname="tests.test_state" name="test_copying_leaves_same_object" time="0.001" /><testcase classname="tests.test_streaming" name="test_fails_when_generator_fails" time="0.001" /><testcase classname="tests.test_streaming" name="test_cancels_when_iteration_cancels" time="0.001" /><testcase classname="tests.test_streaming" name="test_ends_when_generator_ends" time="0.001" /><testcase classname="tests.test_streaming" name="test_delivers_updates_when_generating" time="0.001" /><testcase classname="tests.test_streaming" name="test_streaming_context_variables_access_is_preserved" time="0.001" /><testcase classname="tests.test_streaming" name="test_nested_streaming_streams_correctly" time="0.001" /><testcase classname="tests.test_timeout" name="test_returns_result_when_returning_value" time="0.001" /><testcase classname="tests.test_timeout" name="test_raises_with_error" time="0.001" /><testcase classname="tests.test_timeout" name="test_raises_with_cancel" time="0.011" /><testcase classname="tests.test_timeout" name="test_raises_with_timeout" time="0.011" /></testsuite></testsuites>
1
+ <?xml version="1.0" encoding="utf-8"?><testsuites><testsuite name="pytest" errors="0" failures="0" skipped="0" tests="88" time="1.129" timestamp="2025-04-07T13:19:58.902913" hostname="fv-az1695-695"><testcase classname="tests.test_async_queue" name="test_fails_when_stream_fails" time="0.002" /><testcase classname="tests.test_async_queue" name="test_cancels_when_iteration_cancels" time="0.001" /><testcase classname="tests.test_async_queue" name="test_ends_when_stream_ends" time="0.001" /><testcase classname="tests.test_async_queue" name="test_buffers_values_when_not_reading" time="0.001" /><testcase classname="tests.test_async_queue" name="test_delivers_buffer_when_streaming_fails" time="0.001" /><testcase classname="tests.test_async_queue" name="test_delivers_updates_when_sending" time="0.001" /><testcase classname="tests.test_async_queue" name="test_fails_when_sending_to_finished" time="0.001" /><testcase classname="tests.test_async_queue" name="test_ignores_when_finishing_when_finished" time="0.001" /><testcase classname="tests.test_async_stream" name="test_fails_when_stream_fails" time="0.001" /><testcase classname="tests.test_async_stream" name="test_cancels_when_iteration_cancels" time="0.001" /><testcase classname="tests.test_async_stream" name="test_ends_when_stream_ends" time="0.001" /><testcase classname="tests.test_async_stream" name="test_finishes_without_buffer" time="0.001" /><testcase classname="tests.test_async_stream" name="test_fails_without_buffer" time="0.001" /><testcase classname="tests.test_async_stream" name="test_delivers_updates_when_sending" time="0.001" /><testcase classname="tests.test_async_stream" name="test_ignores_when_sending_to_finished" time="0.001" /><testcase classname="tests.test_async_stream" name="test_ignores_when_sending_to_failed" time="0.001" /><testcase classname="tests.test_async_stream" name="test_ignores_when_finishing_when_finished" time="0.001" /><testcase classname="tests.test_async_stream" name="test_delivers_all_when_sending_async" time="0.001" /><testcase classname="tests.test_attribute_path" name="test_id_path_points_to_self" time="0.000" /><testcase classname="tests.test_attribute_path" name="test_attribute_path_points_to_attribute" time="0.000" /><testcase classname="tests.test_attribute_path" name="test_nested_attribute_path_points_to_nested_attribute" time="0.000" /><testcase classname="tests.test_attribute_path" name="test_recursive_attribute_path_points_to_attribute" time="0.000" /><testcase classname="tests.test_attribute_path" name="test_list_item_path_points_to_item" time="0.000" /><testcase classname="tests.test_attribute_path" name="test_tuple_item_path_points_to_item" time="0.000" /><testcase classname="tests.test_attribute_path" name="test_mixed_tuple_item_path_points_to_item" time="0.000" /><testcase classname="tests.test_attribute_path" name="test_dict_item_path_points_to_item" time="0.000" /><testcase classname="tests.test_attribute_path" name="test_id_path_set_updates_self" time="0.000" /><testcase classname="tests.test_attribute_path" name="test_attribute_path_set_updates_attribute" time="0.000" /><testcase classname="tests.test_attribute_path" name="test_nested_attribute_path_set_updates_nested_attribute" time="0.000" /><testcase classname="tests.test_attribute_path" name="test_recursive_attribute_set_updates_attribute" time="0.000" /><testcase classname="tests.test_attribute_path" name="test_list_item_path_set_updates_item" time="0.001" /><testcase classname="tests.test_attribute_path" name="test_tuple_item_path_set_updates_item" time="0.000" /><testcase classname="tests.test_attribute_path" name="test_mixed_tuple_item_set_updates_item" time="0.000" /><testcase classname="tests.test_attribute_path" name="test_dict_item_path_set_updates_item" time="0.000" /><testcase classname="tests.test_auto_retry" name="test_returns_value_without_errors" time="0.001" /><testcase classname="tests.test_auto_retry" name="test_retries_with_errors" time="0.001" /><testcase classname="tests.test_auto_retry" name="test_logs_issue_with_errors" time="0.001" /><testcase classname="tests.test_auto_retry" name="test_fails_with_exceeding_errors" time="0.001" /><testcase classname="tests.test_auto_retry" name="test_fails_with_cancellation" time="0.001" /><testcase classname="tests.test_auto_retry" name="test_retries_with_selected_errors" time="0.001" /><testcase classname="tests.test_auto_retry" name="test_fails_with_not_selected_errors" time="0.001" /><testcase classname="tests.test_auto_retry" name="test_async_returns_value_without_errors" time="0.001" /><testcase classname="tests.test_auto_retry" name="test_async_retries_with_errors" time="0.001" /><testcase classname="tests.test_auto_retry" name="test_async_fails_with_exceeding_errors" time="0.001" /><testcase classname="tests.test_auto_retry" name="test_async_fails_with_cancellation" time="0.001" /><testcase classname="tests.test_auto_retry" name="test_async_fails_when_cancelled" time="0.021" /><testcase classname="tests.test_auto_retry" name="test_async_uses_delay_with_errors" time="0.102" /><testcase classname="tests.test_auto_retry" name="test_async_uses_computed_delay_with_errors" time="0.107" /><testcase classname="tests.test_auto_retry" name="test_async_logs_issue_with_errors" time="0.001" /><testcase classname="tests.test_auto_retry" name="test_async_retries_with_selected_errors" time="0.001" /><testcase classname="tests.test_auto_retry" name="test_async_fails_with_not_selected_errors" time="0.001" /><testcase classname="tests.test_cache" name="test_returns_cache_value_with_same_argument" time="0.001" /><testcase classname="tests.test_cache" name="test_returns_fresh_value_with_different_argument" time="0.000" /><testcase classname="tests.test_cache" name="test_returns_fresh_value_with_limit_exceed" time="0.000" /><testcase classname="tests.test_cache" name="test_returns_same_value_with_repeating_argument" time="0.000" /><testcase classname="tests.test_cache" name="test_fails_with_error" time="0.000" /><testcase classname="tests.test_cache" name="test_returns_fresh_value_with_expiration_time_exceed" time="0.021" /><testcase classname="tests.test_cache" name="test_async_returns_cache_value_with_same_argument" time="0.001" /><testcase classname="tests.test_cache" name="test_async_returns_fresh_value_with_different_argument" time="0.001" /><testcase classname="tests.test_cache" name="test_async_returns_fresh_value_with_limit_exceed" time="0.001" /><testcase classname="tests.test_cache" name="test_async_returns_same_value_with_repeating_argument" time="0.001" /><testcase classname="tests.test_cache" name="test_async_returns_fresh_value_with_expiration_time_exceed" time="0.021" /><testcase classname="tests.test_cache" name="test_async_cancel_waiting_does_not_cancel_task" time="0.502" /><testcase classname="tests.test_cache" name="test_async_expiration_does_not_cancel_task" time="0.021" /><testcase classname="tests.test_cache" name="test_async_fails_with_error" time="0.001" /><testcase classname="tests.test_context" name="test_state_is_available_according_to_context" time="0.001" /><testcase classname="tests.test_context" name="test_state_update_updates_local_context" time="0.001" /><testcase classname="tests.test_context" name="test_exceptions_are_propagated" time="0.001" /><testcase classname="tests.test_state" name="test_basic_initializes_with_arguments" time="0.002" /><testcase classname="tests.test_state" name="test_basic_initializes_with_defaults" time="0.001" /><testcase classname="tests.test_state" name="test_basic_equals_checks_properties" time="0.001" /><testcase classname="tests.test_state" name="test_basic_initializes_with_arguments_and_defaults" time="0.001" /><testcase classname="tests.test_state" name="test_parametrized_initializes_with_proper_parameters" time="0.000" /><testcase classname="tests.test_state" name="test_nested_initializes_with_proper_arguments" time="0.001" /><testcase classname="tests.test_state" name="test_dict_skips_missing_properties" time="0.001" /><testcase classname="tests.test_state" name="test_initialization_allows_missing_properties" time="0.000" /><testcase classname="tests.test_state" name="test_generic_subtypes_validation" time="0.002" /><testcase classname="tests.test_state" name="test_copying_leaves_same_object" time="0.001" /><testcase classname="tests.test_streaming" name="test_fails_when_generator_fails" time="0.001" /><testcase classname="tests.test_streaming" name="test_cancels_when_iteration_cancels" time="0.001" /><testcase classname="tests.test_streaming" name="test_ends_when_generator_ends" time="0.001" /><testcase classname="tests.test_streaming" name="test_delivers_updates_when_generating" time="0.001" /><testcase classname="tests.test_streaming" name="test_streaming_context_variables_access_is_preserved" time="0.001" /><testcase classname="tests.test_streaming" name="test_nested_streaming_streams_correctly" time="0.001" /><testcase classname="tests.test_timeout" name="test_returns_result_when_returning_value" time="0.001" /><testcase classname="tests.test_timeout" name="test_raises_with_error" time="0.001" /><testcase classname="tests.test_timeout" name="test_raises_with_cancel" time="0.011" /><testcase classname="tests.test_timeout" name="test_raises_with_timeout" time="0.012" /></testsuite></testsuites>
@@ -5,7 +5,7 @@ build-backend = "hatchling.build"
5
5
  [project]
6
6
  name = "haiway"
7
7
  description = "Framework for dependency injection and state management within structured concurrency model."
8
- version = "0.14.0"
8
+ version = "0.15.1"
9
9
  readme = "README.md"
10
10
  maintainers = [
11
11
  { name = "Kacper Kaliński", email = "kacper.kalinski@miquido.com" },
@@ -44,6 +44,9 @@ extend-exclude = [".venv", ".git", ".cache"]
44
44
  lint.select = ["E", "F", "A", "I", "B", "PL", "W", "C", "RUF", "UP"]
45
45
  lint.ignore = ["A005"]
46
46
 
47
+ [tool.ruff.lint.pylint]
48
+ max-args = 12
49
+
47
50
  [tool.ruff.lint.per-file-ignores]
48
51
  "__init__.py" = ["F401", "E402"]
49
52
  "./tests/*.py" = ["PLR2004"]
@@ -1,6 +1,7 @@
1
1
  from asyncio import (
2
2
  CancelledError,
3
3
  Task,
4
+ TaskGroup,
4
5
  current_task,
5
6
  iscoroutinefunction,
6
7
  )
@@ -45,6 +46,7 @@ class ScopeContext:
45
46
  self,
46
47
  label: str,
47
48
  logger: Logger | None,
49
+ task_group: TaskGroup | None,
48
50
  state: tuple[State, ...],
49
51
  disposables: Disposables | None,
50
52
  metrics: MetricsHandler | None,
@@ -64,8 +66,16 @@ class ScopeContext:
64
66
  logger=logger,
65
67
  ),
66
68
  )
67
- # postponing task group creation to include only when needed
68
- self._task_group_context: TaskGroupContext
69
+ self._task_group_context: TaskGroupContext | None
70
+ object.__setattr__(
71
+ self,
72
+ "_task_group_context",
73
+ TaskGroupContext(
74
+ task_group=task_group,
75
+ )
76
+ if task_group is not None or self._identifier.is_root
77
+ else None,
78
+ )
69
79
  # prepare state context to capture current state
70
80
  self._state_context: StateContext
71
81
  object.__setattr__(
@@ -110,6 +120,9 @@ class ScopeContext:
110
120
  )
111
121
 
112
122
  def __enter__(self) -> str:
123
+ assert ( # nosec: B101
124
+ self._task_group_context is None or self._identifier.is_root
125
+ ), "Can't enter synchronous context with task group"
113
126
  assert self._disposables is None, "Can't enter synchronous context with disposables" # nosec: B101
114
127
  self._identifier.__enter__()
115
128
  self._logger_context.__enter__()
@@ -151,23 +164,19 @@ class ScopeContext:
151
164
  async def __aenter__(self) -> str:
152
165
  self._identifier.__enter__()
153
166
  self._logger_context.__enter__()
154
- # lazily initialize group when needed
155
- object.__setattr__(
156
- self,
157
- "_task_group_context",
158
- TaskGroupContext(),
159
- )
160
- await self._task_group_context.__aenter__()
167
+
168
+ if task_group := self._task_group_context:
169
+ await task_group.__aenter__()
161
170
 
162
171
  # lazily initialize state to include disposables results
163
- if self._disposables is not None:
172
+ if disposables := self._disposables:
164
173
  assert self._state_context._token is None # nosec: B101
165
174
  object.__setattr__(
166
175
  self,
167
176
  "_state_context",
168
177
  StateContext(
169
178
  state=self._state_context._state.updated(
170
- await self._disposables.__aenter__(),
179
+ await disposables.__aenter__(),
171
180
  ),
172
181
  ),
173
182
  )
@@ -183,18 +192,19 @@ class ScopeContext:
183
192
  exc_val: BaseException | None,
184
193
  exc_tb: TracebackType | None,
185
194
  ) -> None:
186
- if self._disposables is not None:
187
- await self._disposables.__aexit__(
195
+ if disposables := self._disposables:
196
+ await disposables.__aexit__(
188
197
  exc_type=exc_type,
189
198
  exc_val=exc_val,
190
199
  exc_tb=exc_tb,
191
200
  )
192
201
 
193
- await self._task_group_context.__aexit__(
194
- exc_type=exc_type,
195
- exc_val=exc_val,
196
- exc_tb=exc_tb,
197
- )
202
+ if task_group := self._task_group_context:
203
+ await task_group.__aexit__(
204
+ exc_type=exc_type,
205
+ exc_val=exc_val,
206
+ exc_tb=exc_tb,
207
+ )
198
208
 
199
209
  self._metrics_context.__exit__(
200
210
  exc_type=exc_type,
@@ -278,6 +288,7 @@ class ctx:
278
288
  *state: State,
279
289
  disposables: Disposables | Iterable[Disposable] | None = None,
280
290
  logger: Logger | None = None,
291
+ task_group: TaskGroup | None = None,
281
292
  metrics: MetricsHandler | None = None,
282
293
  ) -> ScopeContext:
283
294
  """
@@ -302,6 +313,10 @@ class ctx:
302
313
  logger used within the scope context, when not provided current logger will be used\
303
314
  if any, otherwise the logger with the scope name will be requested.
304
315
 
316
+ task_group: TaskGroup | None
317
+ task group used for spawning and joining tasks within the context. Root scope will
318
+ always have task group created even when not set.
319
+
305
320
  metrics_store: MetricsStore | None = None
306
321
  metrics storage solution responsible for recording and storing metrics.\
307
322
  Metrics recroding will be ignored if storage is not provided.
@@ -328,6 +343,7 @@ class ctx:
328
343
  return ScopeContext(
329
344
  label=label,
330
345
  logger=logger,
346
+ task_group=task_group,
331
347
  state=state,
332
348
  disposables=resolved_disposables,
333
349
  metrics=metrics,
@@ -1,10 +1,12 @@
1
- from collections.abc import Iterable, MutableMapping
1
+ from asyncio import iscoroutinefunction
2
+ from collections.abc import Callable, Coroutine, Iterable, MutableMapping
2
3
  from contextvars import ContextVar, Token
3
4
  from types import TracebackType
4
- from typing import Any, Self, cast, final
5
+ from typing import Any, Self, cast, final, overload
5
6
 
6
7
  from haiway.context.types import MissingContext, MissingState
7
8
  from haiway.state import State
9
+ from haiway.utils.mimic import mimic_function
8
10
 
9
11
  __all__ = [
10
12
  "ScopeState",
@@ -179,3 +181,41 @@ class StateContext:
179
181
  "_token",
180
182
  None,
181
183
  )
184
+
185
+ @overload
186
+ def __call__[Result, **Arguments](
187
+ self,
188
+ function: Callable[Arguments, Coroutine[Any, Any, Result]],
189
+ ) -> Callable[Arguments, Coroutine[Any, Any, Result]]: ...
190
+
191
+ @overload
192
+ def __call__[Result, **Arguments](
193
+ self,
194
+ function: Callable[Arguments, Result],
195
+ ) -> Callable[Arguments, Result]: ...
196
+
197
+ def __call__[Result, **Arguments](
198
+ self,
199
+ function: Callable[Arguments, Coroutine[Any, Any, Result]] | Callable[Arguments, Result],
200
+ ) -> Callable[Arguments, Coroutine[Any, Any, Result]] | Callable[Arguments, Result]:
201
+ if iscoroutinefunction(function):
202
+
203
+ async def async_context(
204
+ *args: Arguments.args,
205
+ **kwargs: Arguments.kwargs,
206
+ ) -> Result:
207
+ with self:
208
+ return await function(*args, **kwargs)
209
+
210
+ return mimic_function(function, within=async_context)
211
+
212
+ else:
213
+
214
+ def sync_context(
215
+ *args: Arguments.args,
216
+ **kwargs: Arguments.kwargs,
217
+ ) -> Result:
218
+ with self:
219
+ return function(*args, **kwargs) # pyright: ignore[reportReturnType]
220
+
221
+ return mimic_function(function, within=sync_context) # pyright: ignore[reportReturnType]
@@ -40,12 +40,13 @@ class TaskGroupContext:
40
40
 
41
41
  def __init__(
42
42
  self,
43
+ task_group: TaskGroup | None = None,
43
44
  ) -> None:
44
45
  self._group: TaskGroup
45
46
  object.__setattr__(
46
47
  self,
47
48
  "_group",
48
- TaskGroup(),
49
+ task_group if task_group is not None else TaskGroup(),
49
50
  )
50
51
  self._token: Token[TaskGroup] | None
51
52
  object.__setattr__(
@@ -30,12 +30,10 @@ def wrap_async[**Args, Result](
30
30
 
31
31
 
32
32
  @overload
33
- def asynchronous[**Args, Result]() -> (
34
- Callable[
35
- [Callable[Args, Result]],
36
- Callable[Args, Coroutine[Any, Any, Result]],
37
- ]
38
- ): ...
33
+ def asynchronous[**Args, Result]() -> Callable[
34
+ [Callable[Args, Result]],
35
+ Callable[Args, Coroutine[Any, Any, Result]],
36
+ ]: ...
39
37
 
40
38
 
41
39
  @overload
@@ -66,7 +66,7 @@ def cache[**Args, Result, Key](
66
66
  ]: ...
67
67
 
68
68
 
69
- def cache[**Args, Result, Key]( # noqa: PLR0913
69
+ def cache[**Args, Result, Key](
70
70
  function: Callable[Args, Result] | None = None,
71
71
  *,
72
72
  limit: int | None = None,
@@ -143,3 +143,7 @@ class AsyncQueue[Element](AsyncIterator[Element]):
143
143
  "_waiting",
144
144
  None,
145
145
  )
146
+
147
+ def clear(self) -> None:
148
+ if self._waiting is None or self._waiting.done():
149
+ self._queue.clear()
@@ -28,46 +28,46 @@ wheels = [
28
28
 
29
29
  [[package]]
30
30
  name = "coverage"
31
- version = "7.7.1"
31
+ version = "7.8.0"
32
32
  source = { registry = "https://pypi.org/simple" }
33
- sdist = { url = "https://files.pythonhosted.org/packages/6b/bf/3effb7453498de9c14a81ca21e1f92e6723ce7ebdc5402ae30e4dcc490ac/coverage-7.7.1.tar.gz", hash = "sha256:199a1272e642266b90c9f40dec7fd3d307b51bf639fa0d15980dc0b3246c1393", size = 810332 }
33
+ sdist = { url = "https://files.pythonhosted.org/packages/19/4f/2251e65033ed2ce1e68f00f91a0294e0f80c80ae8c3ebbe2f12828c4cd53/coverage-7.8.0.tar.gz", hash = "sha256:7a3d62b3b03b4b6fd41a085f3574874cf946cb4604d2b4d3e8dca8cd570ca501", size = 811872 }
34
34
  wheels = [
35
- { url = "https://files.pythonhosted.org/packages/cf/b0/4eaba302a86ec3528231d7cfc954ae1929ec5d42b032eb6f5b5f5a9155d2/coverage-7.7.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:eff187177d8016ff6addf789dcc421c3db0d014e4946c1cc3fbf697f7852459d", size = 211253 },
36
- { url = "https://files.pythonhosted.org/packages/fd/68/21b973e6780a3f2457e31ede1aca6c2f84bda4359457b40da3ae805dcf30/coverage-7.7.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2444fbe1ba1889e0b29eb4d11931afa88f92dc507b7248f45be372775b3cef4f", size = 211504 },
37
- { url = "https://files.pythonhosted.org/packages/d1/b4/c19e9c565407664390254252496292f1e3076c31c5c01701ffacc060e745/coverage-7.7.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:177d837339883c541f8524683e227adcaea581eca6bb33823a2a1fdae4c988e1", size = 245566 },
38
- { url = "https://files.pythonhosted.org/packages/7b/0e/f9829cdd25e5083638559c8c267ff0577c6bab19dacb1a4fcfc1e70e41c0/coverage-7.7.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:15d54ecef1582b1d3ec6049b20d3c1a07d5e7f85335d8a3b617c9960b4f807e0", size = 242455 },
39
- { url = "https://files.pythonhosted.org/packages/29/57/a3ada2e50a665bf6d9851b5eb3a9a07d7e38f970bdd4d39895f311331d56/coverage-7.7.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75c82b27c56478d5e1391f2e7b2e7f588d093157fa40d53fd9453a471b1191f2", size = 244713 },
40
- { url = "https://files.pythonhosted.org/packages/0f/d3/f15c7d45682a73eca0611427896016bad4c8f635b0fc13aae13a01f8ed9d/coverage-7.7.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:315ff74b585110ac3b7ab631e89e769d294f303c6d21302a816b3554ed4c81af", size = 244476 },
41
- { url = "https://files.pythonhosted.org/packages/19/3b/64540074e256082b220e8810fd72543eff03286c59dc91976281dc0a559c/coverage-7.7.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4dd532dac197d68c478480edde74fd4476c6823355987fd31d01ad9aa1e5fb59", size = 242695 },
42
- { url = "https://files.pythonhosted.org/packages/8a/c1/9cad25372ead7f9395a91bb42d8ae63e6cefe7408eb79fd38797e2b763eb/coverage-7.7.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:385618003e3d608001676bb35dc67ae3ad44c75c0395d8de5780af7bb35be6b2", size = 243888 },
43
- { url = "https://files.pythonhosted.org/packages/66/c6/c3e6c895bc5b95ccfe4cb5838669dbe5226ee4ad10604c46b778c304d6f9/coverage-7.7.1-cp312-cp312-win32.whl", hash = "sha256:63306486fcb5a827449464f6211d2991f01dfa2965976018c9bab9d5e45a35c8", size = 213744 },
44
- { url = "https://files.pythonhosted.org/packages/cc/8a/6df2fcb4c3e38ec6cd7e211ca8391405ada4e3b1295695d00aa07c6ee736/coverage-7.7.1-cp312-cp312-win_amd64.whl", hash = "sha256:37351dc8123c154fa05b7579fdb126b9f8b1cf42fd6f79ddf19121b7bdd4aa04", size = 214546 },
45
- { url = "https://files.pythonhosted.org/packages/ec/2a/1a254eaadb01c163b29d6ce742aa380fc5cfe74a82138ce6eb944c42effa/coverage-7.7.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:eebd927b86761a7068a06d3699fd6c20129becf15bb44282db085921ea0f1585", size = 211277 },
46
- { url = "https://files.pythonhosted.org/packages/cf/00/9636028365efd4eb6db71cdd01d99e59f25cf0d47a59943dbee32dd1573b/coverage-7.7.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2a79c4a09765d18311c35975ad2eb1ac613c0401afdd9cb1ca4110aeb5dd3c4c", size = 211551 },
47
- { url = "https://files.pythonhosted.org/packages/6f/c8/14aed97f80363f055b6cd91e62986492d9fe3b55e06b4b5c82627ae18744/coverage-7.7.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8b1c65a739447c5ddce5b96c0a388fd82e4bbdff7251396a70182b1d83631019", size = 245068 },
48
- { url = "https://files.pythonhosted.org/packages/d6/76/9c5fe3f900e01d7995b0cda08fc8bf9773b4b1be58bdd626f319c7d4ec11/coverage-7.7.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:392cc8fd2b1b010ca36840735e2a526fcbd76795a5d44006065e79868cc76ccf", size = 242109 },
49
- { url = "https://files.pythonhosted.org/packages/c0/81/760993bb536fb674d3a059f718145dcd409ed6d00ae4e3cbf380019fdfd0/coverage-7.7.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9bb47cc9f07a59a451361a850cb06d20633e77a9118d05fd0f77b1864439461b", size = 244129 },
50
- { url = "https://files.pythonhosted.org/packages/00/be/1114a19f93eae0b6cd955dabb5bee80397bd420d846e63cd0ebffc134e3d/coverage-7.7.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:b4c144c129343416a49378e05c9451c34aae5ccf00221e4fa4f487db0816ee2f", size = 244201 },
51
- { url = "https://files.pythonhosted.org/packages/06/8d/9128fd283c660474c7dc2b1ea5c66761bc776b970c1724989ed70e9d6eee/coverage-7.7.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:bc96441c9d9ca12a790b5ae17d2fa6654da4b3962ea15e0eabb1b1caed094777", size = 242282 },
52
- { url = "https://files.pythonhosted.org/packages/d4/2a/6d7dbfe9c1f82e2cdc28d48f4a0c93190cf58f057fa91ba2391b92437fe6/coverage-7.7.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:3d03287eb03186256999539d98818c425c33546ab4901028c8fa933b62c35c3a", size = 243570 },
53
- { url = "https://files.pythonhosted.org/packages/cf/3e/29f1e4ce3bb951bcf74b2037a82d94c5064b3334304a3809a95805628838/coverage-7.7.1-cp313-cp313-win32.whl", hash = "sha256:8fed429c26b99641dc1f3a79179860122b22745dd9af36f29b141e178925070a", size = 213772 },
54
- { url = "https://files.pythonhosted.org/packages/bc/3a/cf029bf34aefd22ad34f0e808eba8d5830f297a1acb483a2124f097ff769/coverage-7.7.1-cp313-cp313-win_amd64.whl", hash = "sha256:092b134129a8bb940c08b2d9ceb4459af5fb3faea77888af63182e17d89e1cf1", size = 214575 },
55
- { url = "https://files.pythonhosted.org/packages/92/4c/fb8b35f186a2519126209dce91ab8644c9a901cf04f8dfa65576ca2dd9e8/coverage-7.7.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:d3154b369141c3169b8133973ac00f63fcf8d6dbcc297d788d36afbb7811e511", size = 212113 },
56
- { url = "https://files.pythonhosted.org/packages/59/90/e834ffc86fd811c5b570a64ee1895b20404a247ec18a896b9ba543b12097/coverage-7.7.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:264ff2bcce27a7f455b64ac0dfe097680b65d9a1a293ef902675fa8158d20b24", size = 212333 },
57
- { url = "https://files.pythonhosted.org/packages/a5/a1/27f0ad39569b3b02410b881c42e58ab403df13fcd465b475db514b83d3d3/coverage-7.7.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ba8480ebe401c2f094d10a8c4209b800a9b77215b6c796d16b6ecdf665048950", size = 256566 },
58
- { url = "https://files.pythonhosted.org/packages/9f/3b/21fa66a1db1b90a0633e771a32754f7c02d60236a251afb1b86d7e15d83a/coverage-7.7.1-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:520af84febb6bb54453e7fbb730afa58c7178fd018c398a8fcd8e269a79bf96d", size = 252276 },
59
- { url = "https://files.pythonhosted.org/packages/d6/e5/4ab83a59b0f8ac4f0029018559fc4c7d042e1b4552a722e2bfb04f652296/coverage-7.7.1-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88d96127ae01ff571d465d4b0be25c123789cef88ba0879194d673fdea52f54e", size = 254616 },
60
- { url = "https://files.pythonhosted.org/packages/db/7a/4224417c0ccdb16a5ba4d8d1fcfaa18439be1624c29435bb9bc88ccabdfb/coverage-7.7.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:0ce92c5a9d7007d838456f4b77ea159cb628187a137e1895331e530973dcf862", size = 255707 },
61
- { url = "https://files.pythonhosted.org/packages/51/20/ff18a329ccaa3d035e2134ecf3a2e92a52d3be6704c76e74ca5589ece260/coverage-7.7.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:0dab4ef76d7b14f432057fdb7a0477e8bffca0ad39ace308be6e74864e632271", size = 253876 },
62
- { url = "https://files.pythonhosted.org/packages/e4/e8/1d6f1a6651672c64f45ffad05306dad9c4c189bec694270822508049b2cb/coverage-7.7.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:7e688010581dbac9cab72800e9076e16f7cccd0d89af5785b70daa11174e94de", size = 254687 },
63
- { url = "https://files.pythonhosted.org/packages/6b/ea/1b9a14cf3e2bc3fd9de23a336a8082091711c5f480b500782d59e84a8fe5/coverage-7.7.1-cp313-cp313t-win32.whl", hash = "sha256:e52eb31ae3afacdacfe50705a15b75ded67935770c460d88c215a9c0c40d0e9c", size = 214486 },
64
- { url = "https://files.pythonhosted.org/packages/cc/bb/faa6bcf769cb7b3b660532a30d77c440289b40636c7f80e498b961295d07/coverage-7.7.1-cp313-cp313t-win_amd64.whl", hash = "sha256:a6b6b3bd121ee2ec4bd35039319f3423d0be282b9752a5ae9f18724bc93ebe7c", size = 215647 },
65
- { url = "https://files.pythonhosted.org/packages/52/26/9f53293ff4cc1d47d98367ce045ca2e62746d6be74a5c6851a474eabf59b/coverage-7.7.1-py3-none-any.whl", hash = "sha256:822fa99dd1ac686061e1219b67868e25d9757989cf2259f735a4802497d6da31", size = 203006 },
35
+ { url = "https://files.pythonhosted.org/packages/aa/12/4792669473297f7973518bec373a955e267deb4339286f882439b8535b39/coverage-7.8.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:bbb5cc845a0292e0c520656d19d7ce40e18d0e19b22cb3e0409135a575bf79fc", size = 211684 },
36
+ { url = "https://files.pythonhosted.org/packages/be/e1/2a4ec273894000ebedd789e8f2fc3813fcaf486074f87fd1c5b2cb1c0a2b/coverage-7.8.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4dfd9a93db9e78666d178d4f08a5408aa3f2474ad4d0e0378ed5f2ef71640cb6", size = 211935 },
37
+ { url = "https://files.pythonhosted.org/packages/f8/3a/7b14f6e4372786709a361729164125f6b7caf4024ce02e596c4a69bccb89/coverage-7.8.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f017a61399f13aa6d1039f75cd467be388d157cd81f1a119b9d9a68ba6f2830d", size = 245994 },
38
+ { url = "https://files.pythonhosted.org/packages/54/80/039cc7f1f81dcbd01ea796d36d3797e60c106077e31fd1f526b85337d6a1/coverage-7.8.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0915742f4c82208ebf47a2b154a5334155ed9ef9fe6190674b8a46c2fb89cb05", size = 242885 },
39
+ { url = "https://files.pythonhosted.org/packages/10/e0/dc8355f992b6cc2f9dcd5ef6242b62a3f73264893bc09fbb08bfcab18eb4/coverage-7.8.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8a40fcf208e021eb14b0fac6bdb045c0e0cab53105f93ba0d03fd934c956143a", size = 245142 },
40
+ { url = "https://files.pythonhosted.org/packages/43/1b/33e313b22cf50f652becb94c6e7dae25d8f02e52e44db37a82de9ac357e8/coverage-7.8.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a1f406a8e0995d654b2ad87c62caf6befa767885301f3b8f6f73e6f3c31ec3a6", size = 244906 },
41
+ { url = "https://files.pythonhosted.org/packages/05/08/c0a8048e942e7f918764ccc99503e2bccffba1c42568693ce6955860365e/coverage-7.8.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:77af0f6447a582fdc7de5e06fa3757a3ef87769fbb0fdbdeba78c23049140a47", size = 243124 },
42
+ { url = "https://files.pythonhosted.org/packages/5b/62/ea625b30623083c2aad645c9a6288ad9fc83d570f9adb913a2abdba562dd/coverage-7.8.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:f2d32f95922927186c6dbc8bc60df0d186b6edb828d299ab10898ef3f40052fe", size = 244317 },
43
+ { url = "https://files.pythonhosted.org/packages/62/cb/3871f13ee1130a6c8f020e2f71d9ed269e1e2124aa3374d2180ee451cee9/coverage-7.8.0-cp312-cp312-win32.whl", hash = "sha256:769773614e676f9d8e8a0980dd7740f09a6ea386d0f383db6821df07d0f08545", size = 214170 },
44
+ { url = "https://files.pythonhosted.org/packages/88/26/69fe1193ab0bfa1eb7a7c0149a066123611baba029ebb448500abd8143f9/coverage-7.8.0-cp312-cp312-win_amd64.whl", hash = "sha256:e5d2b9be5b0693cf21eb4ce0ec8d211efb43966f6657807f6859aab3814f946b", size = 214969 },
45
+ { url = "https://files.pythonhosted.org/packages/f3/21/87e9b97b568e223f3438d93072479c2f36cc9b3f6b9f7094b9d50232acc0/coverage-7.8.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5ac46d0c2dd5820ce93943a501ac5f6548ea81594777ca585bf002aa8854cacd", size = 211708 },
46
+ { url = "https://files.pythonhosted.org/packages/75/be/882d08b28a0d19c9c4c2e8a1c6ebe1f79c9c839eb46d4fca3bd3b34562b9/coverage-7.8.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:771eb7587a0563ca5bb6f622b9ed7f9d07bd08900f7589b4febff05f469bea00", size = 211981 },
47
+ { url = "https://files.pythonhosted.org/packages/7a/1d/ce99612ebd58082fbe3f8c66f6d8d5694976c76a0d474503fa70633ec77f/coverage-7.8.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42421e04069fb2cbcbca5a696c4050b84a43b05392679d4068acbe65449b5c64", size = 245495 },
48
+ { url = "https://files.pythonhosted.org/packages/dc/8d/6115abe97df98db6b2bd76aae395fcc941d039a7acd25f741312ced9a78f/coverage-7.8.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:554fec1199d93ab30adaa751db68acec2b41c5602ac944bb19187cb9a41a8067", size = 242538 },
49
+ { url = "https://files.pythonhosted.org/packages/cb/74/2f8cc196643b15bc096d60e073691dadb3dca48418f08bc78dd6e899383e/coverage-7.8.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5aaeb00761f985007b38cf463b1d160a14a22c34eb3f6a39d9ad6fc27cb73008", size = 244561 },
50
+ { url = "https://files.pythonhosted.org/packages/22/70/c10c77cd77970ac965734fe3419f2c98665f6e982744a9bfb0e749d298f4/coverage-7.8.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:581a40c7b94921fffd6457ffe532259813fc68eb2bdda60fa8cc343414ce3733", size = 244633 },
51
+ { url = "https://files.pythonhosted.org/packages/38/5a/4f7569d946a07c952688debee18c2bb9ab24f88027e3d71fd25dbc2f9dca/coverage-7.8.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:f319bae0321bc838e205bf9e5bc28f0a3165f30c203b610f17ab5552cff90323", size = 242712 },
52
+ { url = "https://files.pythonhosted.org/packages/bb/a1/03a43b33f50475a632a91ea8c127f7e35e53786dbe6781c25f19fd5a65f8/coverage-7.8.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:04bfec25a8ef1c5f41f5e7e5c842f6b615599ca8ba8391ec33a9290d9d2db3a3", size = 244000 },
53
+ { url = "https://files.pythonhosted.org/packages/6a/89/ab6c43b1788a3128e4d1b7b54214548dcad75a621f9d277b14d16a80d8a1/coverage-7.8.0-cp313-cp313-win32.whl", hash = "sha256:dd19608788b50eed889e13a5d71d832edc34fc9dfce606f66e8f9f917eef910d", size = 214195 },
54
+ { url = "https://files.pythonhosted.org/packages/12/12/6bf5f9a8b063d116bac536a7fb594fc35cb04981654cccb4bbfea5dcdfa0/coverage-7.8.0-cp313-cp313-win_amd64.whl", hash = "sha256:a9abbccd778d98e9c7e85038e35e91e67f5b520776781d9a1e2ee9d400869487", size = 214998 },
55
+ { url = "https://files.pythonhosted.org/packages/2a/e6/1e9df74ef7a1c983a9c7443dac8aac37a46f1939ae3499424622e72a6f78/coverage-7.8.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:18c5ae6d061ad5b3e7eef4363fb27a0576012a7447af48be6c75b88494c6cf25", size = 212541 },
56
+ { url = "https://files.pythonhosted.org/packages/04/51/c32174edb7ee49744e2e81c4b1414ac9df3dacfcb5b5f273b7f285ad43f6/coverage-7.8.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:95aa6ae391a22bbbce1b77ddac846c98c5473de0372ba5c463480043a07bff42", size = 212767 },
57
+ { url = "https://files.pythonhosted.org/packages/e9/8f/f454cbdb5212f13f29d4a7983db69169f1937e869a5142bce983ded52162/coverage-7.8.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e013b07ba1c748dacc2a80e69a46286ff145935f260eb8c72df7185bf048f502", size = 256997 },
58
+ { url = "https://files.pythonhosted.org/packages/e6/74/2bf9e78b321216d6ee90a81e5c22f912fc428442c830c4077b4a071db66f/coverage-7.8.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d766a4f0e5aa1ba056ec3496243150698dc0481902e2b8559314368717be82b1", size = 252708 },
59
+ { url = "https://files.pythonhosted.org/packages/92/4d/50d7eb1e9a6062bee6e2f92e78b0998848a972e9afad349b6cdde6fa9e32/coverage-7.8.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad80e6b4a0c3cb6f10f29ae4c60e991f424e6b14219d46f1e7d442b938ee68a4", size = 255046 },
60
+ { url = "https://files.pythonhosted.org/packages/40/9e/71fb4e7402a07c4198ab44fc564d09d7d0ffca46a9fb7b0a7b929e7641bd/coverage-7.8.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:b87eb6fc9e1bb8f98892a2458781348fa37e6925f35bb6ceb9d4afd54ba36c73", size = 256139 },
61
+ { url = "https://files.pythonhosted.org/packages/49/1a/78d37f7a42b5beff027e807c2843185961fdae7fe23aad5a4837c93f9d25/coverage-7.8.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:d1ba00ae33be84066cfbe7361d4e04dec78445b2b88bdb734d0d1cbab916025a", size = 254307 },
62
+ { url = "https://files.pythonhosted.org/packages/58/e9/8fb8e0ff6bef5e170ee19d59ca694f9001b2ec085dc99b4f65c128bb3f9a/coverage-7.8.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:f3c38e4e5ccbdc9198aecc766cedbb134b2d89bf64533973678dfcf07effd883", size = 255116 },
63
+ { url = "https://files.pythonhosted.org/packages/56/b0/d968ecdbe6fe0a863de7169bbe9e8a476868959f3af24981f6a10d2b6924/coverage-7.8.0-cp313-cp313t-win32.whl", hash = "sha256:379fe315e206b14e21db5240f89dc0774bdd3e25c3c58c2c733c99eca96f1ada", size = 214909 },
64
+ { url = "https://files.pythonhosted.org/packages/87/e9/d6b7ef9fecf42dfb418d93544af47c940aa83056c49e6021a564aafbc91f/coverage-7.8.0-cp313-cp313t-win_amd64.whl", hash = "sha256:2e4b6b87bb0c846a9315e3ab4be2d52fac905100565f4b92f02c445c8799e257", size = 216068 },
65
+ { url = "https://files.pythonhosted.org/packages/59/f1/4da7717f0063a222db253e7121bd6a56f6fb1ba439dcc36659088793347c/coverage-7.8.0-py3-none-any.whl", hash = "sha256:dbf364b4c5e7bae9250528167dfe40219b62e2d573c854d74be213e1e52069f7", size = 203435 },
66
66
  ]
67
67
 
68
68
  [[package]]
69
69
  name = "haiway"
70
- version = "0.14.0"
70
+ version = "0.15.1"
71
71
  source = { editable = "." }
72
72
 
73
73
  [package.optional-dependencies]
@@ -172,15 +172,15 @@ wheels = [
172
172
 
173
173
  [[package]]
174
174
  name = "pyright"
175
- version = "1.1.397"
175
+ version = "1.1.398"
176
176
  source = { registry = "https://pypi.org/simple" }
177
177
  dependencies = [
178
178
  { name = "nodeenv" },
179
179
  { name = "typing-extensions" },
180
180
  ]
181
- sdist = { url = "https://files.pythonhosted.org/packages/92/23/cefa10c9cb198e0858ed0b9233371d62bca880337f628e58f50dfdfb12f0/pyright-1.1.397.tar.gz", hash = "sha256:07530fd65a449e4b0b28dceef14be0d8e0995a7a5b1bb2f3f897c3e548451ce3", size = 3818998 }
181
+ sdist = { url = "https://files.pythonhosted.org/packages/24/d6/48740f1d029e9fc4194880d1ad03dcf0ba3a8f802e0e166b8f63350b3584/pyright-1.1.398.tar.gz", hash = "sha256:357a13edd9be8082dc73be51190913e475fa41a6efb6ec0d4b7aab3bc11638d8", size = 3892675 }
182
182
  wheels = [
183
- { url = "https://files.pythonhosted.org/packages/01/b5/98ec41e1e0ad5576ecd42c90ec363560f7b389a441722ea3c7207682dec7/pyright-1.1.397-py3-none-any.whl", hash = "sha256:2e93fba776e714a82b085d68f8345b01f91ba43e1ab9d513e79b70fc85906257", size = 5693631 },
183
+ { url = "https://files.pythonhosted.org/packages/58/e0/5283593f61b3c525d6d7e94cfb6b3ded20b3df66e953acaf7bb4f23b3f6e/pyright-1.1.398-py3-none-any.whl", hash = "sha256:0a70bfd007d9ea7de1cf9740e1ad1a40a122592cfe22a3f6791b06162ad08753", size = 5780235 },
184
184
  ]
185
185
 
186
186
  [[package]]
@@ -251,15 +251,15 @@ wheels = [
251
251
 
252
252
  [[package]]
253
253
  name = "rich"
254
- version = "13.9.4"
254
+ version = "14.0.0"
255
255
  source = { registry = "https://pypi.org/simple" }
256
256
  dependencies = [
257
257
  { name = "markdown-it-py" },
258
258
  { name = "pygments" },
259
259
  ]
260
- sdist = { url = "https://files.pythonhosted.org/packages/ab/3a/0316b28d0761c6734d6bc14e770d85506c986c85ffb239e688eeaab2c2bc/rich-13.9.4.tar.gz", hash = "sha256:439594978a49a09530cff7ebc4b5c7103ef57baf48d5ea3184f21d9a2befa098", size = 223149 }
260
+ sdist = { url = "https://files.pythonhosted.org/packages/a1/53/830aa4c3066a8ab0ae9a9955976fb770fe9c6102117c8ec4ab3ea62d89e8/rich-14.0.0.tar.gz", hash = "sha256:82f1bc23a6a21ebca4ae0c45af9bdbc492ed20231dcb63f297d6d1021a9d5725", size = 224078 }
261
261
  wheels = [
262
- { url = "https://files.pythonhosted.org/packages/19/71/39c7c0d87f8d4e6c020a393182060eaefeeae6c01dab6a84ec346f2567df/rich-13.9.4-py3-none-any.whl", hash = "sha256:6049d5e6ec054bf2779ab3358186963bac2ea89175919d699e378b99738c2a90", size = 242424 },
262
+ { url = "https://files.pythonhosted.org/packages/0d/9b/63f4c7ebc259242c89b3acafdb37b41d1185c07ff0011164674e9076b491/rich-14.0.0-py3-none-any.whl", hash = "sha256:1c9491e1951aac09caffd42f448ee3d04e58923ffe14993f6e83068dc395d7e0", size = 243229 },
263
263
  ]
264
264
 
265
265
  [[package]]
@@ -289,11 +289,11 @@ wheels = [
289
289
 
290
290
  [[package]]
291
291
  name = "setuptools"
292
- version = "77.0.3"
292
+ version = "78.1.0"
293
293
  source = { registry = "https://pypi.org/simple" }
294
- sdist = { url = "https://files.pythonhosted.org/packages/81/ed/7101d53811fd359333583330ff976e5177c5e871ca8b909d1d6c30553aa3/setuptools-77.0.3.tar.gz", hash = "sha256:583b361c8da8de57403743e756609670de6fb2345920e36dc5c2d914c319c945", size = 1367236 }
294
+ sdist = { url = "https://files.pythonhosted.org/packages/a9/5a/0db4da3bc908df06e5efae42b44e75c81dd52716e10192ff36d0c1c8e379/setuptools-78.1.0.tar.gz", hash = "sha256:18fd474d4a82a5f83dac888df697af65afa82dec7323d09c3e37d1f14288da54", size = 1367827 }
295
295
  wheels = [
296
- { url = "https://files.pythonhosted.org/packages/a9/07/99f2cefae815c66eb23148f15d79ec055429c38fa8986edcc712ab5f3223/setuptools-77.0.3-py3-none-any.whl", hash = "sha256:67122e78221da5cf550ddd04cf8742c8fe12094483749a792d56cd669d6cf58c", size = 1255678 },
296
+ { url = "https://files.pythonhosted.org/packages/54/21/f43f0a1fa8b06b32812e0975981f4677d28e0f3271601dc88ac5a5b83220/setuptools-78.1.0-py3-none-any.whl", hash = "sha256:3e386e96793c8702ae83d17b853fb93d3e09ef82ec62722e61da5cd22376dcd8", size = 1256108 },
297
297
  ]
298
298
 
299
299
  [[package]]
@@ -310,9 +310,9 @@ wheels = [
310
310
 
311
311
  [[package]]
312
312
  name = "typing-extensions"
313
- version = "4.12.2"
313
+ version = "4.13.0"
314
314
  source = { registry = "https://pypi.org/simple" }
315
- sdist = { url = "https://files.pythonhosted.org/packages/df/db/f35a00659bc03fec321ba8bce9420de607a1d37f8342eee1863174c69557/typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8", size = 85321 }
315
+ sdist = { url = "https://files.pythonhosted.org/packages/0e/3e/b00a62db91a83fff600de219b6ea9908e6918664899a2d85db222f4fbf19/typing_extensions-4.13.0.tar.gz", hash = "sha256:0a4ac55a5820789d87e297727d229866c9650f6521b64206413c4fbada24d95b", size = 106520 }
316
316
  wheels = [
317
- { url = "https://files.pythonhosted.org/packages/26/9f/ad63fc0248c5379346306f8668cda6e2e2e9c95e01216d2b8ffd9ff037d0/typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d", size = 37438 },
317
+ { url = "https://files.pythonhosted.org/packages/e0/86/39b65d676ec5732de17b7e3c476e45bb80ec64eb50737a8dce1a4178aba1/typing_extensions-4.13.0-py3-none-any.whl", hash = "sha256:c8dd92cc0d6425a97c18fbb9d1954e5ff92c1ca881a309c45f06ebc0b79058e5", size = 45683 },
318
318
  ]
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes