dycw-utilities 0.112.7__tar.gz → 0.112.9__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.112.7 → dycw_utilities-0.112.9}/PKG-INFO +5 -5
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/pyproject.toml +9 -9
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_redis.py +73 -12
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_text.py +30 -5
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/utilities/__init__.py +1 -1
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/utilities/redis.py +107 -39
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/utilities/text.py +2 -2
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/.gitignore +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/LICENSE +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/README.md +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/__init__.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/conftest.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/modules/__init__.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/modules/package_missing/__init__.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/modules/package_missing/module.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/modules/package_with/__init__.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/modules/package_with/outer_1.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/modules/package_with/outer_2.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/modules/package_with/subpackage/__init__.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/modules/package_with/subpackage/inner_1.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/modules/package_with/subpackage/inner_2.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/modules/package_with/subpackage/inner_3.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/modules/package_without/__init__.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/modules/package_without/module_1.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/modules/package_without/module_2.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/modules/standalone.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/modules/with_imports.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/regressions/test_pytest_regressions/TestMultipleRegressionFixtures__test_main__obj.json +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/regressions/test_pytest_regressions/TestMultipleRegressionFixtures__test_main__series.json +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_int.json +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_literal__false.json +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_literal__true.json +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_nested.json +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/regressions/test_pytest_regressions/TestPolarsRegressionFixture__test_dataframe.json +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/regressions/test_pytest_regressions/TestPolarsRegressionFixture__test_series.json +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/scripts/__init__.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/scripts/test_async_service/__init__.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/scripts/test_async_service/__main__.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/scripts/test_async_service/run.sh +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/scripts/test_queue_processor/__init__.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/scripts/test_queue_processor/__main__.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/scripts/test_queue_processor/run.sh +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_altair.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_astor.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_asyncio.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_atomicwrites.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_atools.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_cachetools.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_click.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_concurrent.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_contextlib.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_contextvars.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_cryptography.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_cvxpy.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_dataclasses.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_datetime.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_enum.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_errors.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_eventkit.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_fastapi.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_fpdf2.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_functions.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_functools.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_getpass.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_git.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_hashlib.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_http.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_hypothesis.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_ipython.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_iterables.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_jupyter.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_lightweight_charts.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_logging.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_loguru.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_luigi.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_math.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_memory_profiler.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_modules.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_more_itertools.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_numpy.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_operator.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_optuna.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_orjson.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_os.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_parse.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_pathlib.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_period.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_pickle.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_platform.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_polars.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_polars_ols.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_pqdm.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_pydantic.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_pyinstrument.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_pyrsistent.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_pytest.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_pytest_regressions.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_python_dotenv.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_random.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_re.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_reprlib.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_rich.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_scipy.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_sentinel.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_shelve.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_slack_sdk.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_socket.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_sqlalchemy.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_sqlalchemy_polars.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_statsmodel.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_streamlit.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_sys.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_tempfile.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_tenacity.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_threading.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_timer.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_traceback.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_traceback_funcs/__init__.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_traceback_funcs/chain.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_traceback_funcs/decorated_async.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_traceback_funcs/decorated_sync.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_traceback_funcs/error_bind.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_traceback_funcs/many.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_traceback_funcs/one.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_traceback_funcs/recursive.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_traceback_funcs/task_group_one.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_traceback_funcs/task_group_two.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_traceback_funcs/two.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_traceback_funcs/untraced.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_types.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_typing.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_typing_funcs/__init__.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_typing_funcs/no_future.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_typing_funcs/with_future.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_tzdata.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_tzlocal.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_uuid.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_version.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_warnings.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_whenever.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_zipfile.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/test_zoneinfo.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/utilities/altair.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/utilities/astor.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/utilities/asyncio.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/utilities/atomicwrites.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/utilities/atools.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/utilities/cachetools.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/utilities/click.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/utilities/concurrent.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/utilities/contextlib.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/utilities/contextvars.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/utilities/cryptography.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/utilities/cvxpy.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/utilities/dataclasses.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/utilities/datetime.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/utilities/enum.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/utilities/errors.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/utilities/eventkit.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/utilities/fastapi.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/utilities/fpdf2.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/utilities/functions.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/utilities/functools.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/utilities/getpass.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/utilities/git.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/utilities/hashlib.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/utilities/http.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/utilities/hypothesis.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/utilities/ipython.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/utilities/iterables.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/utilities/jupyter.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/utilities/lightweight_charts.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/utilities/logging.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/utilities/loguru.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/utilities/luigi.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/utilities/math.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/utilities/memory_profiler.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/utilities/modules.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/utilities/more_itertools.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/utilities/numpy.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/utilities/operator.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/utilities/optuna.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/utilities/orjson.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/utilities/os.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/utilities/parse.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/utilities/pathlib.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/utilities/period.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/utilities/pickle.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/utilities/platform.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/utilities/polars.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/utilities/polars_ols.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/utilities/pqdm.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/utilities/py.typed +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/utilities/pydantic.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/utilities/pyinstrument.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/utilities/pyrsistent.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/utilities/pytest.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/utilities/pytest_regressions.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/utilities/python_dotenv.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/utilities/random.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/utilities/re.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/utilities/reprlib.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/utilities/rich.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/utilities/scipy.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/utilities/sentinel.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/utilities/shelve.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/utilities/slack_sdk.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/utilities/socket.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/utilities/sqlalchemy.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/utilities/sqlalchemy_polars.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/utilities/statsmodels.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/utilities/streamlit.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/utilities/sys.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/utilities/tempfile.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/utilities/tenacity.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/utilities/threading.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/utilities/timer.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/utilities/traceback.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/utilities/types.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/utilities/typing.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/utilities/tzdata.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/utilities/tzlocal.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/utilities/uuid.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/utilities/version.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/utilities/warnings.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/utilities/whenever.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/utilities/zipfile.py +0 -0
- {dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/utilities/zoneinfo.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: dycw-utilities
|
3
|
-
Version: 0.112.
|
3
|
+
Version: 0.112.9
|
4
4
|
Author-email: Derek Wan <d.wan@icloud.com>
|
5
5
|
License-File: LICENSE
|
6
6
|
Requires-Python: >=3.12
|
@@ -74,7 +74,7 @@ Requires-Dist: polars-lts-cpu<1.29,>=1.28.1; extra == 'zzz-test-hashlib'
|
|
74
74
|
Requires-Dist: whenever<0.8,>=0.7.3; extra == 'zzz-test-hashlib'
|
75
75
|
Provides-Extra: zzz-test-http
|
76
76
|
Requires-Dist: atomicwrites<1.5,>=1.4.1; extra == 'zzz-test-http'
|
77
|
-
Requires-Dist: orjson<3.11,>=3.10.
|
77
|
+
Requires-Dist: orjson<3.11,>=3.10.18; extra == 'zzz-test-http'
|
78
78
|
Requires-Dist: whenever<0.8,>=0.7.3; extra == 'zzz-test-http'
|
79
79
|
Provides-Extra: zzz-test-hypothesis
|
80
80
|
Requires-Dist: aiosqlite<0.22,>=0.21.0; extra == 'zzz-test-hypothesis'
|
@@ -144,7 +144,7 @@ Provides-Extra: zzz-test-pqdm
|
|
144
144
|
Requires-Dist: pqdm<0.3,>=0.2.0; extra == 'zzz-test-pqdm'
|
145
145
|
Provides-Extra: zzz-test-pydantic
|
146
146
|
Requires-Dist: atomicwrites<1.5,>=1.4.1; extra == 'zzz-test-pydantic'
|
147
|
-
Requires-Dist: pydantic<2.12,>=2.11.
|
147
|
+
Requires-Dist: pydantic<2.12,>=2.11.4; extra == 'zzz-test-pydantic'
|
148
148
|
Provides-Extra: zzz-test-pyinstrument
|
149
149
|
Requires-Dist: atomicwrites<1.5,>=1.4.1; extra == 'zzz-test-pyinstrument'
|
150
150
|
Requires-Dist: pyinstrument<5.1,>=5.0.0; extra == 'zzz-test-pyinstrument'
|
@@ -153,7 +153,7 @@ Provides-Extra: zzz-test-pyrsistent
|
|
153
153
|
Requires-Dist: pyrsistent<0.21,>=0.20.0; extra == 'zzz-test-pyrsistent'
|
154
154
|
Provides-Extra: zzz-test-pytest
|
155
155
|
Requires-Dist: atomicwrites<1.5,>=1.4.1; extra == 'zzz-test-pytest'
|
156
|
-
Requires-Dist: orjson<3.11,>=3.10.
|
156
|
+
Requires-Dist: orjson<3.11,>=3.10.18; extra == 'zzz-test-pytest'
|
157
157
|
Requires-Dist: whenever<0.8,>=0.7.3; extra == 'zzz-test-pytest'
|
158
158
|
Provides-Extra: zzz-test-pytest-regressions
|
159
159
|
Requires-Dist: pytest-regressions<2.8,>=2.7.0; extra == 'zzz-test-pytest-regressions'
|
@@ -197,7 +197,7 @@ Requires-Dist: sqlalchemy<2.1,>=2.0.40; extra == 'zzz-test-sqlalchemy-polars'
|
|
197
197
|
Requires-Dist: tenacity<9.0,>=8.5.0; extra == 'zzz-test-sqlalchemy-polars'
|
198
198
|
Requires-Dist: whenever<0.8,>=0.7.3; extra == 'zzz-test-sqlalchemy-polars'
|
199
199
|
Provides-Extra: zzz-test-streamlit
|
200
|
-
Requires-Dist: streamlit<1.
|
200
|
+
Requires-Dist: streamlit<1.46,>=1.45.0; extra == 'zzz-test-streamlit'
|
201
201
|
Provides-Extra: zzz-test-sys
|
202
202
|
Requires-Dist: atomicwrites<1.5,>=1.4.1; extra == 'zzz-test-sys'
|
203
203
|
Requires-Dist: rich<14.1,>=14.0.0; extra == 'zzz-test-sys'
|
@@ -38,13 +38,13 @@ dev = [
|
|
38
38
|
"nox >= 2025.2.9, < 2025.3",
|
39
39
|
"numpy >= 2.2.5, < 2.3",
|
40
40
|
"optuna >= 4.3.0, < 4.4",
|
41
|
-
"orjson >= 3.10.
|
41
|
+
"orjson >= 3.10.18, < 3.11",
|
42
42
|
"pathvalidate >= 3.2.3, < 3.3",
|
43
43
|
"polars-lts-cpu >= 1.28.1, < 1.29",
|
44
44
|
"polars-ols >= 0.3.5, < 0.4",
|
45
45
|
"pqdm >= 0.2.0, < 0.3",
|
46
46
|
"psycopg2-binary >= 2.9.10, < 2.10", # for sqlalchemy
|
47
|
-
"pydantic >= 2.11.
|
47
|
+
"pydantic >= 2.11.4, < 2.12",
|
48
48
|
"pyinstrument >= 5.0.0, < 5.1",
|
49
49
|
"pyrsistent >= 0.20.0, < 0.21",
|
50
50
|
"pytest >= 8.3.5, < 8.4",
|
@@ -57,7 +57,7 @@ dev = [
|
|
57
57
|
"slack-sdk >= 3.35.0, < 3.36",
|
58
58
|
"sqlalchemy >= 2.0.40, < 2.1",
|
59
59
|
"statsmodels >= 0.14.4, < 0.15",
|
60
|
-
"streamlit >= 1.
|
60
|
+
"streamlit >= 1.45.0, < 1.46",
|
61
61
|
"tenacity >= 8.5.0, < 9.0", # limited by luigi
|
62
62
|
"tomlkit >= 0.13.2, < 0.14",
|
63
63
|
"tzdata >= 2025.2, < 2025.3",
|
@@ -93,7 +93,7 @@ dependencies = [
|
|
93
93
|
name = "dycw-utilities"
|
94
94
|
readme = "README.md"
|
95
95
|
requires-python = ">= 3.12"
|
96
|
-
version = "0.112.
|
96
|
+
version = "0.112.9"
|
97
97
|
|
98
98
|
[project.optional-dependencies]
|
99
99
|
test = [
|
@@ -168,7 +168,7 @@ zzz-test-hashlib = [
|
|
168
168
|
]
|
169
169
|
zzz-test-http = [
|
170
170
|
"atomicwrites >= 1.4.1, < 1.5",
|
171
|
-
"orjson >= 3.10.
|
171
|
+
"orjson >= 3.10.18, < 3.11",
|
172
172
|
"whenever >= 0.7.3, < 0.8",
|
173
173
|
]
|
174
174
|
zzz-test-hypothesis = [
|
@@ -238,7 +238,7 @@ zzz-test-polars = [
|
|
238
238
|
zzz-test-pqdm = ["pqdm >= 0.2.0, < 0.3"]
|
239
239
|
zzz-test-pydantic = [
|
240
240
|
"atomicwrites >= 1.4.1, < 1.5",
|
241
|
-
"pydantic >= 2.11.
|
241
|
+
"pydantic >= 2.11.4, < 2.12",
|
242
242
|
]
|
243
243
|
zzz-test-pyinstrument = [
|
244
244
|
"atomicwrites >= 1.4.1, < 1.5",
|
@@ -248,7 +248,7 @@ zzz-test-pyinstrument = [
|
|
248
248
|
zzz-test-pyrsistent = ["pyrsistent >= 0.20.0, < 0.21"]
|
249
249
|
zzz-test-pytest = [
|
250
250
|
"atomicwrites >= 1.4.1, < 1.5",
|
251
|
-
"orjson >= 3.10.
|
251
|
+
"orjson >= 3.10.18, < 3.11",
|
252
252
|
"whenever >= 0.7.3, < 0.8",
|
253
253
|
]
|
254
254
|
zzz-test-pytest-regressions = ["pytest-regressions >= 2.7.0, < 2.8"]
|
@@ -294,7 +294,7 @@ zzz-test-sqlalchemy-polars = [
|
|
294
294
|
"tenacity >= 8.5.0, < 9.0", # limited by luigi
|
295
295
|
"whenever >= 0.7.3, < 0.8",
|
296
296
|
]
|
297
|
-
zzz-test-streamlit = ["streamlit >= 1.
|
297
|
+
zzz-test-streamlit = ["streamlit >= 1.45.0, < 1.46"]
|
298
298
|
zzz-test-sys = [
|
299
299
|
"atomicwrites >= 1.4.1, < 1.5",
|
300
300
|
"rich >= 14.0.0, < 14.1",
|
@@ -336,7 +336,7 @@ zzz-test-zoneinfo = [
|
|
336
336
|
# bump-my-version
|
337
337
|
[tool.bumpversion]
|
338
338
|
allow_dirty = true
|
339
|
-
current_version = "0.112.
|
339
|
+
current_version = "0.112.9"
|
340
340
|
|
341
341
|
[[tool.bumpversion.files]]
|
342
342
|
filename = "src/utilities/__init__.py"
|
@@ -4,8 +4,15 @@ from asyncio import create_task, get_running_loop, sleep
|
|
4
4
|
from typing import TYPE_CHECKING, Any
|
5
5
|
|
6
6
|
from hypothesis import HealthCheck, Phase, given, settings
|
7
|
-
from hypothesis.strategies import
|
8
|
-
|
7
|
+
from hypothesis.strategies import (
|
8
|
+
DataObject,
|
9
|
+
booleans,
|
10
|
+
data,
|
11
|
+
dictionaries,
|
12
|
+
lists,
|
13
|
+
sampled_from,
|
14
|
+
)
|
15
|
+
from pytest import mark, raises
|
9
16
|
from redis.asyncio import Redis
|
10
17
|
|
11
18
|
from tests.conftest import SKIPIF_CI_AND_NOT_LINUX
|
@@ -30,6 +37,8 @@ from utilities.redis import (
|
|
30
37
|
from utilities.sentinel import SENTINEL_REPR, Sentinel, sentinel
|
31
38
|
|
32
39
|
if TYPE_CHECKING:
|
40
|
+
from collections.abc import Mapping
|
41
|
+
|
33
42
|
from pytest import CaptureFixture
|
34
43
|
|
35
44
|
|
@@ -221,7 +230,6 @@ class TestRedisHashMapKey:
|
|
221
230
|
) -> None:
|
222
231
|
async with yield_test_redis(data) as test:
|
223
232
|
hm_key = redis_hash_map_key(test.key, int, bool)
|
224
|
-
assert await hm_key.get(test.redis, key) is None
|
225
233
|
_ = await hm_key.set(test.redis, key, value)
|
226
234
|
assert await hm_key.get(test.redis, key) is value
|
227
235
|
|
@@ -233,7 +241,6 @@ class TestRedisHashMapKey:
|
|
233
241
|
) -> None:
|
234
242
|
async with yield_test_redis(data) as test:
|
235
243
|
hm_key = redis_hash_map_key(test.key, (bool, int), bool)
|
236
|
-
assert await hm_key.get(test.redis, key) is None
|
237
244
|
_ = await hm_key.set(test.redis, key, value)
|
238
245
|
assert await hm_key.get(test.redis, key) is value
|
239
246
|
|
@@ -250,7 +257,6 @@ class TestRedisHashMapKey:
|
|
250
257
|
hm_key = redis_hash_map_key(
|
251
258
|
test.key, Sentinel, bool, key_serializer=serializer
|
252
259
|
)
|
253
|
-
assert await hm_key.get(test.redis, sentinel) is None
|
254
260
|
_ = await hm_key.set(test.redis, sentinel, value)
|
255
261
|
assert await hm_key.get(test.redis, sentinel) is value
|
256
262
|
|
@@ -262,7 +268,6 @@ class TestRedisHashMapKey:
|
|
262
268
|
) -> None:
|
263
269
|
async with yield_test_redis(data) as test:
|
264
270
|
hm_key = redis_hash_map_key(test.key, int, (bool, int))
|
265
|
-
assert await hm_key.get(test.redis, key) is None
|
266
271
|
_ = await hm_key.set(test.redis, key, value)
|
267
272
|
assert await hm_key.get(test.redis, key) == value
|
268
273
|
|
@@ -287,10 +292,25 @@ class TestRedisHashMapKey:
|
|
287
292
|
value_serializer=serializer,
|
288
293
|
value_deserializer=deserializer,
|
289
294
|
)
|
290
|
-
assert await hm_key.get(test.redis, key) is None
|
291
295
|
_ = await hm_key.set(test.redis, key, sentinel)
|
292
296
|
assert await hm_key.get(test.redis, key) is sentinel
|
293
297
|
|
298
|
+
@given(data=data(), mapping=dictionaries(int64s(), booleans()))
|
299
|
+
@settings_with_reduced_examples(phases={Phase.generate})
|
300
|
+
@SKIPIF_CI_AND_NOT_LINUX
|
301
|
+
async def test_get_and_set_many(
|
302
|
+
self, *, data: DataObject, mapping: Mapping[int, bool]
|
303
|
+
) -> None:
|
304
|
+
async with yield_test_redis(data) as test:
|
305
|
+
hm_key = redis_hash_map_key(test.key, int, bool)
|
306
|
+
_ = await hm_key.set_many(test.redis, mapping)
|
307
|
+
if len(mapping) == 0:
|
308
|
+
keys = []
|
309
|
+
else:
|
310
|
+
keys = data.draw(lists(sampled_from(list(mapping))))
|
311
|
+
expected = [mapping[k] for k in keys]
|
312
|
+
assert await hm_key.get_many(test.redis, keys) == expected
|
313
|
+
|
294
314
|
@given(data=data(), key=int64s(), value=booleans())
|
295
315
|
@settings_with_reduced_examples(phases={Phase.generate})
|
296
316
|
@SKIPIF_CI_AND_NOT_LINUX
|
@@ -300,7 +320,8 @@ class TestRedisHashMapKey:
|
|
300
320
|
_ = await hm_key.set(test.redis, key, value)
|
301
321
|
assert await hm_key.get(test.redis, key) is value
|
302
322
|
_ = await hm_key.delete(test.redis, key)
|
303
|
-
|
323
|
+
with raises(KeyError):
|
324
|
+
_ = await hm_key.get(test.redis, key)
|
304
325
|
|
305
326
|
@given(data=data(), key=int64s(), value=booleans())
|
306
327
|
@settings_with_reduced_examples(phases={Phase.generate})
|
@@ -312,6 +333,37 @@ class TestRedisHashMapKey:
|
|
312
333
|
_ = await hm_key.set(test.redis, key, value)
|
313
334
|
assert await hm_key.exists(test.redis, key)
|
314
335
|
|
336
|
+
@given(data=data(), mapping=dictionaries(int64s(), booleans()))
|
337
|
+
@settings_with_reduced_examples(phases={Phase.generate})
|
338
|
+
@SKIPIF_CI_AND_NOT_LINUX
|
339
|
+
async def test_get_all(
|
340
|
+
self, *, data: DataObject, mapping: Mapping[int, bool]
|
341
|
+
) -> None:
|
342
|
+
async with yield_test_redis(data) as test:
|
343
|
+
hm_key = redis_hash_map_key(test.key, int, bool)
|
344
|
+
_ = await hm_key.set_many(test.redis, mapping)
|
345
|
+
assert await hm_key.get_all(test.redis) == mapping
|
346
|
+
|
347
|
+
@given(data=data(), mapping=dictionaries(int64s(), booleans()))
|
348
|
+
@settings_with_reduced_examples(phases={Phase.generate})
|
349
|
+
@SKIPIF_CI_AND_NOT_LINUX
|
350
|
+
async def test_keys(self, *, data: DataObject, mapping: Mapping[int, bool]) -> None:
|
351
|
+
async with yield_test_redis(data) as test:
|
352
|
+
hm_key = redis_hash_map_key(test.key, int, bool)
|
353
|
+
_ = await hm_key.set_many(test.redis, mapping)
|
354
|
+
assert await hm_key.keys(test.redis) == list(mapping)
|
355
|
+
|
356
|
+
@given(data=data(), mapping=dictionaries(int64s(), booleans()))
|
357
|
+
@settings_with_reduced_examples(phases={Phase.generate})
|
358
|
+
@SKIPIF_CI_AND_NOT_LINUX
|
359
|
+
async def test_length(
|
360
|
+
self, *, data: DataObject, mapping: Mapping[int, bool]
|
361
|
+
) -> None:
|
362
|
+
async with yield_test_redis(data) as test:
|
363
|
+
hm_key = redis_hash_map_key(test.key, int, bool)
|
364
|
+
_ = await hm_key.set_many(test.redis, mapping)
|
365
|
+
assert await hm_key.length(test.redis) == len(mapping)
|
366
|
+
|
315
367
|
@given(data=data(), key=int64s(), value=booleans())
|
316
368
|
@settings(max_examples=1, phases={Phase.generate})
|
317
369
|
@SKIPIF_CI_AND_NOT_LINUX
|
@@ -324,6 +376,17 @@ class TestRedisHashMapKey:
|
|
324
376
|
await sleep(0.05)
|
325
377
|
assert not await test.redis.exists(hm_key.name)
|
326
378
|
|
379
|
+
@given(data=data(), mapping=dictionaries(int64s(), booleans()))
|
380
|
+
@settings_with_reduced_examples(phases={Phase.generate})
|
381
|
+
@SKIPIF_CI_AND_NOT_LINUX
|
382
|
+
async def test_values(
|
383
|
+
self, *, data: DataObject, mapping: Mapping[int, bool]
|
384
|
+
) -> None:
|
385
|
+
async with yield_test_redis(data) as test:
|
386
|
+
hm_key = redis_hash_map_key(test.key, int, bool)
|
387
|
+
_ = await hm_key.set_many(test.redis, mapping)
|
388
|
+
assert await hm_key.values(test.redis) == list(mapping.values())
|
389
|
+
|
327
390
|
|
328
391
|
class TestRedisKey:
|
329
392
|
@given(data=data(), value=booleans())
|
@@ -332,7 +395,6 @@ class TestRedisKey:
|
|
332
395
|
async def test_get_and_set_bool(self, *, data: DataObject, value: bool) -> None:
|
333
396
|
async with yield_test_redis(data) as test:
|
334
397
|
key = redis_key(test.key, bool)
|
335
|
-
assert await key.get(test.redis) is None
|
336
398
|
_ = await key.set(test.redis, value)
|
337
399
|
assert await key.get(test.redis) is value
|
338
400
|
|
@@ -344,7 +406,6 @@ class TestRedisKey:
|
|
344
406
|
) -> None:
|
345
407
|
async with yield_test_redis(data) as test:
|
346
408
|
key = redis_key(test.key, (bool, int))
|
347
|
-
assert await key.get(test.redis) is None
|
348
409
|
_ = await key.set(test.redis, value)
|
349
410
|
assert await key.get(test.redis) == value
|
350
411
|
|
@@ -365,7 +426,6 @@ class TestRedisKey:
|
|
365
426
|
key = redis_key(
|
366
427
|
test.key, Sentinel, serializer=serializer, deserializer=deserializer
|
367
428
|
)
|
368
|
-
assert await key.get(test.redis) is None
|
369
429
|
_ = await key.set(test.redis, sentinel)
|
370
430
|
assert await key.get(test.redis) is sentinel
|
371
431
|
|
@@ -378,7 +438,8 @@ class TestRedisKey:
|
|
378
438
|
_ = await key.set(test.redis, value)
|
379
439
|
assert await key.get(test.redis) is value
|
380
440
|
_ = await key.delete(test.redis)
|
381
|
-
|
441
|
+
with raises(KeyError):
|
442
|
+
_ = await key.get(test.redis)
|
382
443
|
|
383
444
|
@given(data=data(), value=booleans())
|
384
445
|
@settings_with_reduced_examples(phases={Phase.generate})
|
@@ -1,5 +1,6 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
|
+
from itertools import chain
|
3
4
|
from typing import TYPE_CHECKING
|
4
5
|
|
5
6
|
from hypothesis import given
|
@@ -44,14 +45,38 @@ if TYPE_CHECKING:
|
|
44
45
|
class TestParseBool:
|
45
46
|
@given(data=data(), value=booleans())
|
46
47
|
def test_main(self, *, data: DataObject, value: bool) -> None:
|
47
|
-
|
48
|
-
|
49
|
-
|
48
|
+
match value:
|
49
|
+
case True:
|
50
|
+
extra_cased_texts = ["Y", "Yes", "On"]
|
51
|
+
case False:
|
52
|
+
extra_cased_texts = ["N", "No", "Off"]
|
53
|
+
all_cased_texts = list(chain([str(value), str(int(value))], extra_cased_texts))
|
54
|
+
all_texts = list(
|
55
|
+
chain(
|
56
|
+
extra_cased_texts,
|
57
|
+
map(str.lower, all_cased_texts),
|
58
|
+
map(str.upper, all_cased_texts),
|
59
|
+
)
|
50
60
|
)
|
51
|
-
|
61
|
+
text = data.draw(sampled_from(all_texts))
|
62
|
+
result = parse_bool(text)
|
52
63
|
assert result is value
|
53
64
|
|
54
|
-
@given(
|
65
|
+
@given(
|
66
|
+
text=sampled_from([
|
67
|
+
"00",
|
68
|
+
"11",
|
69
|
+
"ffalsee",
|
70
|
+
"invalid",
|
71
|
+
"nn",
|
72
|
+
"nnoo",
|
73
|
+
"oofff",
|
74
|
+
"oonn",
|
75
|
+
"ttruee",
|
76
|
+
"yy",
|
77
|
+
"yyess",
|
78
|
+
])
|
79
|
+
)
|
55
80
|
def test_error(self, *, text: str) -> None:
|
56
81
|
with raises(ParseBoolError, match="Unable to parse boolean value; got '.*'"):
|
57
82
|
_ = parse_bool(text)
|
@@ -31,11 +31,18 @@ from utilities.datetime import (
|
|
31
31
|
)
|
32
32
|
from utilities.errors import ImpossibleCaseError
|
33
33
|
from utilities.functions import ensure_int
|
34
|
-
from utilities.iterables import always_iterable
|
34
|
+
from utilities.iterables import always_iterable, one
|
35
35
|
|
36
36
|
if TYPE_CHECKING:
|
37
37
|
import datetime as dt
|
38
|
-
from collections.abc import
|
38
|
+
from collections.abc import (
|
39
|
+
AsyncIterator,
|
40
|
+
Awaitable,
|
41
|
+
Callable,
|
42
|
+
Iterable,
|
43
|
+
Mapping,
|
44
|
+
Sequence,
|
45
|
+
)
|
39
46
|
|
40
47
|
from redis.asyncio import ConnectionPool
|
41
48
|
from redis.asyncio.client import PubSub
|
@@ -71,6 +78,7 @@ class RedisHashMapKey(Generic[_K, _V]):
|
|
71
78
|
name: str
|
72
79
|
key: TypeLike[_K]
|
73
80
|
key_serializer: Callable[[_K], bytes] | None = None
|
81
|
+
key_deserializer: Callable[[bytes], _K] | None = None
|
74
82
|
value: TypeLike[_V]
|
75
83
|
value_serializer: Callable[[_V], bytes] | None = None
|
76
84
|
value_deserializer: Callable[[bytes], _V] | None = None
|
@@ -95,46 +103,102 @@ class RedisHashMapKey(Generic[_K, _V]):
|
|
95
103
|
"Awaitable[bool]", redis.hexists(self.name, cast("str", key))
|
96
104
|
)
|
97
105
|
|
98
|
-
async def get(self, redis: Redis, key: _K, /) -> _V
|
106
|
+
async def get(self, redis: Redis, key: _K, /) -> _V:
|
107
|
+
"""Get a value from a hashmap in `redis`."""
|
108
|
+
result = one(await self.get_many(redis, [key])) # skipif-ci-and-not-linux
|
109
|
+
if result is None: # skipif-ci-and-not-linux
|
110
|
+
raise KeyError(self.name, key)
|
111
|
+
return result # skipif-ci-and-not-linux
|
112
|
+
|
113
|
+
async def get_all(self, redis: Redis, /) -> Mapping[_K, _V]:
|
99
114
|
"""Get a value from a hashmap in `redis`."""
|
100
|
-
ser_key = _serialize( # skipif-ci-and-not-linux
|
101
|
-
key, serializer=self.key_serializer
|
102
|
-
)
|
103
115
|
async with timeout_dur( # skipif-ci-and-not-linux
|
104
116
|
duration=self.timeout, error=self.error
|
105
117
|
):
|
106
118
|
result = await cast( # skipif-ci-and-not-linux
|
107
|
-
"Awaitable[bytes
|
119
|
+
"Awaitable[Mapping[bytes, bytes]]", redis.hgetall(self.name)
|
108
120
|
)
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
121
|
+
return { # skipif-ci-and-not-linux
|
122
|
+
_deserialize(key, deserializer=self.key_deserializer): _deserialize(
|
123
|
+
value, deserializer=self.value_deserializer
|
124
|
+
)
|
125
|
+
for key, value in result.items()
|
126
|
+
}
|
127
|
+
|
128
|
+
async def get_many(
|
129
|
+
self, redis: Redis, keys: Iterable[_K], /
|
130
|
+
) -> Sequence[_V | None]:
|
131
|
+
"""Get multiple values from a hashmap in `redis`."""
|
132
|
+
keys = list(keys) # skipif-ci-and-not-linux
|
133
|
+
if len(keys) == 0: # skipif-ci-and-not-linux
|
134
|
+
return []
|
135
|
+
ser = [ # skipif-ci-and-not-linux
|
136
|
+
_serialize(key, serializer=self.key_serializer) for key in keys
|
137
|
+
]
|
138
|
+
async with timeout_dur( # skipif-ci-and-not-linux
|
139
|
+
duration=self.timeout, error=self.error
|
140
|
+
):
|
141
|
+
result = await cast( # skipif-ci-and-not-linux
|
142
|
+
"Awaitable[Sequence[bytes | None]]", redis.hmget(self.name, ser)
|
143
|
+
)
|
144
|
+
return [ # skipif-ci-and-not-linux
|
145
|
+
None
|
146
|
+
if data is None
|
147
|
+
else _deserialize(data, deserializer=self.value_deserializer)
|
148
|
+
for data in result
|
149
|
+
]
|
150
|
+
|
151
|
+
async def keys(self, redis: Redis, /) -> Sequence[_K]:
|
152
|
+
"""Get the keys of a hashmap in `redis`."""
|
153
|
+
async with timeout_dur( # skipif-ci-and-not-linux
|
154
|
+
duration=self.timeout, error=self.error
|
155
|
+
):
|
156
|
+
result = await cast("Awaitable[Sequence[bytes]]", redis.hkeys(self.name))
|
157
|
+
return [ # skipif-ci-and-not-linux
|
158
|
+
_deserialize(data, deserializer=self.key_deserializer) for data in result
|
159
|
+
]
|
160
|
+
|
161
|
+
async def length(self, redis: Redis, /) -> int:
|
162
|
+
"""Get the length of a hashmap in `redis`."""
|
163
|
+
async with timeout_dur( # skipif-ci-and-not-linux
|
164
|
+
duration=self.timeout, error=self.error
|
165
|
+
):
|
166
|
+
return await cast("Awaitable[int]", redis.hlen(self.name))
|
116
167
|
|
117
168
|
async def set(self, redis: Redis, key: _K, value: _V, /) -> int:
|
118
169
|
"""Set a value in a hashmap in `redis`."""
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
170
|
+
return await self.set_many(redis, {key: value}) # skipif-ci-and-not-linux
|
171
|
+
|
172
|
+
async def set_many(self, redis: Redis, mapping: Mapping[_K, _V], /) -> int:
|
173
|
+
"""Set multiple value(s) in a hashmap in `redis`."""
|
174
|
+
if len(mapping) == 0: # skipif-ci-and-not-linux
|
175
|
+
return 0
|
176
|
+
ser = { # skipif-ci-and-not-linux
|
177
|
+
_serialize(key, serializer=self.key_serializer): _serialize(
|
178
|
+
value, serializer=self.value_serializer
|
179
|
+
)
|
180
|
+
for key, value in mapping.items()
|
181
|
+
}
|
125
182
|
async with timeout_dur( # skipif-ci-and-not-linux
|
126
183
|
duration=self.timeout, error=self.error
|
127
184
|
):
|
128
185
|
result = await cast(
|
129
|
-
"Awaitable[int]",
|
130
|
-
redis.hset(
|
131
|
-
self.name, key=cast("Any", ser_key), value=cast("Any", ser_value)
|
132
|
-
),
|
186
|
+
"Awaitable[int]", redis.hset(self.name, mapping=cast("Any", ser))
|
133
187
|
)
|
134
188
|
if self.ttl is not None:
|
135
189
|
await redis.pexpire(self.name, datetime_duration_to_timedelta(self.ttl))
|
136
190
|
return result # skipif-ci-and-not-linux
|
137
191
|
|
192
|
+
async def values(self, redis: Redis, /) -> Sequence[_V]:
|
193
|
+
"""Get the values of a hashmap in `redis`."""
|
194
|
+
async with timeout_dur( # skipif-ci-and-not-linux
|
195
|
+
duration=self.timeout, error=self.error
|
196
|
+
):
|
197
|
+
result = await cast("Awaitable[Sequence[bytes]]", redis.hvals(self.name))
|
198
|
+
return [ # skipif-ci-and-not-linux
|
199
|
+
_deserialize(data, deserializer=self.value_deserializer) for data in result
|
200
|
+
]
|
201
|
+
|
138
202
|
|
139
203
|
@overload
|
140
204
|
def redis_hash_map_key(
|
@@ -144,6 +208,7 @@ def redis_hash_map_key(
|
|
144
208
|
/,
|
145
209
|
*,
|
146
210
|
key_serializer: Callable[[_K], bytes] | None = None,
|
211
|
+
key_deserializer: Callable[[bytes], Any] | None = None,
|
147
212
|
value_serializer: Callable[[_V], bytes] | None = None,
|
148
213
|
value_deserializer: Callable[[bytes], _V] | None = None,
|
149
214
|
timeout: Duration | None = None,
|
@@ -158,6 +223,7 @@ def redis_hash_map_key(
|
|
158
223
|
/,
|
159
224
|
*,
|
160
225
|
key_serializer: Callable[[_K], bytes] | None = None,
|
226
|
+
key_deserializer: Callable[[bytes], Any] | None = None,
|
161
227
|
value_serializer: Callable[[_V1 | _V2], bytes] | None = None,
|
162
228
|
value_deserializer: Callable[[bytes], _V1 | _V2] | None = None,
|
163
229
|
timeout: Duration | None = None,
|
@@ -172,6 +238,7 @@ def redis_hash_map_key(
|
|
172
238
|
/,
|
173
239
|
*,
|
174
240
|
key_serializer: Callable[[_K], bytes] | None = None,
|
241
|
+
key_deserializer: Callable[[bytes], Any] | None = None,
|
175
242
|
value_serializer: Callable[[_V1 | _V2 | _V3], bytes] | None = None,
|
176
243
|
value_deserializer: Callable[[bytes], _V1 | _V2 | _V3] | None = None,
|
177
244
|
timeout: Duration | None = None,
|
@@ -186,6 +253,7 @@ def redis_hash_map_key(
|
|
186
253
|
/,
|
187
254
|
*,
|
188
255
|
key_serializer: Callable[[_K1 | _K2], bytes] | None = None,
|
256
|
+
key_deserializer: Callable[[bytes], Any] | None = None,
|
189
257
|
value_serializer: Callable[[_V], bytes] | None = None,
|
190
258
|
value_deserializer: Callable[[bytes], _V] | None = None,
|
191
259
|
timeout: Duration | None = None,
|
@@ -200,6 +268,7 @@ def redis_hash_map_key(
|
|
200
268
|
/,
|
201
269
|
*,
|
202
270
|
key_serializer: Callable[[_K1 | _K2], bytes] | None = None,
|
271
|
+
key_deserializer: Callable[[bytes], Any] | None = None,
|
203
272
|
value_serializer: Callable[[_V1 | _V2], bytes] | None = None,
|
204
273
|
value_deserializer: Callable[[bytes], _V1 | _V2] | None = None,
|
205
274
|
timeout: Duration | None = None,
|
@@ -214,6 +283,7 @@ def redis_hash_map_key(
|
|
214
283
|
/,
|
215
284
|
*,
|
216
285
|
key_serializer: Callable[[_K1 | _K2], bytes] | None = None,
|
286
|
+
key_deserializer: Callable[[bytes], Any] | None = None,
|
217
287
|
value_serializer: Callable[[_V1 | _V2 | _V3], bytes] | None = None,
|
218
288
|
value_deserializer: Callable[[bytes], _V1 | _V2 | _V3] | None = None,
|
219
289
|
timeout: Duration | None = None,
|
@@ -228,6 +298,7 @@ def redis_hash_map_key(
|
|
228
298
|
/,
|
229
299
|
*,
|
230
300
|
key_serializer: Callable[[_K1 | _K2 | _K3], bytes] | None = None,
|
301
|
+
key_deserializer: Callable[[bytes], Any] | None = None,
|
231
302
|
value_serializer: Callable[[_V], bytes] | None = None,
|
232
303
|
value_deserializer: Callable[[bytes], _V] | None = None,
|
233
304
|
timeout: Duration | None = None,
|
@@ -242,6 +313,7 @@ def redis_hash_map_key(
|
|
242
313
|
/,
|
243
314
|
*,
|
244
315
|
key_serializer: Callable[[_K1 | _K2 | _K3], bytes] | None = None,
|
316
|
+
key_deserializer: Callable[[bytes], Any] | None = None,
|
245
317
|
value_serializer: Callable[[_V1 | _V2], bytes] | None = None,
|
246
318
|
value_deserializer: Callable[[bytes], _V1 | _V2] | None = None,
|
247
319
|
timeout: Duration | None = None,
|
@@ -256,6 +328,7 @@ def redis_hash_map_key(
|
|
256
328
|
/,
|
257
329
|
*,
|
258
330
|
key_serializer: Callable[[_K1 | _K2 | _K3], bytes] | None = None,
|
331
|
+
key_deserializer: Callable[[bytes], Any] | None = None,
|
259
332
|
value_serializer: Callable[[_V1 | _V2 | _V3], bytes] | None = None,
|
260
333
|
value_deserializer: Callable[[bytes], _V1 | _V2 | _V3] | None = None,
|
261
334
|
timeout: Duration | None = None,
|
@@ -270,6 +343,7 @@ def redis_hash_map_key(
|
|
270
343
|
/,
|
271
344
|
*,
|
272
345
|
key_serializer: Callable[[_K1 | _K2 | _K3], bytes] | None = None,
|
346
|
+
key_deserializer: Callable[[bytes], Any] | None = None,
|
273
347
|
value_serializer: Callable[[_V1 | _V2 | _V3], bytes] | None = None,
|
274
348
|
value_deserializer: Callable[[bytes], _V1 | _V2 | _V3] | None = None,
|
275
349
|
timeout: Duration | None = None,
|
@@ -283,6 +357,7 @@ def redis_hash_map_key(
|
|
283
357
|
/,
|
284
358
|
*,
|
285
359
|
key_serializer: Callable[[Any], bytes] | None = None,
|
360
|
+
key_deserializer: Callable[[bytes], Any] | None = None,
|
286
361
|
value_serializer: Callable[[Any], bytes] | None = None,
|
287
362
|
value_deserializer: Callable[[bytes], Any] | None = None,
|
288
363
|
timeout: Duration | None = None,
|
@@ -294,6 +369,7 @@ def redis_hash_map_key(
|
|
294
369
|
name=name,
|
295
370
|
key=key,
|
296
371
|
key_serializer=key_serializer,
|
372
|
+
key_deserializer=key_deserializer,
|
297
373
|
value=value,
|
298
374
|
value_serializer=value_serializer,
|
299
375
|
value_deserializer=value_deserializer,
|
@@ -343,23 +419,15 @@ class RedisKey(Generic[_T]):
|
|
343
419
|
duration=self.timeout, error=self.error
|
344
420
|
):
|
345
421
|
result = cast("bytes | None", await redis.get(self.name))
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
from utilities.orjson import deserialize
|
352
|
-
|
353
|
-
return deserialize(data)
|
354
|
-
return self.deserializer(data)
|
355
|
-
case _ as never:
|
356
|
-
assert_never(never)
|
422
|
+
if result is None: # skipif-ci-and-not-linux
|
423
|
+
raise KeyError(self.name)
|
424
|
+
return _deserialize( # skipif-ci-and-not-linux
|
425
|
+
result, deserializer=self.deserializer
|
426
|
+
)
|
357
427
|
|
358
428
|
async def set(self, redis: Redis, value: _T, /) -> int:
|
359
429
|
"""Set a value in `redis`."""
|
360
|
-
|
361
|
-
value, serializer=self.serializer
|
362
|
-
)
|
430
|
+
ser = _serialize(value, serializer=self.serializer) # skipif-ci-and-not-linux
|
363
431
|
ttl = ( # skipif-ci-and-not-linux
|
364
432
|
None
|
365
433
|
if self.ttl is None
|
@@ -369,7 +437,7 @@ class RedisKey(Generic[_T]):
|
|
369
437
|
duration=self.timeout, error=self.error
|
370
438
|
):
|
371
439
|
result = await redis.set( # skipif-ci-and-not-linux
|
372
|
-
self.name,
|
440
|
+
self.name, ser, px=ttl
|
373
441
|
)
|
374
442
|
return ensure_int(result) # skipif-ci-and-not-linux
|
375
443
|
|
@@ -25,9 +25,9 @@ DEFAULT_SEPARATOR = ","
|
|
25
25
|
|
26
26
|
def parse_bool(text: str, /) -> bool:
|
27
27
|
"""Parse text into a boolean value."""
|
28
|
-
if search(r"^(0|False)$", text, flags=IGNORECASE):
|
28
|
+
if search(r"^(0|False|N|No|Off)$", text, flags=IGNORECASE):
|
29
29
|
return False
|
30
|
-
if search(r"^(1|True)$", text, flags=IGNORECASE):
|
30
|
+
if search(r"^(1|True|Y|Yes|On)$", text, flags=IGNORECASE):
|
31
31
|
return True
|
32
32
|
raise ParseBoolError(text=text)
|
33
33
|
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/modules/package_missing/__init__.py
RENAMED
File without changes
|
{dycw_utilities-0.112.7 → dycw_utilities-0.112.9}/src/tests/modules/package_missing/module.py
RENAMED
File without changes
|