dycw-utilities 0.113.2__tar.gz → 0.113.4__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.113.2 → dycw_utilities-0.113.4}/PKG-INFO +7 -7
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/pyproject.toml +13 -13
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_click.py +7 -7
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_datetime.py +82 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/utilities/__init__.py +1 -1
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/utilities/click.py +6 -5
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/utilities/datetime.py +98 -1
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/utilities/redis.py +5 -5
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/.gitignore +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/LICENSE +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/README.md +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/__init__.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/conftest.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/modules/__init__.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/modules/package_missing/__init__.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/modules/package_missing/module.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/modules/package_with/__init__.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/modules/package_with/outer_1.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/modules/package_with/outer_2.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/modules/package_with/subpackage/__init__.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/modules/package_with/subpackage/inner_1.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/modules/package_with/subpackage/inner_2.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/modules/package_with/subpackage/inner_3.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/modules/package_without/__init__.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/modules/package_without/module_1.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/modules/package_without/module_2.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/modules/standalone.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/modules/with_imports.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/regressions/test_pytest_regressions/TestMultipleRegressionFixtures__test_main__obj.json +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/regressions/test_pytest_regressions/TestMultipleRegressionFixtures__test_main__series.json +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_int.json +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_literal__false.json +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_literal__true.json +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_nested.json +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/regressions/test_pytest_regressions/TestPolarsRegressionFixture__test_dataframe.json +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/regressions/test_pytest_regressions/TestPolarsRegressionFixture__test_series.json +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/scripts/__init__.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/scripts/test_async_service/__init__.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/scripts/test_async_service/__main__.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/scripts/test_async_service/run.sh +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/scripts/test_queue_processor/__init__.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/scripts/test_queue_processor/__main__.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/scripts/test_queue_processor/run.sh +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_altair.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_astor.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_asyncio.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_atomicwrites.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_atools.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_cachetools.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_concurrent.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_contextlib.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_contextvars.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_cryptography.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_cvxpy.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_dataclasses.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_enum.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_errors.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_eventkit.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_fastapi.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_fpdf2.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_functions.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_functools.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_getpass.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_git.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_hashlib.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_http.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_hypothesis.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_ipython.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_iterables.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_jupyter.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_lightweight_charts.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_logging.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_loguru.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_luigi.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_math.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_memory_profiler.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_modules.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_more_itertools.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_numpy.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_operator.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_optuna.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_orjson.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_os.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_parse.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_pathlib.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_period.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_pickle.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_platform.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_polars.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_polars_ols.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_pqdm.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_pydantic.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_pyinstrument.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_pyrsistent.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_pytest.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_pytest_regressions.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_python_dotenv.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_random.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_re.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_redis.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_reprlib.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_rich.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_scipy.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_sentinel.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_shelve.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_slack_sdk.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_socket.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_sqlalchemy.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_sqlalchemy_polars.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_statsmodel.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_streamlit.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_sys.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_tempfile.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_tenacity.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_text.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_threading.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_timer.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_traceback.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_traceback_funcs/__init__.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_traceback_funcs/chain.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_traceback_funcs/decorated_async.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_traceback_funcs/decorated_sync.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_traceback_funcs/error_bind.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_traceback_funcs/many.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_traceback_funcs/one.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_traceback_funcs/recursive.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_traceback_funcs/task_group_one.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_traceback_funcs/task_group_two.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_traceback_funcs/two.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_traceback_funcs/untraced.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_types.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_typing.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_typing_funcs/__init__.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_typing_funcs/no_future.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_typing_funcs/with_future.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_tzdata.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_tzlocal.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_uuid.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_version.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_warnings.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_whenever.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_zipfile.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/test_zoneinfo.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/utilities/altair.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/utilities/astor.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/utilities/asyncio.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/utilities/atomicwrites.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/utilities/atools.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/utilities/cachetools.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/utilities/concurrent.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/utilities/contextlib.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/utilities/contextvars.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/utilities/cryptography.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/utilities/cvxpy.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/utilities/dataclasses.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/utilities/enum.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/utilities/errors.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/utilities/eventkit.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/utilities/fastapi.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/utilities/fpdf2.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/utilities/functions.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/utilities/functools.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/utilities/getpass.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/utilities/git.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/utilities/hashlib.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/utilities/http.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/utilities/hypothesis.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/utilities/ipython.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/utilities/iterables.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/utilities/jupyter.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/utilities/lightweight_charts.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/utilities/logging.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/utilities/loguru.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/utilities/luigi.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/utilities/math.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/utilities/memory_profiler.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/utilities/modules.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/utilities/more_itertools.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/utilities/numpy.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/utilities/operator.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/utilities/optuna.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/utilities/orjson.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/utilities/os.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/utilities/parse.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/utilities/pathlib.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/utilities/period.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/utilities/pickle.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/utilities/platform.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/utilities/polars.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/utilities/polars_ols.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/utilities/pqdm.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/utilities/py.typed +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/utilities/pydantic.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/utilities/pyinstrument.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/utilities/pyrsistent.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/utilities/pytest.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/utilities/pytest_regressions.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/utilities/python_dotenv.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/utilities/random.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/utilities/re.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/utilities/reprlib.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/utilities/rich.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/utilities/scipy.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/utilities/sentinel.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/utilities/shelve.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/utilities/slack_sdk.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/utilities/socket.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/utilities/sqlalchemy.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/utilities/sqlalchemy_polars.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/utilities/statsmodels.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/utilities/streamlit.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/utilities/sys.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/utilities/tempfile.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/utilities/tenacity.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/utilities/text.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/utilities/threading.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/utilities/timer.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/utilities/traceback.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/utilities/types.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/utilities/typing.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/utilities/tzdata.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/utilities/tzlocal.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/utilities/uuid.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/utilities/version.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/utilities/warnings.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/utilities/whenever.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/utilities/zipfile.py +0 -0
- {dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/utilities/zoneinfo.py +0 -0
@@ -1,12 +1,12 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: dycw-utilities
|
3
|
-
Version: 0.113.
|
3
|
+
Version: 0.113.4
|
4
4
|
Author-email: Derek Wan <d.wan@icloud.com>
|
5
5
|
License-File: LICENSE
|
6
6
|
Requires-Python: >=3.12
|
7
7
|
Requires-Dist: typing-extensions<4.14,>=4.13.1
|
8
8
|
Provides-Extra: test
|
9
|
-
Requires-Dist: hypothesis<6.132,>=6.131.
|
9
|
+
Requires-Dist: hypothesis<6.132,>=6.131.15; extra == 'test'
|
10
10
|
Requires-Dist: pytest-asyncio<0.27,>=0.26.0; extra == 'test'
|
11
11
|
Requires-Dist: pytest-cov<6.2,>=6.1.1; extra == 'test'
|
12
12
|
Requires-Dist: pytest-instafail<0.6,>=0.5.0; extra == 'test'
|
@@ -14,7 +14,7 @@ Requires-Dist: pytest-lazy-fixtures<1.2,>=1.1.2; extra == 'test'
|
|
14
14
|
Requires-Dist: pytest-only<2.2,>=2.1.2; extra == 'test'
|
15
15
|
Requires-Dist: pytest-randomly<3.17,>=3.16.0; extra == 'test'
|
16
16
|
Requires-Dist: pytest-regressions<2.8,>=2.7.0; extra == 'test'
|
17
|
-
Requires-Dist: pytest-rerunfailures<16,>=15.
|
17
|
+
Requires-Dist: pytest-rerunfailures<16,>=15.1; extra == 'test'
|
18
18
|
Requires-Dist: pytest-rng<1.1,>=1.0.0; extra == 'test'
|
19
19
|
Requires-Dist: pytest-timeout<2.5,>=2.4.0; extra == 'test'
|
20
20
|
Requires-Dist: pytest-xdist<3.7,>=3.6.1; extra == 'test'
|
@@ -37,7 +37,7 @@ Requires-Dist: atools<0.15,>=0.14.2; extra == 'zzz-test-atools'
|
|
37
37
|
Provides-Extra: zzz-test-cachetools
|
38
38
|
Requires-Dist: cachetools<5.6,>=5.5.2; extra == 'zzz-test-cachetools'
|
39
39
|
Provides-Extra: zzz-test-click
|
40
|
-
Requires-Dist: click<8.
|
40
|
+
Requires-Dist: click<8.3,>=8.2.0; extra == 'zzz-test-click'
|
41
41
|
Requires-Dist: sqlalchemy<2.1,>=2.0.40; extra == 'zzz-test-click'
|
42
42
|
Requires-Dist: whenever<0.8,>=0.7.3; extra == 'zzz-test-click'
|
43
43
|
Provides-Extra: zzz-test-contextlib
|
@@ -80,7 +80,7 @@ Provides-Extra: zzz-test-hypothesis
|
|
80
80
|
Requires-Dist: aiosqlite<0.22,>=0.21.0; extra == 'zzz-test-hypothesis'
|
81
81
|
Requires-Dist: asyncpg<0.31,>=0.30.0; extra == 'zzz-test-hypothesis'
|
82
82
|
Requires-Dist: greenlet<3.3,>=3.2.0; extra == 'zzz-test-hypothesis'
|
83
|
-
Requires-Dist: hypothesis<6.132,>=6.131.
|
83
|
+
Requires-Dist: hypothesis<6.132,>=6.131.15; extra == 'zzz-test-hypothesis'
|
84
84
|
Requires-Dist: luigi<3.7,>=3.6.0; extra == 'zzz-test-hypothesis'
|
85
85
|
Requires-Dist: numpy<2.3,>=2.2.5; extra == 'zzz-test-hypothesis'
|
86
86
|
Requires-Dist: pathvalidate<3.3,>=3.2.3; extra == 'zzz-test-hypothesis'
|
@@ -101,7 +101,7 @@ Requires-Dist: polars-lts-cpu<1.30,>=1.29.0; extra == 'zzz-test-jupyter'
|
|
101
101
|
Provides-Extra: zzz-test-logging
|
102
102
|
Requires-Dist: atomicwrites<1.5,>=1.4.1; extra == 'zzz-test-logging'
|
103
103
|
Requires-Dist: coloredlogs<15.1,>=15.0.1; extra == 'zzz-test-logging'
|
104
|
-
Requires-Dist: concurrent-log-handler<0.10,>=0.9.
|
104
|
+
Requires-Dist: concurrent-log-handler<0.10,>=0.9.26; extra == 'zzz-test-logging'
|
105
105
|
Requires-Dist: rich<14.1,>=14.0.0; extra == 'zzz-test-logging'
|
106
106
|
Requires-Dist: tomlkit<0.14,>=0.13.2; extra == 'zzz-test-logging'
|
107
107
|
Requires-Dist: tzlocal<5.4,>=5.3.1; extra == 'zzz-test-logging'
|
@@ -172,7 +172,7 @@ Requires-Dist: whenever<0.8,>=0.7.3; extra == 'zzz-test-redis'
|
|
172
172
|
Provides-Extra: zzz-test-rich
|
173
173
|
Requires-Dist: rich<14.1,>=14.0.0; extra == 'zzz-test-rich'
|
174
174
|
Provides-Extra: zzz-test-scipy
|
175
|
-
Requires-Dist: scipy<1.16,>=1.15.
|
175
|
+
Requires-Dist: scipy<1.16,>=1.15.3; extra == 'zzz-test-scipy'
|
176
176
|
Provides-Extra: zzz-test-sentinel
|
177
177
|
Provides-Extra: zzz-test-shelve
|
178
178
|
Provides-Extra: zzz-test-slack-sdk
|
@@ -16,9 +16,9 @@ dev = [
|
|
16
16
|
"atomicwrites >= 1.4.1, < 1.5",
|
17
17
|
"atools >= 0.14.2, < 0.15",
|
18
18
|
"cachetools >= 5.5.2, < 5.6",
|
19
|
-
"click >= 8.
|
19
|
+
"click >= 8.2.0, < 8.3",
|
20
20
|
"coloredlogs >= 15.0.1, < 15.1",
|
21
|
-
"concurrent-log-handler >= 0.9.
|
21
|
+
"concurrent-log-handler >= 0.9.26, < 0.10",
|
22
22
|
"cryptography >= 44.0.2, < 44.1",
|
23
23
|
"cvxpy >= 1.6.5, < 1.7",
|
24
24
|
"eventkit >= 1.0.3, < 1.1",
|
@@ -26,7 +26,7 @@ dev = [
|
|
26
26
|
"fpdf2 >= 2.8.3, < 2.9",
|
27
27
|
"greenlet >= 3.2.0, < 3.3", # for sqlalchemy async
|
28
28
|
"httpx >= 0.28.1, < 0.29", # for fastapi
|
29
|
-
"hypothesis >= 6.131.
|
29
|
+
"hypothesis >= 6.131.15, < 6.132",
|
30
30
|
"img2pdf >= 0.6.0, < 0.7",
|
31
31
|
"lightweight-charts >= 2.1, < 2.2",
|
32
32
|
"loguru >= 0.7.3, < 0.8",
|
@@ -52,7 +52,7 @@ dev = [
|
|
52
52
|
"redis >= 6.0.0, < 6.1",
|
53
53
|
"rich >= 14.0.0, < 14.1",
|
54
54
|
"scikit-learn >= 1.6.1, < 1.7",
|
55
|
-
"scipy >= 1.15.
|
55
|
+
"scipy >= 1.15.3, < 1.16",
|
56
56
|
"slack-sdk >= 3.35.0, < 3.36",
|
57
57
|
"sqlalchemy >= 2.0.40, < 2.1",
|
58
58
|
"statsmodels >= 0.14.4, < 0.15",
|
@@ -74,7 +74,7 @@ dev = [
|
|
74
74
|
"pytest-lazy-fixtures >= 1.1.2, < 1.2",
|
75
75
|
"pytest-only >= 2.1.2, < 2.2",
|
76
76
|
"pytest-randomly >= 3.16.0, < 3.17",
|
77
|
-
"pytest-rerunfailures >= 15.
|
77
|
+
"pytest-rerunfailures >= 15.1, < 16",
|
78
78
|
"pytest-rng >= 1.0.0, < 1.1",
|
79
79
|
"pytest-timeout >= 2.4.0, < 2.5",
|
80
80
|
"pytest-xdist >= 3.6.1, < 3.7",
|
@@ -92,11 +92,11 @@ dependencies = [
|
|
92
92
|
name = "dycw-utilities"
|
93
93
|
readme = "README.md"
|
94
94
|
requires-python = ">= 3.12"
|
95
|
-
version = "0.113.
|
95
|
+
version = "0.113.4"
|
96
96
|
|
97
97
|
[project.optional-dependencies]
|
98
98
|
test = [
|
99
|
-
"hypothesis >= 6.131.
|
99
|
+
"hypothesis >= 6.131.15, < 6.132",
|
100
100
|
"pytest >= 8.3.5, < 8.4",
|
101
101
|
"pytest-asyncio >= 0.26.0, < 0.27",
|
102
102
|
"pytest-cov >= 6.1.1, < 6.2",
|
@@ -105,7 +105,7 @@ test = [
|
|
105
105
|
"pytest-only >= 2.1.2, < 2.2",
|
106
106
|
"pytest-randomly >= 3.16.0, < 3.17",
|
107
107
|
"pytest-regressions >= 2.7.0, < 2.8",
|
108
|
-
"pytest-rerunfailures >= 15.
|
108
|
+
"pytest-rerunfailures >= 15.1, < 16",
|
109
109
|
"pytest-rng >= 1.0.0, < 1.1",
|
110
110
|
"pytest-timeout >= 2.4.0, < 2.5",
|
111
111
|
"pytest-xdist >= 3.6.1, < 3.7",
|
@@ -127,7 +127,7 @@ zzz-test-atools = [
|
|
127
127
|
]
|
128
128
|
zzz-test-cachetools = ["cachetools >= 5.5.2, < 5.6"]
|
129
129
|
zzz-test-click = [
|
130
|
-
"click >= 8.
|
130
|
+
"click >= 8.2.0, < 8.3",
|
131
131
|
"sqlalchemy >= 2.0.40, < 2.1",
|
132
132
|
"whenever >= 0.7.3, < 0.8",
|
133
133
|
]
|
@@ -174,7 +174,7 @@ zzz-test-hypothesis = [
|
|
174
174
|
"aiosqlite >= 0.21.0, < 0.22",
|
175
175
|
"asyncpg >= 0.30.0, < 0.31", # for sqlalchemy async
|
176
176
|
"greenlet >= 3.2.0, < 3.3", # for sqlalchemy async
|
177
|
-
"hypothesis >= 6.131.
|
177
|
+
"hypothesis >= 6.131.15, < 6.132",
|
178
178
|
"luigi >= 3.6.0, < 3.7",
|
179
179
|
"numpy >= 2.2.5, < 2.3",
|
180
180
|
"pathvalidate >= 3.2.3, < 3.3",
|
@@ -197,7 +197,7 @@ zzz-test-jupyter = [
|
|
197
197
|
zzz-test-logging = [
|
198
198
|
"atomicwrites >= 1.4.1, < 1.5",
|
199
199
|
"coloredlogs >= 15.0.1, < 15.1",
|
200
|
-
"concurrent-log-handler >= 0.9.
|
200
|
+
"concurrent-log-handler >= 0.9.26, < 0.10",
|
201
201
|
"rich >= 14.0.0, < 14.1",
|
202
202
|
"tomlkit >= 0.13.2, < 0.14",
|
203
203
|
"tzlocal >= 5.3.1, < 5.4",
|
@@ -266,7 +266,7 @@ zzz-test-redis = [
|
|
266
266
|
"whenever >= 0.7.3, < 0.8",
|
267
267
|
]
|
268
268
|
zzz-test-rich = ["rich >= 14.0.0, < 14.1"]
|
269
|
-
zzz-test-scipy = ["scipy >= 1.15.
|
269
|
+
zzz-test-scipy = ["scipy >= 1.15.3, < 1.16"]
|
270
270
|
zzz-test-sentinel = []
|
271
271
|
zzz-test-shelve = []
|
272
272
|
zzz-test-slack-sdk = [
|
@@ -334,7 +334,7 @@ zzz-test-zoneinfo = [
|
|
334
334
|
# bump-my-version
|
335
335
|
[tool.bumpversion]
|
336
336
|
allow_dirty = true
|
337
|
-
current_version = "0.113.
|
337
|
+
current_version = "0.113.4"
|
338
338
|
|
339
339
|
[[tool.bumpversion.files]]
|
340
340
|
filename = "src/utilities/__init__.py"
|
@@ -102,12 +102,12 @@ class TestFileAndDirPaths:
|
|
102
102
|
file_path.touch()
|
103
103
|
result = CliRunner().invoke(cli, [str(file_path)])
|
104
104
|
assert result.exit_code == 2
|
105
|
-
assert search("is a file", result.
|
105
|
+
assert search("is a file", result.stderr)
|
106
106
|
|
107
107
|
non_existent = tmp_path.joinpath("non-existent")
|
108
108
|
result = CliRunner().invoke(cli, [str(non_existent)])
|
109
109
|
assert result.exit_code == 2
|
110
|
-
assert search("does not exist", result.
|
110
|
+
assert search("does not exist", result.stderr)
|
111
111
|
|
112
112
|
def test_existing_file_path(self, *, tmp_path: Path) -> None:
|
113
113
|
@command()
|
@@ -119,7 +119,7 @@ class TestFileAndDirPaths:
|
|
119
119
|
|
120
120
|
result = CliRunner().invoke(cli, [str(tmp_path)])
|
121
121
|
assert result.exit_code == 2
|
122
|
-
assert search("is a directory", result.
|
122
|
+
assert search("is a directory", result.stderr)
|
123
123
|
|
124
124
|
file_path = tmp_path.joinpath("file.txt")
|
125
125
|
file_path.touch()
|
@@ -129,7 +129,7 @@ class TestFileAndDirPaths:
|
|
129
129
|
non_existent = tmp_path.joinpath("non-existent")
|
130
130
|
result = CliRunner().invoke(cli, [str(non_existent)])
|
131
131
|
assert result.exit_code == 2
|
132
|
-
assert search("does not exist", result.
|
132
|
+
assert search("does not exist", result.stderr)
|
133
133
|
|
134
134
|
def test_dir_path(self, *, tmp_path: Path) -> None:
|
135
135
|
@command()
|
@@ -146,7 +146,7 @@ class TestFileAndDirPaths:
|
|
146
146
|
file_path.touch()
|
147
147
|
result = CliRunner().invoke(cli, [str(file_path)])
|
148
148
|
assert result.exit_code == 2
|
149
|
-
assert search("is a file", result.
|
149
|
+
assert search("is a file", result.stderr)
|
150
150
|
|
151
151
|
non_existent = tmp_path.joinpath("non-existent")
|
152
152
|
result = CliRunner().invoke(cli, [str(non_existent)])
|
@@ -162,7 +162,7 @@ class TestFileAndDirPaths:
|
|
162
162
|
|
163
163
|
result = CliRunner().invoke(cli, [str(tmp_path)])
|
164
164
|
assert result.exit_code == 2
|
165
|
-
assert search("is a directory", result.
|
165
|
+
assert search("is a directory", result.stderr)
|
166
166
|
|
167
167
|
file_path = tmp_path.joinpath("file.txt")
|
168
168
|
file_path.touch()
|
@@ -394,7 +394,7 @@ class TestParameters:
|
|
394
394
|
assert result.exit_code == 2
|
395
395
|
assert search(
|
396
396
|
"Invalid value for '--value': Object '0' of type 'int' must be a string",
|
397
|
-
result.
|
397
|
+
result.stderr,
|
398
398
|
)
|
399
399
|
|
400
400
|
|
@@ -50,6 +50,7 @@ from utilities.datetime import (
|
|
50
50
|
AreEqualDateTimesError,
|
51
51
|
CheckDateNotDateTimeError,
|
52
52
|
EnsureMonthError,
|
53
|
+
GetMinMaxDateError,
|
53
54
|
MeanDateTimeError,
|
54
55
|
MeanTimeDeltaError,
|
55
56
|
MillisecondsSinceEpochError,
|
@@ -67,6 +68,11 @@ from utilities.datetime import (
|
|
67
68
|
_DateDurationToIntTimeDeltaError,
|
68
69
|
_DateDurationToTimeDeltaFloatError,
|
69
70
|
_DateDurationToTimeDeltaTimeDeltaError,
|
71
|
+
_GetMinMaxDateMaxAgeError,
|
72
|
+
_GetMinMaxDateMaxDateError,
|
73
|
+
_GetMinMaxDateMinAgeError,
|
74
|
+
_GetMinMaxDateMinDateError,
|
75
|
+
_GetMinMaxDatePeriodError,
|
70
76
|
_ParseTwoDigitYearInvalidIntegerError,
|
71
77
|
_ParseTwoDigitYearInvalidStringError,
|
72
78
|
add_duration,
|
@@ -91,6 +97,7 @@ from utilities.datetime import (
|
|
91
97
|
get_date,
|
92
98
|
get_datetime,
|
93
99
|
get_half_years,
|
100
|
+
get_min_max_date,
|
94
101
|
get_months,
|
95
102
|
get_now,
|
96
103
|
get_quarters,
|
@@ -129,6 +136,7 @@ from utilities.datetime import (
|
|
129
136
|
from utilities.functions import not_func
|
130
137
|
from utilities.hypothesis import (
|
131
138
|
assume_does_not_raise,
|
139
|
+
date_durations,
|
132
140
|
int32s,
|
133
141
|
months,
|
134
142
|
pairs,
|
@@ -148,6 +156,7 @@ if TYPE_CHECKING:
|
|
148
156
|
from utilities.sentinel import Sentinel
|
149
157
|
from utilities.types import (
|
150
158
|
DateOrDateTime,
|
159
|
+
Duration,
|
151
160
|
MaybeCallableDate,
|
152
161
|
MaybeCallableDateTime,
|
153
162
|
Number,
|
@@ -675,6 +684,79 @@ class TestGetDateTime:
|
|
675
684
|
assert get_datetime(datetime=lambda: datetime) == datetime
|
676
685
|
|
677
686
|
|
687
|
+
class TestGetMinMaxDate:
|
688
|
+
@given(
|
689
|
+
min_date=dates(max_value=TODAY_UTC) | none(),
|
690
|
+
max_date=dates(max_value=TODAY_UTC) | none(),
|
691
|
+
min_age=date_durations(min_int=0, min_timedelta=ZERO_TIME) | none(),
|
692
|
+
max_age=date_durations(min_int=0, min_timedelta=ZERO_TIME) | none(),
|
693
|
+
)
|
694
|
+
def test_main(
|
695
|
+
self,
|
696
|
+
*,
|
697
|
+
min_date: dt.date | None,
|
698
|
+
max_date: dt.date | None,
|
699
|
+
min_age: Duration | None,
|
700
|
+
max_age: Duration | None,
|
701
|
+
) -> None:
|
702
|
+
with assume_does_not_raise(GetMinMaxDateError, OverflowError):
|
703
|
+
min_date_use, max_date_use = get_min_max_date(
|
704
|
+
min_date=min_date, max_date=max_date, min_age=min_age, max_age=max_age
|
705
|
+
)
|
706
|
+
if (min_date is None) and (max_age is None):
|
707
|
+
assert min_date_use is None
|
708
|
+
else:
|
709
|
+
assert min_date_use is not None
|
710
|
+
if (max_date is None) and (min_age is None):
|
711
|
+
assert max_date_use is None
|
712
|
+
else:
|
713
|
+
assert max_date_use is not None
|
714
|
+
if min_date_use is not None:
|
715
|
+
assert min_date_use <= get_today()
|
716
|
+
if max_date_use is not None:
|
717
|
+
assert max_date_use <= get_today()
|
718
|
+
if (min_date_use is not None) and (max_date_use is not None):
|
719
|
+
assert min_date_use <= max_date_use
|
720
|
+
|
721
|
+
@given(date=dates(min_value=TODAY_UTC + DAY))
|
722
|
+
def test_error_min_date(self, *, date: dt.date) -> None:
|
723
|
+
with raises(
|
724
|
+
_GetMinMaxDateMinDateError,
|
725
|
+
match="Min date must be at most today; got .* > .*",
|
726
|
+
):
|
727
|
+
_ = get_min_max_date(min_date=date)
|
728
|
+
|
729
|
+
@given(duration=date_durations(max_int=-1, max_timedelta=-DAY))
|
730
|
+
def test_error_min_age(self, *, duration: Duration) -> None:
|
731
|
+
with raises(
|
732
|
+
_GetMinMaxDateMinAgeError, match="Min age must be non-negative; got .*"
|
733
|
+
):
|
734
|
+
_ = get_min_max_date(min_age=duration)
|
735
|
+
|
736
|
+
@given(date=dates(min_value=TODAY_UTC + DAY))
|
737
|
+
def test_error_max_date(self, *, date: dt.date) -> None:
|
738
|
+
with raises(
|
739
|
+
_GetMinMaxDateMaxDateError,
|
740
|
+
match="Max date must be at most today; got .* > .*",
|
741
|
+
):
|
742
|
+
_ = get_min_max_date(max_date=date)
|
743
|
+
|
744
|
+
@given(duration=date_durations(max_int=-1, max_timedelta=-DAY))
|
745
|
+
def test_error_max_age(self, *, duration: Duration) -> None:
|
746
|
+
with raises(
|
747
|
+
_GetMinMaxDateMaxAgeError, match="Max age must be non-negative; got .*"
|
748
|
+
):
|
749
|
+
_ = get_min_max_date(max_age=duration)
|
750
|
+
|
751
|
+
@given(dates=pairs(dates(max_value=TODAY_UTC), unique=True, sorted=True))
|
752
|
+
def test_error_period(self, *, dates: tuple[dt.date, dt.date]) -> None:
|
753
|
+
with raises(
|
754
|
+
_GetMinMaxDatePeriodError,
|
755
|
+
match="Min date must be at most max date; got .* > .*",
|
756
|
+
):
|
757
|
+
_ = get_min_max_date(min_date=dates[1], max_date=dates[0])
|
758
|
+
|
759
|
+
|
678
760
|
class TestGetNow:
|
679
761
|
@given(time_zone=timezones())
|
680
762
|
def test_function(self, *, time_zone: ZoneInfo) -> None:
|
@@ -125,7 +125,8 @@ class Enum(ParamType, Generic[TEnum]):
|
|
125
125
|
self.fail(str(error), param, ctx)
|
126
126
|
|
127
127
|
@override
|
128
|
-
def get_metavar(self, param: Parameter) -> str | None:
|
128
|
+
def get_metavar(self, param: Parameter, ctx: Context) -> str | None:
|
129
|
+
_ = ctx
|
129
130
|
desc = ",".join(e.name for e in self._enum)
|
130
131
|
return _make_metavar(param, desc)
|
131
132
|
|
@@ -273,8 +274,8 @@ class FrozenSetParameter(ParamType, Generic[_TParam, _T]):
|
|
273
274
|
return frozenset(self._param.convert(v, param, ctx) for v in values)
|
274
275
|
|
275
276
|
@override
|
276
|
-
def get_metavar(self, param: Parameter) -> str | None:
|
277
|
-
if (metavar := self._param.get_metavar(param)) is None:
|
277
|
+
def get_metavar(self, param: Parameter, ctx: Context) -> str | None:
|
278
|
+
if (metavar := self._param.get_metavar(param, ctx)) is None:
|
278
279
|
name = self.name.upper()
|
279
280
|
else:
|
280
281
|
name = f"FROZENSET{metavar}"
|
@@ -397,8 +398,8 @@ class ListParameter(ParamType, Generic[_TParam, _T]):
|
|
397
398
|
return [self._param.convert(v, param, ctx) for v in values]
|
398
399
|
|
399
400
|
@override
|
400
|
-
def get_metavar(self, param: Parameter) -> str | None:
|
401
|
-
if (metavar := self._param.get_metavar(param)) is None:
|
401
|
+
def get_metavar(self, param: Parameter, ctx: Context) -> str | None:
|
402
|
+
if (metavar := self._param.get_metavar(param, ctx)) is None:
|
402
403
|
name = self.name.upper()
|
403
404
|
else:
|
404
405
|
name = f"LIST{metavar}"
|
@@ -1,7 +1,7 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
3
|
import datetime as dt
|
4
|
-
from collections.abc import Callable, Iterable
|
4
|
+
from collections.abc import Callable, Iterable, Sequence
|
5
5
|
from dataclasses import dataclass, replace
|
6
6
|
from re import search, sub
|
7
7
|
from statistics import fmean
|
@@ -495,6 +495,101 @@ def get_half_years(*, n: int = 1) -> dt.timedelta:
|
|
495
495
|
|
496
496
|
HALF_YEAR = get_half_years(n=1)
|
497
497
|
|
498
|
+
##
|
499
|
+
|
500
|
+
|
501
|
+
def get_min_max_date(
|
502
|
+
*,
|
503
|
+
min_date: dt.date | None = None,
|
504
|
+
max_date: dt.date | None = None,
|
505
|
+
min_age: Duration | None = None,
|
506
|
+
max_age: Duration | None = None,
|
507
|
+
time_zone: TimeZoneLike = UTC,
|
508
|
+
) -> tuple[dt.date | None, dt.date | None]:
|
509
|
+
"""Get the min/max date given a combination of dates/ages."""
|
510
|
+
today = get_today(time_zone=time_zone)
|
511
|
+
min_parts: Sequence[dt.date] = []
|
512
|
+
if min_date is not None:
|
513
|
+
if min_date > today:
|
514
|
+
raise _GetMinMaxDateMinDateError(min_date=min_date, today=today)
|
515
|
+
min_parts.append(min_date)
|
516
|
+
if max_age is not None:
|
517
|
+
if date_duration_to_timedelta(max_age) < ZERO_TIME:
|
518
|
+
raise _GetMinMaxDateMaxAgeError(max_age=max_age)
|
519
|
+
min_parts.append(sub_duration(today, duration=max_age))
|
520
|
+
min_date_use = max(min_parts, default=None)
|
521
|
+
max_parts: Sequence[dt.date] = []
|
522
|
+
if max_date is not None:
|
523
|
+
if max_date > today:
|
524
|
+
raise _GetMinMaxDateMaxDateError(max_date=max_date, today=today)
|
525
|
+
max_parts.append(max_date)
|
526
|
+
if min_age is not None:
|
527
|
+
if date_duration_to_timedelta(min_age) < ZERO_TIME:
|
528
|
+
raise _GetMinMaxDateMinAgeError(min_age=min_age)
|
529
|
+
max_parts.append(sub_duration(today, duration=min_age))
|
530
|
+
max_date_use = min(max_parts, default=None)
|
531
|
+
if (
|
532
|
+
(min_date_use is not None)
|
533
|
+
and (max_date_use is not None)
|
534
|
+
and (min_date_use > max_date_use)
|
535
|
+
):
|
536
|
+
raise _GetMinMaxDatePeriodError(min_date=min_date_use, max_date=max_date_use)
|
537
|
+
return min_date_use, max_date_use
|
538
|
+
|
539
|
+
|
540
|
+
@dataclass(kw_only=True, slots=True)
|
541
|
+
class GetMinMaxDateError(Exception): ...
|
542
|
+
|
543
|
+
|
544
|
+
@dataclass(kw_only=True, slots=True)
|
545
|
+
class _GetMinMaxDateMinDateError(GetMinMaxDateError):
|
546
|
+
min_date: dt.date
|
547
|
+
today: dt.date
|
548
|
+
|
549
|
+
@override
|
550
|
+
def __str__(self) -> str:
|
551
|
+
return f"Min date must be at most today; got {self.min_date} > {self.today}"
|
552
|
+
|
553
|
+
|
554
|
+
@dataclass(kw_only=True, slots=True)
|
555
|
+
class _GetMinMaxDateMinAgeError(GetMinMaxDateError):
|
556
|
+
min_age: Duration
|
557
|
+
|
558
|
+
@override
|
559
|
+
def __str__(self) -> str:
|
560
|
+
return f"Min age must be non-negative; got {self.min_age}"
|
561
|
+
|
562
|
+
|
563
|
+
@dataclass(kw_only=True, slots=True)
|
564
|
+
class _GetMinMaxDateMaxDateError(GetMinMaxDateError):
|
565
|
+
max_date: dt.date
|
566
|
+
today: dt.date
|
567
|
+
|
568
|
+
@override
|
569
|
+
def __str__(self) -> str:
|
570
|
+
return f"Max date must be at most today; got {self.max_date} > {self.today}"
|
571
|
+
|
572
|
+
|
573
|
+
@dataclass(kw_only=True, slots=True)
|
574
|
+
class _GetMinMaxDateMaxAgeError(GetMinMaxDateError):
|
575
|
+
max_age: Duration
|
576
|
+
|
577
|
+
@override
|
578
|
+
def __str__(self) -> str:
|
579
|
+
return f"Max age must be non-negative; got {self.max_age}"
|
580
|
+
|
581
|
+
|
582
|
+
@dataclass(kw_only=True, slots=True)
|
583
|
+
class _GetMinMaxDatePeriodError(GetMinMaxDateError):
|
584
|
+
min_date: dt.date
|
585
|
+
max_date: dt.date
|
586
|
+
|
587
|
+
@override
|
588
|
+
def __str__(self) -> str:
|
589
|
+
return (
|
590
|
+
f"Min date must be at most max date; got {self.min_date} > {self.max_date}"
|
591
|
+
)
|
592
|
+
|
498
593
|
|
499
594
|
##
|
500
595
|
|
@@ -1244,6 +1339,7 @@ __all__ = [
|
|
1244
1339
|
"CheckDateNotDateTimeError",
|
1245
1340
|
"DateOrMonth",
|
1246
1341
|
"EnsureMonthError",
|
1342
|
+
"GetMinMaxDateError",
|
1247
1343
|
"MeanDateTimeError",
|
1248
1344
|
"MeanTimeDeltaError",
|
1249
1345
|
"MillisecondsSinceEpochError",
|
@@ -1280,6 +1376,7 @@ __all__ = [
|
|
1280
1376
|
"get_date",
|
1281
1377
|
"get_datetime",
|
1282
1378
|
"get_half_years",
|
1379
|
+
"get_min_max_date",
|
1283
1380
|
"get_months",
|
1284
1381
|
"get_now",
|
1285
1382
|
"get_quarters",
|
@@ -607,7 +607,7 @@ class Publisher(QueueProcessor[tuple[str, EncodableT]]):
|
|
607
607
|
|
608
608
|
|
609
609
|
_SUBSCRIBE_TIMEOUT: Duration = SECOND
|
610
|
-
_SUBSCRIBE_SLEEP: Duration =
|
610
|
+
_SUBSCRIBE_SLEEP: Duration = MILLISECOND
|
611
611
|
|
612
612
|
|
613
613
|
@overload
|
@@ -617,8 +617,8 @@ def subscribe(
|
|
617
617
|
/,
|
618
618
|
*,
|
619
619
|
deserializer: Callable[[bytes], _T],
|
620
|
-
timeout: Duration | None =
|
621
|
-
sleep: Duration =
|
620
|
+
timeout: Duration | None = _SUBSCRIBE_TIMEOUT,
|
621
|
+
sleep: Duration = _SUBSCRIBE_SLEEP,
|
622
622
|
) -> AsyncIterator[_T]: ...
|
623
623
|
@overload
|
624
624
|
def subscribe(
|
@@ -627,8 +627,8 @@ def subscribe(
|
|
627
627
|
/,
|
628
628
|
*,
|
629
629
|
deserializer: None = None,
|
630
|
-
timeout: Duration | None =
|
631
|
-
sleep: Duration =
|
630
|
+
timeout: Duration | None = _SUBSCRIBE_TIMEOUT,
|
631
|
+
sleep: Duration = _SUBSCRIBE_SLEEP,
|
632
632
|
) -> AsyncIterator[bytes]: ...
|
633
633
|
async def subscribe(
|
634
634
|
pubsub: PubSub,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/modules/package_missing/__init__.py
RENAMED
File without changes
|
{dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/modules/package_missing/module.py
RENAMED
File without changes
|
{dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/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.113.2 → dycw_utilities-0.113.4}/src/tests/modules/package_without/__init__.py
RENAMED
File without changes
|
{dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/modules/package_without/module_1.py
RENAMED
File without changes
|
{dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/modules/package_without/module_2.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/scripts/test_async_service/__init__.py
RENAMED
File without changes
|
{dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/scripts/test_async_service/__main__.py
RENAMED
File without changes
|
{dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/scripts/test_async_service/run.sh
RENAMED
File without changes
|
{dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/scripts/test_queue_processor/__init__.py
RENAMED
File without changes
|
{dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/scripts/test_queue_processor/__main__.py
RENAMED
File without changes
|
{dycw_utilities-0.113.2 → dycw_utilities-0.113.4}/src/tests/scripts/test_queue_processor/run.sh
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
|