dycw-utilities 0.116.6__tar.gz → 0.117.0__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.116.6 → dycw_utilities-0.117.0}/PKG-INFO +1 -1
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/pyproject.toml +2 -2
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_asyncio.py +16 -1
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_datetime.py +56 -56
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/utilities/__init__.py +1 -1
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/utilities/asyncio.py +32 -1
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/utilities/datetime.py +58 -55
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/utilities/whenever.py +2 -2
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/.gitignore +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/LICENSE +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/README.md +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/__init__.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/conftest.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/modules/__init__.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/modules/package_missing/__init__.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/modules/package_missing/module.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/modules/package_with/__init__.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/modules/package_with/outer_1.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/modules/package_with/outer_2.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/modules/package_with/subpackage/__init__.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/modules/package_with/subpackage/inner_1.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/modules/package_with/subpackage/inner_2.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/modules/package_with/subpackage/inner_3.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/modules/package_without/__init__.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/modules/package_without/module_1.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/modules/package_without/module_2.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/modules/standalone.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/modules/with_imports.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/regressions/test_pytest_regressions/TestMultipleRegressionFixtures__test_main__obj.json +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/regressions/test_pytest_regressions/TestMultipleRegressionFixtures__test_main__series.json +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_int.json +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_literal__false.json +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_literal__true.json +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_nested.json +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/regressions/test_pytest_regressions/TestPolarsRegressionFixture__test_dataframe.json +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/regressions/test_pytest_regressions/TestPolarsRegressionFixture__test_series.json +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/scripts/__init__.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/scripts/test_async_service/__init__.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/scripts/test_async_service/__main__.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/scripts/test_async_service/run.sh +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/scripts/test_queue_processor/__init__.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/scripts/test_queue_processor/__main__.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/scripts/test_queue_processor/run.sh +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_altair.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_astor.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_atomicwrites.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_atools.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_cachetools.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_click.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_concurrent.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_contextlib.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_contextvars.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_cryptography.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_cvxpy.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_dataclasses.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_enum.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_errors.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_eventkit.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_fastapi.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_fpdf2.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_functions.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_functools.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_getpass.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_git.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_hashlib.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_http.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_hypothesis.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_importlib.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_ipython.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_iterables.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_jupyter.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_lightweight_charts.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_logging.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_loguru.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_luigi.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_math.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_memory_profiler.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_modules.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_more_itertools.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_numpy.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_operator.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_optuna.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_orjson.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_os.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_parse.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_pathlib.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_period.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_pickle.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_platform.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_polars.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_polars_ols.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_pqdm.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_pydantic.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_pyinstrument.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_pyrsistent.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_pytest.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_pytest_regressions.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_python_dotenv.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_random.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_re.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_redis.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_reprlib.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_rich.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_scipy.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_sentinel.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_shelve.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_slack_sdk.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_socket.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_sqlalchemy.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_sqlalchemy_polars.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_statsmodel.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_streamlit.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_sys.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_tempfile.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_tenacity.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_text.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_threading.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_timer.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_traceback.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_traceback_funcs/__init__.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_traceback_funcs/chain.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_traceback_funcs/decorated_async.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_traceback_funcs/decorated_sync.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_traceback_funcs/error_bind.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_traceback_funcs/many.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_traceback_funcs/one.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_traceback_funcs/recursive.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_traceback_funcs/task_group_one.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_traceback_funcs/task_group_two.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_traceback_funcs/two.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_traceback_funcs/untraced.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_types.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_typing.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_typing_funcs/__init__.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_typing_funcs/no_future.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_typing_funcs/with_future.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_tzdata.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_tzlocal.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_uuid.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_version.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_warnings.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_whenever.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_zipfile.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/test_zoneinfo.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/utilities/altair.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/utilities/astor.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/utilities/atomicwrites.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/utilities/atools.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/utilities/cachetools.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/utilities/click.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/utilities/concurrent.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/utilities/contextlib.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/utilities/contextvars.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/utilities/cryptography.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/utilities/cvxpy.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/utilities/dataclasses.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/utilities/enum.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/utilities/errors.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/utilities/eventkit.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/utilities/fastapi.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/utilities/fpdf2.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/utilities/functions.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/utilities/functools.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/utilities/getpass.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/utilities/git.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/utilities/hashlib.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/utilities/http.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/utilities/hypothesis.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/utilities/importlib.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/utilities/ipython.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/utilities/iterables.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/utilities/jupyter.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/utilities/lightweight_charts.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/utilities/logging.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/utilities/loguru.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/utilities/luigi.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/utilities/math.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/utilities/memory_profiler.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/utilities/modules.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/utilities/more_itertools.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/utilities/numpy.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/utilities/operator.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/utilities/optuna.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/utilities/orjson.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/utilities/os.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/utilities/parse.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/utilities/pathlib.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/utilities/period.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/utilities/pickle.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/utilities/platform.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/utilities/polars.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/utilities/polars_ols.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/utilities/pqdm.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/utilities/py.typed +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/utilities/pydantic.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/utilities/pyinstrument.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/utilities/pyrsistent.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/utilities/pytest.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/utilities/pytest_regressions.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/utilities/python_dotenv.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/utilities/random.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/utilities/re.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/utilities/redis.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/utilities/reprlib.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/utilities/rich.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/utilities/scipy.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/utilities/sentinel.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/utilities/shelve.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/utilities/slack_sdk.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/utilities/socket.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/utilities/sqlalchemy.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/utilities/sqlalchemy_polars.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/utilities/statsmodels.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/utilities/streamlit.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/utilities/sys.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/utilities/tempfile.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/utilities/tenacity.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/utilities/text.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/utilities/threading.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/utilities/timer.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/utilities/traceback.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/utilities/types.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/utilities/typing.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/utilities/tzdata.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/utilities/tzlocal.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/utilities/uuid.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/utilities/version.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/utilities/warnings.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/utilities/zipfile.py +0 -0
- {dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/utilities/zoneinfo.py +0 -0
@@ -92,7 +92,7 @@ dependencies = [
|
|
92
92
|
name = "dycw-utilities"
|
93
93
|
readme = "README.md"
|
94
94
|
requires-python = ">= 3.12"
|
95
|
-
version = "0.
|
95
|
+
version = "0.117.0"
|
96
96
|
|
97
97
|
[project.optional-dependencies]
|
98
98
|
test = [
|
@@ -334,7 +334,7 @@ zzz-test-zoneinfo = [
|
|
334
334
|
# bump-my-version
|
335
335
|
[tool.bumpversion]
|
336
336
|
allow_dirty = true
|
337
|
-
current_version = "0.
|
337
|
+
current_version = "0.117.0"
|
338
338
|
|
339
339
|
[[tool.bumpversion.files]]
|
340
340
|
filename = "src/utilities/__init__.py"
|
@@ -48,11 +48,13 @@ from utilities.asyncio import (
|
|
48
48
|
put_items,
|
49
49
|
put_items_nowait,
|
50
50
|
sleep_dur,
|
51
|
+
sleep_until,
|
52
|
+
sleep_until_rounded,
|
51
53
|
stream_command,
|
52
54
|
timeout_dur,
|
53
55
|
)
|
54
56
|
from utilities.dataclasses import replace_non_sentinel
|
55
|
-
from utilities.datetime import MILLISECOND, datetime_duration_to_timedelta
|
57
|
+
from utilities.datetime import MILLISECOND, datetime_duration_to_timedelta, get_now
|
56
58
|
from utilities.hypothesis import sentinels, text_ascii
|
57
59
|
from utilities.iterables import one, unique_everseen
|
58
60
|
from utilities.pytest import skipif_windows
|
@@ -951,6 +953,19 @@ class TestSleepDur:
|
|
951
953
|
assert timer <= 0.01
|
952
954
|
|
953
955
|
|
956
|
+
class TestSleepUntil:
|
957
|
+
async def test_main(self) -> None:
|
958
|
+
now = get_now()
|
959
|
+
with Timer() as timer:
|
960
|
+
await sleep_until(now + 10 * MILLISECOND)
|
961
|
+
assert timer >= datetime_duration_to_timedelta(5 * MILLISECOND)
|
962
|
+
|
963
|
+
|
964
|
+
class TestSleepUntilRounded:
|
965
|
+
async def test_main(self) -> None:
|
966
|
+
await sleep_until_rounded(10 * MILLISECOND)
|
967
|
+
|
968
|
+
|
954
969
|
class TestStreamCommand:
|
955
970
|
@skipif_windows
|
956
971
|
async def test_main(self) -> None:
|
@@ -88,6 +88,8 @@ from utilities.datetime import (
|
|
88
88
|
date_to_datetime,
|
89
89
|
date_to_month,
|
90
90
|
datetime_duration_to_float,
|
91
|
+
datetime_duration_to_microseconds,
|
92
|
+
datetime_duration_to_milliseconds,
|
91
93
|
datetime_duration_to_timedelta,
|
92
94
|
datetime_utc,
|
93
95
|
days_since_epoch,
|
@@ -128,8 +130,6 @@ from utilities.datetime import (
|
|
128
130
|
serialize_month,
|
129
131
|
sub_duration,
|
130
132
|
timedelta_since_epoch,
|
131
|
-
timedelta_to_microseconds,
|
132
|
-
timedelta_to_milliseconds,
|
133
133
|
yield_days,
|
134
134
|
yield_weekdays,
|
135
135
|
)
|
@@ -520,6 +520,60 @@ class TestDateTimeDurationToFloat:
|
|
520
520
|
assert result == timedelta.total_seconds()
|
521
521
|
|
522
522
|
|
523
|
+
class TestDateTimeDurationToMicrosecondsOrMilliseconds:
|
524
|
+
@given(timedelta=timedeltas())
|
525
|
+
def test_timedelta_to_microseconds(self, *, timedelta: dt.timedelta) -> None:
|
526
|
+
microseconds = datetime_duration_to_microseconds(timedelta)
|
527
|
+
result = microseconds_to_timedelta(microseconds)
|
528
|
+
assert result == timedelta
|
529
|
+
|
530
|
+
@given(microseconds=integers())
|
531
|
+
def test_microseconds_to_timedelta(self, *, microseconds: int) -> None:
|
532
|
+
with assume_does_not_raise(OverflowError):
|
533
|
+
timedelta = microseconds_to_timedelta(microseconds)
|
534
|
+
result = datetime_duration_to_microseconds(timedelta)
|
535
|
+
assert result == microseconds
|
536
|
+
|
537
|
+
@given(timedelta=timedeltas(), strict=booleans())
|
538
|
+
@settings(suppress_health_check={HealthCheck.filter_too_much})
|
539
|
+
def test_timedelta_to_milliseconds_exact(
|
540
|
+
self, *, timedelta: dt.timedelta, strict: bool
|
541
|
+
) -> None:
|
542
|
+
_, remainder = divmod(timedelta.microseconds, _MICROSECONDS_PER_MILLISECOND)
|
543
|
+
_ = assume(remainder == 0)
|
544
|
+
milliseconds = datetime_duration_to_milliseconds(timedelta, strict=strict)
|
545
|
+
assert isinstance(milliseconds, int)
|
546
|
+
result = milliseconds_to_timedelta(milliseconds)
|
547
|
+
assert result == timedelta
|
548
|
+
|
549
|
+
@given(timedelta=timedeltas())
|
550
|
+
def test_timedelta_to_milliseconds_inexact(
|
551
|
+
self, *, timedelta: dt.timedelta
|
552
|
+
) -> None:
|
553
|
+
_, remainder = divmod(timedelta.microseconds, _MICROSECONDS_PER_MILLISECOND)
|
554
|
+
_ = assume(remainder != 0)
|
555
|
+
milliseconds = datetime_duration_to_milliseconds(timedelta)
|
556
|
+
result = milliseconds_to_timedelta(round(milliseconds))
|
557
|
+
assert abs(result - timedelta) <= SECOND
|
558
|
+
|
559
|
+
@given(timedelta=timedeltas())
|
560
|
+
def test_timedelta_to_milliseconds_error(self, *, timedelta: dt.timedelta) -> None:
|
561
|
+
_, microseconds = divmod(timedelta.microseconds, _MICROSECONDS_PER_MILLISECOND)
|
562
|
+
_ = assume(microseconds != 0)
|
563
|
+
with raises(
|
564
|
+
TimedeltaToMillisecondsError,
|
565
|
+
match=r"Unable to convert .* to milliseconds; got .* microsecond\(s\)",
|
566
|
+
):
|
567
|
+
_ = datetime_duration_to_milliseconds(timedelta, strict=True)
|
568
|
+
|
569
|
+
@given(milliseconds=int32s())
|
570
|
+
def test_milliseconds_to_timedelta(self, *, milliseconds: int) -> None:
|
571
|
+
with assume_does_not_raise(OverflowError):
|
572
|
+
timedelta = milliseconds_to_timedelta(milliseconds)
|
573
|
+
result = datetime_duration_to_milliseconds(timedelta)
|
574
|
+
assert result == milliseconds
|
575
|
+
|
576
|
+
|
523
577
|
class TestDateTimeDurationToTimeDelta:
|
524
578
|
@given(n=int32s())
|
525
579
|
def test_int(self, *, n: int) -> None:
|
@@ -1205,60 +1259,6 @@ class TestTimedeltaSinceEpoch:
|
|
1205
1259
|
assert result1 == result2
|
1206
1260
|
|
1207
1261
|
|
1208
|
-
class TestTimedeltaToMicrosecondsOrMilliseconds:
|
1209
|
-
@given(timedelta=timedeltas())
|
1210
|
-
def test_timedelta_to_microseconds(self, *, timedelta: dt.timedelta) -> None:
|
1211
|
-
microseconds = timedelta_to_microseconds(timedelta)
|
1212
|
-
result = microseconds_to_timedelta(microseconds)
|
1213
|
-
assert result == timedelta
|
1214
|
-
|
1215
|
-
@given(microseconds=integers())
|
1216
|
-
def test_microseconds_to_timedelta(self, *, microseconds: int) -> None:
|
1217
|
-
with assume_does_not_raise(OverflowError):
|
1218
|
-
timedelta = microseconds_to_timedelta(microseconds)
|
1219
|
-
result = timedelta_to_microseconds(timedelta)
|
1220
|
-
assert result == microseconds
|
1221
|
-
|
1222
|
-
@given(timedelta=timedeltas(), strict=booleans())
|
1223
|
-
@settings(suppress_health_check={HealthCheck.filter_too_much})
|
1224
|
-
def test_timedelta_to_milliseconds_exact(
|
1225
|
-
self, *, timedelta: dt.timedelta, strict: bool
|
1226
|
-
) -> None:
|
1227
|
-
_, remainder = divmod(timedelta.microseconds, _MICROSECONDS_PER_MILLISECOND)
|
1228
|
-
_ = assume(remainder == 0)
|
1229
|
-
milliseconds = timedelta_to_milliseconds(timedelta, strict=strict)
|
1230
|
-
assert isinstance(milliseconds, int)
|
1231
|
-
result = milliseconds_to_timedelta(milliseconds)
|
1232
|
-
assert result == timedelta
|
1233
|
-
|
1234
|
-
@given(timedelta=timedeltas())
|
1235
|
-
def test_timedelta_to_milliseconds_inexact(
|
1236
|
-
self, *, timedelta: dt.timedelta
|
1237
|
-
) -> None:
|
1238
|
-
_, remainder = divmod(timedelta.microseconds, _MICROSECONDS_PER_MILLISECOND)
|
1239
|
-
_ = assume(remainder != 0)
|
1240
|
-
milliseconds = timedelta_to_milliseconds(timedelta)
|
1241
|
-
result = milliseconds_to_timedelta(round(milliseconds))
|
1242
|
-
assert abs(result - timedelta) <= SECOND
|
1243
|
-
|
1244
|
-
@given(timedelta=timedeltas())
|
1245
|
-
def test_timedelta_to_milliseconds_error(self, *, timedelta: dt.timedelta) -> None:
|
1246
|
-
_, microseconds = divmod(timedelta.microseconds, _MICROSECONDS_PER_MILLISECOND)
|
1247
|
-
_ = assume(microseconds != 0)
|
1248
|
-
with raises(
|
1249
|
-
TimedeltaToMillisecondsError,
|
1250
|
-
match=r"Unable to convert .* to milliseconds; got .* microsecond\(s\)",
|
1251
|
-
):
|
1252
|
-
_ = timedelta_to_milliseconds(timedelta, strict=True)
|
1253
|
-
|
1254
|
-
@given(milliseconds=int32s())
|
1255
|
-
def test_milliseconds_to_timedelta(self, *, milliseconds: int) -> None:
|
1256
|
-
with assume_does_not_raise(OverflowError):
|
1257
|
-
timedelta = milliseconds_to_timedelta(milliseconds)
|
1258
|
-
result = timedelta_to_milliseconds(timedelta)
|
1259
|
-
assert result == milliseconds
|
1260
|
-
|
1261
|
-
|
1262
1262
|
class TestTimedeltas:
|
1263
1263
|
@mark.parametrize(
|
1264
1264
|
"timedelta",
|
@@ -41,7 +41,14 @@ from typing import (
|
|
41
41
|
override,
|
42
42
|
)
|
43
43
|
|
44
|
-
from utilities.datetime import
|
44
|
+
from utilities.datetime import (
|
45
|
+
MILLISECOND,
|
46
|
+
MINUTE,
|
47
|
+
SECOND,
|
48
|
+
datetime_duration_to_float,
|
49
|
+
get_now,
|
50
|
+
round_datetime,
|
51
|
+
)
|
45
52
|
from utilities.errors import ImpossibleCaseError, repr_error
|
46
53
|
from utilities.functions import ensure_int, ensure_not_none, get_class_name
|
47
54
|
from utilities.reprlib import get_repr
|
@@ -55,6 +62,7 @@ from utilities.types import (
|
|
55
62
|
)
|
56
63
|
|
57
64
|
if TYPE_CHECKING:
|
65
|
+
import datetime as dt
|
58
66
|
from asyncio import _CoroutineLike
|
59
67
|
from asyncio.subprocess import Process
|
60
68
|
from collections.abc import AsyncIterator, Sequence
|
@@ -686,6 +694,27 @@ async def sleep_dur(*, duration: Duration | None = None) -> None:
|
|
686
694
|
##
|
687
695
|
|
688
696
|
|
697
|
+
async def sleep_until(datetime: dt.datetime, /) -> None:
|
698
|
+
"""Sleep until a given time."""
|
699
|
+
await sleep_dur(duration=datetime - get_now())
|
700
|
+
|
701
|
+
|
702
|
+
##
|
703
|
+
|
704
|
+
|
705
|
+
async def sleep_until_rounded(
|
706
|
+
duration: Duration, /, *, rel_tol: float | None = None, abs_tol: float | None = None
|
707
|
+
) -> None:
|
708
|
+
"""Sleep until a rounded time; accepts durations."""
|
709
|
+
datetime = round_datetime(
|
710
|
+
get_now(), duration, mode="ceil", rel_tol=rel_tol, abs_tol=abs_tol
|
711
|
+
)
|
712
|
+
await sleep_until(datetime)
|
713
|
+
|
714
|
+
|
715
|
+
##
|
716
|
+
|
717
|
+
|
689
718
|
@dataclass(kw_only=True, slots=True)
|
690
719
|
class StreamCommandOutput:
|
691
720
|
process: Process
|
@@ -768,6 +797,8 @@ __all__ = [
|
|
768
797
|
"put_items",
|
769
798
|
"put_items_nowait",
|
770
799
|
"sleep_dur",
|
800
|
+
"sleep_until",
|
801
|
+
"sleep_until_rounded",
|
771
802
|
"stream_command",
|
772
803
|
"timeout_dur",
|
773
804
|
]
|
@@ -334,6 +334,52 @@ def datetime_duration_to_float(duration: Duration, /) -> float:
|
|
334
334
|
assert_never(never)
|
335
335
|
|
336
336
|
|
337
|
+
def datetime_duration_to_microseconds(duration: Duration, /) -> int:
|
338
|
+
"""Compute the number of microseconds in a datetime duration."""
|
339
|
+
timedelta = datetime_duration_to_timedelta(duration)
|
340
|
+
return (
|
341
|
+
_MICROSECONDS_PER_DAY * timedelta.days
|
342
|
+
+ _MICROSECONDS_PER_SECOND * timedelta.seconds
|
343
|
+
+ timedelta.microseconds
|
344
|
+
)
|
345
|
+
|
346
|
+
|
347
|
+
@overload
|
348
|
+
def datetime_duration_to_milliseconds(
|
349
|
+
duration: Duration, /, *, strict: Literal[True]
|
350
|
+
) -> int: ...
|
351
|
+
@overload
|
352
|
+
def datetime_duration_to_milliseconds(
|
353
|
+
duration: Duration, /, *, strict: bool = False
|
354
|
+
) -> float: ...
|
355
|
+
def datetime_duration_to_milliseconds(
|
356
|
+
duration: Duration, /, *, strict: bool = False
|
357
|
+
) -> int | float:
|
358
|
+
"""Compute the number of milliseconds in a datetime duration."""
|
359
|
+
timedelta = datetime_duration_to_timedelta(duration)
|
360
|
+
microseconds = datetime_duration_to_microseconds(timedelta)
|
361
|
+
milliseconds, remainder = divmod(microseconds, _MICROSECONDS_PER_MILLISECOND)
|
362
|
+
match remainder, strict:
|
363
|
+
case 0, _:
|
364
|
+
return milliseconds
|
365
|
+
case _, True:
|
366
|
+
raise TimedeltaToMillisecondsError(duration=duration, remainder=remainder)
|
367
|
+
case _, False:
|
368
|
+
return milliseconds + remainder / _MICROSECONDS_PER_MILLISECOND
|
369
|
+
case _ as never:
|
370
|
+
assert_never(never)
|
371
|
+
|
372
|
+
|
373
|
+
@dataclass(kw_only=True, slots=True)
|
374
|
+
class TimedeltaToMillisecondsError(Exception):
|
375
|
+
duration: Duration
|
376
|
+
remainder: int
|
377
|
+
|
378
|
+
@override
|
379
|
+
def __str__(self) -> str:
|
380
|
+
return f"Unable to convert {self.duration} to milliseconds; got {self.remainder} microsecond(s)"
|
381
|
+
|
382
|
+
|
337
383
|
def datetime_duration_to_timedelta(duration: Duration, /) -> dt.timedelta:
|
338
384
|
"""Ensure a datetime duration is a timedelta."""
|
339
385
|
match duration:
|
@@ -651,8 +697,9 @@ YEAR = get_years(n=1)
|
|
651
697
|
##
|
652
698
|
|
653
699
|
|
654
|
-
def is_integral_timedelta(
|
655
|
-
"""Check if a
|
700
|
+
def is_integral_timedelta(duration: Duration, /) -> bool:
|
701
|
+
"""Check if a duration is integral."""
|
702
|
+
timedelta = datetime_duration_to_timedelta(duration)
|
656
703
|
return (timedelta.seconds == 0) and (timedelta.microseconds == 0)
|
657
704
|
|
658
705
|
|
@@ -679,9 +726,9 @@ def is_weekday(date: dt.date, /) -> bool:
|
|
679
726
|
##
|
680
727
|
|
681
728
|
|
682
|
-
def is_zero_time(
|
729
|
+
def is_zero_time(duration: Duration, /) -> bool:
|
683
730
|
"""Check if a timedelta is 0."""
|
684
|
-
return
|
731
|
+
return datetime_duration_to_timedelta(duration) == ZERO_TIME
|
685
732
|
|
686
733
|
|
687
734
|
##
|
@@ -763,7 +810,7 @@ def mean_timedelta(
|
|
763
810
|
case 1:
|
764
811
|
return one(timedeltas)
|
765
812
|
case _:
|
766
|
-
microseconds = list(map(
|
813
|
+
microseconds = list(map(datetime_duration_to_microseconds, timedeltas))
|
767
814
|
mean_float = fmean(microseconds, weights=weights)
|
768
815
|
mean_int = round_(mean_float, mode=mode, rel_tol=rel_tol, abs_tol=abs_tol)
|
769
816
|
return microseconds_to_timedelta(mean_int)
|
@@ -781,7 +828,7 @@ class MeanTimeDeltaError(Exception):
|
|
781
828
|
|
782
829
|
def microseconds_since_epoch(datetime: dt.datetime, /) -> int:
|
783
830
|
"""Compute the number of microseconds since the epoch."""
|
784
|
-
return
|
831
|
+
return datetime_duration_to_microseconds(timedelta_since_epoch(datetime))
|
785
832
|
|
786
833
|
|
787
834
|
def microseconds_to_timedelta(microseconds: int, /) -> dt.timedelta:
|
@@ -980,7 +1027,7 @@ class _ParseTwoDigitYearInvalidStringError(Exception):
|
|
980
1027
|
|
981
1028
|
def round_datetime(
|
982
1029
|
datetime: dt.datetime,
|
983
|
-
|
1030
|
+
duration: Duration,
|
984
1031
|
/,
|
985
1032
|
*,
|
986
1033
|
mode: RoundMode = "standard",
|
@@ -990,7 +1037,7 @@ def round_datetime(
|
|
990
1037
|
"""Round a datetime to a timedelta."""
|
991
1038
|
if datetime.tzinfo is None:
|
992
1039
|
dividend = microseconds_since_epoch(datetime)
|
993
|
-
divisor =
|
1040
|
+
divisor = datetime_duration_to_microseconds(duration)
|
994
1041
|
quotient, remainder = divmod(dividend, divisor)
|
995
1042
|
rnd_remainder = round_(
|
996
1043
|
remainder / divisor, mode=mode, rel_tol=rel_tol, abs_tol=abs_tol
|
@@ -1000,7 +1047,7 @@ def round_datetime(
|
|
1000
1047
|
return microseconds_since_epoch_to_datetime(microseconds)
|
1001
1048
|
local = datetime.replace(tzinfo=None)
|
1002
1049
|
rounded = round_datetime(
|
1003
|
-
local,
|
1050
|
+
local, duration, mode=mode, rel_tol=rel_tol, abs_tol=abs_tol
|
1004
1051
|
)
|
1005
1052
|
return rounded.replace(tzinfo=datetime.tzinfo)
|
1006
1053
|
|
@@ -1175,50 +1222,6 @@ def timedelta_since_epoch(date_or_datetime: DateOrDateTime, /) -> dt.timedelta:
|
|
1175
1222
|
assert_never(never)
|
1176
1223
|
|
1177
1224
|
|
1178
|
-
def timedelta_to_microseconds(timedelta: dt.timedelta, /) -> int:
|
1179
|
-
"""Compute the number of microseconds in a timedelta."""
|
1180
|
-
return (
|
1181
|
-
_MICROSECONDS_PER_DAY * timedelta.days
|
1182
|
-
+ _MICROSECONDS_PER_SECOND * timedelta.seconds
|
1183
|
-
+ timedelta.microseconds
|
1184
|
-
)
|
1185
|
-
|
1186
|
-
|
1187
|
-
@overload
|
1188
|
-
def timedelta_to_milliseconds(
|
1189
|
-
timedelta: dt.timedelta, /, *, strict: Literal[True]
|
1190
|
-
) -> int: ...
|
1191
|
-
@overload
|
1192
|
-
def timedelta_to_milliseconds(
|
1193
|
-
timedelta: dt.timedelta, /, *, strict: bool = False
|
1194
|
-
) -> float: ...
|
1195
|
-
def timedelta_to_milliseconds(
|
1196
|
-
timedelta: dt.timedelta, /, *, strict: bool = False
|
1197
|
-
) -> int | float:
|
1198
|
-
"""Compute the number of milliseconds in a timedelta."""
|
1199
|
-
microseconds = timedelta_to_microseconds(timedelta)
|
1200
|
-
milliseconds, remainder = divmod(microseconds, _MICROSECONDS_PER_MILLISECOND)
|
1201
|
-
match remainder, strict:
|
1202
|
-
case 0, _:
|
1203
|
-
return milliseconds
|
1204
|
-
case _, True:
|
1205
|
-
raise TimedeltaToMillisecondsError(timedelta=timedelta, remainder=remainder)
|
1206
|
-
case _, False:
|
1207
|
-
return milliseconds + remainder / _MICROSECONDS_PER_MILLISECOND
|
1208
|
-
case _ as never:
|
1209
|
-
assert_never(never)
|
1210
|
-
|
1211
|
-
|
1212
|
-
@dataclass(kw_only=True, slots=True)
|
1213
|
-
class TimedeltaToMillisecondsError(Exception):
|
1214
|
-
timedelta: dt.timedelta
|
1215
|
-
remainder: int
|
1216
|
-
|
1217
|
-
@override
|
1218
|
-
def __str__(self) -> str:
|
1219
|
-
return f"Unable to convert {self.timedelta} to milliseconds; got {self.remainder} microsecond(s)"
|
1220
|
-
|
1221
|
-
|
1222
1225
|
##
|
1223
1226
|
|
1224
1227
|
|
@@ -1367,6 +1370,8 @@ __all__ = [
|
|
1367
1370
|
"date_to_datetime",
|
1368
1371
|
"date_to_month",
|
1369
1372
|
"datetime_duration_to_float",
|
1373
|
+
"datetime_duration_to_microseconds",
|
1374
|
+
"datetime_duration_to_milliseconds",
|
1370
1375
|
"datetime_duration_to_timedelta",
|
1371
1376
|
"datetime_utc",
|
1372
1377
|
"days_since_epoch",
|
@@ -1407,8 +1412,6 @@ __all__ = [
|
|
1407
1412
|
"serialize_month",
|
1408
1413
|
"sub_duration",
|
1409
1414
|
"timedelta_since_epoch",
|
1410
|
-
"timedelta_to_microseconds",
|
1411
|
-
"timedelta_to_milliseconds",
|
1412
1415
|
"yield_days",
|
1413
1416
|
"yield_weekdays",
|
1414
1417
|
]
|
@@ -14,8 +14,8 @@ from utilities.datetime import (
|
|
14
14
|
_MICROSECONDS_PER_SECOND,
|
15
15
|
ZERO_TIME,
|
16
16
|
check_date_not_datetime,
|
17
|
+
datetime_duration_to_microseconds,
|
17
18
|
parse_two_digit_year,
|
18
|
-
timedelta_to_microseconds,
|
19
19
|
)
|
20
20
|
from utilities.math import ParseNumberError, parse_number
|
21
21
|
from utilities.re import (
|
@@ -601,7 +601,7 @@ class SerializeZonedDateTimeError(Exception):
|
|
601
601
|
|
602
602
|
def _to_datetime_delta(timedelta: dt.timedelta, /) -> DateTimeDelta:
|
603
603
|
"""Serialize a timedelta."""
|
604
|
-
total_microseconds =
|
604
|
+
total_microseconds = datetime_duration_to_microseconds(timedelta)
|
605
605
|
if total_microseconds == 0:
|
606
606
|
return DateTimeDelta()
|
607
607
|
if total_microseconds >= 1:
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/modules/package_missing/__init__.py
RENAMED
File without changes
|
{dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/modules/package_missing/module.py
RENAMED
File without changes
|
{dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/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.116.6 → dycw_utilities-0.117.0}/src/tests/modules/package_without/__init__.py
RENAMED
File without changes
|
{dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/modules/package_without/module_1.py
RENAMED
File without changes
|
{dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/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.116.6 → dycw_utilities-0.117.0}/src/tests/scripts/test_async_service/__init__.py
RENAMED
File without changes
|
{dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/scripts/test_async_service/__main__.py
RENAMED
File without changes
|
{dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/scripts/test_async_service/run.sh
RENAMED
File without changes
|
{dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/scripts/test_queue_processor/__init__.py
RENAMED
File without changes
|
{dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/src/tests/scripts/test_queue_processor/__main__.py
RENAMED
File without changes
|
{dycw_utilities-0.116.6 → dycw_utilities-0.117.0}/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
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|