dycw-utilities 0.125.23__tar.gz → 0.125.24__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.125.23 → dycw_utilities-0.125.24}/PKG-INFO +1 -1
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/pyproject.toml +2 -2
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_asyncio.py +84 -60
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/utilities/__init__.py +1 -1
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/utilities/asyncio.py +12 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/.gitignore +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/LICENSE +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/README.md +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/__init__.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/conftest.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/modules/__init__.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/modules/package_missing/__init__.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/modules/package_missing/module.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/modules/package_with/__init__.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/modules/package_with/outer_1.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/modules/package_with/outer_2.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/modules/package_with/subpackage/__init__.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/modules/package_with/subpackage/inner_1.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/modules/package_with/subpackage/inner_2.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/modules/package_with/subpackage/inner_3.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/modules/package_without/__init__.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/modules/package_without/module_1.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/modules/package_without/module_2.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/modules/standalone.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/modules/with_imports.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/regressions/test_pytest_regressions/TestMultipleRegressionFixtures__test_main__obj.json +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/regressions/test_pytest_regressions/TestMultipleRegressionFixtures__test_main__series.json +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_int.json +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_literal__false.json +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_literal__true.json +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_nested.json +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/regressions/test_pytest_regressions/TestPolarsRegressionFixture__test_dataframe.json +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/regressions/test_pytest_regressions/TestPolarsRegressionFixture__test_series.json +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_altair.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_atomicwrites.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_atools.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_cachetools.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_click.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_concurrent.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_contextlib.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_contextvars.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_cryptography.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_cvxpy.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_dataclasses.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_datetime.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_enum.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_errors.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_eventkit.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_fastapi.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_fpdf2.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_functions.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_functools.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_getpass.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_git.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_hashlib.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_http.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_hypothesis.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_importlib.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_ipython.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_iterables.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_jupyter.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_libcst.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_lightweight_charts.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_logging.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_loguru.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_luigi.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_math.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_memory_profiler.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_modules.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_more_itertools.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_numpy.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_operator.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_optuna.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_orjson.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_os.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_parse.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_pathlib.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_period.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_pickle.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_platform.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_polars.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_polars_ols.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_pqdm.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_psutil.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_pydantic.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_pyinstrument.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_pyrsistent.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_pytest.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_pytest_regressions.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_python_dotenv.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_random.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_re.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_redis.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_reprlib.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_rich.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_scipy.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_sentinel.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_shelve.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_slack_sdk.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_socket.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_sqlalchemy.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_sqlalchemy_polars.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_statsmodel.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_streamlit.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_string.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_sys.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_tempfile.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_tenacity.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_text.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_threading.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_timer.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_traceback.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_traceback_funcs/__init__.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_traceback_funcs/chain.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_traceback_funcs/decorated_async.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_traceback_funcs/decorated_sync.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_traceback_funcs/error_bind.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_traceback_funcs/many.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_traceback_funcs/one.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_traceback_funcs/recursive.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_traceback_funcs/task_group_one.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_traceback_funcs/task_group_two.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_traceback_funcs/two.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_traceback_funcs/untraced.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_types.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_typing.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_typing_funcs/__init__.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_typing_funcs/no_future.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_typing_funcs/with_future.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_tzdata.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_tzlocal.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_uuid.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_version.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_warnings.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_whenever.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_zipfile.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/test_zoneinfo.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/utilities/altair.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/utilities/atomicwrites.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/utilities/atools.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/utilities/cachetools.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/utilities/click.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/utilities/concurrent.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/utilities/contextlib.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/utilities/contextvars.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/utilities/cryptography.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/utilities/cvxpy.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/utilities/dataclasses.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/utilities/datetime.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/utilities/enum.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/utilities/errors.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/utilities/eventkit.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/utilities/fastapi.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/utilities/fpdf2.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/utilities/functions.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/utilities/functools.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/utilities/getpass.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/utilities/git.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/utilities/hashlib.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/utilities/http.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/utilities/hypothesis.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/utilities/importlib.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/utilities/ipython.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/utilities/iterables.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/utilities/jupyter.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/utilities/libcst.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/utilities/lightweight_charts.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/utilities/logging.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/utilities/loguru.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/utilities/luigi.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/utilities/math.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/utilities/memory_profiler.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/utilities/modules.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/utilities/more_itertools.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/utilities/numpy.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/utilities/operator.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/utilities/optuna.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/utilities/orjson.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/utilities/os.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/utilities/parse.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/utilities/pathlib.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/utilities/period.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/utilities/pickle.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/utilities/platform.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/utilities/polars.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/utilities/polars_ols.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/utilities/pqdm.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/utilities/psutil.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/utilities/py.typed +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/utilities/pydantic.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/utilities/pyinstrument.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/utilities/pyrsistent.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/utilities/pytest.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/utilities/pytest_regressions.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/utilities/python_dotenv.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/utilities/random.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/utilities/re.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/utilities/redis.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/utilities/reprlib.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/utilities/rich.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/utilities/scipy.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/utilities/sentinel.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/utilities/shelve.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/utilities/slack_sdk.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/utilities/socket.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/utilities/sqlalchemy.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/utilities/sqlalchemy_polars.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/utilities/statsmodels.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/utilities/streamlit.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/utilities/string.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/utilities/sys.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/utilities/tempfile.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/utilities/tenacity.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/utilities/text.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/utilities/threading.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/utilities/timer.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/utilities/traceback.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/utilities/types.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/utilities/typing.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/utilities/tzdata.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/utilities/tzlocal.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/utilities/uuid.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/utilities/version.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/utilities/warnings.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/utilities/whenever.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/utilities/zipfile.py +0 -0
- {dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/utilities/zoneinfo.py +0 -0
@@ -94,7 +94,7 @@ dependencies = [
|
|
94
94
|
name = "dycw-utilities"
|
95
95
|
readme = "README.md"
|
96
96
|
requires-python = ">= 3.12"
|
97
|
-
version = "0.125.
|
97
|
+
version = "0.125.24"
|
98
98
|
|
99
99
|
[project.optional-dependencies]
|
100
100
|
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.125.
|
338
|
+
current_version = "0.125.24"
|
339
339
|
|
340
340
|
[[tool.bumpversion.files]]
|
341
341
|
filename = "src/utilities/__init__.py"
|
@@ -56,6 +56,7 @@ from utilities.datetime import (
|
|
56
56
|
datetime_duration_to_timedelta,
|
57
57
|
get_now,
|
58
58
|
)
|
59
|
+
from utilities.functions import get_class_name
|
59
60
|
from utilities.hypothesis import sentinels, text_ascii
|
60
61
|
from utilities.iterables import one, unique_everseen
|
61
62
|
from utilities.pytest import skipif_windows
|
@@ -882,7 +883,7 @@ class _ExampleLooperError(Exception): ...
|
|
882
883
|
|
883
884
|
|
884
885
|
@dataclass(kw_only=True)
|
885
|
-
class
|
886
|
+
class _ExampleCounterLooper(Looper[Any]):
|
886
887
|
freq: Duration = field(default=10 * MILLISECOND, repr=False)
|
887
888
|
backoff: Duration = field(default=100 * MILLISECOND, repr=False)
|
888
889
|
_debug: bool = field(default=True, repr=False)
|
@@ -901,13 +902,13 @@ class _ExampleLooper(Looper[Any]):
|
|
901
902
|
|
902
903
|
|
903
904
|
@dataclass(kw_only=True)
|
904
|
-
class _ExampleOuterLooper(
|
905
|
-
inner:
|
905
|
+
class _ExampleOuterLooper(_ExampleCounterLooper):
|
906
|
+
inner: _ExampleCounterLooper = field(init=False, repr=False)
|
906
907
|
|
907
908
|
@override
|
908
909
|
def __post_init__(self) -> None:
|
909
910
|
super().__post_init__()
|
910
|
-
self.inner =
|
911
|
+
self.inner = _ExampleCounterLooper(
|
911
912
|
freq=self.freq / 2,
|
912
913
|
backoff=self.backoff / 2,
|
913
914
|
logger=self.logger,
|
@@ -921,6 +922,15 @@ class _ExampleOuterLooper(_ExampleLooper):
|
|
921
922
|
yield self.inner
|
922
923
|
|
923
924
|
|
925
|
+
@dataclass(kw_only=True)
|
926
|
+
class _ExampleQueueLooper(Looper[int]):
|
927
|
+
@override
|
928
|
+
async def core(self) -> None:
|
929
|
+
await super().core()
|
930
|
+
if not self.empty():
|
931
|
+
_ = self.get_left_nowait()
|
932
|
+
|
933
|
+
|
924
934
|
class TestLooper:
|
925
935
|
sleep_if_failure_cases: ClassVar[list[Any]] = [
|
926
936
|
param(True, "; sleeping for .*"),
|
@@ -928,61 +938,60 @@ class TestLooper:
|
|
928
938
|
]
|
929
939
|
|
930
940
|
async def test_main_with_nothing(self) -> None:
|
931
|
-
looper =
|
941
|
+
looper = _ExampleCounterLooper()
|
932
942
|
async with looper:
|
933
943
|
...
|
934
944
|
assert looper.stats == _LooperStats(entries=1, stops=1)
|
935
945
|
|
936
|
-
|
937
|
-
|
938
|
-
looper = _ExampleLooper()
|
939
|
-
with raises(TimeoutError):
|
940
|
-
async with timeout(1.0), looper:
|
941
|
-
await looper
|
942
|
-
self._assert_stats(looper, stops=1)
|
943
|
-
|
944
|
-
async def test_main_with_auto_start(self) -> None:
|
945
|
-
looper = _ExampleLooper(auto_start=True)
|
946
|
+
async def test_auto_start(self) -> None:
|
947
|
+
looper = _ExampleCounterLooper(auto_start=True)
|
946
948
|
with raises(TimeoutError):
|
947
949
|
async with timeout(1.0), looper:
|
948
950
|
...
|
949
951
|
self._assert_stats(looper)
|
950
952
|
|
951
|
-
|
952
|
-
|
953
|
-
looper = _ExampleLooper(timeout=SECOND)
|
954
|
-
async with looper:
|
955
|
-
with raises(LooperTimeoutError, match="Timeout"):
|
956
|
-
await looper
|
957
|
-
self._assert_stats(looper, stops=1)
|
958
|
-
|
959
|
-
async def test_main_with_auto_start_and_timeout(self) -> None:
|
960
|
-
looper = _ExampleLooper(auto_start=True, timeout=SECOND)
|
953
|
+
async def test_auto_start_and_timeout(self) -> None:
|
954
|
+
looper = _ExampleCounterLooper(auto_start=True, timeout=1.0)
|
961
955
|
async with looper:
|
962
956
|
...
|
963
957
|
self._assert_stats(looper, stops=1)
|
964
958
|
|
965
959
|
async def test_await_without_task(self) -> None:
|
966
|
-
looper =
|
960
|
+
looper = _ExampleCounterLooper()
|
967
961
|
with raises(_LooperNoTaskError, match=".* has no running task"):
|
968
962
|
await looper
|
969
963
|
|
970
964
|
async def test_context_manager_already_entered(
|
971
965
|
self, *, caplog: LogCaptureFixture
|
972
966
|
) -> None:
|
973
|
-
looper =
|
967
|
+
looper = _ExampleCounterLooper(auto_start=True, timeout=SECOND)
|
974
968
|
async with looper, looper:
|
975
969
|
...
|
976
970
|
_ = one(m for m in caplog.messages if search(": already entered$", m))
|
977
971
|
|
978
972
|
def test_empty(self) -> None:
|
979
|
-
looper =
|
973
|
+
looper = _ExampleCounterLooper()
|
980
974
|
assert looper.empty()
|
981
975
|
looper.put_left_nowait(None)
|
982
976
|
assert not looper.empty()
|
983
977
|
|
978
|
+
async def test_empty_upon_exit(self) -> None:
|
979
|
+
looper = _ExampleQueueLooper(freq=0.05, empty_upon_exit=True)
|
980
|
+
looper.put_right_nowait(0)
|
981
|
+
assert not looper.empty()
|
982
|
+
async with timeout(1.0), looper:
|
983
|
+
...
|
984
|
+
assert looper.empty()
|
985
|
+
|
986
|
+
async def test_explicit_start(self) -> None:
|
987
|
+
looper = _ExampleCounterLooper()
|
988
|
+
with raises(TimeoutError):
|
989
|
+
async with timeout(1.0), looper:
|
990
|
+
await looper
|
991
|
+
self._assert_stats(looper, stops=1)
|
992
|
+
|
984
993
|
def test_get_all_nowait(self) -> None:
|
985
|
-
looper =
|
994
|
+
looper = _ExampleCounterLooper()
|
986
995
|
looper.put_left_nowait(None)
|
987
996
|
items = looper.get_all_nowait()
|
988
997
|
assert items == [None]
|
@@ -990,7 +999,7 @@ class TestLooper:
|
|
990
999
|
async def test_initialize_already_initializing(
|
991
1000
|
self, *, caplog: LogCaptureFixture
|
992
1001
|
) -> None:
|
993
|
-
class Example(
|
1002
|
+
class Example(_ExampleCounterLooper):
|
994
1003
|
@override
|
995
1004
|
async def _initialize_core(self) -> None:
|
996
1005
|
if self._initialization_attempts == 1:
|
@@ -1005,7 +1014,7 @@ class TestLooper:
|
|
1005
1014
|
async def test_initialize_failure(
|
1006
1015
|
self, *, sleep_if_failure: bool, extra: str, caplog: LogCaptureFixture
|
1007
1016
|
) -> None:
|
1008
|
-
class Example(
|
1017
|
+
class Example(_ExampleCounterLooper):
|
1009
1018
|
@override
|
1010
1019
|
async def _initialize_core(self) -> None:
|
1011
1020
|
if self._initialization_attempts == 1:
|
@@ -1018,17 +1027,17 @@ class TestLooper:
|
|
1018
1027
|
_ = one(m for m in caplog.messages if search(pattern, m))
|
1019
1028
|
|
1020
1029
|
def test_len_and_qsize(self) -> None:
|
1021
|
-
looper =
|
1030
|
+
looper = _ExampleCounterLooper()
|
1022
1031
|
assert len(looper) == looper.qsize() == 0
|
1023
1032
|
looper.put_left_nowait(None)
|
1024
1033
|
assert len(looper) == looper.qsize() == 1
|
1025
1034
|
|
1026
1035
|
def test_replace(self) -> None:
|
1027
|
-
looper =
|
1028
|
-
assert looper.freq ==
|
1036
|
+
looper = _ExampleCounterLooper().replace(freq=10.0)
|
1037
|
+
assert looper.freq == 10.0
|
1029
1038
|
|
1030
1039
|
async def test_request_restart(self) -> None:
|
1031
|
-
class Example(
|
1040
|
+
class Example(_ExampleCounterLooper):
|
1032
1041
|
@override
|
1033
1042
|
async def core(self) -> None:
|
1034
1043
|
await super().core()
|
@@ -1037,7 +1046,7 @@ class TestLooper:
|
|
1037
1046
|
):
|
1038
1047
|
self.request_restart()
|
1039
1048
|
|
1040
|
-
looper = Example(auto_start=True, timeout=
|
1049
|
+
looper = Example(auto_start=True, timeout=1.0)
|
1041
1050
|
async with looper:
|
1042
1051
|
...
|
1043
1052
|
self._assert_stats(
|
@@ -1053,7 +1062,7 @@ class TestLooper:
|
|
1053
1062
|
def test_request_restart_already_requested(
|
1054
1063
|
self, *, caplog: LogCaptureFixture
|
1055
1064
|
) -> None:
|
1056
|
-
looper =
|
1065
|
+
looper = _ExampleCounterLooper()
|
1057
1066
|
for _ in range(2):
|
1058
1067
|
looper.request_restart()
|
1059
1068
|
_ = one(
|
@@ -1061,7 +1070,7 @@ class TestLooper:
|
|
1061
1070
|
)
|
1062
1071
|
|
1063
1072
|
async def test_request_stop(self) -> None:
|
1064
|
-
class Example(
|
1073
|
+
class Example(_ExampleCounterLooper):
|
1065
1074
|
@override
|
1066
1075
|
async def core(self) -> None:
|
1067
1076
|
await super().core()
|
@@ -1070,7 +1079,7 @@ class TestLooper:
|
|
1070
1079
|
):
|
1071
1080
|
self.request_stop()
|
1072
1081
|
|
1073
|
-
looper = Example(auto_start=True, timeout=
|
1082
|
+
looper = Example(auto_start=True, timeout=1.0)
|
1074
1083
|
async with looper:
|
1075
1084
|
...
|
1076
1085
|
self._assert_stats(
|
@@ -1084,13 +1093,13 @@ class TestLooper:
|
|
1084
1093
|
)
|
1085
1094
|
|
1086
1095
|
def test_request_stop_already_requested(self, *, caplog: LogCaptureFixture) -> None:
|
1087
|
-
looper =
|
1096
|
+
looper = _ExampleCounterLooper()
|
1088
1097
|
for _ in range(2):
|
1089
1098
|
looper.request_stop()
|
1090
1099
|
_ = one(m for m in caplog.messages if search(r": already requested stop$", m))
|
1091
1100
|
|
1092
1101
|
async def test_request_stop_when_empty(self) -> None:
|
1093
|
-
class Example(
|
1102
|
+
class Example(_ExampleCounterLooper):
|
1094
1103
|
@override
|
1095
1104
|
async def core(self) -> None:
|
1096
1105
|
await super().core()
|
@@ -1103,7 +1112,7 @@ class TestLooper:
|
|
1103
1112
|
_ = self.get_right_nowait()
|
1104
1113
|
self.request_stop_when_empty()
|
1105
1114
|
|
1106
|
-
looper = Example(auto_start=True, timeout=
|
1115
|
+
looper = Example(auto_start=True, timeout=1.0)
|
1107
1116
|
for i in range(25):
|
1108
1117
|
match i % 2 == 0:
|
1109
1118
|
case True:
|
@@ -1125,7 +1134,7 @@ class TestLooper:
|
|
1125
1134
|
def test_request_stop_when_empty_already_requested(
|
1126
1135
|
self, *, caplog: LogCaptureFixture
|
1127
1136
|
) -> None:
|
1128
|
-
looper =
|
1137
|
+
looper = _ExampleCounterLooper()
|
1129
1138
|
for _ in range(2):
|
1130
1139
|
looper.request_stop_when_empty()
|
1131
1140
|
_ = one(
|
@@ -1138,7 +1147,7 @@ class TestLooper:
|
|
1138
1147
|
async def test_restart_failure_during_initialization(
|
1139
1148
|
self, *, sleep_if_failure: bool, extra: str, caplog: LogCaptureFixture
|
1140
1149
|
) -> None:
|
1141
|
-
class Example(
|
1150
|
+
class Example(_ExampleCounterLooper):
|
1142
1151
|
@override
|
1143
1152
|
async def _initialize_core(self) -> None:
|
1144
1153
|
if self._initialization_attempts == 1:
|
@@ -1154,7 +1163,7 @@ class TestLooper:
|
|
1154
1163
|
async def test_restart_failure_during_tear_down(
|
1155
1164
|
self, *, sleep_if_failure: bool, extra: str, caplog: LogCaptureFixture
|
1156
1165
|
) -> None:
|
1157
|
-
class Example(
|
1166
|
+
class Example(_ExampleCounterLooper):
|
1158
1167
|
@override
|
1159
1168
|
async def _tear_down_core(self) -> None:
|
1160
1169
|
if self._tear_down_attempts == 1:
|
@@ -1170,7 +1179,7 @@ class TestLooper:
|
|
1170
1179
|
async def test_restart_failure_during_tear_down_and_initialization(
|
1171
1180
|
self, *, sleep_if_failure: bool, extra: str, caplog: LogCaptureFixture
|
1172
1181
|
) -> None:
|
1173
|
-
class Example(
|
1182
|
+
class Example(_ExampleCounterLooper):
|
1174
1183
|
@override
|
1175
1184
|
async def _initialize_core(self) -> None:
|
1176
1185
|
if self._initialization_attempts == 1:
|
@@ -1188,11 +1197,19 @@ class TestLooper:
|
|
1188
1197
|
pattern = rf": encountered _ExampleLooperError\(\) \(tear down\) and then _ExampleLooperError\(\) \(initialization\) whilst restarting{extra}$"
|
1189
1198
|
_ = one(m for m in caplog.messages if search(pattern, m))
|
1190
1199
|
|
1200
|
+
@mark.parametrize("n", [param(0), param(1), param(2)])
|
1201
|
+
async def test_run_until_empty(self, *, n: int) -> None:
|
1202
|
+
looper = _ExampleQueueLooper(freq=0.05)
|
1203
|
+
looper.put_right_nowait(*range(n))
|
1204
|
+
async with timeout(1.0), looper:
|
1205
|
+
await looper.run_until_empty()
|
1206
|
+
assert looper.empty()
|
1207
|
+
|
1191
1208
|
@mark.parametrize("auto_start", [param(True), param(False)])
|
1192
1209
|
async def test_sub_looper_one(
|
1193
1210
|
self, *, auto_start: bool, caplog: LogCaptureFixture
|
1194
1211
|
) -> None:
|
1195
|
-
looper = _ExampleOuterLooper(auto_start=True, timeout=
|
1212
|
+
looper = _ExampleOuterLooper(auto_start=True, timeout=1.0)
|
1196
1213
|
looper.inner.auto_start = auto_start
|
1197
1214
|
async with looper:
|
1198
1215
|
...
|
@@ -1206,7 +1223,7 @@ class TestLooper:
|
|
1206
1223
|
restart_successes=13,
|
1207
1224
|
stops=1,
|
1208
1225
|
)
|
1209
|
-
pattern =
|
1226
|
+
pattern = rf": changing sub-looper {get_class_name(_ExampleCounterLooper)}\(.*?\) to auto-start\.\.\.$"
|
1210
1227
|
matches = [m for m in caplog.messages if bool(search(pattern, m))]
|
1211
1228
|
if auto_start:
|
1212
1229
|
assert len(matches) == 0
|
@@ -1215,14 +1232,14 @@ class TestLooper:
|
|
1215
1232
|
|
1216
1233
|
async def test_sub_loopers_multiple(self) -> None:
|
1217
1234
|
@dataclass(kw_only=True)
|
1218
|
-
class Example(
|
1219
|
-
inner1:
|
1220
|
-
inner2:
|
1235
|
+
class Example(_ExampleCounterLooper):
|
1236
|
+
inner1: _ExampleCounterLooper = field(init=False, repr=False)
|
1237
|
+
inner2: _ExampleCounterLooper = field(init=False, repr=False)
|
1221
1238
|
|
1222
1239
|
@override
|
1223
1240
|
def __post_init__(self) -> None:
|
1224
1241
|
super().__post_init__()
|
1225
|
-
self.inner1 =
|
1242
|
+
self.inner1 = _ExampleCounterLooper(
|
1226
1243
|
freq=self.freq / 2,
|
1227
1244
|
backoff=self.backoff / 2,
|
1228
1245
|
logger=self.logger,
|
@@ -1230,7 +1247,7 @@ class TestLooper:
|
|
1230
1247
|
timeout_error=self.timeout_error,
|
1231
1248
|
max_count=round(self.max_count / 2),
|
1232
1249
|
)
|
1233
|
-
self.inner2 =
|
1250
|
+
self.inner2 = _ExampleCounterLooper(
|
1234
1251
|
freq=self.freq / 2,
|
1235
1252
|
backoff=self.backoff / 2,
|
1236
1253
|
logger=self.logger,
|
@@ -1244,7 +1261,7 @@ class TestLooper:
|
|
1244
1261
|
yield self.inner1
|
1245
1262
|
yield self.inner2
|
1246
1263
|
|
1247
|
-
looper = Example(auto_start=True, timeout=
|
1264
|
+
looper = Example(auto_start=True, timeout=1.0)
|
1248
1265
|
async with looper:
|
1249
1266
|
...
|
1250
1267
|
self._assert_stats(looper, stops=1)
|
@@ -1261,7 +1278,7 @@ class TestLooper:
|
|
1261
1278
|
|
1262
1279
|
async def test_sub_loopers_nested(self) -> None:
|
1263
1280
|
@dataclass(kw_only=True)
|
1264
|
-
class Example(
|
1281
|
+
class Example(_ExampleCounterLooper):
|
1265
1282
|
middle: _ExampleOuterLooper = field(init=False, repr=False)
|
1266
1283
|
|
1267
1284
|
@override
|
@@ -1280,7 +1297,7 @@ class TestLooper:
|
|
1280
1297
|
def _yield_sub_loopers(self) -> Iterator[Looper]:
|
1281
1298
|
yield self.middle
|
1282
1299
|
|
1283
|
-
looper = Example(auto_start=True, timeout=
|
1300
|
+
looper = Example(auto_start=True, timeout=1.0)
|
1284
1301
|
async with looper:
|
1285
1302
|
...
|
1286
1303
|
self._assert_stats(looper, stops=1)
|
@@ -1306,7 +1323,7 @@ class TestLooper:
|
|
1306
1323
|
async def test_tear_down_already_tearing_down(
|
1307
1324
|
self, *, caplog: LogCaptureFixture
|
1308
1325
|
) -> None:
|
1309
|
-
class Example(
|
1326
|
+
class Example(_ExampleCounterLooper):
|
1310
1327
|
@override
|
1311
1328
|
async def _tear_down_core(self) -> None:
|
1312
1329
|
if self._tear_down_attempts == 1:
|
@@ -1321,7 +1338,7 @@ class TestLooper:
|
|
1321
1338
|
async def test_tear_down_failure(
|
1322
1339
|
self, *, sleep_if_failure: bool, extra: str, caplog: LogCaptureFixture
|
1323
1340
|
) -> None:
|
1324
|
-
class Example(
|
1341
|
+
class Example(_ExampleCounterLooper):
|
1325
1342
|
@override
|
1326
1343
|
async def _tear_down_core(self) -> None:
|
1327
1344
|
if self._tear_down_attempts == 1:
|
@@ -1333,14 +1350,21 @@ class TestLooper:
|
|
1333
1350
|
pattern = rf": encountered _ExampleLooperError\(\) whilst tearing down{extra}$"
|
1334
1351
|
_ = one(m for m in caplog.messages if search(pattern, m))
|
1335
1352
|
|
1353
|
+
async def test_timeout(self) -> None:
|
1354
|
+
looper = _ExampleCounterLooper(timeout=1.0)
|
1355
|
+
async with looper:
|
1356
|
+
with raises(LooperTimeoutError, match="Timeout"):
|
1357
|
+
await looper
|
1358
|
+
self._assert_stats(looper, stops=1)
|
1359
|
+
|
1336
1360
|
def test_with_auto_start(self) -> None:
|
1337
|
-
looper =
|
1361
|
+
looper = _ExampleCounterLooper()
|
1338
1362
|
assert not looper.auto_start
|
1339
1363
|
assert looper.with_auto_start.auto_start
|
1340
1364
|
|
1341
1365
|
def _assert_stats(
|
1342
1366
|
self,
|
1343
|
-
looper:
|
1367
|
+
looper: _ExampleCounterLooper,
|
1344
1368
|
/,
|
1345
1369
|
*,
|
1346
1370
|
entries: int = 1,
|
@@ -688,6 +688,7 @@ class Looper(Generic[_T]):
|
|
688
688
|
auto_start: bool = field(default=False, repr=False)
|
689
689
|
freq: Duration = field(default=SECOND, repr=False)
|
690
690
|
backoff: Duration = field(default=10 * SECOND, repr=False)
|
691
|
+
empty_upon_exit: bool = field(default=False, repr=False)
|
691
692
|
logger: str | None = field(default=None, repr=False)
|
692
693
|
timeout: Duration | None = field(default=None, repr=False)
|
693
694
|
timeout_error: type[Exception] = field(default=LooperTimeoutError, repr=False)
|
@@ -791,6 +792,8 @@ class Looper(Generic[_T]):
|
|
791
792
|
)
|
792
793
|
_ = await self._stack.__aexit__(exc_type, exc_value, traceback)
|
793
794
|
await self.stop()
|
795
|
+
if self.empty_upon_exit:
|
796
|
+
await self.run_until_empty()
|
794
797
|
case False:
|
795
798
|
_ = self._debug and self._logger.debug("%s: already exited", self)
|
796
799
|
case _ as never:
|
@@ -891,6 +894,7 @@ class Looper(Generic[_T]):
|
|
891
894
|
self,
|
892
895
|
*,
|
893
896
|
auto_start: bool | Sentinel = sentinel,
|
897
|
+
empty_upon_exit: bool | Sentinel = sentinel,
|
894
898
|
freq: Duration | Sentinel = sentinel,
|
895
899
|
backoff: Duration | Sentinel = sentinel,
|
896
900
|
logger: str | None | Sentinel = sentinel,
|
@@ -902,6 +906,7 @@ class Looper(Generic[_T]):
|
|
902
906
|
return replace_non_sentinel(
|
903
907
|
self,
|
904
908
|
auto_start=auto_start,
|
909
|
+
empty_upon_exit=empty_upon_exit,
|
905
910
|
freq=freq,
|
906
911
|
backoff=backoff,
|
907
912
|
logger=logger,
|
@@ -1061,6 +1066,13 @@ class Looper(Generic[_T]):
|
|
1061
1066
|
self._core_successes += 1
|
1062
1067
|
await sleep(self._freq)
|
1063
1068
|
|
1069
|
+
async def run_until_empty(self) -> None:
|
1070
|
+
"""Run until the queue is empty."""
|
1071
|
+
while not self.empty():
|
1072
|
+
await self.core()
|
1073
|
+
if not self.empty():
|
1074
|
+
await sleep(self._freq)
|
1075
|
+
|
1064
1076
|
@property
|
1065
1077
|
def stats(self) -> _LooperStats:
|
1066
1078
|
"""Return the statistics."""
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/modules/package_missing/__init__.py
RENAMED
File without changes
|
{dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/modules/package_missing/module.py
RENAMED
File without changes
|
{dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/modules/package_with/__init__.py
RENAMED
File without changes
|
{dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/modules/package_with/outer_1.py
RENAMED
File without changes
|
{dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/modules/package_with/outer_2.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/modules/package_without/__init__.py
RENAMED
File without changes
|
{dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/modules/package_without/module_1.py
RENAMED
File without changes
|
{dycw_utilities-0.125.23 → dycw_utilities-0.125.24}/src/tests/modules/package_without/module_2.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|