dycw-utilities 0.136.9__tar.gz → 0.137.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.136.9 → dycw_utilities-0.137.0}/PKG-INFO +2 -2
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/pyproject.toml +5 -5
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_logging.py +10 -6
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_period.py +136 -9
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_sqlalchemy.py +2 -3
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_whenever.py +37 -3
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/utilities/__init__.py +1 -1
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/utilities/fpdf2.py +2 -2
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/utilities/logging.py +9 -4
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/utilities/period.py +45 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/utilities/pyinstrument.py +2 -2
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/utilities/traceback.py +11 -3
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/utilities/whenever.py +29 -4
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/.gitignore +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/LICENSE +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/README.md +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/__init__.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/conftest.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/modules/__init__.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/modules/package_missing/__init__.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/modules/package_missing/module.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/modules/package_with/__init__.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/modules/package_with/outer_1.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/modules/package_with/outer_2.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/modules/package_with/subpackage/__init__.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/modules/package_with/subpackage/inner_1.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/modules/package_with/subpackage/inner_2.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/modules/package_with/subpackage/inner_3.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/modules/package_without/__init__.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/modules/package_without/module_1.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/modules/package_without/module_2.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/modules/standalone.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/modules/with_imports.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/regressions/test_pytest_regressions/TestMultipleRegressionFixtures__test_main__obj.json +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/regressions/test_pytest_regressions/TestMultipleRegressionFixtures__test_main__series.json +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_int.json +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_literal__false.json +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_literal__true.json +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_nested.json +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/regressions/test_pytest_regressions/TestPolarsRegressionFixture__test_dataframe.json +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/regressions/test_pytest_regressions/TestPolarsRegressionFixture__test_series.json +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_aiolimiter.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_altair.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_asyncio.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_asyncio_classes/__init__.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_asyncio_classes/loopers.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_asyncio_classes/redis.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_atomicwrites.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_atools.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_cachetools.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_click.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_concurrent.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_contextlib.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_contextvars.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_cryptography.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_cvxpy.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_dataclasses.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_enum.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_errors.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_eventkit.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_fastapi.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_fpdf2.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_functions.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_functools.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_getpass.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_git.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_hashlib.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_http.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_hypothesis.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_importlib.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_inflect.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_ipython.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_iterables.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_jupyter.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_libcst.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_lightweight_charts.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_luigi.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_math.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_memory_profiler.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_modules.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_more_itertools.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_numpy.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_objects/__init__.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_objects/objects.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_operator.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_optuna.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_orjson.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_os.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_parse.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_pathlib.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_pickle.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_platform.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_polars.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_polars_ols.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_pottery.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_pqdm.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_psutil.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_pydantic.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_pyinstrument.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_pytest.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_pytest_regressions.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_python_dotenv.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_random.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_re.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_redis.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_reprlib.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_scipy.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_sentinel.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_shelve.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_slack_sdk.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_socket.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_sqlalchemy_polars.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_statsmodels.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_streamlit.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_string.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_tempfile.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_text.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_threading.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_timer.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_traceback.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_typed_settings.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_types.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_typing.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_typing_funcs/__init__.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_typing_funcs/no_future.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_typing_funcs/with_future.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_tzdata.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_tzlocal.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_uuid.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_version.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_warnings.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_zipfile.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/test_zoneinfo.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/utilities/aiolimiter.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/utilities/altair.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/utilities/asyncio.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/utilities/atomicwrites.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/utilities/atools.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/utilities/cachetools.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/utilities/click.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/utilities/concurrent.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/utilities/contextlib.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/utilities/contextvars.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/utilities/cryptography.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/utilities/cvxpy.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/utilities/dataclasses.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/utilities/enum.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/utilities/errors.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/utilities/eventkit.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/utilities/fastapi.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/utilities/functions.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/utilities/functools.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/utilities/getpass.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/utilities/git.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/utilities/hashlib.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/utilities/http.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/utilities/hypothesis.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/utilities/importlib.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/utilities/inflect.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/utilities/ipython.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/utilities/iterables.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/utilities/jupyter.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/utilities/libcst.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/utilities/lightweight_charts.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/utilities/luigi.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/utilities/math.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/utilities/memory_profiler.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/utilities/modules.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/utilities/more_itertools.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/utilities/numpy.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/utilities/operator.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/utilities/optuna.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/utilities/orjson.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/utilities/os.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/utilities/parse.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/utilities/pathlib.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/utilities/pickle.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/utilities/platform.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/utilities/polars.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/utilities/polars_ols.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/utilities/pottery.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/utilities/pqdm.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/utilities/psutil.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/utilities/py.typed +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/utilities/pydantic.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/utilities/pytest.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/utilities/pytest_regressions.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/utilities/python_dotenv.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/utilities/random.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/utilities/re.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/utilities/redis.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/utilities/reprlib.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/utilities/scipy.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/utilities/sentinel.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/utilities/shelve.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/utilities/slack_sdk.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/utilities/socket.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/utilities/sqlalchemy.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/utilities/sqlalchemy_polars.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/utilities/statsmodels.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/utilities/streamlit.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/utilities/string.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/utilities/tempfile.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/utilities/text.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/utilities/threading.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/utilities/timer.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/utilities/typed_settings.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/utilities/types.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/utilities/typing.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/utilities/tzdata.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/utilities/tzlocal.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/utilities/uuid.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/utilities/version.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/utilities/warnings.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/utilities/zipfile.py +0 -0
- {dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/utilities/zoneinfo.py +0 -0
@@ -1,13 +1,13 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: dycw-utilities
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.137.0
|
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: atomicwrites<1.5,>=1.4.1
|
8
8
|
Requires-Dist: typing-extensions<4.15,>=4.14.0
|
9
9
|
Requires-Dist: tzlocal<5.4,>=5.3.1
|
10
|
-
Requires-Dist: whenever<0.9,>=0.8.
|
10
|
+
Requires-Dist: whenever<0.9,>=0.8.6
|
11
11
|
Provides-Extra: logging
|
12
12
|
Requires-Dist: coloredlogs<15.1,>=15.0.1; extra == 'logging'
|
13
13
|
Provides-Extra: test
|
@@ -21,7 +21,7 @@ core = [
|
|
21
21
|
"atomicwrites >= 1.4.1, < 1.5",
|
22
22
|
"typing-extensions >= 4.14.0, < 4.15",
|
23
23
|
"tzlocal >= 5.3.1, < 5.4",
|
24
|
-
"whenever >= 0.8.
|
24
|
+
"whenever >= 0.8.6, < 0.9",
|
25
25
|
]
|
26
26
|
cryptography = ["cryptography >= 45.0.4, < 45.1"]
|
27
27
|
cvxpy = ["cvxpy >= 1.6.5, < 1.7"]
|
@@ -76,7 +76,7 @@ pytest = [
|
|
76
76
|
pytest-regressions = ["pytest-regressions >= 2.8.0, < 2.9"]
|
77
77
|
pytest-regressions-test = ["orjson", "polars-lts-cpu"]
|
78
78
|
pytest-test = ["orjson", "pytest-rng", "pytest-rerunfailures"]
|
79
|
-
python-dotenv = ["python-dotenv >= 1.1.
|
79
|
+
python-dotenv = ["python-dotenv >= 1.1.1, < 1.2"]
|
80
80
|
redis = ["redis >= 6.2.0, < 6.3", "orjson"]
|
81
81
|
redis-test = ["pytest-rerunfailures"]
|
82
82
|
reprlib-test = ["rich"]
|
@@ -100,12 +100,12 @@ dependencies = [
|
|
100
100
|
"atomicwrites >= 1.4.1, < 1.5",
|
101
101
|
"typing-extensions >= 4.14.0, < 4.15",
|
102
102
|
"tzlocal >= 5.3.1, < 5.4",
|
103
|
-
"whenever >= 0.8.
|
103
|
+
"whenever >= 0.8.6, < 0.9",
|
104
104
|
]
|
105
105
|
name = "dycw-utilities"
|
106
106
|
readme = "README.md"
|
107
107
|
requires-python = ">= 3.12"
|
108
|
-
version = "0.
|
108
|
+
version = "0.137.0"
|
109
109
|
|
110
110
|
[project.optional-dependencies]
|
111
111
|
logging = [
|
@@ -133,7 +133,7 @@ test = [
|
|
133
133
|
# bump-my-version
|
134
134
|
[tool.bumpversion]
|
135
135
|
allow_dirty = true
|
136
|
-
current_version = "0.
|
136
|
+
current_version = "0.137.0"
|
137
137
|
|
138
138
|
[[tool.bumpversion.files]]
|
139
139
|
filename = "src/utilities/__init__.py"
|
@@ -38,7 +38,7 @@ from utilities.logging import (
|
|
38
38
|
from utilities.text import unique_str
|
39
39
|
from utilities.types import LogLevel
|
40
40
|
from utilities.typing import get_args
|
41
|
-
from utilities.whenever import format_compact, get_now
|
41
|
+
from utilities.whenever import format_compact, get_now, to_local_plain
|
42
42
|
|
43
43
|
if TYPE_CHECKING:
|
44
44
|
from collections.abc import Mapping
|
@@ -192,7 +192,7 @@ class TestComputeRolloverActions:
|
|
192
192
|
|
193
193
|
await sleep(1)
|
194
194
|
tmp_path.joinpath("log.txt").touch()
|
195
|
-
now = format_compact(get_now())
|
195
|
+
now = format_compact(to_local_plain(get_now()))
|
196
196
|
tmp_path.joinpath(f"log.99__{now}__{now}.txt").touch()
|
197
197
|
actions = _compute_rollover_actions(tmp_path, "log", ".txt")
|
198
198
|
assert len(actions.deletions) == 2
|
@@ -319,7 +319,7 @@ class TestRotatingLogFile:
|
|
319
319
|
def test_from_path_with_index_and_end(
|
320
320
|
self, *, index: int, end: ZonedDateTime
|
321
321
|
) -> None:
|
322
|
-
path = Path(f"log.{index}__{format_compact(end)}.txt")
|
322
|
+
path = Path(f"log.{index}__{format_compact(to_local_plain(end))}.txt")
|
323
323
|
result = _RotatingLogFile.from_path(path, "log", ".txt")
|
324
324
|
assert result is not None
|
325
325
|
assert result.stem == "log"
|
@@ -333,7 +333,9 @@ class TestRotatingLogFile:
|
|
333
333
|
self, *, index: int, datetimes: tuple[ZonedDateTime, ZonedDateTime]
|
334
334
|
) -> None:
|
335
335
|
start, end = datetimes
|
336
|
-
path = Path(
|
336
|
+
path = Path(
|
337
|
+
f"log.{index}__{format_compact(to_local_plain(start))}__{format_compact(to_local_plain(end))}.txt"
|
338
|
+
)
|
337
339
|
result = _RotatingLogFile.from_path(path, "log", ".txt")
|
338
340
|
assert result is not None
|
339
341
|
assert result.stem == "log"
|
@@ -363,7 +365,9 @@ class TestRotatingLogFile:
|
|
363
365
|
file = _RotatingLogFile(
|
364
366
|
directory=root, stem="log", suffix=".txt", index=index, end=end
|
365
367
|
)
|
366
|
-
assert file.path == root.joinpath(
|
368
|
+
assert file.path == root.joinpath(
|
369
|
+
f"log.{index}__{format_compact(to_local_plain(end))}.txt"
|
370
|
+
)
|
367
371
|
|
368
372
|
@given(
|
369
373
|
root=temp_paths(),
|
@@ -378,7 +382,7 @@ class TestRotatingLogFile:
|
|
378
382
|
directory=root, stem="log", suffix=".txt", index=index, start=start, end=end
|
379
383
|
)
|
380
384
|
assert file.path == root.joinpath(
|
381
|
-
f"log.{index}__{format_compact(start)}__{format_compact(end)}.txt"
|
385
|
+
f"log.{index}__{format_compact(to_local_plain(start))}__{format_compact(to_local_plain(end))}.txt"
|
382
386
|
)
|
383
387
|
|
384
388
|
|
@@ -4,8 +4,9 @@ from re import search
|
|
4
4
|
from typing import TYPE_CHECKING
|
5
5
|
|
6
6
|
from hypothesis import HealthCheck, given, settings
|
7
|
-
from hypothesis.strategies import DataObject, data
|
8
|
-
from pytest import raises
|
7
|
+
from hypothesis.strategies import DataObject, data
|
8
|
+
from pytest import mark, param, raises
|
9
|
+
from whenever import Date, ZonedDateTime
|
9
10
|
|
10
11
|
from utilities.hypothesis import (
|
11
12
|
assume_does_not_raise,
|
@@ -30,7 +31,7 @@ from utilities.zoneinfo import UTC, get_time_zone_name
|
|
30
31
|
if TYPE_CHECKING:
|
31
32
|
from collections.abc import Callable
|
32
33
|
|
33
|
-
from whenever import
|
34
|
+
from whenever import DateDelta, PlainDateTime, TimeDelta
|
34
35
|
|
35
36
|
|
36
37
|
class TestDatePeriod:
|
@@ -58,13 +59,30 @@ class TestDatePeriod:
|
|
58
59
|
period = DatePeriod(start, end)
|
59
60
|
assert period.delta == (end - start)
|
60
61
|
|
62
|
+
@mark.parametrize(
|
63
|
+
("end", "expected"),
|
64
|
+
[
|
65
|
+
param(Date(2000, 1, 1), "20000101="),
|
66
|
+
param(Date(2000, 1, 2), "20000101-02"),
|
67
|
+
param(Date(2000, 1, 31), "20000101-31"),
|
68
|
+
param(Date(2000, 2, 1), "20000101-0201"),
|
69
|
+
param(Date(2000, 2, 29), "20000101-0229"),
|
70
|
+
param(Date(2000, 12, 31), "20000101-1231"),
|
71
|
+
param(Date(2001, 1, 1), "20000101-20010101"),
|
72
|
+
],
|
73
|
+
)
|
74
|
+
def test_format_compact(self, *, end: Date, expected: str) -> None:
|
75
|
+
period = DatePeriod(Date(2000, 1, 1), end)
|
76
|
+
assert period.format_compact() == expected
|
77
|
+
|
61
78
|
@given(dates=pairs(dates(), sorted=True))
|
62
79
|
def test_hashable(self, *, dates: tuple[Date, Date]) -> None:
|
63
80
|
start, end = dates
|
64
81
|
period = DatePeriod(start, end)
|
65
82
|
_ = hash(period)
|
66
83
|
|
67
|
-
@given(dates=pairs(dates(), sorted=True)
|
84
|
+
@given(dates=pairs(dates(), sorted=True))
|
85
|
+
@mark.parametrize("func", [param(repr), param(str)])
|
68
86
|
def test_repr(self, *, dates: tuple[Date, Date], func: Callable[..., str]) -> None:
|
69
87
|
start, end = dates
|
70
88
|
period = DatePeriod(start, end)
|
@@ -145,17 +163,126 @@ class TestZonedDateTimePeriod:
|
|
145
163
|
period = ZonedDateTimePeriod(start, end)
|
146
164
|
assert period.delta == (end - start)
|
147
165
|
|
166
|
+
@mark.parametrize(
|
167
|
+
("end", "expected"),
|
168
|
+
[
|
169
|
+
param(
|
170
|
+
ZonedDateTime(2000, 1, 1, 10, 20, 30, tz=UTC.key),
|
171
|
+
"20000101T102030[UTC]=",
|
172
|
+
),
|
173
|
+
param(
|
174
|
+
ZonedDateTime(2000, 1, 1, 10, 20, 31, tz=UTC.key),
|
175
|
+
"20000101T102030-102031[UTC]",
|
176
|
+
),
|
177
|
+
param(
|
178
|
+
ZonedDateTime(2000, 1, 1, 10, 20, 59, tz=UTC.key),
|
179
|
+
"20000101T102030-102059[UTC]",
|
180
|
+
),
|
181
|
+
param(
|
182
|
+
ZonedDateTime(2000, 1, 1, 10, 21, tz=UTC.key),
|
183
|
+
"20000101T102030-1021[UTC]",
|
184
|
+
),
|
185
|
+
param(
|
186
|
+
ZonedDateTime(2000, 1, 1, 10, 21, 1, tz=UTC.key),
|
187
|
+
"20000101T102030-102101[UTC]",
|
188
|
+
),
|
189
|
+
param(
|
190
|
+
ZonedDateTime(2000, 1, 1, 10, 59, 59, tz=UTC.key),
|
191
|
+
"20000101T102030-105959[UTC]",
|
192
|
+
),
|
193
|
+
param(ZonedDateTime(2000, 1, 1, 11, tz=UTC.key), "20000101T102030-11[UTC]"),
|
194
|
+
param(
|
195
|
+
ZonedDateTime(2000, 1, 1, 11, 0, 1, tz=UTC.key),
|
196
|
+
"20000101T102030-110001[UTC]",
|
197
|
+
),
|
198
|
+
param(
|
199
|
+
ZonedDateTime(2000, 1, 1, 23, 59, 59, tz=UTC.key),
|
200
|
+
"20000101T102030-235959[UTC]",
|
201
|
+
),
|
202
|
+
param(ZonedDateTime(2000, 1, 2, tz=UTC.key), "20000101T102030-02T00[UTC]"),
|
203
|
+
param(
|
204
|
+
ZonedDateTime(2000, 1, 2, 0, 0, 1, tz=UTC.key),
|
205
|
+
"20000101T102030-02T000001[UTC]",
|
206
|
+
),
|
207
|
+
param(
|
208
|
+
ZonedDateTime(2000, 1, 2, 0, 0, 59, tz=UTC.key),
|
209
|
+
"20000101T102030-02T000059[UTC]",
|
210
|
+
),
|
211
|
+
param(
|
212
|
+
ZonedDateTime(2000, 1, 2, 0, 1, tz=UTC.key),
|
213
|
+
"20000101T102030-02T0001[UTC]",
|
214
|
+
),
|
215
|
+
param(
|
216
|
+
ZonedDateTime(2000, 1, 31, 23, 59, 59, tz=UTC.key),
|
217
|
+
"20000101T102030-31T235959[UTC]",
|
218
|
+
),
|
219
|
+
param(
|
220
|
+
ZonedDateTime(2000, 2, 1, tz=UTC.key), "20000101T102030-0201T00[UTC]"
|
221
|
+
),
|
222
|
+
param(
|
223
|
+
ZonedDateTime(2000, 2, 1, 0, 0, 1, tz=UTC.key),
|
224
|
+
"20000101T102030-0201T000001[UTC]",
|
225
|
+
),
|
226
|
+
param(
|
227
|
+
ZonedDateTime(2000, 2, 1, 0, 0, 59, tz=UTC.key),
|
228
|
+
"20000101T102030-0201T000059[UTC]",
|
229
|
+
),
|
230
|
+
param(
|
231
|
+
ZonedDateTime(2000, 2, 1, 0, 1, tz=UTC.key),
|
232
|
+
"20000101T102030-0201T0001[UTC]",
|
233
|
+
),
|
234
|
+
param(
|
235
|
+
ZonedDateTime(2000, 12, 31, 23, 59, 59, tz=UTC.key),
|
236
|
+
"20000101T102030-1231T235959[UTC]",
|
237
|
+
),
|
238
|
+
param(
|
239
|
+
ZonedDateTime(2001, 1, 1, tz=UTC.key),
|
240
|
+
"20000101T102030-20010101T00[UTC]",
|
241
|
+
),
|
242
|
+
param(
|
243
|
+
ZonedDateTime(2001, 1, 1, 0, 0, 1, tz=UTC.key),
|
244
|
+
"20000101T102030-20010101T000001[UTC]",
|
245
|
+
),
|
246
|
+
param(
|
247
|
+
ZonedDateTime(2001, 1, 1, 0, 0, 59, tz=UTC.key),
|
248
|
+
"20000101T102030-20010101T000059[UTC]",
|
249
|
+
),
|
250
|
+
param(
|
251
|
+
ZonedDateTime(2001, 1, 1, 0, 1, tz=UTC.key),
|
252
|
+
"20000101T102030-20010101T0001[UTC]",
|
253
|
+
),
|
254
|
+
],
|
255
|
+
)
|
256
|
+
def test_format_compact(self, *, end: ZonedDateTime, expected: str) -> None:
|
257
|
+
start = ZonedDateTime(2000, 1, 1, 10, 20, 30, tz=UTC.key)
|
258
|
+
period = ZonedDateTimePeriod(start, end)
|
259
|
+
assert period.format_compact() == expected
|
260
|
+
|
261
|
+
@mark.parametrize(
|
262
|
+
("datetime", "expected"),
|
263
|
+
[
|
264
|
+
param(
|
265
|
+
ZonedDateTime(2000, 1, 1, 10, 20, 30, tz=UTC.key),
|
266
|
+
"20000101T102030[UTC]=",
|
267
|
+
),
|
268
|
+
param(ZonedDateTime(2000, 1, 1, 10, 20, tz=UTC.key), "20000101T1020[UTC]="),
|
269
|
+
param(ZonedDateTime(2000, 1, 1, 10, tz=UTC.key), "20000101T10[UTC]="),
|
270
|
+
],
|
271
|
+
)
|
272
|
+
def test_format_compact_extra(
|
273
|
+
self, *, datetime: ZonedDateTime, expected: str
|
274
|
+
) -> None:
|
275
|
+
period = ZonedDateTimePeriod(datetime, datetime)
|
276
|
+
assert period.format_compact() == expected
|
277
|
+
|
148
278
|
@given(datetimes=pairs(zoned_datetimes(), sorted=True))
|
149
279
|
def test_hashable(self, *, datetimes: tuple[ZonedDateTime, ZonedDateTime]) -> None:
|
150
280
|
start, end = datetimes
|
151
281
|
period = ZonedDateTimePeriod(start, end)
|
152
282
|
_ = hash(period)
|
153
283
|
|
154
|
-
@given(
|
155
|
-
|
156
|
-
datetimes=pairs(zoned_datetimes(), sorted=True),
|
157
|
-
func=sampled_from([repr, str]),
|
158
|
-
)
|
284
|
+
@given(data=data(), datetimes=pairs(zoned_datetimes(), sorted=True))
|
285
|
+
@mark.parametrize("func", [param(repr), param(str)])
|
159
286
|
def test_repr(
|
160
287
|
self,
|
161
288
|
*,
|
@@ -89,7 +89,7 @@ from utilities.sqlalchemy import (
|
|
89
89
|
)
|
90
90
|
from utilities.text import strip_and_dedent
|
91
91
|
from utilities.typing import get_args, get_literal_elements
|
92
|
-
from utilities.whenever import SECOND, format_compact, get_now
|
92
|
+
from utilities.whenever import SECOND, format_compact, get_now, to_local_plain
|
93
93
|
|
94
94
|
if TYPE_CHECKING:
|
95
95
|
from collections.abc import Callable, Iterator
|
@@ -102,9 +102,8 @@ if TYPE_CHECKING:
|
|
102
102
|
|
103
103
|
def _table_names() -> str:
|
104
104
|
"""Generate at unique string."""
|
105
|
-
now = get_now()
|
106
105
|
key = str(uuid4()).replace("-", "")
|
107
|
-
return f"{format_compact(
|
106
|
+
return f"{format_compact(to_local_plain(get_now()))}_{key}"
|
108
107
|
|
109
108
|
|
110
109
|
@overload
|
@@ -20,6 +20,7 @@ from whenever import (
|
|
20
20
|
DateDelta,
|
21
21
|
DateTimeDelta,
|
22
22
|
PlainDateTime,
|
23
|
+
Time,
|
23
24
|
TimeDelta,
|
24
25
|
TimeZoneNotFoundError,
|
25
26
|
ZonedDateTime,
|
@@ -33,7 +34,9 @@ from utilities.hypothesis import (
|
|
33
34
|
freqs,
|
34
35
|
months,
|
35
36
|
pairs,
|
37
|
+
plain_datetimes,
|
36
38
|
sentinels,
|
39
|
+
times,
|
37
40
|
zoned_datetimes,
|
38
41
|
)
|
39
42
|
from utilities.sentinel import Sentinel, sentinel
|
@@ -96,6 +99,7 @@ from utilities.whenever import (
|
|
96
99
|
to_date,
|
97
100
|
to_date_time_delta,
|
98
101
|
to_days,
|
102
|
+
to_local_plain,
|
99
103
|
to_nanos,
|
100
104
|
to_time_delta,
|
101
105
|
to_zoned_date_time,
|
@@ -125,13 +129,36 @@ class TestDatetimeUTC:
|
|
125
129
|
|
126
130
|
|
127
131
|
class TestFormatCompact:
|
128
|
-
@given(
|
129
|
-
def
|
132
|
+
@given(date=dates())
|
133
|
+
def test_date(self, *, date: Date) -> None:
|
134
|
+
result = format_compact(date)
|
135
|
+
assert isinstance(result, str)
|
136
|
+
parsed = Date.parse_common_iso(result)
|
137
|
+
assert parsed == date
|
138
|
+
|
139
|
+
@given(time=times())
|
140
|
+
def test_time(self, *, time: Time) -> None:
|
141
|
+
result = format_compact(time)
|
142
|
+
assert isinstance(result, str)
|
143
|
+
parsed = Time.parse_common_iso(result)
|
144
|
+
assert parsed == time
|
145
|
+
|
146
|
+
@given(datetime=plain_datetimes())
|
147
|
+
def test_plain_datetime(self, *, datetime: PlainDateTime) -> None:
|
130
148
|
result = format_compact(datetime)
|
131
149
|
assert isinstance(result, str)
|
132
150
|
parsed = PlainDateTime.parse_common_iso(result)
|
133
151
|
assert parsed.nanosecond == 0
|
134
|
-
expected = datetime.round()
|
152
|
+
expected = datetime.round()
|
153
|
+
assert parsed == expected
|
154
|
+
|
155
|
+
@given(datetime=zoned_datetimes())
|
156
|
+
def test_zoned_datetime(self, *, datetime: ZonedDateTime) -> None:
|
157
|
+
result = format_compact(datetime)
|
158
|
+
assert isinstance(result, str)
|
159
|
+
parsed = ZonedDateTime.parse_common_iso(result)
|
160
|
+
assert parsed.nanosecond == 0
|
161
|
+
expected = datetime.round()
|
135
162
|
assert parsed == expected
|
136
163
|
|
137
164
|
|
@@ -610,6 +637,13 @@ class TestToDays:
|
|
610
637
|
_ = to_days(delta)
|
611
638
|
|
612
639
|
|
640
|
+
class TestToLocalPlain:
|
641
|
+
@given(date_time=zoned_datetimes())
|
642
|
+
def test_main(self, *, date_time: ZonedDateTime) -> None:
|
643
|
+
result = to_local_plain(date_time)
|
644
|
+
assert isinstance(result, PlainDateTime)
|
645
|
+
|
646
|
+
|
613
647
|
class TestToZonedDateTime:
|
614
648
|
@given(date_time=zoned_datetimes())
|
615
649
|
def test_date_time(self, *, date_time: ZonedDateTime) -> None:
|
@@ -6,7 +6,7 @@ from typing import TYPE_CHECKING, override
|
|
6
6
|
from fpdf import FPDF
|
7
7
|
from fpdf.enums import XPos, YPos
|
8
8
|
|
9
|
-
from utilities.whenever import format_compact, get_now
|
9
|
+
from utilities.whenever import format_compact, get_now, to_local_plain
|
10
10
|
|
11
11
|
if TYPE_CHECKING:
|
12
12
|
from collections.abc import Iterator
|
@@ -47,7 +47,7 @@ def yield_pdf(*, header: str | None = None) -> Iterator[_BasePDF]:
|
|
47
47
|
def footer(self) -> None:
|
48
48
|
self.set_y(-15)
|
49
49
|
self.set_font(family="Helvetica", style="I", size=8)
|
50
|
-
page_no, now = self.page_no(), format_compact(get_now())
|
50
|
+
page_no, now = (self.page_no(), format_compact(to_local_plain(get_now())))
|
51
51
|
text = f"page {page_no}/{{}}; {now}"
|
52
52
|
_ = self.cell(
|
53
53
|
w=0,
|
@@ -45,7 +45,12 @@ from utilities.re import (
|
|
45
45
|
)
|
46
46
|
from utilities.sentinel import Sentinel, sentinel
|
47
47
|
from utilities.tzlocal import LOCAL_TIME_ZONE_NAME
|
48
|
-
from utilities.whenever import
|
48
|
+
from utilities.whenever import (
|
49
|
+
WheneverLogRecord,
|
50
|
+
format_compact,
|
51
|
+
get_now_local,
|
52
|
+
to_local_plain,
|
53
|
+
)
|
49
54
|
|
50
55
|
if TYPE_CHECKING:
|
51
56
|
from collections.abc import Callable, Iterable, Mapping
|
@@ -378,7 +383,7 @@ class SizeAndTimeRotatingFileHandler(BaseRotatingHandler):
|
|
378
383
|
if not self.delay: # pragma: no cover
|
379
384
|
self.stream = self._open()
|
380
385
|
self._time_handler.rolloverAt = ( # skipif-ci-and-windows
|
381
|
-
self._time_handler.computeRollover(
|
386
|
+
self._time_handler.computeRollover(get_now_local().timestamp())
|
382
387
|
)
|
383
388
|
|
384
389
|
def _should_rollover(self, record: LogRecord, /) -> bool:
|
@@ -533,9 +538,9 @@ class _RotatingLogFile:
|
|
533
538
|
case int() as index, None, None:
|
534
539
|
tail = str(index)
|
535
540
|
case int() as index, None, ZonedDateTime() as end:
|
536
|
-
tail = f"{index}__{format_compact(end)}"
|
541
|
+
tail = f"{index}__{format_compact(to_local_plain(end))}"
|
537
542
|
case int() as index, ZonedDateTime() as start, ZonedDateTime() as end:
|
538
|
-
tail = f"{index}__{format_compact(start)}__{format_compact(end)}"
|
543
|
+
tail = f"{index}__{format_compact(to_local_plain(start))}__{format_compact(to_local_plain(end))}"
|
539
544
|
case _: # pragma: no cover
|
540
545
|
raise ImpossibleCaseError(
|
541
546
|
case=[f"{self.index=}", f"{self.start=}", f"{self.end=}"]
|
@@ -9,6 +9,7 @@ from whenever import Date, DateDelta, TimeDelta, ZonedDateTime
|
|
9
9
|
from utilities.dataclasses import replace_non_sentinel
|
10
10
|
from utilities.functions import get_class_name
|
11
11
|
from utilities.sentinel import Sentinel, sentinel
|
12
|
+
from utilities.whenever import format_compact
|
12
13
|
from utilities.zoneinfo import get_time_zone_name
|
13
14
|
|
14
15
|
if TYPE_CHECKING:
|
@@ -53,6 +54,17 @@ class DatePeriod:
|
|
53
54
|
"""The delta of the period."""
|
54
55
|
return self.end - self.start
|
55
56
|
|
57
|
+
def format_compact(self) -> str:
|
58
|
+
"""Format the period in a compact fashion."""
|
59
|
+
fc, start, end = format_compact, self.start, self.end
|
60
|
+
if self.start == self.end:
|
61
|
+
return f"{fc(start)}="
|
62
|
+
if self.start.year_month() == self.end.year_month():
|
63
|
+
return f"{fc(start)}-{fc(end, fmt='%d')}"
|
64
|
+
if self.start.year == self.end.year:
|
65
|
+
return f"{fc(start)}-{fc(end, fmt='%m%d')}"
|
66
|
+
return f"{fc(start)}-{fc(end)}"
|
67
|
+
|
56
68
|
def replace(
|
57
69
|
self, *, start: Date | Sentinel = sentinel, end: Date | Sentinel = sentinel
|
58
70
|
) -> Self:
|
@@ -101,6 +113,39 @@ class ZonedDateTimePeriod:
|
|
101
113
|
"""The duration of the period."""
|
102
114
|
return self.end - self.start
|
103
115
|
|
116
|
+
def format_compact(self) -> str:
|
117
|
+
"""Format the period in a compact fashion."""
|
118
|
+
fc, start, end = format_compact, self.start, self.end
|
119
|
+
if start == end:
|
120
|
+
if end.second != 0:
|
121
|
+
return f"{fc(start)}="
|
122
|
+
if end.minute != 0:
|
123
|
+
return f"{fc(start, fmt='%Y%m%dT%H%M')}="
|
124
|
+
return f"{fc(start, fmt='%Y%m%dT%H')}="
|
125
|
+
if start.date() == end.date():
|
126
|
+
if end.second != 0:
|
127
|
+
return f"{fc(start.to_plain())}-{fc(end, fmt='%H%M%S')}"
|
128
|
+
if end.minute != 0:
|
129
|
+
return f"{fc(start.to_plain())}-{fc(end, fmt='%H%M')}"
|
130
|
+
return f"{fc(start.to_plain())}-{fc(end, fmt='%H')}"
|
131
|
+
if start.date().year_month() == end.date().year_month():
|
132
|
+
if end.second != 0:
|
133
|
+
return f"{fc(start.to_plain())}-{fc(end, fmt='%dT%H%M%S')}"
|
134
|
+
if end.minute != 0:
|
135
|
+
return f"{fc(start.to_plain())}-{fc(end, fmt='%dT%H%M')}"
|
136
|
+
return f"{fc(start.to_plain())}-{fc(end, fmt='%dT%H')}"
|
137
|
+
if start.year == end.year:
|
138
|
+
if end.second != 0:
|
139
|
+
return f"{fc(start.to_plain())}-{fc(end, fmt='%m%dT%H%M%S')}"
|
140
|
+
if end.minute != 0:
|
141
|
+
return f"{fc(start.to_plain())}-{fc(end, fmt='%m%dT%H%M')}"
|
142
|
+
return f"{fc(start.to_plain())}-{fc(end, fmt='%m%dT%H')}"
|
143
|
+
if end.second != 0:
|
144
|
+
return f"{fc(start.to_plain())}-{fc(end)}"
|
145
|
+
if end.minute != 0:
|
146
|
+
return f"{fc(start.to_plain())}-{fc(end, fmt='%Y%m%dT%H%M')}"
|
147
|
+
return f"{fc(start.to_plain())}-{fc(end, fmt='%Y%m%dT%H')}"
|
148
|
+
|
104
149
|
def replace(
|
105
150
|
self,
|
106
151
|
*,
|
@@ -8,7 +8,7 @@ from pyinstrument.profiler import Profiler
|
|
8
8
|
|
9
9
|
from utilities.atomicwrites import writer
|
10
10
|
from utilities.pathlib import get_path
|
11
|
-
from utilities.whenever import format_compact, get_now
|
11
|
+
from utilities.whenever import format_compact, get_now, to_local_plain
|
12
12
|
|
13
13
|
if TYPE_CHECKING:
|
14
14
|
from collections.abc import Iterator
|
@@ -22,7 +22,7 @@ def profile(*, path: MaybeCallablePathLike | None = Path.cwd) -> Iterator[None]:
|
|
22
22
|
with Profiler() as profiler:
|
23
23
|
yield
|
24
24
|
filename = get_path(path=path).joinpath(
|
25
|
-
f"profile__{format_compact(get_now())}.html"
|
25
|
+
f"profile__{format_compact(to_local_plain(get_now()))}.html"
|
26
26
|
)
|
27
27
|
with writer(filename) as temp, temp.open(mode="w") as fh:
|
28
28
|
_ = fh.write(profiler.output_html())
|
@@ -27,7 +27,13 @@ from utilities.reprlib import (
|
|
27
27
|
yield_mapping_repr,
|
28
28
|
)
|
29
29
|
from utilities.version import get_version
|
30
|
-
from utilities.whenever import
|
30
|
+
from utilities.whenever import (
|
31
|
+
format_compact,
|
32
|
+
get_now,
|
33
|
+
get_now_local,
|
34
|
+
to_local_plain,
|
35
|
+
to_zoned_date_time,
|
36
|
+
)
|
31
37
|
|
32
38
|
if TYPE_CHECKING:
|
33
39
|
from collections.abc import Callable, Iterator, Sequence
|
@@ -89,7 +95,7 @@ def _yield_header_lines(
|
|
89
95
|
version: MaybeCallableVersionLike | None = None,
|
90
96
|
) -> Iterator[str]:
|
91
97
|
"""Yield the header lines."""
|
92
|
-
now =
|
98
|
+
now = get_now_local()
|
93
99
|
start_use = to_zoned_date_time(date_time=start)
|
94
100
|
yield f"Date/time | {format_compact(now)}"
|
95
101
|
start_str = "" if start_use is None else format_compact(start_use)
|
@@ -250,7 +256,9 @@ def _make_except_hook_inner(
|
|
250
256
|
_ = sys.stderr.write(f"{slim}\n") # don't 'from sys import stderr'
|
251
257
|
if path is not None:
|
252
258
|
path = (
|
253
|
-
get_path(path=path)
|
259
|
+
get_path(path=path)
|
260
|
+
.joinpath(format_compact(to_local_plain(get_now())))
|
261
|
+
.with_suffix(".txt")
|
254
262
|
)
|
255
263
|
full = format_exception_stack(
|
256
264
|
exc_val,
|
@@ -23,6 +23,7 @@ from whenever import (
|
|
23
23
|
DateDelta,
|
24
24
|
DateTimeDelta,
|
25
25
|
PlainDateTime,
|
26
|
+
Time,
|
26
27
|
TimeDelta,
|
27
28
|
ZonedDateTime,
|
28
29
|
)
|
@@ -160,10 +161,25 @@ def datetime_utc(
|
|
160
161
|
##
|
161
162
|
|
162
163
|
|
163
|
-
def format_compact(
|
164
|
-
|
165
|
-
|
166
|
-
|
164
|
+
def format_compact(
|
165
|
+
obj: Date | Time | PlainDateTime | ZonedDateTime, /, *, fmt: str | None = None
|
166
|
+
) -> str:
|
167
|
+
"""Format the date/datetime in a compact fashion."""
|
168
|
+
match obj:
|
169
|
+
case Date() as date:
|
170
|
+
obj_use = date.py_date()
|
171
|
+
fmt_use = "%Y%m%d" if fmt is None else fmt
|
172
|
+
case Time() as time:
|
173
|
+
obj_use = time.py_time()
|
174
|
+
fmt_use = "%H%M%S" if fmt is None else fmt
|
175
|
+
case PlainDateTime() as datetime:
|
176
|
+
obj_use = datetime.round().py_datetime()
|
177
|
+
fmt_use = "%Y%m%dT%H%M%S" if fmt is None else fmt
|
178
|
+
case ZonedDateTime() as datetime:
|
179
|
+
return f"{format_compact(datetime.to_plain(), fmt=fmt)}[{datetime.tz}]"
|
180
|
+
case _ as never:
|
181
|
+
assert_never(never)
|
182
|
+
return obj_use.strftime(get_strftime(fmt_use))
|
167
183
|
|
168
184
|
|
169
185
|
##
|
@@ -652,6 +668,14 @@ def to_date_time_delta(nanos: int, /) -> DateTimeDelta:
|
|
652
668
|
##
|
653
669
|
|
654
670
|
|
671
|
+
def to_local_plain(date_time: ZonedDateTime, /) -> PlainDateTime:
|
672
|
+
"""Convert a datetime to its local/plain variant."""
|
673
|
+
return date_time.to_tz(LOCAL_TIME_ZONE_NAME).to_plain()
|
674
|
+
|
675
|
+
|
676
|
+
##
|
677
|
+
|
678
|
+
|
655
679
|
def to_nanos(delta: DateTimeDelta, /) -> int:
|
656
680
|
"""Compute the number of nanoseconds in a date-time delta."""
|
657
681
|
months, days, _, _ = delta.in_months_days_secs_nanos()
|
@@ -885,6 +909,7 @@ __all__ = [
|
|
885
909
|
"to_date",
|
886
910
|
"to_date_time_delta",
|
887
911
|
"to_days",
|
912
|
+
"to_local_plain",
|
888
913
|
"to_nanos",
|
889
914
|
"to_zoned_date_time",
|
890
915
|
]
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/modules/package_missing/__init__.py
RENAMED
File without changes
|
{dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/modules/package_missing/module.py
RENAMED
File without changes
|
{dycw_utilities-0.136.9 → dycw_utilities-0.137.0}/src/tests/modules/package_with/__init__.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|