dycw-utilities 0.129.1__tar.gz → 0.129.3__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.129.1 → dycw_utilities-0.129.3}/PKG-INFO +1 -1
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/pyproject.toml +2 -2
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_asyncio.py +93 -38
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_sqlalchemy.py +1 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/utilities/__init__.py +1 -1
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/utilities/asyncio.py +53 -51
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/.gitignore +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/LICENSE +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/README.md +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/__init__.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/conftest.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/modules/__init__.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/modules/package_missing/__init__.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/modules/package_missing/module.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/modules/package_with/__init__.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/modules/package_with/outer_1.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/modules/package_with/outer_2.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/modules/package_with/subpackage/__init__.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/modules/package_with/subpackage/inner_1.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/modules/package_with/subpackage/inner_2.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/modules/package_with/subpackage/inner_3.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/modules/package_without/__init__.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/modules/package_without/module_1.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/modules/package_without/module_2.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/modules/standalone.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/modules/with_imports.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/regressions/test_pytest_regressions/TestMultipleRegressionFixtures__test_main__obj.json +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/regressions/test_pytest_regressions/TestMultipleRegressionFixtures__test_main__series.json +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_int.json +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_literal__false.json +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_literal__true.json +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_nested.json +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/regressions/test_pytest_regressions/TestPolarsRegressionFixture__test_dataframe.json +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/regressions/test_pytest_regressions/TestPolarsRegressionFixture__test_series.json +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_altair.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_asyncio_classes/__init__.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_asyncio_classes/loopers.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_asyncio_classes/redis.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_atomicwrites.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_atools.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_cachetools.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_click.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_concurrent.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_contextlib.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_contextvars.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_cryptography.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_cvxpy.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_dataclasses.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_datetime.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_enum.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_errors.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_eventkit.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_fastapi.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_fpdf2.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_functions.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_functools.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_getpass.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_hashlib.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_http.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_hypothesis.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_importlib.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_ipython.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_iterables.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_jupyter.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_libcst.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_lightweight_charts.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_logging.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_loguru.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_luigi.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_math.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_memory_profiler.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_modules.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_more_itertools.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_numpy.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_operator.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_optuna.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_orjson.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_os.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_parse.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_pathlib.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_period.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_pickle.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_platform.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_polars.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_polars_ols.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_pottery.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_pqdm.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_psutil.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_pydantic.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_pyinstrument.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_pyrsistent.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_pytest.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_pytest_regressions.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_python_dotenv.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_random.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_re.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_redis.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_reprlib.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_scipy.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_sentinel.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_shelve.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_slack_sdk.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_socket.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_sqlalchemy_polars.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_statsmodel.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_streamlit.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_string.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_sys.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_tempfile.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_tenacity.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_text.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_threading.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_timer.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_traceback.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_traceback_funcs/__init__.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_traceback_funcs/chain.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_traceback_funcs/decorated_async.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_traceback_funcs/decorated_sync.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_traceback_funcs/error_bind.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_traceback_funcs/many.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_traceback_funcs/one.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_traceback_funcs/recursive.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_traceback_funcs/task_group_one.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_traceback_funcs/task_group_two.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_traceback_funcs/two.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_traceback_funcs/untraced.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_types.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_typing.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_typing_funcs/__init__.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_typing_funcs/no_future.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_typing_funcs/with_future.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_tzdata.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_tzlocal.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_uuid.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_version.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_warnings.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_whenever.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_zipfile.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_zoneinfo.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/utilities/altair.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/utilities/atomicwrites.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/utilities/atools.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/utilities/cachetools.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/utilities/click.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/utilities/concurrent.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/utilities/contextlib.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/utilities/contextvars.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/utilities/cryptography.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/utilities/cvxpy.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/utilities/dataclasses.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/utilities/datetime.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/utilities/enum.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/utilities/errors.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/utilities/eventkit.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/utilities/fastapi.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/utilities/fpdf2.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/utilities/functions.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/utilities/functools.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/utilities/getpass.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/utilities/hashlib.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/utilities/http.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/utilities/hypothesis.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/utilities/importlib.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/utilities/ipython.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/utilities/iterables.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/utilities/jupyter.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/utilities/libcst.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/utilities/lightweight_charts.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/utilities/logging.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/utilities/loguru.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/utilities/luigi.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/utilities/math.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/utilities/memory_profiler.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/utilities/modules.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/utilities/more_itertools.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/utilities/numpy.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/utilities/operator.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/utilities/optuna.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/utilities/orjson.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/utilities/os.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/utilities/parse.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/utilities/pathlib.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/utilities/period.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/utilities/pickle.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/utilities/platform.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/utilities/polars.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/utilities/polars_ols.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/utilities/pottery.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/utilities/pqdm.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/utilities/psutil.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/utilities/py.typed +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/utilities/pydantic.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/utilities/pyinstrument.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/utilities/pyrsistent.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/utilities/pytest.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/utilities/pytest_regressions.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/utilities/python_dotenv.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/utilities/random.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/utilities/re.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/utilities/redis.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/utilities/reprlib.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/utilities/scipy.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/utilities/sentinel.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/utilities/shelve.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/utilities/slack_sdk.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/utilities/socket.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/utilities/sqlalchemy.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/utilities/sqlalchemy_polars.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/utilities/statsmodels.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/utilities/streamlit.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/utilities/string.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/utilities/sys.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/utilities/tempfile.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/utilities/tenacity.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/utilities/text.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/utilities/threading.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/utilities/timer.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/utilities/traceback.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/utilities/types.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/utilities/typing.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/utilities/tzdata.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/utilities/tzlocal.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/utilities/uuid.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/utilities/version.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/utilities/warnings.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/utilities/whenever.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/utilities/zipfile.py +0 -0
- {dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/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.129.
|
97
|
+
version = "0.129.3"
|
98
98
|
|
99
99
|
[project.optional-dependencies]
|
100
100
|
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.129.
|
337
|
+
current_version = "0.129.3"
|
338
338
|
|
339
339
|
[[tool.bumpversion.files]]
|
340
340
|
filename = "src/utilities/__init__.py"
|
@@ -21,7 +21,10 @@ from hypothesis.strategies import (
|
|
21
21
|
)
|
22
22
|
from pytest import LogCaptureFixture, approx, mark, param, raises
|
23
23
|
|
24
|
+
from tests.conftest import IS_CI
|
24
25
|
from tests.test_asyncio_classes.loopers import (
|
26
|
+
_BACKOFF,
|
27
|
+
_FREQ,
|
25
28
|
_REL,
|
26
29
|
CountingLooper,
|
27
30
|
CountingLooperError,
|
@@ -63,6 +66,7 @@ from utilities.sentinel import Sentinel, sentinel
|
|
63
66
|
from utilities.timer import Timer
|
64
67
|
|
65
68
|
if TYPE_CHECKING:
|
69
|
+
import datetime as dt
|
66
70
|
from collections.abc import AsyncIterator
|
67
71
|
|
68
72
|
from utilities.types import Duration, MaybeCallableEvent
|
@@ -255,9 +259,15 @@ class TestGetItems:
|
|
255
259
|
|
256
260
|
|
257
261
|
class TestLooper:
|
258
|
-
|
259
|
-
|
260
|
-
|
262
|
+
_restart_min_elapsed: ClassVar[dt.timedelta] = datetime_duration_to_timedelta(
|
263
|
+
(0.8 if IS_CI else 1.0) * _BACKOFF
|
264
|
+
)
|
265
|
+
_restart_max_elapsed: ClassVar[dt.timedelta] = datetime_duration_to_timedelta(
|
266
|
+
(1.2 if IS_CI else 1.0) * _FREQ
|
267
|
+
)
|
268
|
+
skip_sleep_if_failure_cases: ClassVar[list[Any]] = [
|
269
|
+
param(True, ""),
|
270
|
+
param(False, "; sleeping for .*"),
|
261
271
|
]
|
262
272
|
|
263
273
|
async def test_main_with_nothing(self) -> None:
|
@@ -330,16 +340,16 @@ class TestLooper:
|
|
330
340
|
@override
|
331
341
|
async def _initialize_core(self) -> None:
|
332
342
|
if self._initialization_attempts == 1:
|
333
|
-
_ = await super().initialize(
|
343
|
+
_ = await super().initialize()
|
334
344
|
await super()._initialize_core()
|
335
345
|
|
336
346
|
looper = Example()
|
337
|
-
_ = await looper.initialize(
|
347
|
+
_ = await looper.initialize()
|
338
348
|
_ = one(m for m in caplog.messages if search(": already initializing$", m))
|
339
349
|
|
340
|
-
@mark.parametrize(("
|
350
|
+
@mark.parametrize(("skip_sleep_if_failure", "extra"), skip_sleep_if_failure_cases)
|
341
351
|
async def test_initialize_failure(
|
342
|
-
self, *,
|
352
|
+
self, *, skip_sleep_if_failure: bool, extra: str, caplog: LogCaptureFixture
|
343
353
|
) -> None:
|
344
354
|
class Example(CountingLooper):
|
345
355
|
@override
|
@@ -349,7 +359,7 @@ class TestLooper:
|
|
349
359
|
await super()._initialize_core()
|
350
360
|
|
351
361
|
looper = Example()
|
352
|
-
_ = await looper.initialize(
|
362
|
+
_ = await looper.initialize(skip_sleep_if_failure=skip_sleep_if_failure)
|
353
363
|
pattern = rf": encountered {get_class_name(CountingLooperError)}\(\) whilst initializing{extra}$"
|
354
364
|
_ = one(m for m in caplog.messages if search(pattern, m))
|
355
365
|
|
@@ -443,6 +453,40 @@ class TestLooper:
|
|
443
453
|
looper = CountingLooper().replace(freq=10.0)
|
444
454
|
assert looper.freq == 10.0
|
445
455
|
|
456
|
+
async def test_request_back_off(self) -> None:
|
457
|
+
class Example(CountingLooper):
|
458
|
+
@override
|
459
|
+
async def core(self) -> None:
|
460
|
+
await super().core()
|
461
|
+
if (self._initialization_attempts >= 2) and (
|
462
|
+
self.count >= (self.max_count / 2)
|
463
|
+
):
|
464
|
+
self.request_back_off()
|
465
|
+
|
466
|
+
looper = Example(auto_start=True, timeout=1.0)
|
467
|
+
async with looper:
|
468
|
+
...
|
469
|
+
assert_looper_stats(
|
470
|
+
looper,
|
471
|
+
entries=1,
|
472
|
+
core_successes=23,
|
473
|
+
core_failures=2,
|
474
|
+
initialization_successes=3,
|
475
|
+
tear_down_successes=2,
|
476
|
+
restart_successes=2,
|
477
|
+
stops=1,
|
478
|
+
)
|
479
|
+
|
480
|
+
async def test_request_back_off_already_requested(
|
481
|
+
self, *, caplog: LogCaptureFixture
|
482
|
+
) -> None:
|
483
|
+
looper = CountingLooper()
|
484
|
+
for _ in range(2):
|
485
|
+
looper.request_back_off()
|
486
|
+
_ = one(
|
487
|
+
m for m in caplog.messages if search(r": already requested back off$", m)
|
488
|
+
)
|
489
|
+
|
446
490
|
async def test_request_restart(self) -> None:
|
447
491
|
class Example(CountingLooper):
|
448
492
|
@override
|
@@ -459,11 +503,11 @@ class TestLooper:
|
|
459
503
|
assert_looper_stats(
|
460
504
|
looper,
|
461
505
|
entries=1,
|
462
|
-
core_successes=
|
506
|
+
core_successes=35,
|
463
507
|
core_failures=1,
|
464
|
-
initialization_successes=
|
465
|
-
tear_down_successes=
|
466
|
-
restart_successes=
|
508
|
+
initialization_successes=7,
|
509
|
+
tear_down_successes=6,
|
510
|
+
restart_successes=6,
|
467
511
|
stops=1,
|
468
512
|
)
|
469
513
|
|
@@ -553,9 +597,8 @@ class TestLooper:
|
|
553
597
|
if search(r": already requested stop when empty$", m)
|
554
598
|
)
|
555
599
|
|
556
|
-
@mark.parametrize(("sleep_if_failure", "extra"), sleep_if_failure_cases)
|
557
600
|
async def test_restart_failure_during_initialization(
|
558
|
-
self, *,
|
601
|
+
self, *, caplog: LogCaptureFixture
|
559
602
|
) -> None:
|
560
603
|
class Example(CountingLooper):
|
561
604
|
@override
|
@@ -565,13 +608,14 @@ class TestLooper:
|
|
565
608
|
await super()._initialize_core()
|
566
609
|
|
567
610
|
looper = Example()
|
568
|
-
|
569
|
-
|
611
|
+
with Timer() as timer:
|
612
|
+
await looper.restart()
|
613
|
+
assert timer.timedelta >= self._restart_min_elapsed
|
614
|
+
pattern = rf": encountered {get_class_name(CountingLooperError)}\(\) whilst restarting \(initialize\); sleeping for .*\.\.\.$"
|
570
615
|
_ = one(m for m in caplog.messages if search(pattern, m))
|
571
616
|
|
572
|
-
@mark.parametrize(("sleep_if_failure", "extra"), sleep_if_failure_cases)
|
573
617
|
async def test_restart_failure_during_tear_down(
|
574
|
-
self, *,
|
618
|
+
self, *, caplog: LogCaptureFixture
|
575
619
|
) -> None:
|
576
620
|
class Example(CountingLooper):
|
577
621
|
@override
|
@@ -581,13 +625,14 @@ class TestLooper:
|
|
581
625
|
await super()._tear_down_core()
|
582
626
|
|
583
627
|
looper = Example()
|
584
|
-
|
585
|
-
|
628
|
+
with Timer() as timer:
|
629
|
+
await looper.restart()
|
630
|
+
assert timer.timedelta >= self._restart_min_elapsed
|
631
|
+
pattern = rf": encountered {get_class_name(CountingLooperError)}\(\) whilst restarting \(tear down\); sleeping for .*\.\.\.$"
|
586
632
|
_ = one(m for m in caplog.messages if search(pattern, m))
|
587
633
|
|
588
|
-
@mark.parametrize(("sleep_if_failure", "extra"), sleep_if_failure_cases)
|
589
634
|
async def test_restart_failure_during_tear_down_and_initialization(
|
590
|
-
self, *,
|
635
|
+
self, *, caplog: LogCaptureFixture
|
591
636
|
) -> None:
|
592
637
|
class Example(CountingLooper):
|
593
638
|
@override
|
@@ -603,8 +648,18 @@ class TestLooper:
|
|
603
648
|
await super()._tear_down_core()
|
604
649
|
|
605
650
|
looper = Example()
|
606
|
-
|
607
|
-
|
651
|
+
with Timer() as timer:
|
652
|
+
await looper.restart()
|
653
|
+
assert timer.timedelta >= self._restart_min_elapsed
|
654
|
+
pattern = rf": encountered {get_class_name(CountingLooperError)}\(\) \(tear down\) and then {get_class_name(CountingLooperError)}\(\) \(initialization\) whilst restarting; sleeping for .*\.\.\.$"
|
655
|
+
_ = one(m for m in caplog.messages if search(pattern, m))
|
656
|
+
|
657
|
+
async def test_restart_success(self, *, caplog: LogCaptureFixture) -> None:
|
658
|
+
looper = CountingLooper()
|
659
|
+
with Timer() as timer:
|
660
|
+
await looper.restart()
|
661
|
+
assert timer.timedelta <= self._restart_max_elapsed
|
662
|
+
pattern = r": finished restarting$"
|
608
663
|
_ = one(m for m in caplog.messages if search(pattern, m))
|
609
664
|
|
610
665
|
@mark.parametrize("n", [param(0), param(1), param(2)])
|
@@ -698,16 +753,16 @@ class TestLooper:
|
|
698
753
|
@override
|
699
754
|
async def _tear_down_core(self) -> None:
|
700
755
|
if self._tear_down_attempts == 1:
|
701
|
-
_ = await super().tear_down(
|
756
|
+
_ = await super().tear_down()
|
702
757
|
await super()._tear_down_core()
|
703
758
|
|
704
759
|
looper = Example()
|
705
|
-
_ = await looper.tear_down(
|
760
|
+
_ = await looper.tear_down()
|
706
761
|
_ = one(m for m in caplog.messages if search(": already tearing down$", m))
|
707
762
|
|
708
|
-
@mark.parametrize(("
|
763
|
+
@mark.parametrize(("skip_sleep_if_failure", "extra"), skip_sleep_if_failure_cases)
|
709
764
|
async def test_tear_down_failure(
|
710
|
-
self, *,
|
765
|
+
self, *, skip_sleep_if_failure: bool, extra: str, caplog: LogCaptureFixture
|
711
766
|
) -> None:
|
712
767
|
class Example(CountingLooper):
|
713
768
|
@override
|
@@ -717,7 +772,7 @@ class TestLooper:
|
|
717
772
|
await super()._tear_down_core()
|
718
773
|
|
719
774
|
looper = Example()
|
720
|
-
_ = await looper.tear_down(
|
775
|
+
_ = await looper.tear_down(skip_sleep_if_failure=skip_sleep_if_failure)
|
721
776
|
pattern = rf": encountered {get_class_name(CountingLooperError)}\(\) whilst tearing down{extra}$"
|
722
777
|
_ = one(m for m in caplog.messages if search(pattern, m))
|
723
778
|
|
@@ -751,7 +806,7 @@ class TestLooper:
|
|
751
806
|
assert_looper_stats(
|
752
807
|
looper,
|
753
808
|
entries=1,
|
754
|
-
core_successes=
|
809
|
+
core_successes=47,
|
755
810
|
core_failures=5,
|
756
811
|
initialization_successes=6,
|
757
812
|
tear_down_successes=5,
|
@@ -767,10 +822,10 @@ class TestLooper:
|
|
767
822
|
looper,
|
768
823
|
entries=1,
|
769
824
|
core_successes=56,
|
770
|
-
core_failures=
|
771
|
-
initialization_successes=
|
772
|
-
tear_down_successes=
|
773
|
-
restart_successes=
|
825
|
+
core_failures=14,
|
826
|
+
initialization_successes=15,
|
827
|
+
tear_down_successes=14,
|
828
|
+
restart_successes=14,
|
774
829
|
stops=stops,
|
775
830
|
rel=rel,
|
776
831
|
)
|
@@ -781,7 +836,7 @@ class TestLooper:
|
|
781
836
|
assert_looper_stats(
|
782
837
|
looper,
|
783
838
|
entries=1,
|
784
|
-
core_successes=
|
839
|
+
core_successes=48,
|
785
840
|
core_failures=24,
|
786
841
|
initialization_successes=25,
|
787
842
|
tear_down_successes=24,
|
@@ -798,9 +853,9 @@ class TestLooper:
|
|
798
853
|
entries=1,
|
799
854
|
core_successes=35,
|
800
855
|
core_failures=35,
|
801
|
-
initialization_successes=
|
802
|
-
tear_down_successes=
|
803
|
-
restart_successes=
|
856
|
+
initialization_successes=36,
|
857
|
+
tear_down_successes=35,
|
858
|
+
restart_successes=35,
|
804
859
|
stops=stops,
|
805
860
|
rel=rel,
|
806
861
|
)
|
@@ -1332,6 +1332,7 @@ class TestUpsertItems:
|
|
1332
1332
|
await upsert_items(engine, item)
|
1333
1333
|
|
1334
1334
|
@given(data=data(), triples=_upsert_lists(nullable=True, min_size=1))
|
1335
|
+
@mark.flaky
|
1335
1336
|
@settings_with_reduced_examples(phases={Phase.generate})
|
1336
1337
|
async def test_multiple_elements_with_the_same_primary_key(
|
1337
1338
|
self, *, data: DataObject, triples: list[tuple[int, bool, bool | None]]
|
@@ -353,6 +353,7 @@ class Looper(Generic[_T]):
|
|
353
353
|
_is_entered: Event = field(default_factory=Event, init=False, repr=False)
|
354
354
|
_is_initialized: Event = field(default_factory=Event, init=False, repr=False)
|
355
355
|
_is_initializing: Event = field(default_factory=Event, init=False, repr=False)
|
356
|
+
_is_pending_back_off: Event = field(default_factory=Event, init=False, repr=False)
|
356
357
|
_is_pending_restart: Event = field(default_factory=Event, init=False, repr=False)
|
357
358
|
_is_pending_stop: Event = field(default_factory=Event, init=False, repr=False)
|
358
359
|
_is_pending_stop_when_empty: Event = field(
|
@@ -439,6 +440,11 @@ class Looper(Generic[_T]):
|
|
439
440
|
def __len__(self) -> int:
|
440
441
|
return self._queue.qsize()
|
441
442
|
|
443
|
+
async def _apply_back_off(self) -> None:
|
444
|
+
"""Apply a back off period."""
|
445
|
+
await sleep(self._backoff)
|
446
|
+
self._is_pending_back_off.clear()
|
447
|
+
|
442
448
|
async def core(self) -> None:
|
443
449
|
"""Core part of running the looper."""
|
444
450
|
|
@@ -458,7 +464,9 @@ class Looper(Generic[_T]):
|
|
458
464
|
"""Remove and return an item from the end of the queue without blocking."""
|
459
465
|
return self._queue.get_right_nowait()
|
460
466
|
|
461
|
-
async def initialize(
|
467
|
+
async def initialize(
|
468
|
+
self, *, skip_sleep_if_failure: bool = False
|
469
|
+
) -> Exception | None:
|
462
470
|
"""Initialize the looper."""
|
463
471
|
match self._is_initializing.is_set():
|
464
472
|
case True:
|
@@ -476,21 +484,21 @@ class Looper(Generic[_T]):
|
|
476
484
|
async with self._lock:
|
477
485
|
self._initialization_failures += 1
|
478
486
|
ret = error
|
479
|
-
match
|
487
|
+
match skip_sleep_if_failure:
|
480
488
|
case True:
|
481
489
|
_ = self._logger.warning(
|
482
|
-
"%s: encountered %s whilst initializing
|
490
|
+
"%s: encountered %s whilst initializing",
|
483
491
|
self,
|
484
492
|
repr_error(error),
|
485
|
-
self.backoff,
|
486
493
|
)
|
487
|
-
await sleep(self._backoff)
|
488
494
|
case False:
|
489
495
|
_ = self._logger.warning(
|
490
|
-
"%s: encountered %s whilst initializing",
|
496
|
+
"%s: encountered %s whilst initializing; sleeping for %s...",
|
491
497
|
self,
|
492
498
|
repr_error(error),
|
499
|
+
self.backoff,
|
493
500
|
)
|
501
|
+
await self._apply_back_off()
|
494
502
|
case _ as never:
|
495
503
|
assert_never(never)
|
496
504
|
else:
|
@@ -547,6 +555,21 @@ class Looper(Generic[_T]):
|
|
547
555
|
**kwargs,
|
548
556
|
)
|
549
557
|
|
558
|
+
def request_back_off(self) -> None:
|
559
|
+
"""Request the looper to back off."""
|
560
|
+
match self._is_pending_back_off.is_set():
|
561
|
+
case True:
|
562
|
+
_ = self._debug and self._logger.debug(
|
563
|
+
"%s: already requested back off", self
|
564
|
+
)
|
565
|
+
case False:
|
566
|
+
_ = self._debug and self._logger.debug(
|
567
|
+
"%s: requesting back off...", self
|
568
|
+
)
|
569
|
+
self._is_pending_back_off.set()
|
570
|
+
case _ as never:
|
571
|
+
assert_never(never)
|
572
|
+
|
550
573
|
def request_restart(self) -> None:
|
551
574
|
"""Request the looper to restart."""
|
552
575
|
match self._is_pending_restart.is_set():
|
@@ -561,6 +584,7 @@ class Looper(Generic[_T]):
|
|
561
584
|
self._is_pending_restart.set()
|
562
585
|
case _ as never:
|
563
586
|
assert_never(never)
|
587
|
+
self.request_back_off()
|
564
588
|
|
565
589
|
def request_stop(self) -> None:
|
566
590
|
"""Request the looper to stop."""
|
@@ -590,20 +614,20 @@ class Looper(Generic[_T]):
|
|
590
614
|
case _ as never:
|
591
615
|
assert_never(never)
|
592
616
|
|
593
|
-
async def restart(self
|
617
|
+
async def restart(self) -> None:
|
594
618
|
"""Restart the looper."""
|
595
619
|
_ = self._debug and self._logger.debug("%s: restarting...", self)
|
596
620
|
self._is_pending_restart.clear()
|
597
621
|
async with self._lock:
|
598
622
|
self._restart_attempts += 1
|
599
|
-
tear_down = await self.tear_down(
|
600
|
-
initialization = await self.initialize(
|
601
|
-
match tear_down, initialization
|
602
|
-
case None, None
|
623
|
+
tear_down = await self.tear_down(skip_sleep_if_failure=True)
|
624
|
+
initialization = await self.initialize(skip_sleep_if_failure=True)
|
625
|
+
match tear_down, initialization:
|
626
|
+
case None, None:
|
603
627
|
_ = self._debug and self._logger.debug("%s: finished restarting", self)
|
604
628
|
async with self._lock:
|
605
629
|
self._restart_successes += 1
|
606
|
-
case Exception(), None
|
630
|
+
case Exception(), None:
|
607
631
|
async with self._lock:
|
608
632
|
self._restart_failures += 1
|
609
633
|
_ = self._logger.warning(
|
@@ -612,16 +636,8 @@ class Looper(Generic[_T]):
|
|
612
636
|
repr_error(tear_down),
|
613
637
|
self.backoff,
|
614
638
|
)
|
615
|
-
await
|
616
|
-
case Exception()
|
617
|
-
async with self._lock:
|
618
|
-
self._restart_failures += 1
|
619
|
-
_ = self._logger.warning(
|
620
|
-
"%s: encountered %s whilst restarting (tear down)",
|
621
|
-
self,
|
622
|
-
repr_error(tear_down),
|
623
|
-
)
|
624
|
-
case None, Exception(), True:
|
639
|
+
await self._apply_back_off()
|
640
|
+
case None, Exception():
|
625
641
|
async with self._lock:
|
626
642
|
self._restart_failures += 1
|
627
643
|
_ = self._logger.warning(
|
@@ -630,16 +646,8 @@ class Looper(Generic[_T]):
|
|
630
646
|
repr_error(initialization),
|
631
647
|
self.backoff,
|
632
648
|
)
|
633
|
-
await
|
634
|
-
case
|
635
|
-
async with self._lock:
|
636
|
-
self._restart_failures += 1
|
637
|
-
_ = self._logger.warning(
|
638
|
-
"%s: encountered %s whilst restarting (initialize)",
|
639
|
-
self,
|
640
|
-
repr_error(initialization),
|
641
|
-
)
|
642
|
-
case Exception(), Exception(), True:
|
649
|
+
await self._apply_back_off()
|
650
|
+
case Exception(), Exception():
|
643
651
|
async with self._lock:
|
644
652
|
self._restart_failures += 1
|
645
653
|
_ = self._logger.warning(
|
@@ -649,16 +657,7 @@ class Looper(Generic[_T]):
|
|
649
657
|
repr_error(initialization),
|
650
658
|
self.backoff,
|
651
659
|
)
|
652
|
-
await
|
653
|
-
case Exception(), Exception(), False:
|
654
|
-
async with self._lock:
|
655
|
-
self._restart_failures += 1
|
656
|
-
_ = self._logger.warning(
|
657
|
-
"%s: encountered %s (tear down) and then %s (initialization) whilst restarting",
|
658
|
-
self,
|
659
|
-
repr_error(tear_down),
|
660
|
-
repr_error(initialization),
|
661
|
-
)
|
660
|
+
await self._apply_back_off()
|
662
661
|
case _ as never:
|
663
662
|
assert_never(never)
|
664
663
|
|
@@ -674,10 +673,12 @@ class Looper(Generic[_T]):
|
|
674
673
|
self._is_pending_stop_when_empty.is_set() and self.empty()
|
675
674
|
):
|
676
675
|
await self.stop()
|
676
|
+
elif self._is_pending_back_off.is_set():
|
677
|
+
await self._apply_back_off()
|
677
678
|
elif self._is_pending_restart.is_set():
|
678
|
-
await self.restart(
|
679
|
+
await self.restart()
|
679
680
|
elif not self._is_initialized.is_set():
|
680
|
-
_ = await self.initialize(
|
681
|
+
_ = await self.initialize()
|
681
682
|
else:
|
682
683
|
_ = self._debug and self._logger.debug(
|
683
684
|
"%s: running core...", self
|
@@ -695,7 +696,6 @@ class Looper(Generic[_T]):
|
|
695
696
|
async with self._lock:
|
696
697
|
self._core_failures += 1
|
697
698
|
self.request_restart()
|
698
|
-
await sleep(self._backoff)
|
699
699
|
else:
|
700
700
|
async with self._lock:
|
701
701
|
self._core_successes += 1
|
@@ -749,7 +749,9 @@ class Looper(Generic[_T]):
|
|
749
749
|
case _ as never:
|
750
750
|
assert_never(never)
|
751
751
|
|
752
|
-
async def tear_down(
|
752
|
+
async def tear_down(
|
753
|
+
self, *, skip_sleep_if_failure: bool = False
|
754
|
+
) -> Exception | None:
|
753
755
|
"""Tear down the looper."""
|
754
756
|
match self._is_tearing_down.is_set():
|
755
757
|
case True:
|
@@ -766,21 +768,21 @@ class Looper(Generic[_T]):
|
|
766
768
|
async with self._lock:
|
767
769
|
self._tear_down_failures += 1
|
768
770
|
ret = error
|
769
|
-
match
|
771
|
+
match skip_sleep_if_failure:
|
770
772
|
case True:
|
771
773
|
_ = self._logger.warning(
|
772
|
-
"%s: encountered %s whilst tearing down
|
774
|
+
"%s: encountered %s whilst tearing down",
|
773
775
|
self,
|
774
776
|
repr_error(error),
|
775
|
-
self.backoff,
|
776
777
|
)
|
777
|
-
await sleep(self._backoff)
|
778
778
|
case False:
|
779
779
|
_ = self._logger.warning(
|
780
|
-
"%s: encountered %s whilst tearing down",
|
780
|
+
"%s: encountered %s whilst tearing down; sleeping for %s...",
|
781
781
|
self,
|
782
782
|
repr_error(error),
|
783
|
+
self.backoff,
|
783
784
|
)
|
785
|
+
await self._apply_back_off()
|
784
786
|
case _ as never:
|
785
787
|
assert_never(never)
|
786
788
|
else:
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/modules/package_missing/__init__.py
RENAMED
File without changes
|
{dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/modules/package_missing/module.py
RENAMED
File without changes
|
{dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/modules/package_with/__init__.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/modules/package_without/__init__.py
RENAMED
File without changes
|
{dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/modules/package_without/module_1.py
RENAMED
File without changes
|
{dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/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
|
{dycw_utilities-0.129.1 → dycw_utilities-0.129.3}/src/tests/test_asyncio_classes/__init__.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
|