dycw-utilities 0.125.12__tar.gz → 0.125.14__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.12 → dycw_utilities-0.125.14}/PKG-INFO +1 -1
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/pyproject.toml +2 -2
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_asyncio.py +54 -20
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/utilities/__init__.py +1 -1
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/utilities/asyncio.py +120 -45
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/.gitignore +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/LICENSE +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/README.md +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/__init__.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/conftest.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/modules/__init__.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/modules/package_missing/__init__.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/modules/package_missing/module.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/modules/package_with/__init__.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/modules/package_with/outer_1.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/modules/package_with/outer_2.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/modules/package_with/subpackage/__init__.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/modules/package_with/subpackage/inner_1.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/modules/package_with/subpackage/inner_2.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/modules/package_with/subpackage/inner_3.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/modules/package_without/__init__.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/modules/package_without/module_1.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/modules/package_without/module_2.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/modules/standalone.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/modules/with_imports.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/regressions/test_pytest_regressions/TestMultipleRegressionFixtures__test_main__obj.json +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/regressions/test_pytest_regressions/TestMultipleRegressionFixtures__test_main__series.json +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_int.json +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_literal__false.json +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_literal__true.json +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_nested.json +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/regressions/test_pytest_regressions/TestPolarsRegressionFixture__test_dataframe.json +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/regressions/test_pytest_regressions/TestPolarsRegressionFixture__test_series.json +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_altair.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_atomicwrites.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_atools.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_cachetools.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_click.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_concurrent.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_contextlib.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_contextvars.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_cryptography.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_cvxpy.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_dataclasses.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_datetime.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_enum.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_errors.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_eventkit.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_fastapi.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_fpdf2.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_functions.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_functools.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_getpass.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_git.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_hashlib.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_http.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_hypothesis.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_importlib.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_ipython.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_iterables.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_jupyter.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_libcst.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_lightweight_charts.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_logging.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_loguru.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_luigi.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_math.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_memory_profiler.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_modules.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_more_itertools.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_numpy.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_operator.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_optuna.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_orjson.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_os.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_parse.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_pathlib.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_period.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_pickle.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_platform.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_polars.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_polars_ols.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_pqdm.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_pydantic.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_pyinstrument.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_pyrsistent.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_pytest.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_pytest_regressions.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_python_dotenv.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_random.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_re.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_redis.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_reprlib.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_rich.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_scipy.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_sentinel.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_shelve.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_slack_sdk.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_socket.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_sqlalchemy.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_sqlalchemy_polars.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_statsmodel.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_streamlit.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_sys.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_tempfile.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_tenacity.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_text.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_threading.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_timer.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_traceback.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_traceback_funcs/__init__.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_traceback_funcs/chain.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_traceback_funcs/decorated_async.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_traceback_funcs/decorated_sync.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_traceback_funcs/error_bind.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_traceback_funcs/many.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_traceback_funcs/one.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_traceback_funcs/recursive.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_traceback_funcs/task_group_one.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_traceback_funcs/task_group_two.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_traceback_funcs/two.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_traceback_funcs/untraced.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_types.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_typing.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_typing_funcs/__init__.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_typing_funcs/no_future.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_typing_funcs/with_future.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_tzdata.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_tzlocal.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_uuid.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_version.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_warnings.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_whenever.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_zipfile.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/test_zoneinfo.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/utilities/altair.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/utilities/atomicwrites.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/utilities/atools.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/utilities/cachetools.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/utilities/click.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/utilities/concurrent.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/utilities/contextlib.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/utilities/contextvars.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/utilities/cryptography.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/utilities/cvxpy.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/utilities/dataclasses.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/utilities/datetime.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/utilities/enum.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/utilities/errors.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/utilities/eventkit.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/utilities/fastapi.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/utilities/fpdf2.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/utilities/functions.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/utilities/functools.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/utilities/getpass.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/utilities/git.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/utilities/hashlib.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/utilities/http.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/utilities/hypothesis.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/utilities/importlib.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/utilities/ipython.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/utilities/iterables.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/utilities/jupyter.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/utilities/libcst.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/utilities/lightweight_charts.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/utilities/logging.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/utilities/loguru.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/utilities/luigi.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/utilities/math.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/utilities/memory_profiler.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/utilities/modules.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/utilities/more_itertools.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/utilities/numpy.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/utilities/operator.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/utilities/optuna.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/utilities/orjson.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/utilities/os.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/utilities/parse.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/utilities/pathlib.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/utilities/period.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/utilities/pickle.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/utilities/platform.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/utilities/polars.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/utilities/polars_ols.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/utilities/pqdm.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/utilities/py.typed +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/utilities/pydantic.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/utilities/pyinstrument.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/utilities/pyrsistent.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/utilities/pytest.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/utilities/pytest_regressions.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/utilities/python_dotenv.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/utilities/random.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/utilities/re.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/utilities/redis.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/utilities/reprlib.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/utilities/rich.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/utilities/scipy.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/utilities/sentinel.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/utilities/shelve.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/utilities/slack_sdk.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/utilities/socket.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/utilities/sqlalchemy.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/utilities/sqlalchemy_polars.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/utilities/statsmodels.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/utilities/streamlit.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/utilities/sys.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/utilities/tempfile.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/utilities/tenacity.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/utilities/text.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/utilities/threading.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/utilities/timer.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/utilities/traceback.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/utilities/types.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/utilities/typing.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/utilities/tzdata.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/utilities/tzlocal.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/utilities/uuid.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/utilities/version.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/utilities/warnings.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/utilities/whenever.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/utilities/zipfile.py +0 -0
- {dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/utilities/zoneinfo.py +0 -0
@@ -93,7 +93,7 @@ dependencies = [
|
|
93
93
|
name = "dycw-utilities"
|
94
94
|
readme = "README.md"
|
95
95
|
requires-python = ">= 3.12"
|
96
|
-
version = "0.125.
|
96
|
+
version = "0.125.14"
|
97
97
|
|
98
98
|
[project.optional-dependencies]
|
99
99
|
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.125.
|
337
|
+
current_version = "0.125.14"
|
338
338
|
|
339
339
|
[[tool.bumpversion.files]]
|
340
340
|
filename = "src/utilities/__init__.py"
|
@@ -975,6 +975,12 @@ class TestLooper:
|
|
975
975
|
looper.put_left_nowait(None)
|
976
976
|
assert not looper.empty()
|
977
977
|
|
978
|
+
def test_get_all_nowait(self) -> None:
|
979
|
+
looper = _ExampleLooper()
|
980
|
+
looper.put_left_nowait(None)
|
981
|
+
items = looper.get_all_nowait()
|
982
|
+
assert items == [None]
|
983
|
+
|
978
984
|
async def test_initialize_already_initializing(
|
979
985
|
self, *, caplog: LogCaptureFixture
|
980
986
|
) -> None:
|
@@ -982,14 +988,20 @@ class TestLooper:
|
|
982
988
|
@override
|
983
989
|
async def _initialize_core(self) -> None:
|
984
990
|
if self._initialization_attempts == 1:
|
985
|
-
_ = await super().initialize()
|
991
|
+
_ = await super().initialize(sleep_if_failure=False)
|
986
992
|
await super()._initialize_core()
|
987
993
|
|
988
994
|
looper = Example()
|
989
|
-
_ = await looper.initialize()
|
995
|
+
_ = await looper.initialize(sleep_if_failure=False)
|
990
996
|
_ = one(m for m in caplog.messages if search(": already initializing$", m))
|
991
997
|
|
992
|
-
|
998
|
+
@given(case=sampled_from([(True, "; sleeping for .*"), (False, "")]))
|
999
|
+
@settings(suppress_health_check={HealthCheck.function_scoped_fixture})
|
1000
|
+
async def test_initialize_failure(
|
1001
|
+
self, *, case: tuple[bool, str], caplog: LogCaptureFixture
|
1002
|
+
) -> None:
|
1003
|
+
sleep_if_failure, extra = case
|
1004
|
+
|
993
1005
|
class Example(_ExampleLooper):
|
994
1006
|
@override
|
995
1007
|
async def _initialize_core(self) -> None:
|
@@ -998,11 +1010,13 @@ class TestLooper:
|
|
998
1010
|
await super()._initialize_core()
|
999
1011
|
|
1000
1012
|
looper = Example()
|
1001
|
-
_ = await looper.initialize()
|
1013
|
+
_ = await looper.initialize(sleep_if_failure=sleep_if_failure)
|
1002
1014
|
_ = one(
|
1003
1015
|
m
|
1004
1016
|
for m in caplog.messages
|
1005
|
-
if search(
|
1017
|
+
if search(
|
1018
|
+
rf": encountered _ExampleLooperError\(\) whilst initializing{extra}$", m
|
1019
|
+
)
|
1006
1020
|
)
|
1007
1021
|
|
1008
1022
|
def test_len_and_qsize(self) -> None:
|
@@ -1122,9 +1136,13 @@ class TestLooper:
|
|
1122
1136
|
if search(r": already requested stop when empty$", m)
|
1123
1137
|
)
|
1124
1138
|
|
1139
|
+
@given(case=sampled_from([(True, "; sleeping for .*"), (False, "")]))
|
1140
|
+
@settings(suppress_health_check={HealthCheck.function_scoped_fixture})
|
1125
1141
|
async def test_restart_failure_during_initialization(
|
1126
|
-
self, *, caplog: LogCaptureFixture
|
1142
|
+
self, *, case: tuple[bool, str], caplog: LogCaptureFixture
|
1127
1143
|
) -> None:
|
1144
|
+
sleep_if_failure, extra = case
|
1145
|
+
|
1128
1146
|
class Example(_ExampleLooper):
|
1129
1147
|
@override
|
1130
1148
|
async def _initialize_core(self) -> None:
|
@@ -1133,19 +1151,23 @@ class TestLooper:
|
|
1133
1151
|
await super()._initialize_core()
|
1134
1152
|
|
1135
1153
|
looper = Example()
|
1136
|
-
await looper.restart()
|
1154
|
+
await looper.restart(sleep_if_failure=sleep_if_failure)
|
1137
1155
|
_ = one(
|
1138
1156
|
m
|
1139
1157
|
for m in caplog.messages
|
1140
1158
|
if search(
|
1141
|
-
|
1159
|
+
rf": encountered _ExampleLooperError\(\) whilst restarting \(initialize\){extra}$",
|
1142
1160
|
m,
|
1143
1161
|
)
|
1144
1162
|
)
|
1145
1163
|
|
1164
|
+
@given(case=sampled_from([(True, "; sleeping for .*"), (False, "")]))
|
1165
|
+
@settings(suppress_health_check={HealthCheck.function_scoped_fixture})
|
1146
1166
|
async def test_restart_failure_during_tear_down(
|
1147
|
-
self, *, caplog: LogCaptureFixture
|
1167
|
+
self, *, case: tuple[bool, str], caplog: LogCaptureFixture
|
1148
1168
|
) -> None:
|
1169
|
+
sleep_if_failure, extra = case
|
1170
|
+
|
1149
1171
|
class Example(_ExampleLooper):
|
1150
1172
|
@override
|
1151
1173
|
async def _tear_down_core(self) -> None:
|
@@ -1154,19 +1176,23 @@ class TestLooper:
|
|
1154
1176
|
await super()._tear_down_core()
|
1155
1177
|
|
1156
1178
|
looper = Example()
|
1157
|
-
await looper.restart()
|
1179
|
+
await looper.restart(sleep_if_failure=sleep_if_failure)
|
1158
1180
|
_ = one(
|
1159
1181
|
m
|
1160
1182
|
for m in caplog.messages
|
1161
1183
|
if search(
|
1162
|
-
|
1184
|
+
rf": encountered _ExampleLooperError\(\) whilst restarting \(tear down\){extra}$",
|
1163
1185
|
m,
|
1164
1186
|
)
|
1165
1187
|
)
|
1166
1188
|
|
1189
|
+
@given(case=sampled_from([(True, "; sleeping for .*"), (False, "")]))
|
1190
|
+
@settings(suppress_health_check={HealthCheck.function_scoped_fixture})
|
1167
1191
|
async def test_restart_failure_during_tear_down_and_initialization(
|
1168
|
-
self, *, caplog: LogCaptureFixture
|
1192
|
+
self, *, case: tuple[bool, str], caplog: LogCaptureFixture
|
1169
1193
|
) -> None:
|
1194
|
+
sleep_if_failure, extra = case
|
1195
|
+
|
1170
1196
|
class Example(_ExampleLooper):
|
1171
1197
|
@override
|
1172
1198
|
async def _initialize_core(self) -> None:
|
@@ -1181,12 +1207,12 @@ class TestLooper:
|
|
1181
1207
|
await super()._tear_down_core()
|
1182
1208
|
|
1183
1209
|
looper = Example()
|
1184
|
-
await looper.restart()
|
1210
|
+
await looper.restart(sleep_if_failure=sleep_if_failure)
|
1185
1211
|
_ = one(
|
1186
1212
|
m
|
1187
1213
|
for m in caplog.messages
|
1188
1214
|
if search(
|
1189
|
-
|
1215
|
+
rf": encountered _ExampleLooperError\(\) \(tear down\) and then _ExampleLooperError\(\) \(initialization\) whilst restarting{extra}$",
|
1190
1216
|
m,
|
1191
1217
|
)
|
1192
1218
|
)
|
@@ -1221,21 +1247,27 @@ class TestLooper:
|
|
1221
1247
|
)
|
1222
1248
|
)
|
1223
1249
|
|
1224
|
-
async def
|
1250
|
+
async def test_tear_down_already_tearing_down(
|
1225
1251
|
self, *, caplog: LogCaptureFixture
|
1226
1252
|
) -> None:
|
1227
1253
|
class Example(_ExampleLooper):
|
1228
1254
|
@override
|
1229
1255
|
async def _tear_down_core(self) -> None:
|
1230
1256
|
if self._tear_down_attempts == 1:
|
1231
|
-
_ = await super().tear_down()
|
1257
|
+
_ = await super().tear_down(sleep_if_failure=False)
|
1232
1258
|
await super()._tear_down_core()
|
1233
1259
|
|
1234
1260
|
looper = Example()
|
1235
|
-
_ = await looper.tear_down()
|
1261
|
+
_ = await looper.tear_down(sleep_if_failure=False)
|
1236
1262
|
_ = one(m for m in caplog.messages if search(": already tearing down$", m))
|
1237
1263
|
|
1238
|
-
|
1264
|
+
@given(case=sampled_from([(True, "; sleeping for .*"), (False, "")]))
|
1265
|
+
@settings(suppress_health_check={HealthCheck.function_scoped_fixture})
|
1266
|
+
async def test_tear_down_failure(
|
1267
|
+
self, *, case: tuple[bool, str], caplog: LogCaptureFixture
|
1268
|
+
) -> None:
|
1269
|
+
sleep_if_failure, extra = case
|
1270
|
+
|
1239
1271
|
class Example(_ExampleLooper):
|
1240
1272
|
@override
|
1241
1273
|
async def _tear_down_core(self) -> None:
|
@@ -1244,11 +1276,13 @@ class TestLooper:
|
|
1244
1276
|
await super()._tear_down_core()
|
1245
1277
|
|
1246
1278
|
looper = Example()
|
1247
|
-
_ = await looper.tear_down()
|
1279
|
+
_ = await looper.tear_down(sleep_if_failure=sleep_if_failure)
|
1248
1280
|
_ = one(
|
1249
1281
|
m
|
1250
1282
|
for m in caplog.messages
|
1251
|
-
if search(
|
1283
|
+
if search(
|
1284
|
+
rf": encountered _ExampleLooperError\(\) whilst tearing down{extra}$", m
|
1285
|
+
)
|
1252
1286
|
)
|
1253
1287
|
|
1254
1288
|
def _assert_stats(
|
@@ -5,6 +5,7 @@ from abc import ABC, abstractmethod
|
|
5
5
|
from asyncio import (
|
6
6
|
CancelledError,
|
7
7
|
Event,
|
8
|
+
Lock,
|
8
9
|
PriorityQueue,
|
9
10
|
Queue,
|
10
11
|
QueueEmpty,
|
@@ -719,6 +720,7 @@ class Looper(Generic[_T]):
|
|
719
720
|
_is_stopped: Event = field(default_factory=Event, init=False, repr=False)
|
720
721
|
_is_tearing_down: Event = field(default_factory=Event, init=False, repr=False)
|
721
722
|
# internal objects
|
723
|
+
_lock: Lock = field(default_factory=Lock, init=False, repr=False, hash=False)
|
722
724
|
_logger: Logger = field(init=False, repr=False, hash=False)
|
723
725
|
_queue: EnhancedQueue[_T] = field(
|
724
726
|
default_factory=EnhancedQueue, init=False, repr=False, hash=False
|
@@ -742,8 +744,9 @@ class Looper(Generic[_T]):
|
|
742
744
|
case False:
|
743
745
|
_ = self._debug and self._logger.debug("%s: entering context...", self)
|
744
746
|
self._is_entered.set()
|
745
|
-
self.
|
746
|
-
|
747
|
+
async with self._lock:
|
748
|
+
self._entries += 1
|
749
|
+
self._task = create_task(self.run_looper())
|
747
750
|
for looper in self._yield_sub_loopers():
|
748
751
|
_ = self._debug and self._logger.debug(
|
749
752
|
"%s: adding sub-looper %s", self, looper
|
@@ -752,7 +755,8 @@ class Looper(Generic[_T]):
|
|
752
755
|
self._logger.warning(
|
753
756
|
"%s: changing sub-looper %s to auto-start...", self, looper
|
754
757
|
)
|
755
|
-
|
758
|
+
async with self._lock:
|
759
|
+
looper.auto_start = True
|
756
760
|
_ = await self._stack.enter_async_context(looper)
|
757
761
|
if self.auto_start:
|
758
762
|
_ = self._debug and self._logger.debug("%s: auto-starting...", self)
|
@@ -797,9 +801,6 @@ class Looper(Generic[_T]):
|
|
797
801
|
case Task() as task:
|
798
802
|
return task.__await__()
|
799
803
|
case _ as never:
|
800
|
-
self._logger.warning( # pragma: no cover
|
801
|
-
"Got %s of type %s", self._task, type(self._task)
|
802
|
-
)
|
803
804
|
assert_never(never)
|
804
805
|
|
805
806
|
def __len__(self) -> int:
|
@@ -812,6 +813,10 @@ class Looper(Generic[_T]):
|
|
812
813
|
"""Check if the queue is empty."""
|
813
814
|
return self._queue.empty()
|
814
815
|
|
816
|
+
def get_all_nowait(self, *, reverse: bool = False) -> Sequence[_T]:
|
817
|
+
"""Remove and return all items from the queue without blocking."""
|
818
|
+
return self._queue.get_all_nowait(reverse=reverse)
|
819
|
+
|
815
820
|
def get_left_nowait(self) -> _T:
|
816
821
|
"""Remove and return an item from the start of the queue without blocking."""
|
817
822
|
return self._queue.get_left_nowait()
|
@@ -820,7 +825,7 @@ class Looper(Generic[_T]):
|
|
820
825
|
"""Remove and return an item from the end of the queue without blocking."""
|
821
826
|
return self._queue.get_right_nowait()
|
822
827
|
|
823
|
-
async def initialize(self) -> Exception | None:
|
828
|
+
async def initialize(self, *, sleep_if_failure: bool) -> Exception | None:
|
824
829
|
"""Initialize the looper."""
|
825
830
|
match self._is_initializing.is_set():
|
826
831
|
case True:
|
@@ -830,23 +835,38 @@ class Looper(Generic[_T]):
|
|
830
835
|
_ = self._debug and self._logger.debug("%s: initializing...", self)
|
831
836
|
self._is_initializing.set()
|
832
837
|
self._is_initialized.clear()
|
833
|
-
self.
|
838
|
+
async with self._lock:
|
839
|
+
self._initialization_attempts += 1
|
834
840
|
try:
|
835
841
|
await self._initialize_core()
|
836
842
|
except Exception as error: # noqa: BLE001
|
837
|
-
|
838
|
-
|
839
|
-
self,
|
840
|
-
repr_error(error),
|
841
|
-
)
|
842
|
-
self._initialization_failures += 1
|
843
|
+
async with self._lock:
|
844
|
+
self._initialization_failures += 1
|
843
845
|
ret = error
|
846
|
+
match sleep_if_failure:
|
847
|
+
case True:
|
848
|
+
_ = self._logger.warning(
|
849
|
+
"%s: encountered %s whilst initializing; sleeping for %s...",
|
850
|
+
self,
|
851
|
+
repr_error(error),
|
852
|
+
self.backoff,
|
853
|
+
)
|
854
|
+
await sleep(self._backoff)
|
855
|
+
case False:
|
856
|
+
_ = self._logger.warning(
|
857
|
+
"%s: encountered %s whilst initializing",
|
858
|
+
self,
|
859
|
+
repr_error(error),
|
860
|
+
)
|
861
|
+
case _ as never:
|
862
|
+
assert_never(never)
|
844
863
|
else:
|
845
864
|
_ = self._debug and self._logger.debug(
|
846
865
|
"%s: finished initializing", self
|
847
866
|
)
|
848
867
|
self._is_initialized.set()
|
849
|
-
self.
|
868
|
+
async with self._lock:
|
869
|
+
self._initialization_successes += 1
|
850
870
|
ret = None
|
851
871
|
finally:
|
852
872
|
self._is_initializing.clear()
|
@@ -931,39 +951,75 @@ class Looper(Generic[_T]):
|
|
931
951
|
case _ as never:
|
932
952
|
assert_never(never)
|
933
953
|
|
934
|
-
async def restart(self) -> None:
|
954
|
+
async def restart(self, *, sleep_if_failure: bool) -> None:
|
935
955
|
"""Restart the looper."""
|
936
956
|
_ = self._debug and self._logger.debug("%s: restarting...", self)
|
937
957
|
self._is_pending_restart.clear()
|
938
|
-
self.
|
939
|
-
|
940
|
-
|
941
|
-
|
942
|
-
|
958
|
+
async with self._lock:
|
959
|
+
self._restart_attempts += 1
|
960
|
+
tear_down = await self.tear_down(sleep_if_failure=False)
|
961
|
+
initialization = await self.initialize(sleep_if_failure=False)
|
962
|
+
match tear_down, initialization, sleep_if_failure:
|
963
|
+
case None, None, bool():
|
943
964
|
_ = self._debug and self._logger.debug("%s: finished restarting", self)
|
944
|
-
self.
|
945
|
-
|
965
|
+
async with self._lock:
|
966
|
+
self._restart_successes += 1
|
967
|
+
case Exception(), None, True:
|
968
|
+
async with self._lock:
|
969
|
+
self._restart_failures += 1
|
970
|
+
_ = self._logger.warning(
|
971
|
+
"%s: encountered %s whilst restarting (tear down); sleeping for %s...",
|
972
|
+
self,
|
973
|
+
repr_error(tear_down),
|
974
|
+
self.backoff,
|
975
|
+
)
|
976
|
+
await sleep(self._backoff)
|
977
|
+
case Exception(), None, False:
|
978
|
+
async with self._lock:
|
979
|
+
self._restart_failures += 1
|
946
980
|
_ = self._logger.warning(
|
947
|
-
"%s: encountered %s whilst restarting
|
981
|
+
"%s: encountered %s whilst restarting (tear down)",
|
948
982
|
self,
|
949
983
|
repr_error(tear_down),
|
950
984
|
)
|
951
|
-
|
952
|
-
|
985
|
+
case None, Exception(), True:
|
986
|
+
async with self._lock:
|
987
|
+
self._restart_failures += 1
|
953
988
|
_ = self._logger.warning(
|
954
|
-
"%s: encountered %s whilst restarting
|
989
|
+
"%s: encountered %s whilst restarting (initialize); sleeping for %s...",
|
955
990
|
self,
|
956
991
|
repr_error(initialization),
|
992
|
+
self.backoff,
|
957
993
|
)
|
958
|
-
self.
|
959
|
-
case Exception(),
|
994
|
+
await sleep(self._backoff)
|
995
|
+
case None, Exception(), False:
|
996
|
+
async with self._lock:
|
997
|
+
self._restart_failures += 1
|
998
|
+
_ = self._logger.warning(
|
999
|
+
"%s: encountered %s whilst restarting (initialize)",
|
1000
|
+
self,
|
1001
|
+
repr_error(initialization),
|
1002
|
+
)
|
1003
|
+
case Exception(), Exception(), True:
|
1004
|
+
async with self._lock:
|
1005
|
+
self._restart_failures += 1
|
1006
|
+
_ = self._logger.warning(
|
1007
|
+
"%s: encountered %s (tear down) and then %s (initialization) whilst restarting; sleeping for %s...",
|
1008
|
+
self,
|
1009
|
+
repr_error(tear_down),
|
1010
|
+
repr_error(initialization),
|
1011
|
+
self.backoff,
|
1012
|
+
)
|
1013
|
+
await sleep(self._backoff)
|
1014
|
+
case Exception(), Exception(), False:
|
1015
|
+
async with self._lock:
|
1016
|
+
self._restart_failures += 1
|
960
1017
|
_ = self._logger.warning(
|
961
1018
|
"%s: encountered %s (tear down) and then %s (initialization) whilst restarting",
|
962
1019
|
self,
|
963
1020
|
repr_error(tear_down),
|
964
1021
|
repr_error(initialization),
|
965
1022
|
)
|
966
|
-
self._restart_failures += 1
|
967
1023
|
case _ as never:
|
968
1024
|
assert_never(never)
|
969
1025
|
|
@@ -979,12 +1035,13 @@ class Looper(Generic[_T]):
|
|
979
1035
|
):
|
980
1036
|
await self.stop()
|
981
1037
|
elif self._is_pending_restart.is_set():
|
982
|
-
await self.restart()
|
1038
|
+
await self.restart(sleep_if_failure=True)
|
983
1039
|
elif not self._is_initialized.is_set():
|
984
|
-
_ = await self.initialize()
|
1040
|
+
_ = await self.initialize(sleep_if_failure=True)
|
985
1041
|
else:
|
986
1042
|
_ = self._debug and self._logger.debug("%s: running core...", self)
|
987
|
-
self.
|
1043
|
+
async with self._lock:
|
1044
|
+
self._core_attempts += 1
|
988
1045
|
try:
|
989
1046
|
await self.core()
|
990
1047
|
except Exception as error: # noqa: BLE001
|
@@ -993,11 +1050,13 @@ class Looper(Generic[_T]):
|
|
993
1050
|
self,
|
994
1051
|
repr_error(error),
|
995
1052
|
)
|
996
|
-
self.
|
1053
|
+
async with self._lock:
|
1054
|
+
self._core_failures += 1
|
997
1055
|
self.request_restart()
|
998
1056
|
await sleep(self._backoff)
|
999
1057
|
else:
|
1000
|
-
self.
|
1058
|
+
async with self._lock:
|
1059
|
+
self._core_successes += 1
|
1001
1060
|
await sleep(self._freq)
|
1002
1061
|
|
1003
1062
|
@property
|
@@ -1029,12 +1088,13 @@ class Looper(Generic[_T]):
|
|
1029
1088
|
_ = self._debug and self._logger.debug("%s: stopping...", self)
|
1030
1089
|
self._is_pending_stop.clear()
|
1031
1090
|
self._is_stopped.set()
|
1032
|
-
self.
|
1091
|
+
async with self._lock:
|
1092
|
+
self._stops += 1
|
1033
1093
|
_ = self._debug and self._logger.debug("%s: stopped", self)
|
1034
1094
|
case _ as never:
|
1035
1095
|
assert_never(never)
|
1036
1096
|
|
1037
|
-
async def tear_down(self) -> Exception | None:
|
1097
|
+
async def tear_down(self, *, sleep_if_failure: bool) -> Exception | None:
|
1038
1098
|
"""Tear down the looper."""
|
1039
1099
|
match self._is_tearing_down.is_set():
|
1040
1100
|
case True:
|
@@ -1043,22 +1103,37 @@ class Looper(Generic[_T]):
|
|
1043
1103
|
case False:
|
1044
1104
|
_ = self._debug and self._logger.debug("%s: tearing down...", self)
|
1045
1105
|
self._is_tearing_down.set()
|
1046
|
-
self.
|
1106
|
+
async with self._lock:
|
1107
|
+
self._tear_down_attempts += 1
|
1047
1108
|
try:
|
1048
1109
|
await self._tear_down_core()
|
1049
1110
|
except Exception as error: # noqa: BLE001
|
1050
|
-
|
1051
|
-
|
1052
|
-
self,
|
1053
|
-
repr_error(error),
|
1054
|
-
)
|
1055
|
-
self._tear_down_failures += 1
|
1111
|
+
async with self._lock:
|
1112
|
+
self._tear_down_failures += 1
|
1056
1113
|
ret = error
|
1114
|
+
match sleep_if_failure:
|
1115
|
+
case True:
|
1116
|
+
_ = self._logger.warning(
|
1117
|
+
"%s: encountered %s whilst tearing down; sleeping for %s...",
|
1118
|
+
self,
|
1119
|
+
repr_error(error),
|
1120
|
+
self.backoff,
|
1121
|
+
)
|
1122
|
+
await sleep(self._backoff)
|
1123
|
+
case False:
|
1124
|
+
_ = self._logger.warning(
|
1125
|
+
"%s: encountered %s whilst tearing down",
|
1126
|
+
self,
|
1127
|
+
repr_error(error),
|
1128
|
+
)
|
1129
|
+
case _ as never:
|
1130
|
+
assert_never(never)
|
1057
1131
|
else:
|
1058
1132
|
_ = self._debug and self._logger.debug(
|
1059
1133
|
"%s: finished tearing down", self
|
1060
1134
|
)
|
1061
|
-
self.
|
1135
|
+
async with self._lock:
|
1136
|
+
self._tear_down_successes += 1
|
1062
1137
|
ret = None
|
1063
1138
|
finally:
|
1064
1139
|
self._is_tearing_down.clear()
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/modules/package_missing/__init__.py
RENAMED
File without changes
|
{dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/modules/package_missing/module.py
RENAMED
File without changes
|
{dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/modules/package_with/__init__.py
RENAMED
File without changes
|
{dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/modules/package_with/outer_1.py
RENAMED
File without changes
|
{dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/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.12 → dycw_utilities-0.125.14}/src/tests/modules/package_without/__init__.py
RENAMED
File without changes
|
{dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/src/tests/modules/package_without/module_1.py
RENAMED
File without changes
|
{dycw_utilities-0.125.12 → dycw_utilities-0.125.14}/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
|