dycw-utilities 0.109.15__tar.gz → 0.109.17__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 (226) hide show
  1. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/PKG-INFO +1 -1
  2. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/pyproject.toml +2 -2
  3. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_hypothesis.py +2 -1
  4. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_numpy.py +104 -1
  5. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_orjson.py +2 -1
  6. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/utilities/__init__.py +1 -1
  7. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/utilities/numpy.py +137 -2
  8. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/.gitignore +0 -0
  9. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/LICENSE +0 -0
  10. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/README.md +0 -0
  11. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/__init__.py +0 -0
  12. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/conftest.py +0 -0
  13. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/modules/__init__.py +0 -0
  14. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/modules/package_missing/__init__.py +0 -0
  15. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/modules/package_missing/module.py +0 -0
  16. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/modules/package_with/__init__.py +0 -0
  17. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/modules/package_with/outer_1.py +0 -0
  18. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/modules/package_with/outer_2.py +0 -0
  19. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/modules/package_with/subpackage/__init__.py +0 -0
  20. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/modules/package_with/subpackage/inner_1.py +0 -0
  21. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/modules/package_with/subpackage/inner_2.py +0 -0
  22. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/modules/package_with/subpackage/inner_3.py +0 -0
  23. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/modules/package_without/__init__.py +0 -0
  24. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/modules/package_without/module_1.py +0 -0
  25. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/modules/package_without/module_2.py +0 -0
  26. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/modules/standalone.py +0 -0
  27. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/modules/with_imports.py +0 -0
  28. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/regressions/test_pytest_regressions/TestMultipleRegressionFixtures__test_main__obj.json +0 -0
  29. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/regressions/test_pytest_regressions/TestMultipleRegressionFixtures__test_main__series.json +0 -0
  30. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_int.json +0 -0
  31. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_literal__false.json +0 -0
  32. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_literal__true.json +0 -0
  33. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_nested.json +0 -0
  34. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/regressions/test_pytest_regressions/TestPolarsRegressionFixture__test_dataframe.json +0 -0
  35. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/regressions/test_pytest_regressions/TestPolarsRegressionFixture__test_series.json +0 -0
  36. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/scripts/__init__.py +0 -0
  37. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/scripts/test_async_service/__init__.py +0 -0
  38. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/scripts/test_async_service/__main__.py +0 -0
  39. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/scripts/test_async_service/run.sh +0 -0
  40. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/scripts/test_queue_processor/__init__.py +0 -0
  41. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/scripts/test_queue_processor/__main__.py +0 -0
  42. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/scripts/test_queue_processor/run.sh +0 -0
  43. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_altair.py +0 -0
  44. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_astor.py +0 -0
  45. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_asyncio.py +0 -0
  46. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_atomicwrites.py +0 -0
  47. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_atools.py +0 -0
  48. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_cachetools.py +0 -0
  49. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_click.py +0 -0
  50. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_concurrent.py +0 -0
  51. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_contextlib.py +0 -0
  52. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_contextvars.py +0 -0
  53. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_cryptography.py +0 -0
  54. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_cvxpy.py +0 -0
  55. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_dataclasses.py +0 -0
  56. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_datetime.py +0 -0
  57. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_enum.py +0 -0
  58. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_errors.py +0 -0
  59. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_eventkit.py +0 -0
  60. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_fastapi.py +0 -0
  61. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_fpdf2.py +0 -0
  62. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_functions.py +0 -0
  63. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_functools.py +0 -0
  64. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_getpass.py +0 -0
  65. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_git.py +0 -0
  66. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_hashlib.py +0 -0
  67. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_http.py +0 -0
  68. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_ipython.py +0 -0
  69. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_iterables.py +0 -0
  70. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_jupyter.py +0 -0
  71. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_lightweight_charts.py +0 -0
  72. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_logging.py +0 -0
  73. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_loguru.py +0 -0
  74. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_luigi.py +0 -0
  75. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_math.py +0 -0
  76. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_memory_profiler.py +0 -0
  77. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_modules.py +0 -0
  78. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_more_itertools.py +0 -0
  79. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_operator.py +0 -0
  80. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_optuna.py +0 -0
  81. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_os.py +0 -0
  82. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_parse.py +0 -0
  83. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_pathlib.py +0 -0
  84. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_period.py +0 -0
  85. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_pickle.py +0 -0
  86. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_platform.py +0 -0
  87. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_polars.py +0 -0
  88. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_polars_ols.py +0 -0
  89. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_pqdm.py +0 -0
  90. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_pydantic.py +0 -0
  91. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_pyinstrument.py +0 -0
  92. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_pyrsistent.py +0 -0
  93. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_pytest.py +0 -0
  94. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_pytest_regressions.py +0 -0
  95. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_python_dotenv.py +0 -0
  96. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_random.py +0 -0
  97. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_re.py +0 -0
  98. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_redis.py +0 -0
  99. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_reprlib.py +0 -0
  100. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_rich.py +0 -0
  101. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_scipy.py +0 -0
  102. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_sentinel.py +0 -0
  103. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_shelve.py +0 -0
  104. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_slack_sdk.py +0 -0
  105. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_socket.py +0 -0
  106. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_sqlalchemy.py +0 -0
  107. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_sqlalchemy_polars.py +0 -0
  108. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_streamlit.py +0 -0
  109. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_sys.py +0 -0
  110. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_tempfile.py +0 -0
  111. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_tenacity.py +0 -0
  112. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_text.py +0 -0
  113. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_threading.py +0 -0
  114. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_timer.py +0 -0
  115. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_traceback.py +0 -0
  116. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_traceback_funcs/__init__.py +0 -0
  117. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_traceback_funcs/chain.py +0 -0
  118. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_traceback_funcs/decorated_async.py +0 -0
  119. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_traceback_funcs/decorated_sync.py +0 -0
  120. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_traceback_funcs/error_bind.py +0 -0
  121. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_traceback_funcs/many.py +0 -0
  122. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_traceback_funcs/one.py +0 -0
  123. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_traceback_funcs/recursive.py +0 -0
  124. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_traceback_funcs/task_group_one.py +0 -0
  125. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_traceback_funcs/task_group_two.py +0 -0
  126. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_traceback_funcs/two.py +0 -0
  127. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_traceback_funcs/untraced.py +0 -0
  128. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_types.py +0 -0
  129. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_typing.py +0 -0
  130. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_typing_funcs/__init__.py +0 -0
  131. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_typing_funcs/no_future.py +0 -0
  132. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_typing_funcs/with_future.py +0 -0
  133. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_tzdata.py +0 -0
  134. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_tzlocal.py +0 -0
  135. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_uuid.py +0 -0
  136. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_version.py +0 -0
  137. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_warnings.py +0 -0
  138. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_whenever.py +0 -0
  139. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_zipfile.py +0 -0
  140. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/tests/test_zoneinfo.py +0 -0
  141. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/utilities/altair.py +0 -0
  142. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/utilities/astor.py +0 -0
  143. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/utilities/asyncio.py +0 -0
  144. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/utilities/atomicwrites.py +0 -0
  145. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/utilities/atools.py +0 -0
  146. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/utilities/cachetools.py +0 -0
  147. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/utilities/click.py +0 -0
  148. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/utilities/concurrent.py +0 -0
  149. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/utilities/contextlib.py +0 -0
  150. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/utilities/contextvars.py +0 -0
  151. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/utilities/cryptography.py +0 -0
  152. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/utilities/cvxpy.py +0 -0
  153. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/utilities/dataclasses.py +0 -0
  154. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/utilities/datetime.py +0 -0
  155. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/utilities/enum.py +0 -0
  156. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/utilities/errors.py +0 -0
  157. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/utilities/eventkit.py +0 -0
  158. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/utilities/fastapi.py +0 -0
  159. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/utilities/fpdf2.py +0 -0
  160. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/utilities/functions.py +0 -0
  161. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/utilities/functools.py +0 -0
  162. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/utilities/getpass.py +0 -0
  163. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/utilities/git.py +0 -0
  164. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/utilities/hashlib.py +0 -0
  165. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/utilities/http.py +0 -0
  166. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/utilities/hypothesis.py +0 -0
  167. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/utilities/ipython.py +0 -0
  168. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/utilities/iterables.py +0 -0
  169. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/utilities/jupyter.py +0 -0
  170. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/utilities/lightweight_charts.py +0 -0
  171. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/utilities/logging.py +0 -0
  172. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/utilities/loguru.py +0 -0
  173. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/utilities/luigi.py +0 -0
  174. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/utilities/math.py +0 -0
  175. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/utilities/memory_profiler.py +0 -0
  176. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/utilities/modules.py +0 -0
  177. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/utilities/more_itertools.py +0 -0
  178. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/utilities/operator.py +0 -0
  179. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/utilities/optuna.py +0 -0
  180. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/utilities/orjson.py +0 -0
  181. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/utilities/os.py +0 -0
  182. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/utilities/parse.py +0 -0
  183. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/utilities/pathlib.py +0 -0
  184. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/utilities/period.py +0 -0
  185. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/utilities/pickle.py +0 -0
  186. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/utilities/platform.py +0 -0
  187. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/utilities/polars.py +0 -0
  188. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/utilities/polars_ols.py +0 -0
  189. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/utilities/pqdm.py +0 -0
  190. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/utilities/py.typed +0 -0
  191. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/utilities/pydantic.py +0 -0
  192. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/utilities/pyinstrument.py +0 -0
  193. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/utilities/pyrsistent.py +0 -0
  194. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/utilities/pytest.py +0 -0
  195. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/utilities/pytest_regressions.py +0 -0
  196. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/utilities/python_dotenv.py +0 -0
  197. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/utilities/random.py +0 -0
  198. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/utilities/re.py +0 -0
  199. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/utilities/redis.py +0 -0
  200. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/utilities/reprlib.py +0 -0
  201. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/utilities/rich.py +0 -0
  202. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/utilities/scipy.py +0 -0
  203. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/utilities/sentinel.py +0 -0
  204. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/utilities/shelve.py +0 -0
  205. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/utilities/slack_sdk.py +0 -0
  206. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/utilities/socket.py +0 -0
  207. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/utilities/sqlalchemy.py +0 -0
  208. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/utilities/sqlalchemy_polars.py +0 -0
  209. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/utilities/streamlit.py +0 -0
  210. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/utilities/sys.py +0 -0
  211. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/utilities/tempfile.py +0 -0
  212. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/utilities/tenacity.py +0 -0
  213. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/utilities/text.py +0 -0
  214. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/utilities/threading.py +0 -0
  215. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/utilities/timer.py +0 -0
  216. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/utilities/traceback.py +0 -0
  217. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/utilities/types.py +0 -0
  218. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/utilities/typing.py +0 -0
  219. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/utilities/tzdata.py +0 -0
  220. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/utilities/tzlocal.py +0 -0
  221. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/utilities/uuid.py +0 -0
  222. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/utilities/version.py +0 -0
  223. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/utilities/warnings.py +0 -0
  224. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/utilities/whenever.py +0 -0
  225. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/utilities/zipfile.py +0 -0
  226. {dycw_utilities-0.109.15 → dycw_utilities-0.109.17}/src/utilities/zoneinfo.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dycw-utilities
3
- Version: 0.109.15
3
+ Version: 0.109.17
4
4
  Author-email: Derek Wan <d.wan@icloud.com>
5
5
  License-File: LICENSE
6
6
  Requires-Python: >=3.12
@@ -92,7 +92,7 @@ dependencies = [
92
92
  name = "dycw-utilities"
93
93
  readme = "README.md"
94
94
  requires-python = ">= 3.12"
95
- version = "0.109.15"
95
+ version = "0.109.17"
96
96
 
97
97
  [project.optional-dependencies]
98
98
  test = [
@@ -335,7 +335,7 @@ zzz-test-zoneinfo = [
335
335
  # bump-my-version
336
336
  [tool.bumpversion]
337
337
  allow_dirty = true
338
- current_version = "0.109.15"
338
+ current_version = "0.109.17"
339
339
 
340
340
  [[tool.bumpversion.files]]
341
341
  filename = "src/utilities/__init__.py"
@@ -29,7 +29,7 @@ from hypothesis.strategies import (
29
29
  from luigi import Task
30
30
  from numpy import inf, int64, isfinite, isinf, isnan, ravel, rint
31
31
  from pathvalidate import validate_filepath
32
- from pytest import raises
32
+ from pytest import mark, raises
33
33
  from sqlalchemy import Column, Integer, MetaData, Table, insert, select
34
34
  from sqlalchemy.ext.asyncio import AsyncEngine
35
35
 
@@ -1033,6 +1033,7 @@ class TestTempPaths:
1033
1033
  assert len(set(path.iterdir())) == 0
1034
1034
 
1035
1035
  @given(path=temp_paths(), contents=sets(text_ascii(min_size=1), max_size=10))
1036
+ @mark.flaky
1036
1037
  def test_writing_files(self, *, path: Path, contents: AbstractSet[str]) -> None:
1037
1038
  assert len(set(path.iterdir())) == 0
1038
1039
  as_set = set(maybe_yield_lower_case(contents))
@@ -3,6 +3,7 @@ from __future__ import annotations
3
3
  from re import escape
4
4
  from typing import TYPE_CHECKING, Any, Literal
5
5
 
6
+ import numpy as np
6
7
  from hypothesis import assume, given
7
8
  from hypothesis.strategies import DataObject, data, floats, integers, none
8
9
  from numpy import (
@@ -12,18 +13,21 @@ from numpy import (
12
13
  full,
13
14
  inf,
14
15
  isclose,
16
+ linspace,
15
17
  median,
16
18
  nan,
17
19
  ndarray,
18
20
  ones,
21
+ pi,
19
22
  zeros,
20
23
  zeros_like,
21
24
  )
25
+ from numpy.fft import fft, fftfreq
22
26
  from numpy.random import Generator
23
27
  from numpy.testing import assert_equal
24
28
  from pytest import mark, param, raises
25
29
 
26
- from utilities.hypothesis import float_arrays
30
+ from utilities.hypothesis import float_arrays, pairs
27
31
  from utilities.numpy import (
28
32
  DEFAULT_RNG,
29
33
  AsIntError,
@@ -32,11 +36,18 @@ from utilities.numpy import (
32
36
  NDArrayF,
33
37
  NDArrayI,
34
38
  ShiftError,
39
+ SigmoidError,
40
+ _BoxCarLocationsError,
41
+ _BoxCarLowerBoundSlopeError,
42
+ _BoxCarUpperBoundSlopeError,
35
43
  array_indexer,
36
44
  as_int,
45
+ boxcar,
37
46
  discretize,
38
47
  fillna,
48
+ filter_frequencies,
39
49
  flatn0,
50
+ get_frequency_spectrum,
40
51
  has_dtype,
41
52
  is_at_least,
42
53
  is_at_least_or_nan,
@@ -88,6 +99,7 @@ from utilities.numpy import (
88
99
  minimum,
89
100
  shift,
90
101
  shift_bool,
102
+ sigmoid,
91
103
  )
92
104
 
93
105
  if TYPE_CHECKING:
@@ -246,6 +258,56 @@ class TestDiscretize:
246
258
  assert_equal(result, expected)
247
259
 
248
260
 
261
+ class TestBoxCar:
262
+ @given(
263
+ locs=pairs(floats(-10.0, 10.0), sorted=True),
264
+ slope_low=floats(0.1, 10.0),
265
+ slope_high=floats(0.1, 10.0),
266
+ )
267
+ def test_main(
268
+ self, *, locs: tuple[float, float], slope_low: float, slope_high: float
269
+ ) -> None:
270
+ loc_low, loc_high = locs
271
+ n = 1000
272
+ x = linspace(0, 2 * pi, n)
273
+ y = boxcar(
274
+ x,
275
+ loc_low=loc_low,
276
+ slope_low=slope_low,
277
+ loc_high=loc_high,
278
+ slope_high=slope_high,
279
+ )
280
+ assert y.shape == (n,)
281
+ assert is_between(y, 0.0, 1.0).all()
282
+
283
+ def test_error_locations(self) -> None:
284
+ n = 1000
285
+ x = linspace(0, 2 * pi, n)
286
+ with raises(
287
+ _BoxCarLocationsError,
288
+ match="Location parameters must be consistent; got 1.0 and -1.0",
289
+ ):
290
+ _ = boxcar(x, loc_low=1.0, loc_high=-1.0)
291
+
292
+ def test_error_lower_bound_slope(self) -> None:
293
+ n = 1000
294
+ x = linspace(0, 2 * pi, n)
295
+ with raises(
296
+ _BoxCarLowerBoundSlopeError,
297
+ match="Lower-bound slope parameter must be positive; got 0.0",
298
+ ):
299
+ _ = boxcar(x, slope_low=0.0)
300
+
301
+ def test_error_upper_bound_slope(self) -> None:
302
+ n = 1000
303
+ x = linspace(0, 2 * pi, n)
304
+ with raises(
305
+ _BoxCarUpperBoundSlopeError,
306
+ match="Upper-bound slope parameter must be positive; got 0.0",
307
+ ):
308
+ _ = boxcar(x, slope_high=0.0)
309
+
310
+
249
311
  class TestFillNa:
250
312
  @mark.parametrize(
251
313
  ("init", "value", "expected_v"),
@@ -268,6 +330,19 @@ class TestFillNa:
268
330
  assert_equal(result, expected)
269
331
 
270
332
 
333
+ class TestFilterFrequencies:
334
+ def test_main(self) -> None:
335
+ n = 1000
336
+ x = linspace(0, 2 * pi, n)
337
+ noise = DEFAULT_RNG.normal(scale=0.25, size=n)
338
+ y = x + noise
339
+ result = filter_frequencies(y, lambda f: np.abs(f) <= 0.02)
340
+ assert result.shape == (n,)
341
+ fft_vals = fft(result)
342
+ freqs = fftfreq(n)
343
+ assert np.allclose(fft_vals[np.abs(freqs) > 0.02], 0.0)
344
+
345
+
271
346
  class TestFlatN0:
272
347
  @given(data=data(), n=integers(1, 10))
273
348
  def test_main(self, *, data: DataObject, n: int) -> None:
@@ -288,6 +363,18 @@ class TestFlatN0:
288
363
  _ = flatn0(ones(2, dtype=bool))
289
364
 
290
365
 
366
+ class TestGetFrequencySpectrum:
367
+ def test_main(self) -> None:
368
+ n = 1000
369
+ x = linspace(0, 2 * pi, n)
370
+ noise = DEFAULT_RNG.normal(scale=0.25, size=n)
371
+ y = x + noise
372
+ y2 = filter_frequencies(y, lambda f: np.abs(f) <= 0.02)
373
+ result = get_frequency_spectrum(y2)
374
+ assert result.shape == (n, 2)
375
+ assert np.allclose(result[result[:, 0] > 0.02, 1], 0.0)
376
+
377
+
291
378
  class TestHasDtype:
292
379
  @mark.parametrize(("dtype", "expected"), [param(float, True), param(int, False)])
293
380
  @mark.parametrize("is_tuple", [param(True), param(False)])
@@ -1047,3 +1134,19 @@ class TestShiftBool:
1047
1134
  [fill_value if e is None else e for e in expected_v], dtype=bool
1048
1135
  )
1049
1136
  assert_equal(result, expected)
1137
+
1138
+
1139
+ class TestSigmoid:
1140
+ @given(loc=floats(-10.0, 10.0), slope=floats(-10.0, -0.1) | floats(0.1, 10.0))
1141
+ def test_main(self, *, loc: float, slope: float) -> None:
1142
+ n = 1000
1143
+ x = linspace(0, 2 * pi, n)
1144
+ y = sigmoid(x, loc=loc, slope=slope)
1145
+ assert y.shape == (n,)
1146
+ assert is_between(y, 0.0, 1.0).all()
1147
+
1148
+ def test_error(self) -> None:
1149
+ n = 1000
1150
+ x = linspace(0, 2 * pi, n)
1151
+ with raises(SigmoidError, match="Slope must be non-zero"):
1152
+ _ = sigmoid(x, slope=0.0)
@@ -23,7 +23,7 @@ from hypothesis.strategies import (
23
23
  )
24
24
  from orjson import JSONDecodeError
25
25
  from polars import Object, String, UInt64
26
- from pytest import approx, raises
26
+ from pytest import approx, mark, raises
27
27
 
28
28
  from tests.conftest import SKIPIF_CI_AND_WINDOWS
29
29
  from tests.test_operator import (
@@ -204,6 +204,7 @@ class TestGetLogRecords:
204
204
  min_log_file_line_num=integers() | none(),
205
205
  max_log_file_line_num=integers() | none(),
206
206
  )
207
+ @mark.flaky
207
208
  def test_filter(
208
209
  self,
209
210
  *,
@@ -1,3 +1,3 @@
1
1
  from __future__ import annotations
2
2
 
3
- __version__ = "0.109.15"
3
+ __version__ = "0.109.17"
@@ -1,19 +1,23 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  from dataclasses import dataclass
4
- from functools import reduce
4
+ from functools import partial, reduce
5
5
  from itertools import repeat
6
6
  from typing import TYPE_CHECKING, Any, overload, override
7
7
 
8
8
  import numpy as np
9
9
  from numpy import (
10
+ argsort,
10
11
  array,
11
12
  bool_,
13
+ complex128,
12
14
  digitize,
13
15
  dtype,
14
16
  errstate,
17
+ exp,
15
18
  flatnonzero,
16
19
  float64,
20
+ floating,
17
21
  full_like,
18
22
  inf,
19
23
  int64,
@@ -30,6 +34,7 @@ from numpy import (
30
34
  roll,
31
35
  where,
32
36
  )
37
+ from numpy.fft import fft, fftfreq, ifft
33
38
  from numpy.linalg import det, eig
34
39
  from numpy.random import default_rng
35
40
  from numpy.typing import NDArray
@@ -37,7 +42,7 @@ from numpy.typing import NDArray
37
42
  from utilities.iterables import is_iterable_not_str
38
43
 
39
44
  if TYPE_CHECKING:
40
- from collections.abc import Iterable
45
+ from collections.abc import Callable, Iterable
41
46
 
42
47
 
43
48
  ##
@@ -129,6 +134,65 @@ class AsIntError(Exception): ...
129
134
  ##
130
135
 
131
136
 
137
+ def boxcar(
138
+ array: NDArray[floating[Any]],
139
+ /,
140
+ *,
141
+ loc_low: float = -1.0,
142
+ slope_low: float = 1.0,
143
+ loc_high: float = 1.0,
144
+ slope_high: float = 1.0,
145
+ rtol: float | None = None,
146
+ atol: float | None = None,
147
+ ) -> NDArray[floating[Any]]:
148
+ """Construct a boxcar function."""
149
+ if not is_at_most(loc_low, loc_high, rtol=rtol, atol=atol):
150
+ raise _BoxCarLocationsError(low=loc_low, high=loc_high)
151
+ if not is_positive(slope_low, rtol=rtol, atol=atol):
152
+ raise _BoxCarLowerBoundSlopeError(slope=slope_low)
153
+ if not is_positive(slope_high, rtol=rtol, atol=atol):
154
+ raise _BoxCarUpperBoundSlopeError(slope=slope_high)
155
+ return (
156
+ sigmoid(array, loc=loc_low, slope=slope_low)
157
+ + sigmoid(array, loc=loc_high, slope=-slope_high)
158
+ ) / 2
159
+
160
+
161
+ @dataclass(kw_only=True, slots=True)
162
+ class BoxCarError(Exception): ...
163
+
164
+
165
+ @dataclass(kw_only=True, slots=True)
166
+ class _BoxCarLocationsError(BoxCarError):
167
+ low: float
168
+ high: float
169
+
170
+ @override
171
+ def __str__(self) -> str:
172
+ return f"Location parameters must be consistent; got {self.low} and {self.high}"
173
+
174
+
175
+ @dataclass(kw_only=True, slots=True)
176
+ class _BoxCarLowerBoundSlopeError(BoxCarError):
177
+ slope: float
178
+
179
+ @override
180
+ def __str__(self) -> str:
181
+ return f"Lower-bound slope parameter must be positive; got {self.slope}"
182
+
183
+
184
+ @dataclass(kw_only=True, slots=True)
185
+ class _BoxCarUpperBoundSlopeError(BoxCarError):
186
+ slope: float
187
+
188
+ @override
189
+ def __str__(self) -> str:
190
+ return f"Upper-bound slope parameter must be positive; got {self.slope}"
191
+
192
+
193
+ ##
194
+
195
+
132
196
  def discretize(x: NDArrayF, bins: int | Iterable[float], /) -> NDArrayF:
133
197
  """Discretize an array of floats.
134
198
 
@@ -160,6 +224,33 @@ def fillna(array: NDArrayF, /, *, value: float = 0.0) -> NDArrayF:
160
224
  ##
161
225
 
162
226
 
227
+ def filter_frequencies(
228
+ array: NDArrayF,
229
+ /,
230
+ *filters: Callable[[NDArray[floating[Any]]], NDArrayB],
231
+ d: int = 1,
232
+ ) -> NDArrayF:
233
+ """Filter an array by the frequencies of its FFT."""
234
+ (n,) = array.shape
235
+ fft_vals = fft(array)
236
+ freqs = fftfreq(n, d=d)
237
+ reduced = reduce(partial(_filter_frequencies_one, freqs=freqs), filters, fft_vals)
238
+ return ifft(reduced).real
239
+
240
+
241
+ def _filter_frequencies_one(
242
+ acc: NDArray[complex128],
243
+ el: Callable[[NDArray[floating[Any]]], NDArrayB],
244
+ /,
245
+ *,
246
+ freqs: NDArray[floating[Any]],
247
+ ) -> NDArray[complex128]:
248
+ return where(el(freqs), acc, 0.0)
249
+
250
+
251
+ ##
252
+
253
+
163
254
  def flatn0(array: NDArrayB, /) -> int:
164
255
  """Return the index of the unique True element."""
165
256
  if not array.any():
@@ -193,6 +284,19 @@ class FlatN0MultipleError(FlatN0Error):
193
284
  ##
194
285
 
195
286
 
287
+ def get_frequency_spectrum(array: NDArrayF, /, *, d: int = 1) -> NDArray[floating[Any]]:
288
+ """Get the frequency spectrum."""
289
+ (n,) = array.shape
290
+ fft_vals = fft(array)
291
+ freqs = fftfreq(n, d=d)
292
+ amplitudes = np.abs(fft_vals)
293
+ data = np.hstack([freqs.reshape(-1, 1), amplitudes.reshape(-1, 1)])
294
+ return data[argsort(data[:, 0])]
295
+
296
+
297
+ ##
298
+
299
+
196
300
  def has_dtype(x: Any, dtype: Any, /) -> bool:
197
301
  """Check if an object has the required dtype."""
198
302
  if is_iterable_not_str(dtype):
@@ -803,6 +907,31 @@ def shift_bool(
803
907
  ##
804
908
 
805
909
 
910
+ def sigmoid(
911
+ array: NDArray[floating[Any]],
912
+ /,
913
+ *,
914
+ loc: float = 0.0,
915
+ slope: float = 1.0,
916
+ rtol: float | None = None,
917
+ atol: float | None = None,
918
+ ) -> NDArray[floating[Any]]:
919
+ """Construct a sigmoid function."""
920
+ if is_zero(slope, rtol=rtol, atol=atol):
921
+ raise SigmoidError
922
+ return 1 / (1 + exp(-slope * (array - loc)))
923
+
924
+
925
+ @dataclass(kw_only=True, slots=True)
926
+ class SigmoidError(Exception):
927
+ @override
928
+ def __str__(self) -> str:
929
+ return "Slope must be non-zero"
930
+
931
+
932
+ ##
933
+
934
+
806
935
  def _is_close(
807
936
  x: Any,
808
937
  y: Any,
@@ -825,6 +954,7 @@ def _is_close(
825
954
  __all__ = [
826
955
  "DEFAULT_RNG",
827
956
  "AsIntError",
957
+ "BoxCarError",
828
958
  "FlatN0EmptyError",
829
959
  "FlatN0Error",
830
960
  "FlatN0MultipleError",
@@ -834,8 +964,10 @@ __all__ = [
834
964
  "NDArrayI",
835
965
  "NDArrayO",
836
966
  "ShiftError",
967
+ "SigmoidError",
837
968
  "array_indexer",
838
969
  "as_int",
970
+ "boxcar",
839
971
  "datetime64D",
840
972
  "datetime64M",
841
973
  "datetime64W",
@@ -851,7 +983,9 @@ __all__ = [
851
983
  "datetime64us",
852
984
  "discretize",
853
985
  "fillna",
986
+ "filter_frequencies",
854
987
  "flatn0",
988
+ "get_frequency_spectrum",
855
989
  "has_dtype",
856
990
  "is_at_least",
857
991
  "is_at_least_or_nan",
@@ -902,4 +1036,5 @@ __all__ = [
902
1036
  "maximum",
903
1037
  "minimum",
904
1038
  "shift_bool",
1039
+ "sigmoid",
905
1040
  ]