dycw-utilities 0.122.1__tar.gz → 0.124.0__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.
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/PKG-INFO +1 -1
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/pyproject.toml +3 -2
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_asyncio.py +153 -89
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_redis.py +2 -2
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_sqlalchemy.py +1 -1
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/__init__.py +1 -1
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/asyncio.py +191 -61
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/redis.py +2 -2
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/slack_sdk.py +6 -10
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/sqlalchemy.py +2 -1
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/.gitignore +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/LICENSE +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/README.md +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/__init__.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/conftest.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/modules/__init__.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/modules/package_missing/__init__.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/modules/package_missing/module.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/modules/package_with/__init__.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/modules/package_with/outer_1.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/modules/package_with/outer_2.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/modules/package_with/subpackage/__init__.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/modules/package_with/subpackage/inner_1.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/modules/package_with/subpackage/inner_2.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/modules/package_with/subpackage/inner_3.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/modules/package_without/__init__.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/modules/package_without/module_1.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/modules/package_without/module_2.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/modules/standalone.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/modules/with_imports.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/regressions/test_pytest_regressions/TestMultipleRegressionFixtures__test_main__obj.json +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/regressions/test_pytest_regressions/TestMultipleRegressionFixtures__test_main__series.json +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_int.json +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_literal__false.json +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_literal__true.json +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_nested.json +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/regressions/test_pytest_regressions/TestPolarsRegressionFixture__test_dataframe.json +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/regressions/test_pytest_regressions/TestPolarsRegressionFixture__test_series.json +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_altair.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_astor.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_atomicwrites.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_atools.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_cachetools.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_click.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_concurrent.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_contextlib.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_contextvars.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_cryptography.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_cvxpy.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_dataclasses.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_datetime.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_enum.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_errors.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_eventkit.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_fastapi.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_fpdf2.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_functions.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_functools.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_getpass.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_git.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_hashlib.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_http.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_hypothesis.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_importlib.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_ipython.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_iterables.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_jupyter.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_lightweight_charts.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_logging.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_loguru.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_luigi.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_math.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_memory_profiler.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_modules.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_more_itertools.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_numpy.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_operator.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_optuna.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_orjson.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_os.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_parse.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_pathlib.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_period.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_pickle.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_platform.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_polars.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_polars_ols.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_pqdm.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_pydantic.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_pyinstrument.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_pyrsistent.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_pytest.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_pytest_regressions.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_python_dotenv.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_random.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_re.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_reprlib.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_rich.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_scipy.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_sentinel.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_shelve.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_slack_sdk.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_socket.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_sqlalchemy_polars.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_statsmodel.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_streamlit.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_sys.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_tempfile.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_tenacity.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_text.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_threading.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_timer.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_traceback.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_traceback_funcs/__init__.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_traceback_funcs/chain.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_traceback_funcs/decorated_async.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_traceback_funcs/decorated_sync.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_traceback_funcs/error_bind.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_traceback_funcs/many.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_traceback_funcs/one.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_traceback_funcs/recursive.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_traceback_funcs/task_group_one.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_traceback_funcs/task_group_two.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_traceback_funcs/two.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_traceback_funcs/untraced.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_types.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_typing.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_typing_funcs/__init__.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_typing_funcs/no_future.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_typing_funcs/with_future.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_tzdata.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_tzlocal.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_uuid.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_version.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_warnings.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_whenever.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_zipfile.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_zoneinfo.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/altair.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/astor.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/atomicwrites.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/atools.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/cachetools.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/click.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/concurrent.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/contextlib.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/contextvars.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/cryptography.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/cvxpy.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/dataclasses.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/datetime.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/enum.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/errors.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/eventkit.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/fastapi.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/fpdf2.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/functions.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/functools.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/getpass.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/git.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/hashlib.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/http.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/hypothesis.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/importlib.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/ipython.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/iterables.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/jupyter.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/lightweight_charts.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/logging.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/loguru.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/luigi.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/math.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/memory_profiler.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/modules.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/more_itertools.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/numpy.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/operator.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/optuna.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/orjson.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/os.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/parse.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/pathlib.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/period.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/pickle.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/platform.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/polars.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/polars_ols.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/pqdm.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/py.typed +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/pydantic.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/pyinstrument.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/pyrsistent.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/pytest.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/pytest_regressions.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/python_dotenv.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/random.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/re.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/reprlib.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/rich.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/scipy.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/sentinel.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/shelve.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/socket.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/sqlalchemy_polars.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/statsmodels.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/streamlit.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/sys.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/tempfile.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/tenacity.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/text.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/threading.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/timer.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/traceback.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/types.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/typing.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/tzdata.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/tzlocal.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/uuid.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/version.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/warnings.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/whenever.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/zipfile.py +0 -0
- {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/zoneinfo.py +0 -0
@@ -92,7 +92,7 @@ dependencies = [
|
|
92
92
|
name = "dycw-utilities"
|
93
93
|
readme = "README.md"
|
94
94
|
requires-python = ">= 3.12"
|
95
|
-
version = "0.
|
95
|
+
version = "0.124.0"
|
96
96
|
|
97
97
|
[project.optional-dependencies]
|
98
98
|
test = [
|
@@ -334,7 +334,7 @@ zzz-test-zoneinfo = [
|
|
334
334
|
# bump-my-version
|
335
335
|
[tool.bumpversion]
|
336
336
|
allow_dirty = true
|
337
|
-
current_version = "0.
|
337
|
+
current_version = "0.124.0"
|
338
338
|
|
339
339
|
[[tool.bumpversion.files]]
|
340
340
|
filename = "src/utilities/__init__.py"
|
@@ -433,6 +433,7 @@ addopts = [
|
|
433
433
|
"--durations=10",
|
434
434
|
"--durations-min=10",
|
435
435
|
"--strict-markers",
|
436
|
+
"--timeout=300",
|
436
437
|
]
|
437
438
|
asyncio_default_fixture_loop_scope = "function"
|
438
439
|
asyncio_mode = "auto"
|
@@ -1,6 +1,7 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
|
-
from asyncio import CancelledError, Event, Queue,
|
3
|
+
from asyncio import CancelledError, Event, Queue, run, sleep
|
4
|
+
from collections import deque
|
4
5
|
from contextlib import asynccontextmanager
|
5
6
|
from dataclasses import dataclass, field
|
6
7
|
from functools import partial
|
@@ -8,9 +9,10 @@ from itertools import chain, count
|
|
8
9
|
from re import search
|
9
10
|
from typing import TYPE_CHECKING, Any, ClassVar, Self, cast, override
|
10
11
|
|
11
|
-
from hypothesis import HealthCheck, Phase, given, settings
|
12
|
+
from hypothesis import HealthCheck, Phase, assume, given, settings
|
12
13
|
from hypothesis.strategies import (
|
13
14
|
DataObject,
|
15
|
+
booleans,
|
14
16
|
data,
|
15
17
|
integers,
|
16
18
|
just,
|
@@ -22,6 +24,7 @@ from hypothesis.strategies import (
|
|
22
24
|
from pytest import LogCaptureFixture, mark, param, raises
|
23
25
|
|
24
26
|
from utilities.asyncio import (
|
27
|
+
EnhancedQueue,
|
25
28
|
EnhancedTaskGroup,
|
26
29
|
InfiniteLooper,
|
27
30
|
InfiniteQueueLooper,
|
@@ -65,41 +68,118 @@ if TYPE_CHECKING:
|
|
65
68
|
)
|
66
69
|
|
67
70
|
|
71
|
+
class TestEnhancedQueue:
|
72
|
+
@given(
|
73
|
+
xs=lists(integers()),
|
74
|
+
wait=booleans(),
|
75
|
+
put_all=booleans(),
|
76
|
+
get_reverse=booleans(),
|
77
|
+
)
|
78
|
+
async def test_left(
|
79
|
+
self, *, xs: list[int], wait: int, put_all: bool, get_reverse: bool
|
80
|
+
) -> None:
|
81
|
+
_ = assume(not ((len(xs) == 0) and wait))
|
82
|
+
deq: deque[int] = deque()
|
83
|
+
for x in xs:
|
84
|
+
deq.appendleft(x)
|
85
|
+
queue: EnhancedQueue[int] = EnhancedQueue()
|
86
|
+
if put_all:
|
87
|
+
if wait:
|
88
|
+
await queue.put_left(*xs)
|
89
|
+
else:
|
90
|
+
queue.put_left_nowait(*xs)
|
91
|
+
else:
|
92
|
+
for i, x in enumerate(xs, start=1):
|
93
|
+
if wait:
|
94
|
+
await queue.put_left(x)
|
95
|
+
else:
|
96
|
+
queue.put_left_nowait(x)
|
97
|
+
assert queue.qsize() == i
|
98
|
+
assert list(deq) == xs[::-1]
|
99
|
+
if wait:
|
100
|
+
res = await queue.get_all(reverse=get_reverse)
|
101
|
+
else:
|
102
|
+
res = queue.get_all_nowait(reverse=get_reverse)
|
103
|
+
expected = xs if get_reverse else xs[::-1]
|
104
|
+
assert res == expected
|
105
|
+
|
106
|
+
@given(
|
107
|
+
xs=lists(integers()),
|
108
|
+
wait=booleans(),
|
109
|
+
put_all=booleans(),
|
110
|
+
get_reverse=booleans(),
|
111
|
+
)
|
112
|
+
async def test_right(
|
113
|
+
self, *, xs: list[int], wait: int, put_all: bool, get_reverse: bool
|
114
|
+
) -> None:
|
115
|
+
_ = assume(not ((len(xs) == 0) and wait))
|
116
|
+
deq: deque[int] = deque()
|
117
|
+
for x in xs:
|
118
|
+
deq.append(x)
|
119
|
+
queue: EnhancedQueue[int] = EnhancedQueue()
|
120
|
+
if put_all:
|
121
|
+
if wait:
|
122
|
+
await queue.put_right(*xs)
|
123
|
+
else:
|
124
|
+
queue.put_right_nowait(*xs)
|
125
|
+
assert queue.qsize() == len(xs)
|
126
|
+
else:
|
127
|
+
for i, x in enumerate(xs, start=1):
|
128
|
+
if wait:
|
129
|
+
await queue.put_right(x)
|
130
|
+
else:
|
131
|
+
queue.put_right_nowait(x)
|
132
|
+
assert queue.qsize() == i
|
133
|
+
assert list(deq) == xs
|
134
|
+
if wait:
|
135
|
+
res = await queue.get_all(reverse=get_reverse)
|
136
|
+
else:
|
137
|
+
res = queue.get_all_nowait(reverse=get_reverse)
|
138
|
+
expected = xs[::-1] if get_reverse else xs
|
139
|
+
assert res == expected
|
140
|
+
|
141
|
+
|
68
142
|
class TestEnhancedTaskGroup:
|
69
|
-
async def
|
70
|
-
|
143
|
+
async def test_create_task_context_coroutine(self) -> None:
|
144
|
+
flag: bool = False
|
71
145
|
|
72
146
|
@asynccontextmanager
|
73
|
-
async def
|
74
|
-
nonlocal
|
147
|
+
async def yield_true() -> AsyncIterator[None]:
|
148
|
+
nonlocal flag
|
75
149
|
try:
|
76
|
-
|
150
|
+
flag = True
|
77
151
|
yield
|
78
152
|
finally:
|
79
|
-
|
153
|
+
flag = False
|
80
154
|
|
81
|
-
|
155
|
+
assert not flag
|
156
|
+
async with EnhancedTaskGroup(timeout=0.1) as tg:
|
157
|
+
_ = tg.create_task_context(yield_true())
|
158
|
+
await sleep(0.05)
|
159
|
+
assert flag
|
160
|
+
assert not flag
|
82
161
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
assert
|
100
|
-
|
101
|
-
|
102
|
-
|
162
|
+
async def test_create_task_context_looper(self) -> None:
|
163
|
+
@dataclass(kw_only=True)
|
164
|
+
class Example(InfiniteLooper[None]):
|
165
|
+
running: bool = False
|
166
|
+
|
167
|
+
@override
|
168
|
+
async def _initialize(self) -> None:
|
169
|
+
self.running = True
|
170
|
+
|
171
|
+
@override
|
172
|
+
async def _teardown(self) -> None:
|
173
|
+
self.running = False
|
174
|
+
|
175
|
+
looper = Example(duration=0.1)
|
176
|
+
assert not looper.running
|
177
|
+
async with EnhancedTaskGroup(timeout=0.1) as tg:
|
178
|
+
assert not looper.running
|
179
|
+
_ = tg.create_task_context(looper)
|
180
|
+
await sleep(0.05)
|
181
|
+
assert looper.running
|
182
|
+
assert not looper.running
|
103
183
|
|
104
184
|
async def test_max_tasks_disabled(self) -> None:
|
105
185
|
with Timer() as timer:
|
@@ -169,6 +249,24 @@ class TestGetEvent:
|
|
169
249
|
assert get_event(event=lambda: event) is event
|
170
250
|
|
171
251
|
|
252
|
+
class TestGetItems:
|
253
|
+
@given(
|
254
|
+
xs=lists(integers(), min_size=1),
|
255
|
+
max_size=integers(1, 10) | none(),
|
256
|
+
wait=booleans(),
|
257
|
+
)
|
258
|
+
async def test_main(
|
259
|
+
self, *, xs: list[int], max_size: int | None, wait: bool
|
260
|
+
) -> None:
|
261
|
+
queue: Queue[int] = Queue()
|
262
|
+
put_items_nowait(xs, queue)
|
263
|
+
if wait:
|
264
|
+
result = await get_items(queue, max_size=max_size)
|
265
|
+
else:
|
266
|
+
result = get_items_nowait(queue, max_size=max_size)
|
267
|
+
assert result == xs[:max_size]
|
268
|
+
|
269
|
+
|
172
270
|
class TestInfiniteLooper:
|
173
271
|
sleep_restart_cases: ClassVar[list[Any]] = [
|
174
272
|
param(60.0, "for 0:01:00"),
|
@@ -350,7 +448,7 @@ class TestInfiniteLooper:
|
|
350
448
|
|
351
449
|
async def inc_external(obj: Example, /) -> None:
|
352
450
|
nonlocal external
|
353
|
-
|
451
|
+
for _ in range(100): # infinite doesn't work on CI
|
354
452
|
external += 1
|
355
453
|
obj.counter += 1
|
356
454
|
await sleep(0.05)
|
@@ -380,9 +478,9 @@ class TestInfiniteLooper:
|
|
380
478
|
Example(sleep_core=0.05, sleep_restart=0.05) as looper,
|
381
479
|
):
|
382
480
|
...
|
383
|
-
assert
|
384
|
-
assert 0 <= looper.counter <=
|
385
|
-
assert
|
481
|
+
assert 3 <= looper.initializations <= 7
|
482
|
+
assert 0 <= looper.counter <= 8
|
483
|
+
assert 13 <= external <= 22
|
386
484
|
|
387
485
|
async def test_with_coroutine_self_error(self) -> None:
|
388
486
|
class CustomError(Exception): ...
|
@@ -655,13 +753,13 @@ class TestInfiniteQueueLooper:
|
|
655
753
|
counter: int = 0
|
656
754
|
|
657
755
|
@override
|
658
|
-
async def
|
659
|
-
self.counter += len(
|
756
|
+
async def _process_queue(self) -> None:
|
757
|
+
self.counter += len(self._queue.get_all_nowait())
|
660
758
|
|
661
759
|
async with timeout_dur(duration=1.0), Example(sleep_core=0.05) as looper:
|
662
760
|
await sleep(0.1)
|
663
761
|
for i in range(10):
|
664
|
-
looper.
|
762
|
+
looper.put_right_nowait(i)
|
665
763
|
await sleep(0.05)
|
666
764
|
|
667
765
|
assert looper.counter == 10
|
@@ -672,13 +770,13 @@ class TestInfiniteQueueLooper:
|
|
672
770
|
output: set[int] = field(default_factory=set)
|
673
771
|
|
674
772
|
@override
|
675
|
-
async def
|
676
|
-
self.output.update(
|
773
|
+
async def _process_queue(self) -> None:
|
774
|
+
self.output.update(self._queue.get_all_nowait())
|
677
775
|
|
678
776
|
looper = Example(sleep_core=0.05)
|
679
777
|
assert len(looper) == 0
|
680
778
|
assert looper.empty()
|
681
|
-
looper.
|
779
|
+
looper.put_right_nowait(*range(n))
|
682
780
|
assert len(looper) == n
|
683
781
|
assert not looper.empty()
|
684
782
|
|
@@ -688,11 +786,11 @@ class TestInfiniteQueueLooper:
|
|
688
786
|
output: set[int] = field(default_factory=set)
|
689
787
|
|
690
788
|
@override
|
691
|
-
async def
|
692
|
-
self.output.update(
|
789
|
+
async def _process_queue(self) -> None:
|
790
|
+
self.output.update(self._queue.get_all_nowait())
|
693
791
|
|
694
792
|
looper = Example(sleep_core=0.05)
|
695
|
-
looper.
|
793
|
+
looper.put_right_nowait(*range(10))
|
696
794
|
async with looper:
|
697
795
|
await looper.run_until_empty()
|
698
796
|
assert looper.empty()
|
@@ -709,66 +807,32 @@ class TestInfiniteQueueLooper:
|
|
709
807
|
output: set[int] = field(default_factory=set)
|
710
808
|
|
711
809
|
@override
|
712
|
-
async def
|
713
|
-
raise CustomError
|
810
|
+
async def _process_queue(self) -> None:
|
811
|
+
raise CustomError
|
714
812
|
|
715
813
|
async with (
|
716
814
|
timeout_dur(duration=1.0),
|
717
815
|
Example(sleep_core=0.05, logger=logger) as looper,
|
718
816
|
):
|
719
|
-
looper.
|
817
|
+
looper.put_left_nowait(1)
|
720
818
|
if logger is not None:
|
721
819
|
message = caplog.messages[0]
|
722
|
-
expected = "'Example' encountered CustomError(
|
820
|
+
expected = "'Example' encountered 'CustomError()'; sleeping for 0:01:00..."
|
723
821
|
assert message == expected
|
724
822
|
|
725
823
|
|
726
|
-
class
|
727
|
-
@given(xs=lists(integers(), min_size=1),
|
728
|
-
async def
|
824
|
+
class TestPutItems:
|
825
|
+
@given(xs=lists(integers(), min_size=1), wait=booleans())
|
826
|
+
async def test_main(self, *, xs: list[int], wait: bool) -> None:
|
729
827
|
queue: Queue[int] = Queue()
|
730
|
-
|
731
|
-
|
732
|
-
if max_size is None:
|
733
|
-
assert result == xs
|
828
|
+
if wait:
|
829
|
+
put_items_nowait(xs, queue)
|
734
830
|
else:
|
735
|
-
assert result == xs[:max_size]
|
736
|
-
|
737
|
-
@given(xs=lists(integers(), min_size=1), max_size=integers(1, 10) | none())
|
738
|
-
async def test_get_then_put(self, *, xs: list[int], max_size: int | None) -> None:
|
739
|
-
queue: Queue[int] = Queue()
|
740
|
-
|
741
|
-
async def put() -> None:
|
742
|
-
await sleep(0.01)
|
743
831
|
await put_items(xs, queue)
|
744
|
-
|
745
|
-
|
746
|
-
|
747
|
-
|
748
|
-
result = task.result()
|
749
|
-
if max_size is None:
|
750
|
-
assert result == xs
|
751
|
-
else:
|
752
|
-
assert result == xs[:max_size]
|
753
|
-
|
754
|
-
async def test_empty(self) -> None:
|
755
|
-
queue: Queue[int] = Queue()
|
756
|
-
with raises(TimeoutError): # noqa: PT012
|
757
|
-
async with timeout(0.01), TaskGroup() as tg:
|
758
|
-
_ = tg.create_task(get_items(queue))
|
759
|
-
_ = tg.create_task(sleep(0.02))
|
760
|
-
|
761
|
-
|
762
|
-
class TestPutAndGetItemsNoWait:
|
763
|
-
@given(xs=lists(integers(), min_size=1), max_size=integers(1, 10) | none())
|
764
|
-
def test_main(self, *, xs: list[int], max_size: int | None) -> None:
|
765
|
-
queue: Queue[int] = Queue()
|
766
|
-
put_items_nowait(xs, queue)
|
767
|
-
result = get_items_nowait(queue, max_size=max_size)
|
768
|
-
if max_size is None:
|
769
|
-
assert result == xs
|
770
|
-
else:
|
771
|
-
assert result == xs[:max_size]
|
832
|
+
result: list[int] = []
|
833
|
+
while not queue.empty():
|
834
|
+
result.append(await queue.get())
|
835
|
+
assert result == xs
|
772
836
|
|
773
837
|
|
774
838
|
class TestUniquePriorityQueue:
|
@@ -150,7 +150,7 @@ class TestPublisher:
|
|
150
150
|
|
151
151
|
async def sleep_then_put() -> None:
|
152
152
|
await sleep(0.1)
|
153
|
-
publisher.
|
153
|
+
publisher.put_right_nowait((channel, obj))
|
154
154
|
|
155
155
|
with raises(ExceptionGroup): # noqa: PT012
|
156
156
|
async with EnhancedTaskGroup(timeout=1.0) as tg:
|
@@ -187,7 +187,7 @@ class TestPublisher:
|
|
187
187
|
|
188
188
|
async def sleep_then_put() -> None:
|
189
189
|
await sleep(0.1)
|
190
|
-
publisher.
|
190
|
+
publisher.put_right_nowait((channel, text))
|
191
191
|
|
192
192
|
with raises(ExceptionGroup): # noqa: PT012
|
193
193
|
async with EnhancedTaskGroup(timeout=1.0) as tg:
|
@@ -1169,7 +1169,7 @@ class TestUpserter:
|
|
1169
1169
|
engine = await sqlalchemy_engines(data, table)
|
1170
1170
|
pairs = [(id_, init) for id_, init, _ in triples]
|
1171
1171
|
async with Upserter(duration=1.0, sleep_core=0.1, engine=engine) as upserter:
|
1172
|
-
upserter.
|
1172
|
+
upserter.put_right_nowait((pairs, table))
|
1173
1173
|
|
1174
1174
|
sel = select(table)
|
1175
1175
|
async with engine.begin() as conn:
|