dycw-utilities 0.133.0__tar.gz → 0.133.1__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.133.0 → dycw_utilities-0.133.1}/PKG-INFO +1 -1
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/pyproject.toml +4 -2
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_click.py +3 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_hypothesis.py +13 -1
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_typed_settings.py +3 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_whenever.py +74 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/utilities/__init__.py +1 -1
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/utilities/click.py +26 -1
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/utilities/hypothesis.py +36 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/utilities/typed_settings.py +2 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/utilities/whenever.py +129 -2
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/.gitignore +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/LICENSE +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/README.md +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/__init__.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/conftest.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/modules/__init__.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/modules/package_missing/__init__.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/modules/package_missing/module.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/modules/package_with/__init__.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/modules/package_with/outer_1.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/modules/package_with/outer_2.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/modules/package_with/subpackage/__init__.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/modules/package_with/subpackage/inner_1.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/modules/package_with/subpackage/inner_2.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/modules/package_with/subpackage/inner_3.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/modules/package_without/__init__.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/modules/package_without/module_1.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/modules/package_without/module_2.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/modules/standalone.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/modules/with_imports.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/regressions/test_pytest_regressions/TestMultipleRegressionFixtures__test_main__obj.json +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/regressions/test_pytest_regressions/TestMultipleRegressionFixtures__test_main__series.json +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_int.json +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_literal__false.json +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_literal__true.json +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_nested.json +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/regressions/test_pytest_regressions/TestPolarsRegressionFixture__test_dataframe.json +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/regressions/test_pytest_regressions/TestPolarsRegressionFixture__test_series.json +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_aiolimiter.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_altair.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_arq.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_asyncio.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_asyncio_classes/__init__.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_asyncio_classes/loopers.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_asyncio_classes/redis.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_atomicwrites.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_atools.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_cachetools.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_concurrent.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_contextlib.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_contextvars.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_cryptography.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_cvxpy.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_dataclasses.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_enum.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_errors.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_eventkit.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_fastapi.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_fpdf2.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_functions.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_functools.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_getpass.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_git.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_hashlib.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_http.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_importlib.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_inflect.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_ipython.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_iterables.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_jupyter.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_libcst.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_lightweight_charts.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_logging.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_luigi.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_math.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_memory_profiler.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_modules.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_more_itertools.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_numpy.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_objects/__init__.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_objects/objects.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_operator.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_optuna.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_orjson.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_os.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_parse.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_pathlib.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_period.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_pickle.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_platform.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_polars.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_polars_ols.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_pottery.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_pqdm.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_psutil.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_pydantic.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_pyinstrument.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_pytest.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_pytest_regressions.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_python_dotenv.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_random.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_re.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_redis.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_reprlib.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_scipy.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_sentinel.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_shelve.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_slack_sdk.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_socket.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_sqlalchemy.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_sqlalchemy_polars.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_statsmodels.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_streamlit.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_string.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_tempfile.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_text.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_threading.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_timer.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_traceback.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_types.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_typing.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_typing_funcs/__init__.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_typing_funcs/no_future.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_typing_funcs/with_future.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_tzdata.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_tzlocal.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_uuid.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_version.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_warnings.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_zipfile.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_zoneinfo.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/utilities/aiolimiter.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/utilities/altair.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/utilities/arq.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/utilities/asyncio.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/utilities/atomicwrites.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/utilities/atools.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/utilities/cachetools.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/utilities/concurrent.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/utilities/contextlib.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/utilities/contextvars.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/utilities/cryptography.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/utilities/cvxpy.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/utilities/dataclasses.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/utilities/enum.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/utilities/errors.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/utilities/eventkit.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/utilities/fastapi.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/utilities/fpdf2.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/utilities/functions.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/utilities/functools.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/utilities/getpass.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/utilities/git.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/utilities/hashlib.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/utilities/http.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/utilities/importlib.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/utilities/inflect.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/utilities/ipython.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/utilities/iterables.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/utilities/jupyter.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/utilities/libcst.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/utilities/lightweight_charts.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/utilities/logging.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/utilities/luigi.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/utilities/math.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/utilities/memory_profiler.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/utilities/modules.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/utilities/more_itertools.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/utilities/numpy.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/utilities/operator.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/utilities/optuna.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/utilities/orjson.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/utilities/os.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/utilities/parse.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/utilities/pathlib.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/utilities/period.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/utilities/pickle.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/utilities/platform.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/utilities/polars.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/utilities/polars_ols.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/utilities/pottery.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/utilities/pqdm.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/utilities/psutil.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/utilities/py.typed +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/utilities/pydantic.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/utilities/pyinstrument.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/utilities/pytest.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/utilities/pytest_regressions.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/utilities/python_dotenv.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/utilities/random.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/utilities/re.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/utilities/redis.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/utilities/reprlib.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/utilities/scipy.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/utilities/sentinel.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/utilities/shelve.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/utilities/slack_sdk.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/utilities/socket.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/utilities/sqlalchemy.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/utilities/sqlalchemy_polars.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/utilities/statsmodels.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/utilities/streamlit.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/utilities/string.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/utilities/tempfile.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/utilities/text.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/utilities/threading.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/utilities/timer.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/utilities/traceback.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/utilities/types.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/utilities/typing.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/utilities/tzdata.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/utilities/tzlocal.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/utilities/uuid.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/utilities/version.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/utilities/warnings.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/utilities/zipfile.py +0 -0
- {dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/utilities/zoneinfo.py +0 -0
@@ -30,6 +30,7 @@ dataclasses-test = ["orjson", "polars-lts-cpu"]
|
|
30
30
|
dev = [
|
31
31
|
"coloredlogs >= 15.0.1, < 15.1",
|
32
32
|
"coverage-conditional-plugin >= 0.9.0, < 0.10",
|
33
|
+
"dycw-pytest-only >= 2.1.1, < 2.2",
|
33
34
|
"pyright[nodejs] >= 1.1.401, < 1.2",
|
34
35
|
"pytest-cov >= 6.1.1, < 6.2",
|
35
36
|
]
|
@@ -103,7 +104,7 @@ dependencies = [
|
|
103
104
|
name = "dycw-utilities"
|
104
105
|
readme = "README.md"
|
105
106
|
requires-python = ">= 3.12"
|
106
|
-
version = "0.133.
|
107
|
+
version = "0.133.1"
|
107
108
|
|
108
109
|
[project.optional-dependencies]
|
109
110
|
logging = [
|
@@ -129,7 +130,7 @@ test = [
|
|
129
130
|
# bump-my-version
|
130
131
|
[tool.bumpversion]
|
131
132
|
allow_dirty = true
|
132
|
-
current_version = "0.133.
|
133
|
+
current_version = "0.133.1"
|
133
134
|
|
134
135
|
[[tool.bumpversion.files]]
|
135
136
|
filename = "src/utilities/__init__.py"
|
@@ -238,6 +239,7 @@ filterwarnings = [
|
|
238
239
|
"error",
|
239
240
|
"ignore:.*utcfromtimestamp.* is deprecated and scheduled for removal in a future version:DeprecationWarning", # luigi
|
240
241
|
"ignore:Exception ignored in.* <coroutine object .* at .*>:pytest.PytestUnraisableExceptionWarning",
|
242
|
+
"ignore:Exception in thread Thread-.*:pytest.PytestUnhandledThreadExceptionWarning",
|
241
243
|
"ignore:Implicitly cleaning up <TemporaryDirectory '.*'>:ResourceWarning",
|
242
244
|
"ignore:ResourceTracker called reentrantly for resource cleanup, which is unsupported:UserWarning",
|
243
245
|
"ignore:Task .* without outputs has no custom complete.* method:UserWarning", # luigi
|
@@ -34,6 +34,7 @@ from utilities.click import (
|
|
34
34
|
ExistingDirPath,
|
35
35
|
ExistingFilePath,
|
36
36
|
FilePath,
|
37
|
+
Freq,
|
37
38
|
FrozenSetChoices,
|
38
39
|
FrozenSetEnums,
|
39
40
|
FrozenSetStrs,
|
@@ -51,6 +52,7 @@ from utilities.hypothesis import (
|
|
51
52
|
date_deltas,
|
52
53
|
date_time_deltas,
|
53
54
|
dates,
|
55
|
+
freqs,
|
54
56
|
months,
|
55
57
|
pairs,
|
56
58
|
plain_datetimes,
|
@@ -209,6 +211,7 @@ class TestParameters:
|
|
209
211
|
attrgetter("name"),
|
210
212
|
True,
|
211
213
|
),
|
214
|
+
param(Freq(), "FREQ", freqs(), utilities.whenever.Freq.serialize, True),
|
212
215
|
param(
|
213
216
|
FrozenSetChoices(["a", "b", "c"]),
|
214
217
|
"FROZENSET[Choice(['a', 'b', 'c'])]",
|
@@ -41,6 +41,7 @@ from utilities.hypothesis import (
|
|
41
41
|
Shape,
|
42
42
|
_Draw2DefaultGeneratedSentinelError,
|
43
43
|
_Draw2InputResolvedToSentinelError,
|
44
|
+
_freq_units,
|
44
45
|
assume_does_not_raise,
|
45
46
|
bool_arrays,
|
46
47
|
date_deltas,
|
@@ -51,6 +52,7 @@ from utilities.hypothesis import (
|
|
51
52
|
float64s,
|
52
53
|
float_arrays,
|
53
54
|
floats_extra,
|
55
|
+
freqs,
|
54
56
|
git_repos,
|
55
57
|
hashables,
|
56
58
|
int32s,
|
@@ -107,6 +109,7 @@ from utilities.version import Version
|
|
107
109
|
from utilities.whenever import (
|
108
110
|
DATE_TWO_DIGIT_YEAR_MAX,
|
109
111
|
DATE_TWO_DIGIT_YEAR_MIN,
|
112
|
+
Freq,
|
110
113
|
Month,
|
111
114
|
to_days,
|
112
115
|
to_nanos,
|
@@ -118,7 +121,7 @@ if TYPE_CHECKING:
|
|
118
121
|
from zoneinfo import ZoneInfo
|
119
122
|
|
120
123
|
from utilities.tempfile import TemporaryDirectory
|
121
|
-
from utilities.types import Number
|
124
|
+
from utilities.types import DateTimeRoundUnit, Number
|
122
125
|
|
123
126
|
|
124
127
|
class TestAssumeDoesNotRaise:
|
@@ -486,6 +489,15 @@ class TestFloatsExtra:
|
|
486
489
|
assert x == round(x)
|
487
490
|
|
488
491
|
|
492
|
+
class TestFreqs:
|
493
|
+
@given(data=data(), unit=_freq_units() | none())
|
494
|
+
def test_main(self, *, data: DataObject, unit: DateTimeRoundUnit | None) -> None:
|
495
|
+
freq = data.draw(freqs(unit=unit))
|
496
|
+
assert isinstance(freq, Freq)
|
497
|
+
if unit is not None:
|
498
|
+
assert freq.unit == unit
|
499
|
+
|
500
|
+
|
489
501
|
class TestGitRepos:
|
490
502
|
@given(data=data())
|
491
503
|
@settings_with_reduced_examples()
|
@@ -23,6 +23,7 @@ from utilities.hypothesis import (
|
|
23
23
|
date_deltas,
|
24
24
|
date_time_deltas,
|
25
25
|
dates,
|
26
|
+
freqs,
|
26
27
|
plain_datetimes,
|
27
28
|
temp_paths,
|
28
29
|
text_ascii,
|
@@ -37,6 +38,7 @@ from utilities.typed_settings import (
|
|
37
38
|
LoadSettingsError,
|
38
39
|
load_settings,
|
39
40
|
)
|
41
|
+
from utilities.whenever import Freq
|
40
42
|
|
41
43
|
app_names = text_ascii(min_size=1).map(str.lower)
|
42
44
|
|
@@ -56,6 +58,7 @@ class TestExtendedTSConverter:
|
|
56
58
|
date_time_deltas(parsable=True),
|
57
59
|
DateTimeDelta.format_common_iso,
|
58
60
|
),
|
61
|
+
param(Freq, freqs(), Freq.serialize),
|
59
62
|
param(IPv4Address, ip_addresses(v=4), IPv4Address),
|
60
63
|
param(IPv6Address, ip_addresses(v=6), IPv6Address),
|
61
64
|
param(PlainDateTime, plain_datetimes(), PlainDateTime.format_common_iso),
|
@@ -30,12 +30,15 @@ from utilities.hypothesis import (
|
|
30
30
|
assume_does_not_raise,
|
31
31
|
date_deltas,
|
32
32
|
dates,
|
33
|
+
freqs,
|
33
34
|
months,
|
34
35
|
pairs,
|
35
36
|
sentinels,
|
36
37
|
zoned_datetimes,
|
37
38
|
)
|
38
39
|
from utilities.sentinel import Sentinel, sentinel
|
40
|
+
from utilities.types import DateTimeRoundUnit
|
41
|
+
from utilities.typing import get_literal_elements
|
39
42
|
from utilities.tzdata import HongKong, Tokyo
|
40
43
|
from utilities.tzlocal import LOCAL_TIME_ZONE_NAME
|
41
44
|
from utilities.whenever import (
|
@@ -64,12 +67,16 @@ from utilities.whenever import (
|
|
64
67
|
ZERO_DAYS,
|
65
68
|
ZONED_DATE_TIME_MAX,
|
66
69
|
ZONED_DATE_TIME_MIN,
|
70
|
+
Freq,
|
67
71
|
MeanDateTimeError,
|
68
72
|
MinMaxDateError,
|
69
73
|
Month,
|
70
74
|
ToDaysError,
|
71
75
|
ToNanosError,
|
72
76
|
WheneverLogRecord,
|
77
|
+
_FreqDayIncrementError,
|
78
|
+
_FreqIncrementError,
|
79
|
+
_FreqParseError,
|
73
80
|
_MinMaxDateMaxDateError,
|
74
81
|
_MinMaxDateMinDateError,
|
75
82
|
_MinMaxDatePeriodError,
|
@@ -128,6 +135,73 @@ class TestFormatCompact:
|
|
128
135
|
assert parsed == expected
|
129
136
|
|
130
137
|
|
138
|
+
class TestFreq:
|
139
|
+
@given(freq=freqs())
|
140
|
+
def test_main(self, *, freq: Freq) -> None:
|
141
|
+
_ = get_now().round(unit=freq.unit, increment=freq.increment, mode="floor")
|
142
|
+
|
143
|
+
@given(unit=sampled_from(get_literal_elements(DateTimeRoundUnit)))
|
144
|
+
def test_abbreviate_and_expand(self, *, unit: DateTimeRoundUnit) -> None:
|
145
|
+
result = Freq._expand(Freq._abbreviate(unit))
|
146
|
+
assert result == unit
|
147
|
+
|
148
|
+
@given(freqs=pairs(freqs()))
|
149
|
+
def test_eq(self, *, freqs: tuple[Freq, Freq]) -> None:
|
150
|
+
x, y = freqs
|
151
|
+
result = x == y
|
152
|
+
assert isinstance(result, bool)
|
153
|
+
|
154
|
+
@given(freq=freqs())
|
155
|
+
def test_eq_non_freq(self, *, freq: Freq) -> None:
|
156
|
+
result = freq == 0
|
157
|
+
assert not result
|
158
|
+
|
159
|
+
@given(freq=freqs())
|
160
|
+
def test_hashable(self, *, freq: Freq) -> None:
|
161
|
+
_ = hash(freq)
|
162
|
+
|
163
|
+
@given(freq=freqs())
|
164
|
+
def test_repr(self, *, freq: Freq) -> None:
|
165
|
+
_ = repr(freq)
|
166
|
+
|
167
|
+
@given(freq=freqs())
|
168
|
+
def test_serialize_and_parse(self, *, freq: Freq) -> None:
|
169
|
+
result = Freq.parse(freq.serialize())
|
170
|
+
assert result == freq
|
171
|
+
|
172
|
+
def test_error_day(self) -> None:
|
173
|
+
with raises(
|
174
|
+
_FreqDayIncrementError,
|
175
|
+
match="Increment must be 1 for the 'day' unit; got 2",
|
176
|
+
):
|
177
|
+
_ = Freq(unit="day", increment=2)
|
178
|
+
|
179
|
+
def test_error_hour(self) -> None:
|
180
|
+
with raises(
|
181
|
+
_FreqIncrementError,
|
182
|
+
match="Increment must be a proper divisor of 24 for the 'hour' unit; got 5",
|
183
|
+
):
|
184
|
+
_ = Freq(unit="hour", increment=5)
|
185
|
+
|
186
|
+
def test_error_minute(self) -> None:
|
187
|
+
with raises(
|
188
|
+
_FreqIncrementError,
|
189
|
+
match="Increment must be a proper divisor of 60 for the 'minute' unit; got 7",
|
190
|
+
):
|
191
|
+
_ = Freq(unit="minute", increment=7)
|
192
|
+
|
193
|
+
def test_error_milliseond(self) -> None:
|
194
|
+
with raises(
|
195
|
+
_FreqIncrementError,
|
196
|
+
match="Increment must be a proper divisor of 1000 for the 'millisecond' unit; got 3",
|
197
|
+
):
|
198
|
+
_ = Freq(unit="millisecond", increment=3)
|
199
|
+
|
200
|
+
def test_error_parse(self) -> None:
|
201
|
+
with raises(_FreqParseError, match="Unable to parse frequency; got 's'"):
|
202
|
+
_ = Freq.parse("s")
|
203
|
+
|
204
|
+
|
131
205
|
class TestFromTimeStamp:
|
132
206
|
@given(
|
133
207
|
datetime=zoned_datetimes(time_zone=timezones()).map(lambda d: d.round("second"))
|
@@ -29,7 +29,7 @@ from utilities.types import (
|
|
29
29
|
TimeLike,
|
30
30
|
ZonedDateTimeLike,
|
31
31
|
)
|
32
|
-
from utilities.whenever import _MonthParseCommonISOError
|
32
|
+
from utilities.whenever import FreqLike, _FreqParseError, _MonthParseCommonISOError
|
33
33
|
|
34
34
|
if TYPE_CHECKING:
|
35
35
|
from collections.abc import Iterable, Sequence
|
@@ -177,6 +177,30 @@ class Enum(ParamType, Generic[TEnum]):
|
|
177
177
|
return _make_metavar(param, desc)
|
178
178
|
|
179
179
|
|
180
|
+
class Freq(ParamType):
|
181
|
+
"""An frequency-valued parameter."""
|
182
|
+
|
183
|
+
@override
|
184
|
+
def __repr__(self) -> str:
|
185
|
+
return "FREQ"
|
186
|
+
|
187
|
+
@override
|
188
|
+
def convert(
|
189
|
+
self, value: FreqLike, param: Parameter | None, ctx: Context | None
|
190
|
+
) -> utilities.whenever.Freq:
|
191
|
+
"""Convert a value into the `Freq` type."""
|
192
|
+
match value:
|
193
|
+
case utilities.whenever.Freq():
|
194
|
+
return value
|
195
|
+
case str():
|
196
|
+
try:
|
197
|
+
return utilities.whenever.Freq.parse(value)
|
198
|
+
except _FreqParseError as error:
|
199
|
+
self.fail(str(error), param, ctx)
|
200
|
+
case _ as never:
|
201
|
+
assert_never(never)
|
202
|
+
|
203
|
+
|
180
204
|
class IPv4Address(ParamType):
|
181
205
|
"""An IPv4 address-valued parameter."""
|
182
206
|
|
@@ -519,6 +543,7 @@ __all__ = [
|
|
519
543
|
"ExistingDirPath",
|
520
544
|
"ExistingFilePath",
|
521
545
|
"FilePath",
|
546
|
+
"Freq",
|
522
547
|
"FrozenSetChoices",
|
523
548
|
"FrozenSetEnums",
|
524
549
|
"FrozenSetParameter",
|
@@ -77,6 +77,8 @@ from utilities.pathlib import temp_cwd
|
|
77
77
|
from utilities.platform import IS_WINDOWS
|
78
78
|
from utilities.sentinel import Sentinel, sentinel
|
79
79
|
from utilities.tempfile import TEMP_DIR, TemporaryDirectory
|
80
|
+
from utilities.types import DateTimeRoundUnit
|
81
|
+
from utilities.typing import get_literal_elements
|
80
82
|
from utilities.version import Version
|
81
83
|
from utilities.whenever import (
|
82
84
|
DATE_DELTA_MAX,
|
@@ -100,6 +102,7 @@ from utilities.whenever import (
|
|
100
102
|
TIME_DELTA_MIN,
|
101
103
|
TIME_MAX,
|
102
104
|
TIME_MIN,
|
105
|
+
Freq,
|
103
106
|
Month,
|
104
107
|
to_date_time_delta,
|
105
108
|
to_days,
|
@@ -502,6 +505,38 @@ def floats_extra(
|
|
502
505
|
##
|
503
506
|
|
504
507
|
|
508
|
+
@composite
|
509
|
+
def freqs(
|
510
|
+
draw: DrawFn, /, *, unit: MaybeSearchStrategy[DateTimeRoundUnit | None] = None
|
511
|
+
) -> Freq:
|
512
|
+
unit_ = draw2(draw, unit, _freq_units())
|
513
|
+
match unit_:
|
514
|
+
case "day":
|
515
|
+
return Freq(unit=unit_)
|
516
|
+
case "hour":
|
517
|
+
return Freq(unit=unit_, increment=draw(_freq_increments(24)))
|
518
|
+
case "minute" | "second":
|
519
|
+
return Freq(unit=unit_, increment=draw(_freq_increments(60)))
|
520
|
+
case "millisecond" | "microsecond" | "nanosecond":
|
521
|
+
return Freq(unit=unit_, increment=draw(_freq_increments(1000)))
|
522
|
+
case _ as never:
|
523
|
+
assert_never(never)
|
524
|
+
|
525
|
+
|
526
|
+
@composite
|
527
|
+
def _freq_units(draw: DrawFn, /) -> DateTimeRoundUnit:
|
528
|
+
return draw(sampled_from(get_literal_elements(DateTimeRoundUnit)))
|
529
|
+
|
530
|
+
|
531
|
+
@composite
|
532
|
+
def _freq_increments(draw: DrawFn, n: int, /) -> int:
|
533
|
+
divisors = [i for i in range(1, n) if n % i == 0]
|
534
|
+
return draw(sampled_from(divisors))
|
535
|
+
|
536
|
+
|
537
|
+
##
|
538
|
+
|
539
|
+
|
505
540
|
@composite
|
506
541
|
def git_repos(draw: DrawFn, /) -> Path:
|
507
542
|
path = draw(temp_paths())
|
@@ -1264,6 +1299,7 @@ __all__ = [
|
|
1264
1299
|
"float64s",
|
1265
1300
|
"float_arrays",
|
1266
1301
|
"floats_extra",
|
1302
|
+
"freqs",
|
1267
1303
|
"git_repos",
|
1268
1304
|
"hashables",
|
1269
1305
|
"int32s",
|
@@ -21,6 +21,7 @@ from whenever import (
|
|
21
21
|
)
|
22
22
|
|
23
23
|
from utilities.iterables import always_iterable
|
24
|
+
from utilities.whenever import Freq
|
24
25
|
|
25
26
|
if TYPE_CHECKING:
|
26
27
|
from collections.abc import Callable
|
@@ -52,6 +53,7 @@ class ExtendedTSConverter(TSConverter):
|
|
52
53
|
(Date, Date.parse_common_iso),
|
53
54
|
(DateDelta, DateDelta.parse_common_iso),
|
54
55
|
(DateTimeDelta, DateTimeDelta.parse_common_iso),
|
56
|
+
(Freq, Freq.parse),
|
55
57
|
(IPv4Address, IPv4Address),
|
56
58
|
(IPv6Address, IPv6Address),
|
57
59
|
(PlainDateTime, PlainDateTime.parse_common_iso),
|
@@ -1,6 +1,6 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
|
-
from collections.abc import Callable, Iterable
|
3
|
+
from collections.abc import Callable, Iterable, Mapping
|
4
4
|
from dataclasses import dataclass, replace
|
5
5
|
from functools import cache
|
6
6
|
from logging import LogRecord
|
@@ -8,9 +8,12 @@ from statistics import fmean
|
|
8
8
|
from typing import (
|
9
9
|
TYPE_CHECKING,
|
10
10
|
Any,
|
11
|
+
ClassVar,
|
12
|
+
Literal,
|
11
13
|
Self,
|
12
14
|
SupportsFloat,
|
13
15
|
assert_never,
|
16
|
+
cast,
|
14
17
|
overload,
|
15
18
|
override,
|
16
19
|
)
|
@@ -28,7 +31,7 @@ from utilities.math import sign
|
|
28
31
|
from utilities.platform import get_strftime
|
29
32
|
from utilities.re import ExtractGroupsError, extract_groups
|
30
33
|
from utilities.sentinel import Sentinel, sentinel
|
31
|
-
from utilities.types import MaybeStr
|
34
|
+
from utilities.types import DateTimeRoundUnit, MaybeStr
|
32
35
|
from utilities.tzlocal import LOCAL_TIME_ZONE, LOCAL_TIME_ZONE_NAME
|
33
36
|
from utilities.zoneinfo import UTC, get_time_zone_name
|
34
37
|
|
@@ -166,6 +169,127 @@ def format_compact(datetime: ZonedDateTime, /) -> str:
|
|
166
169
|
##
|
167
170
|
|
168
171
|
|
172
|
+
class Freq:
|
173
|
+
"""A rounding frequency."""
|
174
|
+
|
175
|
+
unit: DateTimeRoundUnit
|
176
|
+
increment: int
|
177
|
+
_mapping: ClassVar[Mapping[DateTimeRoundUnit, _DateTimeRoundUnitAbbrev]] = {
|
178
|
+
"day": "D",
|
179
|
+
"hour": "H",
|
180
|
+
"minute": "M",
|
181
|
+
"second": "S",
|
182
|
+
"millisecond": "ms",
|
183
|
+
"microsecond": "us",
|
184
|
+
"nanosecond": "ns",
|
185
|
+
}
|
186
|
+
|
187
|
+
def __init__(
|
188
|
+
self, *, unit: DateTimeRoundUnit = "second", increment: int = 1
|
189
|
+
) -> None:
|
190
|
+
super().__init__()
|
191
|
+
if (unit == "day") and (increment != 1):
|
192
|
+
raise _FreqDayIncrementError(increment=increment)
|
193
|
+
if (unit == "hour") and not ((0 < increment < 24) and (24 % increment == 0)):
|
194
|
+
raise _FreqIncrementError(unit=unit, increment=increment, divisor=24)
|
195
|
+
if (unit in {"minute", "second"}) and not (
|
196
|
+
(0 < increment < 60) and (60 % increment == 0)
|
197
|
+
):
|
198
|
+
raise _FreqIncrementError(unit=unit, increment=increment, divisor=60)
|
199
|
+
if (unit in {"millisecond", "microsecond", "nanosecond"}) and not (
|
200
|
+
(0 < increment < 1000) and (1000 % increment == 0)
|
201
|
+
):
|
202
|
+
raise _FreqIncrementError(unit=unit, increment=increment, divisor=1000)
|
203
|
+
self.unit = unit
|
204
|
+
self.increment = increment
|
205
|
+
|
206
|
+
@override
|
207
|
+
def __eq__(self, other: object, /) -> bool:
|
208
|
+
if not isinstance(other, Freq):
|
209
|
+
return NotImplemented
|
210
|
+
return (self.unit == other.unit) and (self.increment == other.increment)
|
211
|
+
|
212
|
+
@override
|
213
|
+
def __hash__(self) -> int:
|
214
|
+
return hash((self.unit, self.increment))
|
215
|
+
|
216
|
+
@override
|
217
|
+
def __repr__(self) -> str:
|
218
|
+
return f"{type(self).__name__}(unit={self.unit!r}, increment={self.increment})"
|
219
|
+
|
220
|
+
@classmethod
|
221
|
+
def parse(cls, text: str, /) -> Self:
|
222
|
+
try:
|
223
|
+
increment, abbrev = extract_groups(r"^(\d*)(D|H|M|S|ms|us|ns)$", text)
|
224
|
+
except ExtractGroupsError:
|
225
|
+
raise _FreqParseError(text=text) from None
|
226
|
+
return cls(
|
227
|
+
unit=cls._expand(cast("_DateTimeRoundUnitAbbrev", abbrev)),
|
228
|
+
increment=int(increment) if len(increment) >= 1 else 1,
|
229
|
+
)
|
230
|
+
|
231
|
+
def serialize(self) -> str:
|
232
|
+
if self.increment == 1:
|
233
|
+
return self._abbreviation
|
234
|
+
return f"{self.increment}{self._abbreviation}"
|
235
|
+
|
236
|
+
@classmethod
|
237
|
+
def _abbreviate(cls, unit: DateTimeRoundUnit, /) -> _DateTimeRoundUnitAbbrev:
|
238
|
+
return cls._mapping[unit]
|
239
|
+
|
240
|
+
@property
|
241
|
+
def _abbreviation(self) -> _DateTimeRoundUnitAbbrev:
|
242
|
+
return self._mapping[self.unit]
|
243
|
+
|
244
|
+
@classmethod
|
245
|
+
def _expand(cls, unit: _DateTimeRoundUnitAbbrev, /) -> DateTimeRoundUnit:
|
246
|
+
values: set[DateTimeRoundUnit] = {
|
247
|
+
k for k, v in cls._mapping.items() if v == unit
|
248
|
+
}
|
249
|
+
(value,) = values
|
250
|
+
return value
|
251
|
+
|
252
|
+
|
253
|
+
type FreqLike = MaybeStr[Freq]
|
254
|
+
type _DateTimeRoundUnitAbbrev = Literal["D", "H", "M", "S", "ms", "us", "ns"]
|
255
|
+
|
256
|
+
|
257
|
+
@dataclass(kw_only=True, slots=True)
|
258
|
+
class FreqError(Exception): ...
|
259
|
+
|
260
|
+
|
261
|
+
@dataclass(kw_only=True, slots=True)
|
262
|
+
class _FreqDayIncrementError(FreqError):
|
263
|
+
increment: int
|
264
|
+
|
265
|
+
@override
|
266
|
+
def __str__(self) -> str:
|
267
|
+
return f"Increment must be 1 for the 'day' unit; got {self.increment}"
|
268
|
+
|
269
|
+
|
270
|
+
@dataclass(kw_only=True, slots=True)
|
271
|
+
class _FreqIncrementError(FreqError):
|
272
|
+
unit: DateTimeRoundUnit
|
273
|
+
increment: int
|
274
|
+
divisor: int
|
275
|
+
|
276
|
+
@override
|
277
|
+
def __str__(self) -> str:
|
278
|
+
return f"Increment must be a proper divisor of {self.divisor} for the {self.unit!r} unit; got {self.increment}"
|
279
|
+
|
280
|
+
|
281
|
+
@dataclass(kw_only=True, slots=True)
|
282
|
+
class _FreqParseError(FreqError):
|
283
|
+
text: str
|
284
|
+
|
285
|
+
@override
|
286
|
+
def __str__(self) -> str:
|
287
|
+
return f"Unable to parse frequency; got {self.text!r}"
|
288
|
+
|
289
|
+
|
290
|
+
##
|
291
|
+
|
292
|
+
|
169
293
|
def from_timestamp(i: float, /, *, time_zone: TimeZoneLike = UTC) -> ZonedDateTime:
|
170
294
|
"""Get a zoned datetime from a timestamp."""
|
171
295
|
return ZonedDateTime.from_timestamp(i, tz=get_time_zone_name(time_zone))
|
@@ -736,6 +860,9 @@ __all__ = [
|
|
736
860
|
"ZONED_DATE_TIME_MAX",
|
737
861
|
"ZONED_DATE_TIME_MIN",
|
738
862
|
"DateOrMonth",
|
863
|
+
"Freq",
|
864
|
+
"FreqError",
|
865
|
+
"FreqLike",
|
739
866
|
"MeanDateTimeError",
|
740
867
|
"MinMaxDateError",
|
741
868
|
"Month",
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/modules/package_missing/__init__.py
RENAMED
File without changes
|
{dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/modules/package_missing/module.py
RENAMED
File without changes
|
{dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/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.133.0 → dycw_utilities-0.133.1}/src/tests/modules/package_without/__init__.py
RENAMED
File without changes
|
{dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/modules/package_without/module_1.py
RENAMED
File without changes
|
{dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/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
|
{dycw_utilities-0.133.0 → dycw_utilities-0.133.1}/src/tests/test_asyncio_classes/__init__.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|