dycw-utilities 0.162.7__tar.gz → 0.162.8__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/PKG-INFO +1 -1
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/pyproject.toml +2 -2
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/test_redis.py +99 -2
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/utilities/__init__.py +1 -1
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/utilities/redis.py +69 -23
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/.gitignore +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/LICENSE +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/README.md +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/__init__.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/conftest.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/modules/__init__.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/modules/package_missing/__init__.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/modules/package_missing/module.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/modules/package_with/__init__.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/modules/package_with/outer_1.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/modules/package_with/outer_2.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/modules/package_with/subpackage/__init__.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/modules/package_with/subpackage/inner_1.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/modules/package_with/subpackage/inner_2.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/modules/package_with/subpackage/inner_3.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/modules/package_without/__init__.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/modules/package_without/module_1.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/modules/package_without/module_2.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/modules/standalone.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/modules/with_imports.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/regressions/test_pytest_regressions/TestMultipleRegressionFixtures__test_main__obj.json +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/regressions/test_pytest_regressions/TestMultipleRegressionFixtures__test_main__series.json +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_int.json +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_literal__false.json +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_literal__true.json +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_nested.json +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/regressions/test_pytest_regressions/TestPolarsRegressionFixture__test_dataframe.json +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/regressions/test_pytest_regressions/TestPolarsRegressionFixture__test_series.json +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/test_aeventkit.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/test_altair.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/test_asyncio.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/test_atomicwrites.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/test_atools.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/test_cachetools.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/test_click.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/test_concurrent.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/test_contextlib.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/test_contextvars.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/test_cryptography.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/test_cvxpy.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/test_dataclasses.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/test_enum.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/test_errors.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/test_fastapi.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/test_fpdf2.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/test_functions.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/test_functools.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/test_getpass.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/test_gzip.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/test_hashlib.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/test_http.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/test_hypothesis.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/test_importlib.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/test_inflect.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/test_ipython.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/test_iterables.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/test_json.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/test_jupyter.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/test_libcst.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/test_lightweight_charts.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/test_logging.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/test_math.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/test_memory_profiler.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/test_modules.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/test_more_itertools.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/test_numpy.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/test_objects/__init__.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/test_objects/objects.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/test_operator.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/test_optuna.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/test_orjson.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/test_os.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/test_parse.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/test_pathlib.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/test_pickle.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/test_platform.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/test_polars.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/test_polars_ols.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/test_postgres.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/test_pottery.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/test_pqdm.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/test_psutil.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/test_pyinstrument.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/test_pytest.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/test_pytest_randomly.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/test_pytest_regressions.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/test_random.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/test_re.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/test_reprlib.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/test_scipy.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/test_sentinel.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/test_shelve.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/test_slack_sdk.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/test_socket.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/test_sqlalchemy.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/test_sqlalchemy_polars.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/test_statsmodels.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/test_string.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/test_tempfile.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/test_testbook.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/test_text.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/test_threading.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/test_timer.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/test_traceback.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/test_typed_settings.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/test_types.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/test_typing.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/test_typing_funcs/__init__.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/test_typing_funcs/no_future.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/test_typing_funcs/with_future.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/test_tzdata.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/test_tzlocal.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/test_uuid.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/test_version.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/test_warnings.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/test_whenever.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/test_zipfile.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/test_zoneinfo.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/utilities/aeventkit.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/utilities/altair.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/utilities/asyncio.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/utilities/atomicwrites.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/utilities/atools.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/utilities/cachetools.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/utilities/click.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/utilities/concurrent.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/utilities/contextlib.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/utilities/contextvars.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/utilities/cryptography.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/utilities/cvxpy.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/utilities/dataclasses.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/utilities/enum.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/utilities/errors.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/utilities/fastapi.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/utilities/fpdf2.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/utilities/functions.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/utilities/functools.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/utilities/getpass.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/utilities/gzip.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/utilities/hashlib.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/utilities/http.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/utilities/hypothesis.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/utilities/importlib.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/utilities/inflect.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/utilities/ipython.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/utilities/iterables.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/utilities/json.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/utilities/jupyter.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/utilities/libcst.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/utilities/lightweight_charts.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/utilities/logging.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/utilities/math.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/utilities/memory_profiler.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/utilities/modules.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/utilities/more_itertools.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/utilities/numpy.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/utilities/operator.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/utilities/optuna.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/utilities/orjson.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/utilities/os.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/utilities/parse.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/utilities/pathlib.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/utilities/pickle.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/utilities/platform.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/utilities/polars.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/utilities/polars_ols.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/utilities/postgres.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/utilities/pottery.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/utilities/pqdm.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/utilities/psutil.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/utilities/py.typed +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/utilities/pyinstrument.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/utilities/pytest.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/utilities/pytest_plugins/__init__.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/utilities/pytest_plugins/pytest_randomly.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/utilities/pytest_plugins/pytest_regressions.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/utilities/pytest_regressions.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/utilities/random.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/utilities/re.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/utilities/reprlib.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/utilities/scipy.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/utilities/sentinel.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/utilities/shelve.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/utilities/slack_sdk.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/utilities/socket.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/utilities/sqlalchemy.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/utilities/sqlalchemy_polars.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/utilities/statsmodels.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/utilities/string.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/utilities/tempfile.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/utilities/testbook.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/utilities/text.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/utilities/threading.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/utilities/timer.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/utilities/traceback.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/utilities/typed_settings.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/utilities/types.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/utilities/typing.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/utilities/tzdata.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/utilities/tzlocal.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/utilities/uuid.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/utilities/version.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/utilities/warnings.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/utilities/whenever.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/utilities/zipfile.py +0 -0
- {dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/utilities/zoneinfo.py +0 -0
@@ -230,7 +230,7 @@ dependencies = [
|
|
230
230
|
name = "dycw-utilities"
|
231
231
|
readme = "README.md"
|
232
232
|
requires-python = ">= 3.12"
|
233
|
-
version = "0.162.
|
233
|
+
version = "0.162.8"
|
234
234
|
|
235
235
|
[project.entry-points.pytest11]
|
236
236
|
pytest-randomly = "utilities.pytest_plugins.pytest_randomly"
|
@@ -263,7 +263,7 @@ test = [
|
|
263
263
|
# bump-my-version
|
264
264
|
[tool.bumpversion]
|
265
265
|
allow_dirty = true
|
266
|
-
current_version = "0.162.
|
266
|
+
current_version = "0.162.8"
|
267
267
|
|
268
268
|
[[tool.bumpversion.files]]
|
269
269
|
filename = "src/utilities/__init__.py"
|
@@ -2,7 +2,8 @@ from __future__ import annotations
|
|
2
2
|
|
3
3
|
from asyncio import Queue
|
4
4
|
from itertools import chain, repeat
|
5
|
-
from
|
5
|
+
from logging import getLogger
|
6
|
+
from typing import TYPE_CHECKING, Any, ClassVar, cast
|
6
7
|
|
7
8
|
from hypothesis import HealthCheck, Phase, given, settings
|
8
9
|
from hypothesis.strategies import (
|
@@ -15,18 +16,22 @@ from hypothesis.strategies import (
|
|
15
16
|
permutations,
|
16
17
|
sampled_from,
|
17
18
|
)
|
18
|
-
from pytest import mark, param, raises
|
19
|
+
from pytest import LogCaptureFixture, fixture, mark, param, raises
|
19
20
|
from redis.asyncio import Redis
|
20
21
|
from redis.asyncio.client import PubSub
|
21
22
|
|
22
23
|
from tests.conftest import SKIPIF_CI_AND_NOT_LINUX
|
23
24
|
from tests.test_objects.objects import objects
|
24
25
|
from utilities.asyncio import get_items_nowait, sleep_td
|
26
|
+
from utilities.functions import get_class_name, identity
|
25
27
|
from utilities.hypothesis import int64s, pairs, text_ascii
|
28
|
+
from utilities.iterables import one
|
26
29
|
from utilities.operator import is_equal
|
27
30
|
from utilities.orjson import deserialize, serialize
|
28
31
|
from utilities.redis import (
|
29
32
|
PublishError,
|
33
|
+
_decoded_data,
|
34
|
+
_handle_message,
|
30
35
|
_is_message,
|
31
36
|
_RedisMessage,
|
32
37
|
publish,
|
@@ -50,6 +55,98 @@ if TYPE_CHECKING:
|
|
50
55
|
_PUB_SUB_SLEEP: TimeDelta = 0.1 * SECOND
|
51
56
|
|
52
57
|
|
58
|
+
@fixture
|
59
|
+
def queue() -> Queue[Any]:
|
60
|
+
return Queue()
|
61
|
+
|
62
|
+
|
63
|
+
class TestHandleMessage:
|
64
|
+
message: ClassVar[_RedisMessage] = _RedisMessage(
|
65
|
+
type="message", pattern=None, channel=b"channel", data=b"data"
|
66
|
+
)
|
67
|
+
|
68
|
+
def test_main(self, *, queue: Queue[Any]) -> None:
|
69
|
+
_handle_message(self.message, identity, queue)
|
70
|
+
assert queue.qsize() == 1
|
71
|
+
assert queue.get_nowait() == self.message
|
72
|
+
|
73
|
+
def test_transform(self, *, queue: Queue[Any]) -> None:
|
74
|
+
_handle_message(self.message, _decoded_data, queue)
|
75
|
+
assert queue.qsize() == 1
|
76
|
+
assert queue.get_nowait() == "data"
|
77
|
+
|
78
|
+
def test_error_transform_no_handler(self, *, queue: Queue[Any]) -> None:
|
79
|
+
class CustomError(Exception): ...
|
80
|
+
|
81
|
+
def transform(message: _RedisMessage, /) -> None:
|
82
|
+
raise CustomError(message)
|
83
|
+
|
84
|
+
_handle_message(self.message, transform, queue)
|
85
|
+
assert queue.empty()
|
86
|
+
|
87
|
+
def test_error_transform_with_handler(
|
88
|
+
self, *, caplog: LogCaptureFixture, queue: Queue[Any]
|
89
|
+
) -> None:
|
90
|
+
logger = getLogger(name := unique_str())
|
91
|
+
|
92
|
+
class CustomError(Exception): ...
|
93
|
+
|
94
|
+
def transform(message: _RedisMessage, /) -> None:
|
95
|
+
raise CustomError(message)
|
96
|
+
|
97
|
+
def error_transform(message: _RedisMessage, error: Exception, /) -> None:
|
98
|
+
logger.warning("Got %r transforming %r", get_class_name(error), message)
|
99
|
+
|
100
|
+
_handle_message(self.message, transform, queue, error_transform=error_transform)
|
101
|
+
assert queue.empty()
|
102
|
+
record = one(r for r in caplog.records if r.name == name)
|
103
|
+
assert record.message == f"Got 'CustomError' transforming {self.message}"
|
104
|
+
|
105
|
+
@mark.parametrize(
|
106
|
+
("min_length", "expected"),
|
107
|
+
[param(3, False), param(4, False), param(5, True), param(6, True)],
|
108
|
+
)
|
109
|
+
def test_filter(
|
110
|
+
self, *, queue: Queue[Any], min_length: int, expected: bool
|
111
|
+
) -> None:
|
112
|
+
_handle_message(
|
113
|
+
self.message,
|
114
|
+
_decoded_data,
|
115
|
+
queue,
|
116
|
+
filter_=lambda text: len(text) >= min_length,
|
117
|
+
)
|
118
|
+
result = queue.empty()
|
119
|
+
assert result is expected
|
120
|
+
|
121
|
+
def test_error_filter_no_handler(self, *, queue: Queue[Any]) -> None:
|
122
|
+
_handle_message(
|
123
|
+
self.message,
|
124
|
+
identity,
|
125
|
+
queue,
|
126
|
+
filter_=lambda text: cast("Any", text)["invalid"],
|
127
|
+
)
|
128
|
+
assert queue.empty()
|
129
|
+
|
130
|
+
def test_error_filter_with_handler(
|
131
|
+
self, *, caplog: LogCaptureFixture, queue: Queue[Any]
|
132
|
+
) -> None:
|
133
|
+
logger = getLogger(name := unique_str())
|
134
|
+
|
135
|
+
def error_filter(message: _RedisMessage, error: Exception, /) -> None:
|
136
|
+
logger.warning("Got %r filtering %r", get_class_name(error), message)
|
137
|
+
|
138
|
+
_handle_message(
|
139
|
+
self.message,
|
140
|
+
identity,
|
141
|
+
queue,
|
142
|
+
filter_=lambda text: cast("Any", text)["invalid"],
|
143
|
+
error_filter=error_filter,
|
144
|
+
)
|
145
|
+
assert queue.empty()
|
146
|
+
record = one(r for r in caplog.records if r.name == name)
|
147
|
+
assert record.message == f"Got 'KeyError' filtering {self.message}"
|
148
|
+
|
149
|
+
|
53
150
|
class TestIsMessage:
|
54
151
|
@mark.parametrize(
|
55
152
|
("message", "channels", "expected"),
|
@@ -639,9 +639,11 @@ def subscribe(
|
|
639
639
|
/,
|
640
640
|
*,
|
641
641
|
timeout: Delta | None = _SUBSCRIBE_TIMEOUT,
|
642
|
-
sleep: Delta = _SUBSCRIBE_SLEEP,
|
643
642
|
output: Literal["raw"],
|
644
|
-
|
643
|
+
error_transform: Callable[[_RedisMessage, Exception], None] | None = None,
|
644
|
+
filter_: Callable[[bytes], bool] | None = None,
|
645
|
+
error_filter: Callable[[bytes, Exception], None] | None = None,
|
646
|
+
sleep: Delta = _SUBSCRIBE_SLEEP,
|
645
647
|
) -> AsyncIterator[Task[None]]: ...
|
646
648
|
@overload
|
647
649
|
@enhanced_async_context_manager
|
@@ -652,9 +654,11 @@ def subscribe(
|
|
652
654
|
/,
|
653
655
|
*,
|
654
656
|
timeout: Delta | None = _SUBSCRIBE_TIMEOUT,
|
655
|
-
sleep: Delta = _SUBSCRIBE_SLEEP,
|
656
657
|
output: Literal["bytes"],
|
658
|
+
error_transform: Callable[[_RedisMessage, Exception], None] | None = None,
|
657
659
|
filter_: Callable[[bytes], bool] | None = None,
|
660
|
+
error_filter: Callable[[bytes, Exception], None] | None = None,
|
661
|
+
sleep: Delta = _SUBSCRIBE_SLEEP,
|
658
662
|
) -> AsyncIterator[Task[None]]: ...
|
659
663
|
@overload
|
660
664
|
@enhanced_async_context_manager
|
@@ -665,9 +669,11 @@ def subscribe(
|
|
665
669
|
/,
|
666
670
|
*,
|
667
671
|
timeout: Delta | None = _SUBSCRIBE_TIMEOUT,
|
668
|
-
sleep: Delta = _SUBSCRIBE_SLEEP,
|
669
672
|
output: Literal["text"] = "text",
|
673
|
+
error_transform: Callable[[_RedisMessage, Exception], None] | None = None,
|
670
674
|
filter_: Callable[[str], bool] | None = None,
|
675
|
+
error_filter: Callable[[str, Exception], None] | None = None,
|
676
|
+
sleep: Delta = _SUBSCRIBE_SLEEP,
|
671
677
|
) -> AsyncIterator[Task[None]]: ...
|
672
678
|
@overload
|
673
679
|
@enhanced_async_context_manager
|
@@ -678,34 +684,35 @@ def subscribe[T](
|
|
678
684
|
/,
|
679
685
|
*,
|
680
686
|
timeout: Delta | None = _SUBSCRIBE_TIMEOUT,
|
681
|
-
sleep: Delta = _SUBSCRIBE_SLEEP,
|
682
687
|
output: Callable[[bytes], T],
|
688
|
+
error_transform: Callable[[_RedisMessage, Exception], None] | None = None,
|
683
689
|
filter_: Callable[[T], bool] | None = None,
|
690
|
+
error_filter: Callable[[T, Exception], None] | None = None,
|
691
|
+
sleep: Delta = _SUBSCRIBE_SLEEP,
|
684
692
|
) -> AsyncIterator[Task[None]]: ...
|
685
693
|
@enhanced_async_context_manager
|
686
|
-
async def subscribe[T](
|
694
|
+
async def subscribe[T, U](
|
687
695
|
redis: Redis,
|
688
696
|
channels: MaybeIterable[str],
|
689
697
|
queue: Queue[_RedisMessage] | Queue[bytes] | Queue[T],
|
690
698
|
/,
|
691
699
|
*,
|
692
700
|
timeout: Delta | None = _SUBSCRIBE_TIMEOUT,
|
693
|
-
sleep: Delta = _SUBSCRIBE_SLEEP,
|
694
701
|
output: Literal["raw", "bytes", "text"] | Callable[[bytes], T] = "text",
|
695
|
-
|
702
|
+
error_transform: Callable[[_RedisMessage, Exception], None] | None = None,
|
703
|
+
filter_: Callable[[T], bool] | None = None,
|
704
|
+
error_filter: Callable[[T, Exception], None] | None = None,
|
705
|
+
sleep: Delta = _SUBSCRIBE_SLEEP,
|
696
706
|
) -> AsyncIterator[Task[None]]:
|
697
707
|
"""Subscribe to the data of a given channel(s)."""
|
698
708
|
channels = list(always_iterable(channels)) # skipif-ci-and-not-linux
|
699
709
|
match output: # skipif-ci-and-not-linux
|
700
710
|
case "raw":
|
701
|
-
transform = cast("
|
711
|
+
transform = cast("Callable[[_RedisMessage], T]", identity)
|
702
712
|
case "bytes":
|
703
|
-
transform = cast("
|
713
|
+
transform = cast("Callable[[_RedisMessage], T]", itemgetter("data"))
|
704
714
|
case "text":
|
705
|
-
|
706
|
-
def transform(message: _RedisMessage, /) -> str: # pyright: ignore[reportRedeclaration]
|
707
|
-
return message["data"].decode()
|
708
|
-
|
715
|
+
transform = cast("Callable[[_RedisMessage], T]", _decoded_data)
|
709
716
|
case Callable() as deserialize:
|
710
717
|
|
711
718
|
def transform(message: _RedisMessage, /) -> T:
|
@@ -721,8 +728,10 @@ async def subscribe[T](
|
|
721
728
|
transform,
|
722
729
|
queue,
|
723
730
|
timeout=timeout,
|
724
|
-
|
731
|
+
error_transform=error_transform,
|
725
732
|
filter_=filter_,
|
733
|
+
error_filter=error_filter,
|
734
|
+
sleep=sleep,
|
726
735
|
)
|
727
736
|
)
|
728
737
|
try: # skipif-ci-and-not-linux
|
@@ -737,16 +746,22 @@ async def subscribe[T](
|
|
737
746
|
await task
|
738
747
|
|
739
748
|
|
740
|
-
|
749
|
+
def _decoded_data(message: _RedisMessage, /) -> str:
|
750
|
+
return message["data"].decode()
|
751
|
+
|
752
|
+
|
753
|
+
async def _subscribe_core[T](
|
741
754
|
redis: Redis,
|
742
755
|
channels: MaybeIterable[str],
|
743
|
-
transform: Callable[[_RedisMessage],
|
756
|
+
transform: Callable[[_RedisMessage], T],
|
744
757
|
queue: Queue[Any],
|
745
758
|
/,
|
746
759
|
*,
|
747
760
|
timeout: Delta | None = _SUBSCRIBE_TIMEOUT,
|
761
|
+
error_transform: Callable[[_RedisMessage, Exception], None] | None = None,
|
762
|
+
filter_: Callable[[T], bool] | None = None,
|
763
|
+
error_filter: Callable[[T, Exception], None] | None = None,
|
748
764
|
sleep: Delta = _SUBSCRIBE_SLEEP,
|
749
|
-
filter_: Callable[[Any], bool] | None = None,
|
750
765
|
) -> None:
|
751
766
|
timeout_use = ( # skipif-ci-and-not-linux
|
752
767
|
None if timeout is None else to_seconds(timeout)
|
@@ -758,11 +773,15 @@ async def _subscribe_core(
|
|
758
773
|
while True:
|
759
774
|
message = await pubsub.get_message(timeout=timeout_use)
|
760
775
|
if is_subscribe_message(message):
|
761
|
-
|
762
|
-
|
763
|
-
|
764
|
-
|
765
|
-
|
776
|
+
_handle_message(
|
777
|
+
message,
|
778
|
+
transform,
|
779
|
+
queue,
|
780
|
+
error_transform=error_transform,
|
781
|
+
filter_=filter_,
|
782
|
+
error_filter=error_filter,
|
783
|
+
)
|
784
|
+
await sleep_td(sleep)
|
766
785
|
|
767
786
|
|
768
787
|
def _is_message(
|
@@ -781,6 +800,33 @@ def _is_message(
|
|
781
800
|
)
|
782
801
|
|
783
802
|
|
803
|
+
def _handle_message[T](
|
804
|
+
message: _RedisMessage,
|
805
|
+
transform: Callable[[_RedisMessage], T],
|
806
|
+
queue: Queue[Any],
|
807
|
+
/,
|
808
|
+
*,
|
809
|
+
error_transform: Callable[[_RedisMessage, Exception], None] | None = None,
|
810
|
+
filter_: Callable[[T], bool] | None = None,
|
811
|
+
error_filter: Callable[[T, Exception], None] | None = None,
|
812
|
+
) -> None:
|
813
|
+
try:
|
814
|
+
transformed = transform(message)
|
815
|
+
except Exception as error: # noqa: BLE001
|
816
|
+
if error_transform is not None:
|
817
|
+
error_transform(message, error)
|
818
|
+
return
|
819
|
+
if filter_ is None:
|
820
|
+
queue.put_nowait(transformed)
|
821
|
+
return
|
822
|
+
try:
|
823
|
+
if filter_(transformed):
|
824
|
+
queue.put_nowait(transformed)
|
825
|
+
except Exception as error: # noqa: BLE001
|
826
|
+
if error_filter is not None:
|
827
|
+
error_filter(transformed, error)
|
828
|
+
|
829
|
+
|
784
830
|
class _RedisMessage(TypedDict):
|
785
831
|
type: Literal["subscribe", "psubscribe", "message", "pmessage"]
|
786
832
|
pattern: str | None
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/modules/package_missing/__init__.py
RENAMED
File without changes
|
{dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/modules/package_missing/module.py
RENAMED
File without changes
|
{dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/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.162.7 → dycw_utilities-0.162.8}/src/tests/modules/package_without/__init__.py
RENAMED
File without changes
|
{dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/modules/package_without/module_1.py
RENAMED
File without changes
|
{dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/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
|
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
|
{dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/tests/test_typing_funcs/with_future.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
|
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
|
{dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/utilities/pytest_plugins/pytest_randomly.py
RENAMED
File without changes
|
{dycw_utilities-0.162.7 → dycw_utilities-0.162.8}/src/utilities/pytest_plugins/pytest_regressions.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
|