dycw-utilities 0.153.7__tar.gz → 0.153.8__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 (212) hide show
  1. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/PKG-INFO +1 -1
  2. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/pyproject.toml +2 -2
  3. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/conftest.py +46 -27
  4. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/test_sqlalchemy.py +34 -0
  5. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/utilities/__init__.py +1 -1
  6. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/utilities/sqlalchemy.py +25 -3
  7. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/.gitignore +0 -0
  8. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/LICENSE +0 -0
  9. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/README.md +0 -0
  10. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/__init__.py +0 -0
  11. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/modules/__init__.py +0 -0
  12. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/modules/package_missing/__init__.py +0 -0
  13. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/modules/package_missing/module.py +0 -0
  14. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/modules/package_with/__init__.py +0 -0
  15. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/modules/package_with/outer_1.py +0 -0
  16. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/modules/package_with/outer_2.py +0 -0
  17. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/modules/package_with/subpackage/__init__.py +0 -0
  18. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/modules/package_with/subpackage/inner_1.py +0 -0
  19. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/modules/package_with/subpackage/inner_2.py +0 -0
  20. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/modules/package_with/subpackage/inner_3.py +0 -0
  21. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/modules/package_without/__init__.py +0 -0
  22. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/modules/package_without/module_1.py +0 -0
  23. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/modules/package_without/module_2.py +0 -0
  24. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/modules/standalone.py +0 -0
  25. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/modules/with_imports.py +0 -0
  26. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/regressions/test_pytest_regressions/TestMultipleRegressionFixtures__test_main__obj.json +0 -0
  27. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/regressions/test_pytest_regressions/TestMultipleRegressionFixtures__test_main__series.json +0 -0
  28. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_int.json +0 -0
  29. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_literal__false.json +0 -0
  30. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_literal__true.json +0 -0
  31. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_nested.json +0 -0
  32. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/regressions/test_pytest_regressions/TestPolarsRegressionFixture__test_dataframe.json +0 -0
  33. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/regressions/test_pytest_regressions/TestPolarsRegressionFixture__test_series.json +0 -0
  34. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/test_altair.py +0 -0
  35. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/test_asyncio.py +0 -0
  36. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/test_atomicwrites.py +0 -0
  37. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/test_atools.py +0 -0
  38. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/test_cachetools.py +0 -0
  39. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/test_click.py +0 -0
  40. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/test_concurrent.py +0 -0
  41. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/test_contextlib.py +0 -0
  42. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/test_contextvars.py +0 -0
  43. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/test_cryptography.py +0 -0
  44. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/test_cvxpy.py +0 -0
  45. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/test_dataclasses.py +0 -0
  46. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/test_enum.py +0 -0
  47. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/test_errors.py +0 -0
  48. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/test_eventkit.py +0 -0
  49. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/test_fastapi.py +0 -0
  50. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/test_fpdf2.py +0 -0
  51. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/test_functions.py +0 -0
  52. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/test_functools.py +0 -0
  53. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/test_getpass.py +0 -0
  54. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/test_gzip.py +0 -0
  55. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/test_hashlib.py +0 -0
  56. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/test_http.py +0 -0
  57. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/test_hypothesis.py +0 -0
  58. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/test_importlib.py +0 -0
  59. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/test_inflect.py +0 -0
  60. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/test_ipython.py +0 -0
  61. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/test_iterables.py +0 -0
  62. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/test_json.py +0 -0
  63. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/test_jupyter.py +0 -0
  64. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/test_libcst.py +0 -0
  65. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/test_lightweight_charts.py +0 -0
  66. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/test_logging.py +0 -0
  67. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/test_math.py +0 -0
  68. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/test_memory_profiler.py +0 -0
  69. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/test_modules.py +0 -0
  70. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/test_more_itertools.py +0 -0
  71. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/test_numpy.py +0 -0
  72. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/test_objects/__init__.py +0 -0
  73. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/test_objects/objects.py +0 -0
  74. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/test_operator.py +0 -0
  75. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/test_optuna.py +0 -0
  76. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/test_orjson.py +0 -0
  77. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/test_os.py +0 -0
  78. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/test_parse.py +0 -0
  79. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/test_pathlib.py +0 -0
  80. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/test_pickle.py +0 -0
  81. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/test_platform.py +0 -0
  82. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/test_polars.py +0 -0
  83. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/test_polars_ols.py +0 -0
  84. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/test_postgres.py +0 -0
  85. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/test_pottery.py +0 -0
  86. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/test_pqdm.py +0 -0
  87. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/test_psutil.py +0 -0
  88. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/test_pyinstrument.py +0 -0
  89. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/test_pytest.py +0 -0
  90. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/test_pytest_randomly.py +0 -0
  91. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/test_pytest_regressions.py +0 -0
  92. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/test_random.py +0 -0
  93. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/test_re.py +0 -0
  94. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/test_redis.py +0 -0
  95. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/test_reprlib.py +0 -0
  96. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/test_scipy.py +0 -0
  97. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/test_sentinel.py +0 -0
  98. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/test_shelve.py +0 -0
  99. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/test_slack_sdk.py +0 -0
  100. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/test_socket.py +0 -0
  101. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/test_sqlalchemy_polars.py +0 -0
  102. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/test_statsmodels.py +0 -0
  103. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/test_string.py +0 -0
  104. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/test_tempfile.py +0 -0
  105. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/test_text.py +0 -0
  106. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/test_threading.py +0 -0
  107. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/test_timer.py +0 -0
  108. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/test_traceback.py +0 -0
  109. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/test_typed_settings.py +0 -0
  110. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/test_types.py +0 -0
  111. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/test_typing.py +0 -0
  112. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/test_typing_funcs/__init__.py +0 -0
  113. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/test_typing_funcs/no_future.py +0 -0
  114. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/test_typing_funcs/with_future.py +0 -0
  115. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/test_tzdata.py +0 -0
  116. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/test_tzlocal.py +0 -0
  117. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/test_uuid.py +0 -0
  118. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/test_version.py +0 -0
  119. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/test_warnings.py +0 -0
  120. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/test_whenever.py +0 -0
  121. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/test_yield_access/__init__.py +0 -0
  122. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/test_yield_access/script.py +0 -0
  123. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/test_yield_access/script.sh +0 -0
  124. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/test_zipfile.py +0 -0
  125. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/tests/test_zoneinfo.py +0 -0
  126. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/utilities/altair.py +0 -0
  127. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/utilities/asyncio.py +0 -0
  128. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/utilities/atomicwrites.py +0 -0
  129. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/utilities/atools.py +0 -0
  130. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/utilities/cachetools.py +0 -0
  131. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/utilities/click.py +0 -0
  132. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/utilities/concurrent.py +0 -0
  133. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/utilities/contextlib.py +0 -0
  134. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/utilities/contextvars.py +0 -0
  135. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/utilities/cryptography.py +0 -0
  136. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/utilities/cvxpy.py +0 -0
  137. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/utilities/dataclasses.py +0 -0
  138. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/utilities/enum.py +0 -0
  139. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/utilities/errors.py +0 -0
  140. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/utilities/eventkit.py +0 -0
  141. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/utilities/fastapi.py +0 -0
  142. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/utilities/fpdf2.py +0 -0
  143. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/utilities/functions.py +0 -0
  144. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/utilities/functools.py +0 -0
  145. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/utilities/getpass.py +0 -0
  146. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/utilities/gzip.py +0 -0
  147. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/utilities/hashlib.py +0 -0
  148. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/utilities/http.py +0 -0
  149. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/utilities/hypothesis.py +0 -0
  150. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/utilities/importlib.py +0 -0
  151. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/utilities/inflect.py +0 -0
  152. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/utilities/ipython.py +0 -0
  153. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/utilities/iterables.py +0 -0
  154. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/utilities/json.py +0 -0
  155. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/utilities/jupyter.py +0 -0
  156. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/utilities/libcst.py +0 -0
  157. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/utilities/lightweight_charts.py +0 -0
  158. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/utilities/logging.py +0 -0
  159. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/utilities/math.py +0 -0
  160. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/utilities/memory_profiler.py +0 -0
  161. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/utilities/modules.py +0 -0
  162. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/utilities/more_itertools.py +0 -0
  163. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/utilities/numpy.py +0 -0
  164. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/utilities/operator.py +0 -0
  165. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/utilities/optuna.py +0 -0
  166. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/utilities/orjson.py +0 -0
  167. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/utilities/os.py +0 -0
  168. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/utilities/parse.py +0 -0
  169. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/utilities/pathlib.py +0 -0
  170. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/utilities/pickle.py +0 -0
  171. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/utilities/platform.py +0 -0
  172. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/utilities/polars.py +0 -0
  173. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/utilities/polars_ols.py +0 -0
  174. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/utilities/postgres.py +0 -0
  175. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/utilities/pottery.py +0 -0
  176. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/utilities/pqdm.py +0 -0
  177. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/utilities/psutil.py +0 -0
  178. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/utilities/py.typed +0 -0
  179. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/utilities/pyinstrument.py +0 -0
  180. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/utilities/pytest.py +0 -0
  181. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/utilities/pytest_plugins/__init__.py +0 -0
  182. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/utilities/pytest_plugins/pytest_randomly.py +0 -0
  183. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/utilities/pytest_plugins/pytest_regressions.py +0 -0
  184. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/utilities/pytest_regressions.py +0 -0
  185. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/utilities/random.py +0 -0
  186. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/utilities/re.py +0 -0
  187. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/utilities/redis.py +0 -0
  188. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/utilities/reprlib.py +0 -0
  189. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/utilities/scipy.py +0 -0
  190. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/utilities/sentinel.py +0 -0
  191. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/utilities/shelve.py +0 -0
  192. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/utilities/slack_sdk.py +0 -0
  193. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/utilities/socket.py +0 -0
  194. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/utilities/sqlalchemy_polars.py +0 -0
  195. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/utilities/statsmodels.py +0 -0
  196. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/utilities/string.py +0 -0
  197. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/utilities/tempfile.py +0 -0
  198. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/utilities/text.py +0 -0
  199. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/utilities/threading.py +0 -0
  200. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/utilities/timer.py +0 -0
  201. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/utilities/traceback.py +0 -0
  202. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/utilities/typed_settings.py +0 -0
  203. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/utilities/types.py +0 -0
  204. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/utilities/typing.py +0 -0
  205. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/utilities/tzdata.py +0 -0
  206. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/utilities/tzlocal.py +0 -0
  207. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/utilities/uuid.py +0 -0
  208. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/utilities/version.py +0 -0
  209. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/utilities/warnings.py +0 -0
  210. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/utilities/whenever.py +0 -0
  211. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/utilities/zipfile.py +0 -0
  212. {dycw_utilities-0.153.7 → dycw_utilities-0.153.8}/src/utilities/zoneinfo.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dycw-utilities
3
- Version: 0.153.7
3
+ Version: 0.153.8
4
4
  Author-email: Derek Wan <d.wan@icloud.com>
5
5
  License-File: LICENSE
6
6
  Requires-Python: >=3.12
@@ -229,7 +229,7 @@ dependencies = [
229
229
  name = "dycw-utilities"
230
230
  readme = "README.md"
231
231
  requires-python = ">= 3.12"
232
- version = "0.153.7"
232
+ version = "0.153.8"
233
233
 
234
234
  [project.entry-points.pytest11]
235
235
  pytest-randomly = "utilities.pytest_plugins.pytest_randomly"
@@ -262,7 +262,7 @@ test = [
262
262
  # bump-my-version
263
263
  [tool.bumpversion]
264
264
  allow_dirty = true
265
- current_version = "0.153.7"
265
+ current_version = "0.153.8"
266
266
 
267
267
  [[tool.bumpversion.files]]
268
268
  filename = "src/utilities/__init__.py"
@@ -114,42 +114,61 @@ def test_engine(*, request: SubRequest, tmp_path: Path) -> Engine:
114
114
 
115
115
 
116
116
  @fixture(params=[param("sqlite"), param("postgresql", marks=SKIPIF_CI)])
117
- async def test_async_engine(*, request: SubRequest, tmp_path: Path) -> AsyncEngine:
118
- from utilities.sqlalchemy import create_engine
119
-
117
+ async def test_async_engine(
118
+ *,
119
+ request: SubRequest,
120
+ test_async_sqlite_engine: AsyncEngine,
121
+ test_async_postgres_engine: AsyncEngine,
122
+ ) -> AsyncEngine:
120
123
  dialect = request.param
121
124
  match dialect:
122
125
  case "sqlite":
123
- db_path = tmp_path / "db.sqlite"
124
- return create_engine("sqlite+aiosqlite", database=str(db_path), async_=True)
126
+ return test_async_sqlite_engine
125
127
  case "postgresql":
126
- from asyncpg.exceptions import InvalidCatalogNameError
127
-
128
- engine = create_engine(
129
- "postgresql+asyncpg",
130
- host="localhost",
131
- port=5432,
132
- database="testing",
133
- async_=True,
134
- )
135
- try:
136
- async with engine.begin() as conn:
137
- tables: Sequence[str] = (
138
- (await conn.execute(_select_tables())).scalars().all()
139
- )
140
- except InvalidCatalogNameError:
141
- ...
142
- else:
143
- for table in filter(_is_to_drop, tables):
144
- async with engine.begin() as conn:
145
- with suppress(Exception):
146
- _ = await conn.execute(_drop_table(table))
147
- return engine
128
+ return test_async_postgres_engine
148
129
  case _:
149
130
  msg = f"Unsupported dialect: {dialect}"
150
131
  raise NotImplementedError(msg)
151
132
 
152
133
 
134
+ @fixture
135
+ async def test_async_sqlite_engine(*, tmp_path: Path) -> AsyncEngine:
136
+ from utilities.sqlalchemy import create_engine
137
+
138
+ db_path = tmp_path / "db.sqlite"
139
+ return create_engine("sqlite+aiosqlite", database=str(db_path), async_=True)
140
+
141
+
142
+ @fixture
143
+ async def test_async_postgres_engine() -> AsyncEngine:
144
+ from asyncpg.exceptions import InvalidCatalogNameError
145
+
146
+ from utilities.sqlalchemy import create_engine
147
+
148
+ if IS_CI:
149
+ skip(reason="Skipped for CI")
150
+ engine = create_engine(
151
+ "postgresql+asyncpg",
152
+ host="localhost",
153
+ port=5432,
154
+ database="testing",
155
+ async_=True,
156
+ )
157
+ try:
158
+ async with engine.begin() as conn:
159
+ tables: Sequence[str] = (
160
+ (await conn.execute(_select_tables())).scalars().all()
161
+ )
162
+ except InvalidCatalogNameError:
163
+ ...
164
+ else:
165
+ for table in filter(_is_to_drop, tables):
166
+ async with engine.begin() as conn:
167
+ with suppress(Exception):
168
+ _ = await conn.execute(_drop_table(table))
169
+ return engine
170
+
171
+
153
172
  def _is_to_drop(table: str, /) -> bool:
154
173
  try:
155
174
  datetime_str = extract_group(r"^(\d{8}T\d{6})_", table)
@@ -1,6 +1,8 @@
1
1
  from __future__ import annotations
2
2
 
3
+ from asyncio import sleep
3
4
  from enum import Enum, StrEnum, auto
5
+ from getpass import getuser
4
6
  from itertools import chain
5
7
  from typing import TYPE_CHECKING, Any, Literal, cast, overload, override
6
8
  from uuid import uuid4
@@ -29,6 +31,7 @@ from sqlalchemy.orm import (
29
31
  relationship,
30
32
  )
31
33
 
34
+ from tests.conftest import SKIPIF_CI
32
35
  from utilities.hypothesis import int32s, pairs, urls
33
36
  from utilities.iterables import one
34
37
  from utilities.modules import is_installed
@@ -72,6 +75,8 @@ from utilities.sqlalchemy import (
72
75
  columnwise_max,
73
76
  columnwise_min,
74
77
  create_engine,
78
+ ensure_database_created,
79
+ ensure_database_dropped,
75
80
  ensure_tables_created,
76
81
  ensure_tables_dropped,
77
82
  enum_name,
@@ -253,6 +258,35 @@ class TestCreateEngine:
253
258
  assert isinstance(engine, cls)
254
259
 
255
260
 
261
+ @SKIPIF_CI
262
+ class TestEnsureDatabaseCreatedAndDropped:
263
+ async def test_main(self) -> None:
264
+ url = URL.create(
265
+ "postgresql+asyncpg",
266
+ username=getuser(),
267
+ password="password", # noqa: S106
268
+ host="localhost",
269
+ port=5432,
270
+ database="postgres",
271
+ )
272
+ database = f"testing_{_table_names()}"
273
+ for _ in range(2):
274
+ await ensure_database_created(url, database)
275
+ await sleep(0.1)
276
+ for _ in range(2):
277
+ await ensure_database_dropped(url, database)
278
+ await sleep(0.1)
279
+
280
+ async def _run_test(
281
+ self, engine: AsyncEngine, table_or_orm: TableOrORMInstOrClass, /
282
+ ) -> None:
283
+ for _ in range(2):
284
+ await ensure_tables_created(engine, table_or_orm)
285
+ sel = select(get_table(table_or_orm))
286
+ async with engine.begin() as conn:
287
+ _ = (await conn.execute(sel)).all()
288
+
289
+
256
290
  class TestEnsureTablesCreated:
257
291
  async def test_table(self, *, test_async_engine: AsyncEngine) -> None:
258
292
  table = Table(
@@ -1,3 +1,3 @@
1
1
  from __future__ import annotations
2
2
 
3
- __version__ = "0.153.7"
3
+ __version__ = "0.153.8"
@@ -30,7 +30,6 @@ from typing import (
30
30
  )
31
31
 
32
32
  import sqlalchemy
33
- import sqlalchemy.ext.asyncio
34
33
  from sqlalchemy import (
35
34
  URL,
36
35
  Column,
@@ -63,7 +62,7 @@ from sqlalchemy.exc import (
63
62
  OperationalError,
64
63
  ProgrammingError,
65
64
  )
66
- from sqlalchemy.ext.asyncio import AsyncConnection, AsyncEngine
65
+ from sqlalchemy.ext.asyncio import AsyncConnection, AsyncEngine, create_async_engine
67
66
  from sqlalchemy.orm import (
68
67
  DeclarativeBase,
69
68
  InstrumentedAttribute,
@@ -311,7 +310,7 @@ def create_engine(
311
310
  case False:
312
311
  return sqlalchemy.create_engine(url, poolclass=poolclass)
313
312
  case True:
314
- return sqlalchemy.ext.asyncio.create_async_engine(url, poolclass=poolclass)
313
+ return create_async_engine(url, poolclass=poolclass)
315
314
  case never:
316
315
  assert_never(never)
317
316
 
@@ -319,6 +318,27 @@ def create_engine(
319
318
  ##
320
319
 
321
320
 
321
+ async def ensure_database_created(super_: URL, database: str, /) -> None:
322
+ """Ensure a database is created."""
323
+ engine = create_async_engine(super_, isolation_level="AUTOCOMMIT")
324
+ async with engine.begin() as conn:
325
+ try:
326
+ _ = await conn.execute(text(f"CREATE DATABASE {database}"))
327
+ except (OperationalError, ProgrammingError) as error:
328
+ if not search('database ".*" already exists', ensure_str(one(error.args))):
329
+ raise
330
+
331
+
332
+ async def ensure_database_dropped(super_: URL, database: str, /) -> None:
333
+ """Ensure a database is dropped."""
334
+ engine = create_async_engine(super_, isolation_level="AUTOCOMMIT")
335
+ async with engine.begin() as conn:
336
+ _ = await conn.execute(text(f"DROP DATABASE IF EXISTS {database}"))
337
+
338
+
339
+ ##
340
+
341
+
322
342
  async def ensure_tables_created(
323
343
  engine: AsyncEngine,
324
344
  /,
@@ -1284,6 +1304,8 @@ __all__ = [
1284
1304
  "columnwise_max",
1285
1305
  "columnwise_min",
1286
1306
  "create_engine",
1307
+ "ensure_database_created",
1308
+ "ensure_database_dropped",
1287
1309
  "ensure_tables_created",
1288
1310
  "ensure_tables_dropped",
1289
1311
  "enum_name",