dycw-utilities 0.136.3__tar.gz → 0.136.5__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 (218) hide show
  1. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/PKG-INFO +1 -1
  2. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/pyproject.toml +4 -5
  3. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_hypothesis.py +43 -1
  4. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_libcst.py +17 -17
  5. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/utilities/__init__.py +1 -1
  6. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/utilities/hypothesis.py +80 -3
  7. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/utilities/libcst.py +11 -11
  8. dycw_utilities-0.136.3/src/tests/test_arq.py +0 -58
  9. dycw_utilities-0.136.3/src/utilities/arq.py +0 -216
  10. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/.gitignore +0 -0
  11. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/LICENSE +0 -0
  12. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/README.md +0 -0
  13. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/__init__.py +0 -0
  14. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/conftest.py +0 -0
  15. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/modules/__init__.py +0 -0
  16. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/modules/package_missing/__init__.py +0 -0
  17. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/modules/package_missing/module.py +0 -0
  18. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/modules/package_with/__init__.py +0 -0
  19. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/modules/package_with/outer_1.py +0 -0
  20. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/modules/package_with/outer_2.py +0 -0
  21. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/modules/package_with/subpackage/__init__.py +0 -0
  22. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/modules/package_with/subpackage/inner_1.py +0 -0
  23. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/modules/package_with/subpackage/inner_2.py +0 -0
  24. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/modules/package_with/subpackage/inner_3.py +0 -0
  25. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/modules/package_without/__init__.py +0 -0
  26. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/modules/package_without/module_1.py +0 -0
  27. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/modules/package_without/module_2.py +0 -0
  28. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/modules/standalone.py +0 -0
  29. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/modules/with_imports.py +0 -0
  30. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/regressions/test_pytest_regressions/TestMultipleRegressionFixtures__test_main__obj.json +0 -0
  31. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/regressions/test_pytest_regressions/TestMultipleRegressionFixtures__test_main__series.json +0 -0
  32. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_int.json +0 -0
  33. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_literal__false.json +0 -0
  34. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_literal__true.json +0 -0
  35. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_nested.json +0 -0
  36. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/regressions/test_pytest_regressions/TestPolarsRegressionFixture__test_dataframe.json +0 -0
  37. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/regressions/test_pytest_regressions/TestPolarsRegressionFixture__test_series.json +0 -0
  38. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_aiolimiter.py +0 -0
  39. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_altair.py +0 -0
  40. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_asyncio.py +0 -0
  41. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_asyncio_classes/__init__.py +0 -0
  42. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_asyncio_classes/loopers.py +0 -0
  43. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_asyncio_classes/redis.py +0 -0
  44. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_atomicwrites.py +0 -0
  45. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_atools.py +0 -0
  46. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_cachetools.py +0 -0
  47. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_click.py +0 -0
  48. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_concurrent.py +0 -0
  49. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_contextlib.py +0 -0
  50. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_contextvars.py +0 -0
  51. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_cryptography.py +0 -0
  52. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_cvxpy.py +0 -0
  53. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_dataclasses.py +0 -0
  54. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_enum.py +0 -0
  55. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_errors.py +0 -0
  56. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_eventkit.py +0 -0
  57. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_fastapi.py +0 -0
  58. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_fpdf2.py +0 -0
  59. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_functions.py +0 -0
  60. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_functools.py +0 -0
  61. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_getpass.py +0 -0
  62. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_git.py +0 -0
  63. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_hashlib.py +0 -0
  64. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_http.py +0 -0
  65. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_importlib.py +0 -0
  66. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_inflect.py +0 -0
  67. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_ipython.py +0 -0
  68. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_iterables.py +0 -0
  69. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_jupyter.py +0 -0
  70. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_lightweight_charts.py +0 -0
  71. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_logging.py +0 -0
  72. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_luigi.py +0 -0
  73. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_math.py +0 -0
  74. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_memory_profiler.py +0 -0
  75. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_modules.py +0 -0
  76. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_more_itertools.py +0 -0
  77. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_numpy.py +0 -0
  78. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_objects/__init__.py +0 -0
  79. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_objects/objects.py +0 -0
  80. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_operator.py +0 -0
  81. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_optuna.py +0 -0
  82. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_orjson.py +0 -0
  83. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_os.py +0 -0
  84. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_parse.py +0 -0
  85. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_pathlib.py +0 -0
  86. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_period.py +0 -0
  87. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_pickle.py +0 -0
  88. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_platform.py +0 -0
  89. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_polars.py +0 -0
  90. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_polars_ols.py +0 -0
  91. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_pottery.py +0 -0
  92. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_pqdm.py +0 -0
  93. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_psutil.py +0 -0
  94. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_pydantic.py +0 -0
  95. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_pyinstrument.py +0 -0
  96. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_pytest.py +0 -0
  97. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_pytest_regressions.py +0 -0
  98. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_python_dotenv.py +0 -0
  99. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_random.py +0 -0
  100. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_re.py +0 -0
  101. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_redis.py +0 -0
  102. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_reprlib.py +0 -0
  103. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_scipy.py +0 -0
  104. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_sentinel.py +0 -0
  105. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_shelve.py +0 -0
  106. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_slack_sdk.py +0 -0
  107. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_socket.py +0 -0
  108. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_sqlalchemy.py +0 -0
  109. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_sqlalchemy_polars.py +0 -0
  110. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_statsmodels.py +0 -0
  111. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_streamlit.py +0 -0
  112. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_string.py +0 -0
  113. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_tempfile.py +0 -0
  114. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_text.py +0 -0
  115. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_threading.py +0 -0
  116. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_timer.py +0 -0
  117. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_traceback.py +0 -0
  118. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_typed_settings.py +0 -0
  119. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_types.py +0 -0
  120. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_typing.py +0 -0
  121. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_typing_funcs/__init__.py +0 -0
  122. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_typing_funcs/no_future.py +0 -0
  123. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_typing_funcs/with_future.py +0 -0
  124. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_tzdata.py +0 -0
  125. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_tzlocal.py +0 -0
  126. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_uuid.py +0 -0
  127. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_version.py +0 -0
  128. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_warnings.py +0 -0
  129. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_whenever.py +0 -0
  130. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_zipfile.py +0 -0
  131. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/tests/test_zoneinfo.py +0 -0
  132. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/utilities/aiolimiter.py +0 -0
  133. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/utilities/altair.py +0 -0
  134. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/utilities/asyncio.py +0 -0
  135. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/utilities/atomicwrites.py +0 -0
  136. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/utilities/atools.py +0 -0
  137. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/utilities/cachetools.py +0 -0
  138. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/utilities/click.py +0 -0
  139. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/utilities/concurrent.py +0 -0
  140. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/utilities/contextlib.py +0 -0
  141. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/utilities/contextvars.py +0 -0
  142. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/utilities/cryptography.py +0 -0
  143. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/utilities/cvxpy.py +0 -0
  144. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/utilities/dataclasses.py +0 -0
  145. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/utilities/enum.py +0 -0
  146. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/utilities/errors.py +0 -0
  147. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/utilities/eventkit.py +0 -0
  148. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/utilities/fastapi.py +0 -0
  149. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/utilities/fpdf2.py +0 -0
  150. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/utilities/functions.py +0 -0
  151. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/utilities/functools.py +0 -0
  152. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/utilities/getpass.py +0 -0
  153. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/utilities/git.py +0 -0
  154. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/utilities/hashlib.py +0 -0
  155. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/utilities/http.py +0 -0
  156. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/utilities/importlib.py +0 -0
  157. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/utilities/inflect.py +0 -0
  158. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/utilities/ipython.py +0 -0
  159. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/utilities/iterables.py +0 -0
  160. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/utilities/jupyter.py +0 -0
  161. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/utilities/lightweight_charts.py +0 -0
  162. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/utilities/logging.py +0 -0
  163. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/utilities/luigi.py +0 -0
  164. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/utilities/math.py +0 -0
  165. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/utilities/memory_profiler.py +0 -0
  166. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/utilities/modules.py +0 -0
  167. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/utilities/more_itertools.py +0 -0
  168. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/utilities/numpy.py +0 -0
  169. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/utilities/operator.py +0 -0
  170. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/utilities/optuna.py +0 -0
  171. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/utilities/orjson.py +0 -0
  172. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/utilities/os.py +0 -0
  173. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/utilities/parse.py +0 -0
  174. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/utilities/pathlib.py +0 -0
  175. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/utilities/period.py +0 -0
  176. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/utilities/pickle.py +0 -0
  177. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/utilities/platform.py +0 -0
  178. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/utilities/polars.py +0 -0
  179. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/utilities/polars_ols.py +0 -0
  180. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/utilities/pottery.py +0 -0
  181. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/utilities/pqdm.py +0 -0
  182. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/utilities/psutil.py +0 -0
  183. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/utilities/py.typed +0 -0
  184. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/utilities/pydantic.py +0 -0
  185. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/utilities/pyinstrument.py +0 -0
  186. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/utilities/pytest.py +0 -0
  187. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/utilities/pytest_regressions.py +0 -0
  188. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/utilities/python_dotenv.py +0 -0
  189. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/utilities/random.py +0 -0
  190. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/utilities/re.py +0 -0
  191. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/utilities/redis.py +0 -0
  192. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/utilities/reprlib.py +0 -0
  193. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/utilities/scipy.py +0 -0
  194. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/utilities/sentinel.py +0 -0
  195. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/utilities/shelve.py +0 -0
  196. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/utilities/slack_sdk.py +0 -0
  197. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/utilities/socket.py +0 -0
  198. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/utilities/sqlalchemy.py +0 -0
  199. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/utilities/sqlalchemy_polars.py +0 -0
  200. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/utilities/statsmodels.py +0 -0
  201. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/utilities/streamlit.py +0 -0
  202. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/utilities/string.py +0 -0
  203. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/utilities/tempfile.py +0 -0
  204. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/utilities/text.py +0 -0
  205. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/utilities/threading.py +0 -0
  206. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/utilities/timer.py +0 -0
  207. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/utilities/traceback.py +0 -0
  208. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/utilities/typed_settings.py +0 -0
  209. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/utilities/types.py +0 -0
  210. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/utilities/typing.py +0 -0
  211. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/utilities/tzdata.py +0 -0
  212. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/utilities/tzlocal.py +0 -0
  213. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/utilities/uuid.py +0 -0
  214. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/utilities/version.py +0 -0
  215. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/utilities/warnings.py +0 -0
  216. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/utilities/whenever.py +0 -0
  217. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/utilities/zipfile.py +0 -0
  218. {dycw_utilities-0.136.3 → dycw_utilities-0.136.5}/src/utilities/zoneinfo.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dycw-utilities
3
- Version: 0.136.3
3
+ Version: 0.136.5
4
4
  Author-email: Derek Wan <d.wan@icloud.com>
5
5
  License-File: LICENSE
6
6
  Requires-Python: >=3.12
@@ -14,7 +14,6 @@ altair-test = [
14
14
  "img2pdf",
15
15
  "vl-convert-python",
16
16
  ]
17
- arq = ["arq >= 0.26.3, < 0.27"]
18
17
  atools = ["atools >= 0.14.2, < 0.15"]
19
18
  cachetools = ["cachetools >= 6.1.0, < 6.2"]
20
19
  click = ["click >= 8.2.1, < 8.3"]
@@ -42,7 +41,7 @@ fpdf2 = ["fpdf2 >= 2.8.3, < 2.9"]
42
41
  hashlib-test = ["orjson"]
43
42
  http-test = ["orjson"]
44
43
  hypothesis = ["hypothesis >= 6.135.2, < 6.136"]
45
- hypothesis-test = ["luigi", "pathvalidate", "numpy", "pytest-rerunfailures"]
44
+ hypothesis-test = ["libcst", "luigi", "pathvalidate", "numpy", "pytest-rerunfailures"]
46
45
  inflect = ["inflect >= 7.5.0, < 7.6"]
47
46
  jupyter-test = ["pandas", "polars"]
48
47
  libcst = ["libcst >= 1.8.0, < 1.9"]
@@ -78,7 +77,7 @@ pytest-regressions = ["pytest-regressions >= 2.8.0, < 2.9"]
78
77
  pytest-regressions-test = ["orjson", "polars-lts-cpu"]
79
78
  pytest-test = ["orjson", "pytest-rng", "pytest-rerunfailures"]
80
79
  python-dotenv = ["python-dotenv >= 1.1.0, < 1.2"]
81
- redis = ["redis >= 5.3.0, < 6.0", "orjson"]
80
+ redis = ["redis >= 6.2.0, < 6.3", "orjson"]
82
81
  redis-test = ["pytest-rerunfailures"]
83
82
  reprlib-test = ["rich"]
84
83
  scipy = ["scipy >= 1.15.3, < 1.16"]
@@ -106,7 +105,7 @@ dependencies = [
106
105
  name = "dycw-utilities"
107
106
  readme = "README.md"
108
107
  requires-python = ">= 3.12"
109
- version = "0.136.3"
108
+ version = "0.136.5"
110
109
 
111
110
  [project.optional-dependencies]
112
111
  logging = [
@@ -134,7 +133,7 @@ test = [
134
133
  # bump-my-version
135
134
  [tool.bumpversion]
136
135
  allow_dirty = true
137
- current_version = "0.136.3"
136
+ current_version = "0.136.5"
138
137
 
139
138
  [[tool.bumpversion.files]]
140
139
  filename = "src/utilities/__init__.py"
@@ -21,6 +21,7 @@ from hypothesis.strategies import (
21
21
  sets,
22
22
  timezones,
23
23
  )
24
+ from libcst import Import, ImportFrom
24
25
  from luigi import Task
25
26
  from numpy import inf, int64, isfinite, isinf, isnan, ravel, rint
26
27
  from pathvalidate import validate_filepath
@@ -55,6 +56,8 @@ from utilities.hypothesis import (
55
56
  freqs,
56
57
  git_repos,
57
58
  hashables,
59
+ import_froms,
60
+ imports,
58
61
  int32s,
59
62
  int64s,
60
63
  int_arrays,
@@ -88,6 +91,8 @@ from utilities.hypothesis import (
88
91
  versions,
89
92
  zoned_datetimes,
90
93
  )
94
+ from utilities.iterables import one
95
+ from utilities.libcst import parse_import
91
96
  from utilities.math import (
92
97
  MAX_FLOAT32,
93
98
  MAX_FLOAT64,
@@ -514,6 +519,36 @@ class TestHashables:
514
519
  _ = hash(x)
515
520
 
516
521
 
522
+ class TestImports:
523
+ @given(data=data())
524
+ def test_main(self, *, data: DataObject) -> None:
525
+ min_depth = data.draw(integers(0, 10) | none())
526
+ max_depth = data.draw(integers(0, 10) | none())
527
+ with assume_does_not_raise(InvalidArgument):
528
+ imp = data.draw(imports(min_depth=min_depth, max_depth=max_depth))
529
+ assert isinstance(imp, Import)
530
+ parsed = one(parse_import(imp))
531
+ if min_depth is not None:
532
+ assert len(parsed.module.split(".")) >= min_depth
533
+ if max_depth is not None:
534
+ assert len(parsed.module.split(".")) <= max_depth
535
+
536
+
537
+ class TestImportFroms:
538
+ @given(data=data())
539
+ def test_main(self, *, data: DataObject) -> None:
540
+ min_depth = data.draw(integers(0, 10) | none())
541
+ max_depth = data.draw(integers(0, 10) | none())
542
+ with assume_does_not_raise(InvalidArgument):
543
+ imp = data.draw(import_froms(min_depth=min_depth, max_depth=max_depth))
544
+ assert isinstance(imp, ImportFrom)
545
+ parsed = one(parse_import(imp))
546
+ if min_depth is not None:
547
+ assert len(parsed.module.split(".")) >= min_depth
548
+ if max_depth is not None:
549
+ assert len(parsed.module.split(".")) <= max_depth
550
+
551
+
517
552
  class TestIntArrays:
518
553
  @given(
519
554
  data=data(),
@@ -648,10 +683,17 @@ class TestPairs:
648
683
  class TestPaths:
649
684
  @given(data=data())
650
685
  def test_main(self, *, data: DataObject) -> None:
651
- path = data.draw(paths())
686
+ min_depth = data.draw(integers(0, 10) | none())
687
+ max_depth = data.draw(integers(0, 10) | none())
688
+ with assume_does_not_raise(InvalidArgument):
689
+ path = data.draw(paths(min_depth=min_depth, max_depth=max_depth))
652
690
  assert isinstance(path, Path)
653
691
  assert not path.is_absolute()
654
692
  validate_filepath(str(path))
693
+ if min_depth is not None:
694
+ assert len(path.parts) >= min_depth
695
+ if max_depth is not None:
696
+ assert len(path.parts) <= max_depth
655
697
 
656
698
 
657
699
  class TestPlainDateTimes:
@@ -25,8 +25,8 @@ from utilities.libcst import (
25
25
  _ParseImportAliasError,
26
26
  _ParseImportEmptyModuleError,
27
27
  generate_f_string,
28
- generate_from_import,
29
28
  generate_import,
29
+ generate_import_from,
30
30
  join_dotted_str,
31
31
  parse_import,
32
32
  render_module,
@@ -42,22 +42,6 @@ class TestGenerateFString:
42
42
  assert result == expected
43
43
 
44
44
 
45
- class TestGenerateFromImport:
46
- @given(
47
- case=sampled_from([
48
- ("foo", "bar", None, "from foo import bar"),
49
- ("foo", "bar", "bar2", "from foo import bar as bar2"),
50
- ("foo.bar", "baz", None, "from foo.bar import baz"),
51
- ("foo.bar", "baz", "baz2", "from foo.bar import baz as baz2"),
52
- ])
53
- )
54
- def test_main(self, *, case: tuple[str, str, str | None, str]) -> None:
55
- module, name, asname, expected = case
56
- imp = generate_from_import(module, name, asname=asname)
57
- result = Module([SimpleStatementLine([imp])]).code.strip("\n")
58
- assert result == expected
59
-
60
-
61
45
  class TestGenerateImport:
62
46
  @given(
63
47
  case=sampled_from([
@@ -74,6 +58,22 @@ class TestGenerateImport:
74
58
  assert result == expected
75
59
 
76
60
 
61
+ class TestGenerateImportFrom:
62
+ @given(
63
+ case=sampled_from([
64
+ ("foo", "bar", None, "from foo import bar"),
65
+ ("foo", "bar", "bar2", "from foo import bar as bar2"),
66
+ ("foo.bar", "baz", None, "from foo.bar import baz"),
67
+ ("foo.bar", "baz", "baz2", "from foo.bar import baz as baz2"),
68
+ ])
69
+ )
70
+ def test_main(self, *, case: tuple[str, str, str | None, str]) -> None:
71
+ module, name, asname, expected = case
72
+ imp = generate_import_from(module, name, asname=asname)
73
+ result = Module([SimpleStatementLine([imp])]).code.strip("\n")
74
+ assert result == expected
75
+
76
+
77
77
  class TestParseImport:
78
78
  def test_import_one_name(self) -> None:
79
79
  imp = Import(names=[ImportAlias(Name("foo"))])
@@ -1,3 +1,3 @@
1
1
  from __future__ import annotations
2
2
 
3
- __version__ = "0.136.3"
3
+ __version__ = "0.136.5"
@@ -106,6 +106,7 @@ if TYPE_CHECKING:
106
106
  from collections.abc import Collection, Hashable, Iterable, Iterator
107
107
 
108
108
  from hypothesis.database import ExampleDatabase
109
+ from libcst import Import, ImportFrom
109
110
  from numpy.random import RandomState
110
111
 
111
112
  from utilities.numpy import NDArrayB, NDArrayF, NDArrayI, NDArrayO
@@ -555,6 +556,59 @@ def hashables() -> SearchStrategy[Hashable]:
555
556
  ##
556
557
 
557
558
 
559
+ @composite
560
+ def import_froms(
561
+ draw: DrawFn,
562
+ /,
563
+ *,
564
+ min_depth: MaybeSearchStrategy[int | None] = None,
565
+ max_depth: MaybeSearchStrategy[int | None] = None,
566
+ ) -> ImportFrom:
567
+ """Strategy for generating import-froms."""
568
+ from utilities.libcst import generate_import_from
569
+
570
+ min_depth_, max_depth_ = [draw2(draw, d) for d in [min_depth, max_depth]]
571
+ path = draw(
572
+ paths(
573
+ min_depth=1 if min_depth_ is None else max(min_depth_, 1),
574
+ max_depth=max_depth_,
575
+ )
576
+ )
577
+ module = ".".join(path.parts)
578
+ name = draw(text_ascii(min_size=1))
579
+ asname = draw(text_ascii(min_size=1) | none())
580
+ return generate_import_from(module, name, asname=asname)
581
+
582
+
583
+ ##
584
+
585
+
586
+ @composite
587
+ def imports(
588
+ draw: DrawFn,
589
+ /,
590
+ *,
591
+ min_depth: MaybeSearchStrategy[int | None] = None,
592
+ max_depth: MaybeSearchStrategy[int | None] = None,
593
+ ) -> Import:
594
+ """Strategy for generating imports."""
595
+ from utilities.libcst import generate_import
596
+
597
+ min_depth_, max_depth_ = [draw2(draw, d) for d in [min_depth, max_depth]]
598
+ path = draw(
599
+ paths(
600
+ min_depth=1 if min_depth_ is None else max(min_depth_, 1),
601
+ max_depth=max_depth_,
602
+ )
603
+ )
604
+ module = ".".join(path.parts)
605
+ asname = draw(text_ascii(min_size=1) | none())
606
+ return generate_import(module, asname=asname)
607
+
608
+
609
+ ##
610
+
611
+
558
612
  @composite
559
613
  def int_arrays(
560
614
  draw: DrawFn,
@@ -746,11 +800,32 @@ def _pairs_map[T](elements: list[T], /) -> tuple[T, T]:
746
800
  ##
747
801
 
748
802
 
749
- def paths() -> SearchStrategy[Path]:
803
+ @composite
804
+ def paths(
805
+ draw: DrawFn,
806
+ /,
807
+ *,
808
+ min_depth: MaybeSearchStrategy[int | None] = None,
809
+ max_depth: MaybeSearchStrategy[int | None] = None,
810
+ ) -> Path:
750
811
  """Strategy for generating `Path`s."""
812
+ min_depth_, max_depth_ = [draw2(draw, d) for d in [min_depth, max_depth]]
813
+ parts = draw(
814
+ lists(
815
+ _path_parts(),
816
+ min_size=0 if min_depth_ is None else min_depth_,
817
+ max_size=max_depth_,
818
+ )
819
+ )
820
+ return Path(*parts)
821
+
822
+
823
+ @composite
824
+ def _path_parts(draw: DrawFn, /) -> str:
825
+ part = draw(text_ascii(min_size=1, max_size=10))
751
826
  reserved = {"AUX", "NUL"}
752
- strategy = text_ascii(min_size=1, max_size=10).filter(lambda x: x not in reserved)
753
- return lists(strategy, max_size=10).map(lambda parts: Path(*parts))
827
+ _ = assume(part not in reserved)
828
+ return part
754
829
 
755
830
 
756
831
  ##
@@ -1292,6 +1367,8 @@ __all__ = [
1292
1367
  "freqs",
1293
1368
  "git_repos",
1294
1369
  "hashables",
1370
+ "import_froms",
1371
+ "imports",
1295
1372
  "int32s",
1296
1373
  "int64s",
1297
1374
  "int_arrays",
@@ -23,16 +23,6 @@ from libcst import (
23
23
  from utilities.errors import ImpossibleCaseError
24
24
 
25
25
 
26
- def generate_from_import(
27
- module: str, name: str, /, *, asname: str | None = None
28
- ) -> ImportFrom:
29
- """Generate an `ImportFrom` object."""
30
- alias = ImportAlias(
31
- name=Name(name), asname=AsName(Name(asname)) if asname else None
32
- )
33
- return ImportFrom(module=split_dotted_str(module), names=[alias])
34
-
35
-
36
26
  def generate_f_string(var: str, suffix: str, /) -> FormattedString:
37
27
  """Generate an f-string."""
38
28
  return FormattedString([
@@ -49,6 +39,16 @@ def generate_import(module: str, /, *, asname: str | None = None) -> Import:
49
39
  return Import(names=[alias])
50
40
 
51
41
 
42
+ def generate_import_from(
43
+ module: str, name: str, /, *, asname: str | None = None
44
+ ) -> ImportFrom:
45
+ """Generate an `ImportFrom` object."""
46
+ alias = ImportAlias(
47
+ name=Name(name), asname=AsName(Name(asname)) if asname else None
48
+ )
49
+ return ImportFrom(module=split_dotted_str(module), names=[alias])
50
+
51
+
52
52
  ##
53
53
 
54
54
 
@@ -170,8 +170,8 @@ def render_module(source: str | Module, /) -> str:
170
170
  __all__ = [
171
171
  "ParseImportError",
172
172
  "generate_f_string",
173
- "generate_from_import",
174
173
  "generate_import",
174
+ "generate_import_from",
175
175
  "join_dotted_str",
176
176
  "parse_import",
177
177
  "render_module",
@@ -1,58 +0,0 @@
1
- from __future__ import annotations
2
-
3
- from asyncio import sleep
4
- from typing import TYPE_CHECKING, Any, cast
5
-
6
- from arq.connections import ArqRedis
7
- from hypothesis import given
8
- from hypothesis.strategies import integers
9
-
10
- from tests.conftest import SKIPIF_CI_AND_NOT_LINUX
11
- from utilities.arq import Worker, cron_raw, job_enqueuer
12
- from utilities.iterables import one
13
-
14
- if TYPE_CHECKING:
15
- from collections.abc import Callable, Sequence
16
-
17
- from arq.typing import WorkerCoroutine
18
-
19
- from utilities.types import Coro
20
-
21
-
22
- class TestCronRaw:
23
- @given(x=integers(), y=integers())
24
- async def test_main(self, *, x: int, y: int) -> None:
25
- async def func(x: int, y: int, /) -> int:
26
- await sleep(0.01)
27
- return x + y
28
-
29
- job = cron_raw(func, args=(x, y))
30
- result = await job.coroutine({})
31
- assert result == (x + y)
32
-
33
-
34
- class TestJobEnqueuer:
35
- @given(x=integers(), y=integers())
36
- @SKIPIF_CI_AND_NOT_LINUX
37
- async def test_main(self, *, x: int, y: int) -> None:
38
- async def func(x: int, y: int, /) -> int:
39
- await sleep(0.01)
40
- return x + y
41
-
42
- redis = ArqRedis(db=15)
43
- _ = await job_enqueuer.settings(queue_name="test")(redis, func, x, y)
44
-
45
-
46
- class TestWorker:
47
- @given(x=integers(), y=integers())
48
- async def test_main(self, *, x: int, y: int) -> None:
49
- async def func(x: int, y: int, /) -> int:
50
- await sleep(0.01)
51
- return x + y
52
-
53
- class Example(Worker):
54
- functions_raw: Sequence[Callable[..., Coro[Any]]] = [func]
55
-
56
- func_use = cast("WorkerCoroutine", one(Example.functions))
57
- result = await func_use({}, x, y)
58
- assert result == (x + y)
@@ -1,216 +0,0 @@
1
- from __future__ import annotations
2
-
3
- from dataclasses import dataclass
4
- from functools import wraps
5
- from itertools import chain
6
- from typing import TYPE_CHECKING, Any, Self, cast, override
7
-
8
- from arq.constants import default_queue_name, expires_extra_ms
9
- from arq.cron import cron
10
-
11
- from utilities.dataclasses import replace_non_sentinel
12
- from utilities.sentinel import Sentinel, sentinel
13
-
14
- if TYPE_CHECKING:
15
- from collections.abc import Callable, Iterable, Sequence
16
- from datetime import datetime, timedelta, timezone
17
-
18
- from arq.connections import ArqRedis, RedisSettings
19
- from arq.cron import CronJob
20
- from arq.jobs import Deserializer, Job, Serializer
21
- from arq.typing import (
22
- OptionType,
23
- SecondsTimedelta,
24
- StartupShutdown,
25
- WeekdayOptionType,
26
- WorkerCoroutine,
27
- )
28
- from arq.worker import Function
29
-
30
- from utilities.types import Coro, StrMapping
31
-
32
-
33
- def cron_raw(
34
- coroutine: Callable[..., Coro[Any]],
35
- /,
36
- *,
37
- name: str | None = None,
38
- month: OptionType = None,
39
- day: OptionType = None,
40
- weekday: WeekdayOptionType = None,
41
- hour: OptionType = None,
42
- minute: OptionType = None,
43
- second: OptionType = 0,
44
- microsecond: int = 123_456,
45
- run_at_startup: bool = False,
46
- unique: bool = True,
47
- job_id: str | None = None,
48
- timeout: SecondsTimedelta | None = None,
49
- keep_result: float | None = 0,
50
- keep_result_forever: bool | None = False,
51
- max_tries: int | None = 1,
52
- args: Iterable[Any] | None = None,
53
- kwargs: StrMapping | None = None,
54
- ) -> CronJob:
55
- """Create a cron job with a raw coroutine function."""
56
- lifted = _lift_cron(
57
- coroutine, *(() if args is None else args), **({} if kwargs is None else kwargs)
58
- )
59
- return cron(
60
- lifted,
61
- name=name,
62
- month=month,
63
- day=day,
64
- weekday=weekday,
65
- hour=hour,
66
- minute=minute,
67
- second=second,
68
- microsecond=microsecond,
69
- run_at_startup=run_at_startup,
70
- unique=unique,
71
- job_id=job_id,
72
- timeout=timeout,
73
- keep_result=keep_result,
74
- keep_result_forever=keep_result_forever,
75
- max_tries=max_tries,
76
- )
77
-
78
-
79
- def _lift_cron[**P, T](
80
- func: Callable[P, Coro[T]], *args: P.args, **kwargs: P.kwargs
81
- ) -> WorkerCoroutine:
82
- """Lift a coroutine function & call arg/kwargs for `cron`."""
83
-
84
- @wraps(func)
85
- async def wrapped(ctx: StrMapping, /) -> T:
86
- _ = ctx
87
- return await func(*args, **kwargs)
88
-
89
- return cast("Any", wrapped)
90
-
91
-
92
- ##
93
-
94
-
95
- @dataclass(kw_only=True, slots=True)
96
- class _JobEnqueuer:
97
- """Enqueuer of jobs."""
98
-
99
- job_id: str | None = None
100
- queue_name: str | None = None
101
- defer_until: datetime | None = None
102
- defer_by: int | float | timedelta | None = None
103
- expires: int | float | timedelta | None = None
104
- job_try: int | None = None
105
-
106
- async def __call__[**P, T](
107
- self,
108
- redis: ArqRedis,
109
- function: Callable[P, Coro[T]],
110
- *args: P.args,
111
- **kwargs: P.kwargs,
112
- ) -> Job | None:
113
- return await redis.enqueue_job( # skipif-ci-and-not-linux
114
- function.__name__,
115
- *args,
116
- _job_id=self.job_id,
117
- _queue_name=self.queue_name,
118
- _defer_until=self.defer_until,
119
- _defer_by=self.defer_by,
120
- _expires=self.expires,
121
- _job_try=self.job_try,
122
- **kwargs,
123
- )
124
-
125
- def settings(
126
- self,
127
- *,
128
- job_id: str | None | Sentinel = sentinel,
129
- queue_name: str | None | Sentinel = sentinel,
130
- defer_until: datetime | None | Sentinel = sentinel,
131
- defer_by: float | timedelta | None | Sentinel = sentinel,
132
- expires: float | timedelta | None | Sentinel = sentinel,
133
- job_try: int | None | Sentinel = sentinel,
134
- ) -> Self:
135
- """Replace elements of the enqueuer."""
136
- return replace_non_sentinel( # skipif-ci-and-not-linux
137
- self,
138
- job_id=job_id,
139
- queue_name=queue_name,
140
- defer_until=defer_until,
141
- defer_by=defer_by,
142
- expires=expires,
143
- job_try=job_try,
144
- )
145
-
146
-
147
- job_enqueuer = _JobEnqueuer()
148
-
149
-
150
- ##
151
-
152
-
153
- class _WorkerMeta(type):
154
- @override
155
- def __new__(
156
- mcs: type[_WorkerMeta],
157
- name: str,
158
- bases: tuple[type, ...],
159
- namespace: dict[str, Any],
160
- /,
161
- ) -> type[Worker]:
162
- cls = cast("type[Worker]", super().__new__(mcs, name, bases, namespace))
163
- cls.functions = tuple(chain(cls.functions, map(cls._lift, cls.functions_raw)))
164
- return cls
165
-
166
- @classmethod
167
- def _lift[**P, T](cls, func: Callable[P, Coro[T]]) -> WorkerCoroutine:
168
- """Lift a coroutine function to accept the required `ctx` argument."""
169
-
170
- @wraps(func)
171
- async def wrapped(ctx: StrMapping, *args: P.args, **kwargs: P.kwargs) -> T:
172
- _ = ctx
173
- return await func(*args, **kwargs)
174
-
175
- return cast("Any", wrapped)
176
-
177
-
178
- @dataclass(kw_only=True)
179
- class Worker(metaclass=_WorkerMeta):
180
- """Base class for all workers."""
181
-
182
- functions: Sequence[Function | WorkerCoroutine] = ()
183
- functions_raw: Sequence[Callable[..., Coro[Any]]] = ()
184
- queue_name: str | None = default_queue_name
185
- cron_jobs: Sequence[CronJob] | None = None
186
- redis_settings: RedisSettings | None = None
187
- redis_pool: ArqRedis | None = None
188
- burst: bool = False
189
- on_startup: StartupShutdown | None = None
190
- on_shutdown: StartupShutdown | None = None
191
- on_job_start: StartupShutdown | None = None
192
- on_job_end: StartupShutdown | None = None
193
- after_job_end: StartupShutdown | None = None
194
- handle_signals: bool = True
195
- job_completion_wait: int = 0
196
- max_jobs: int = 10
197
- job_timeout: SecondsTimedelta = 300
198
- keep_result: SecondsTimedelta = 3600
199
- keep_result_forever: bool = False
200
- poll_delay: SecondsTimedelta = 0.5
201
- queue_read_limit: int | None = None
202
- max_tries: int = 5
203
- health_check_interval: SecondsTimedelta = 3600
204
- health_check_key: str | None = None
205
- ctx: dict[Any, Any] | None = None
206
- retry_jobs: bool = True
207
- allow_abort_jobs: bool = False
208
- max_burst_jobs: int = -1
209
- job_serializer: Serializer | None = None
210
- job_deserializer: Deserializer | None = None
211
- expires_extra_ms: int = expires_extra_ms
212
- timezone: timezone | None = None
213
- log_results: bool = True
214
-
215
-
216
- __all__ = ["Worker", "cron", "job_enqueuer"]