dycw-utilities 0.160.2__tar.gz → 0.161.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/PKG-INFO +1 -1
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/pyproject.toml +2 -2
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/conftest.py +3 -1
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/test_hypothesis.py +22 -11
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/test_polars.py +12 -12
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/test_types.py +2 -3
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/test_whenever.py +51 -47
- dycw_utilities-0.161.1/src/tests/test_zoneinfo.py +131 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/utilities/__init__.py +1 -1
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/utilities/hypothesis.py +20 -4
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/utilities/polars.py +6 -6
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/utilities/types.py +11 -1
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/utilities/whenever.py +21 -33
- dycw_utilities-0.161.1/src/utilities/zoneinfo.py +133 -0
- dycw_utilities-0.160.2/src/tests/test_zoneinfo.py +0 -103
- dycw_utilities-0.160.2/src/utilities/zoneinfo.py +0 -75
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/.gitignore +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/LICENSE +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/README.md +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/__init__.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/modules/__init__.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/modules/package_missing/__init__.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/modules/package_missing/module.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/modules/package_with/__init__.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/modules/package_with/outer_1.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/modules/package_with/outer_2.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/modules/package_with/subpackage/__init__.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/modules/package_with/subpackage/inner_1.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/modules/package_with/subpackage/inner_2.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/modules/package_with/subpackage/inner_3.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/modules/package_without/__init__.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/modules/package_without/module_1.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/modules/package_without/module_2.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/modules/standalone.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/modules/with_imports.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/regressions/test_pytest_regressions/TestMultipleRegressionFixtures__test_main__obj.json +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/regressions/test_pytest_regressions/TestMultipleRegressionFixtures__test_main__series.json +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_int.json +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_literal__false.json +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_literal__true.json +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_nested.json +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/regressions/test_pytest_regressions/TestPolarsRegressionFixture__test_dataframe.json +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/regressions/test_pytest_regressions/TestPolarsRegressionFixture__test_series.json +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/test_altair.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/test_asyncio.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/test_atomicwrites.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/test_atools.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/test_cachetools.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/test_click.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/test_concurrent.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/test_contextlib.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/test_contextvars.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/test_cryptography.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/test_cvxpy.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/test_dataclasses.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/test_enum.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/test_errors.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/test_eventkit.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/test_fastapi.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/test_fpdf2.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/test_functions.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/test_functools.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/test_getpass.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/test_gzip.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/test_hashlib.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/test_http.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/test_importlib.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/test_inflect.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/test_ipython.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/test_iterables.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/test_json.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/test_jupyter.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/test_libcst.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/test_lightweight_charts.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/test_logging.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/test_math.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/test_memory_profiler.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/test_modules.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/test_more_itertools.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/test_numpy.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/test_objects/__init__.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/test_objects/objects.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/test_operator.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/test_optuna.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/test_orjson.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/test_os.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/test_parse.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/test_pathlib.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/test_pickle.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/test_platform.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/test_polars_ols.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/test_postgres.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/test_pottery.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/test_pqdm.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/test_psutil.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/test_pyinstrument.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/test_pytest.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/test_pytest_randomly.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/test_pytest_regressions.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/test_random.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/test_re.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/test_redis.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/test_reprlib.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/test_scipy.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/test_sentinel.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/test_shelve.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/test_slack_sdk.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/test_socket.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/test_sqlalchemy.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/test_sqlalchemy_polars.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/test_statsmodels.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/test_string.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/test_tempfile.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/test_text.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/test_threading.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/test_timer.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/test_traceback.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/test_typed_settings.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/test_typing.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/test_typing_funcs/__init__.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/test_typing_funcs/no_future.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/test_typing_funcs/with_future.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/test_tzdata.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/test_tzlocal.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/test_uuid.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/test_version.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/test_warnings.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/tests/test_zipfile.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/utilities/altair.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/utilities/asyncio.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/utilities/atomicwrites.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/utilities/atools.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/utilities/cachetools.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/utilities/click.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/utilities/concurrent.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/utilities/contextlib.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/utilities/contextvars.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/utilities/cryptography.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/utilities/cvxpy.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/utilities/dataclasses.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/utilities/enum.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/utilities/errors.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/utilities/eventkit.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/utilities/fastapi.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/utilities/fpdf2.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/utilities/functions.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/utilities/functools.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/utilities/getpass.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/utilities/gzip.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/utilities/hashlib.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/utilities/http.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/utilities/importlib.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/utilities/inflect.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/utilities/ipython.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/utilities/iterables.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/utilities/json.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/utilities/jupyter.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/utilities/libcst.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/utilities/lightweight_charts.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/utilities/logging.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/utilities/math.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/utilities/memory_profiler.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/utilities/modules.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/utilities/more_itertools.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/utilities/numpy.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/utilities/operator.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/utilities/optuna.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/utilities/orjson.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/utilities/os.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/utilities/parse.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/utilities/pathlib.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/utilities/pickle.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/utilities/platform.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/utilities/polars_ols.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/utilities/postgres.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/utilities/pottery.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/utilities/pqdm.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/utilities/psutil.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/utilities/py.typed +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/utilities/pyinstrument.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/utilities/pytest.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/utilities/pytest_plugins/__init__.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/utilities/pytest_plugins/pytest_randomly.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/utilities/pytest_plugins/pytest_regressions.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/utilities/pytest_regressions.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/utilities/random.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/utilities/re.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/utilities/redis.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/utilities/reprlib.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/utilities/scipy.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/utilities/sentinel.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/utilities/shelve.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/utilities/slack_sdk.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/utilities/socket.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/utilities/sqlalchemy.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/utilities/sqlalchemy_polars.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/utilities/statsmodels.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/utilities/string.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/utilities/tempfile.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/utilities/text.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/utilities/threading.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/utilities/timer.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/utilities/traceback.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/utilities/typed_settings.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/utilities/typing.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/utilities/tzdata.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/utilities/tzlocal.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/utilities/uuid.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/utilities/version.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/utilities/warnings.py +0 -0
- {dycw_utilities-0.160.2 → dycw_utilities-0.161.1}/src/utilities/zipfile.py +0 -0
@@ -227,7 +227,7 @@ dependencies = [
|
|
227
227
|
name = "dycw-utilities"
|
228
228
|
readme = "README.md"
|
229
229
|
requires-python = ">= 3.12"
|
230
|
-
version = "0.
|
230
|
+
version = "0.161.1"
|
231
231
|
|
232
232
|
[project.entry-points.pytest11]
|
233
233
|
pytest-randomly = "utilities.pytest_plugins.pytest_randomly"
|
@@ -259,7 +259,7 @@ test = [
|
|
259
259
|
# bump-my-version
|
260
260
|
[tool.bumpversion]
|
261
261
|
allow_dirty = true
|
262
|
-
current_version = "0.
|
262
|
+
current_version = "0.161.1"
|
263
263
|
|
264
264
|
[[tool.bumpversion.files]]
|
265
265
|
filename = "src/utilities/__init__.py"
|
@@ -9,7 +9,7 @@ from hypothesis import HealthCheck
|
|
9
9
|
from pytest import fixture, mark, param, skip
|
10
10
|
|
11
11
|
from utilities.contextlib import enhanced_context_manager
|
12
|
-
from utilities.platform import IS_MAC, IS_NOT_LINUX, IS_WINDOWS
|
12
|
+
from utilities.platform import IS_LINUX, IS_MAC, IS_NOT_LINUX, IS_WINDOWS
|
13
13
|
from utilities.re import ExtractGroupError, extract_group
|
14
14
|
from utilities.whenever import MINUTE, get_now, parse_plain_local
|
15
15
|
|
@@ -29,11 +29,13 @@ SKIPIF_CI = mark.skipif(IS_CI, reason="Skipped for CI")
|
|
29
29
|
IS_CI_AND_NOT_LINUX = IS_CI and IS_NOT_LINUX
|
30
30
|
IS_CI_AND_WINDOWS = IS_CI and IS_WINDOWS
|
31
31
|
IS_CI_AND_MAC = IS_CI and IS_MAC
|
32
|
+
IS_CI_AND_LINUX = IS_CI and IS_LINUX
|
32
33
|
SKIPIF_CI_AND_NOT_LINUX = mark.skipif(
|
33
34
|
IS_CI_AND_NOT_LINUX, reason="Skipped for CI/non-Linux"
|
34
35
|
)
|
35
36
|
SKIPIF_CI_AND_WINDOWS = mark.skipif(IS_CI_AND_WINDOWS, reason="Skipped for CI/Windows")
|
36
37
|
SKIPIF_CI_AND_MAC = mark.skipif(IS_CI_AND_MAC, reason="Skipped for CI/Mac")
|
38
|
+
SKIPIF_CI_AND_LINUX = mark.skipif(IS_CI_AND_LINUX, reason="Skipped for CI/Linux")
|
37
39
|
|
38
40
|
|
39
41
|
# hypothesis
|
@@ -5,6 +5,7 @@ from itertools import pairwise
|
|
5
5
|
from pathlib import Path
|
6
6
|
from re import search
|
7
7
|
from typing import TYPE_CHECKING, Any, cast
|
8
|
+
from zoneinfo import ZoneInfo
|
8
9
|
|
9
10
|
from hypothesis import assume, given, settings
|
10
11
|
from hypothesis.errors import InvalidArgument
|
@@ -20,7 +21,6 @@ from hypothesis.strategies import (
|
|
20
21
|
just,
|
21
22
|
none,
|
22
23
|
sets,
|
23
|
-
timezones,
|
24
24
|
)
|
25
25
|
from libcst import Import, ImportFrom
|
26
26
|
from numpy import inf, int64, isfinite, isinf, isnan, ravel, rint
|
@@ -34,7 +34,6 @@ from whenever import (
|
|
34
34
|
PlainDateTime,
|
35
35
|
Time,
|
36
36
|
TimeDelta,
|
37
|
-
TimeZoneNotFoundError,
|
38
37
|
YearMonth,
|
39
38
|
ZonedDateTime,
|
40
39
|
)
|
@@ -97,6 +96,7 @@ from utilities.hypothesis import (
|
|
97
96
|
urls,
|
98
97
|
versions,
|
99
98
|
year_months,
|
99
|
+
zone_infos,
|
100
100
|
zoned_date_time_periods,
|
101
101
|
zoned_date_times,
|
102
102
|
)
|
@@ -134,6 +134,7 @@ from utilities.whenever import (
|
|
134
134
|
DatePeriod,
|
135
135
|
TimePeriod,
|
136
136
|
ZonedDateTimePeriod,
|
137
|
+
get_now,
|
137
138
|
to_days,
|
138
139
|
to_nanoseconds,
|
139
140
|
to_py_time_delta,
|
@@ -141,7 +142,6 @@ from utilities.whenever import (
|
|
141
142
|
|
142
143
|
if TYPE_CHECKING:
|
143
144
|
from collections.abc import Set as AbstractSet
|
144
|
-
from zoneinfo import ZoneInfo
|
145
145
|
|
146
146
|
from utilities.sentinel import Sentinel
|
147
147
|
from utilities.tempfile import TemporaryDirectory
|
@@ -1186,11 +1186,21 @@ class TestYearMonths:
|
|
1186
1186
|
assert year_month.on_day(28) <= DATE_TWO_DIGIT_YEAR_MAX
|
1187
1187
|
|
1188
1188
|
|
1189
|
+
class TestZoneInfos:
|
1190
|
+
@given(data=data())
|
1191
|
+
def test_main(self, *, data: DataObject) -> None:
|
1192
|
+
time_zone = data.draw(zone_infos())
|
1193
|
+
assert isinstance(time_zone, ZoneInfo)
|
1194
|
+
assert time_zone.key not in {"Etc/UTC", "localtime"}
|
1195
|
+
_ = get_now(time_zone)
|
1196
|
+
|
1197
|
+
|
1189
1198
|
class TestZonedDateTimePeriods:
|
1190
|
-
@given(data=data()
|
1191
|
-
def test_main(self, *, data: DataObject
|
1199
|
+
@given(data=data())
|
1200
|
+
def test_main(self, *, data: DataObject) -> None:
|
1192
1201
|
min_value = data.draw(zoned_date_times() | none())
|
1193
1202
|
max_value = data.draw(zoned_date_times() | none())
|
1203
|
+
time_zone = data.draw(zone_infos())
|
1194
1204
|
with assume_does_not_raise(InvalidArgument):
|
1195
1205
|
period = data.draw(
|
1196
1206
|
zoned_date_time_periods(
|
@@ -1206,10 +1216,11 @@ class TestZonedDateTimePeriods:
|
|
1206
1216
|
|
1207
1217
|
|
1208
1218
|
class TestZonedDateTimes:
|
1209
|
-
@given(data=data()
|
1210
|
-
def test_main(self, *, data: DataObject
|
1219
|
+
@given(data=data())
|
1220
|
+
def test_main(self, *, data: DataObject) -> None:
|
1211
1221
|
min_value = data.draw(zoned_date_times() | none())
|
1212
1222
|
max_value = data.draw(zoned_date_times() | none())
|
1223
|
+
time_zone = data.draw(zone_infos())
|
1213
1224
|
with assume_does_not_raise(InvalidArgument):
|
1214
1225
|
datetime = data.draw(
|
1215
1226
|
zoned_date_times(
|
@@ -1225,9 +1236,9 @@ class TestZonedDateTimes:
|
|
1225
1236
|
if max_value is not None:
|
1226
1237
|
assert datetime <= max_value
|
1227
1238
|
|
1228
|
-
@given(data=data()
|
1229
|
-
def test_examples(self, *, data: DataObject
|
1230
|
-
|
1231
|
-
|
1239
|
+
@given(data=data())
|
1240
|
+
def test_examples(self, *, data: DataObject) -> None:
|
1241
|
+
time_zone = data.draw(zone_infos())
|
1242
|
+
max_value = ZonedDateTime(1, 1, 2, tz=time_zone.key)
|
1232
1243
|
datetime = data.draw(zoned_date_times(max_value=max_value, time_zone=time_zone))
|
1233
1244
|
_ = datetime.py_datetime()
|
@@ -222,7 +222,7 @@ from utilities.whenever import (
|
|
222
222
|
get_now_plain,
|
223
223
|
get_today,
|
224
224
|
)
|
225
|
-
from utilities.zoneinfo import UTC,
|
225
|
+
from utilities.zoneinfo import UTC, to_time_zone_name
|
226
226
|
|
227
227
|
if TYPE_CHECKING:
|
228
228
|
from collections.abc import Callable, Iterable, Mapping, Sequence
|
@@ -1426,18 +1426,18 @@ class TestDataClassToSchema:
|
|
1426
1426
|
|
1427
1427
|
|
1428
1428
|
class TestDatetimeDTypes:
|
1429
|
-
@
|
1430
|
-
|
1431
|
-
|
1432
|
-
(
|
1433
|
-
(
|
1434
|
-
(
|
1435
|
-
(
|
1436
|
-
|
1429
|
+
@mark.parametrize(
|
1430
|
+
("time_zone", "dtype"),
|
1431
|
+
[
|
1432
|
+
param(HongKong, DatetimeHongKong),
|
1433
|
+
param(Tokyo, DatetimeTokyo),
|
1434
|
+
param(USCentral, DatetimeUSCentral),
|
1435
|
+
param(USEastern, DatetimeUSEastern),
|
1436
|
+
param(UTC, DatetimeUTC),
|
1437
|
+
],
|
1437
1438
|
)
|
1438
|
-
def test_main(self, *,
|
1439
|
-
|
1440
|
-
name = get_time_zone_name(time_zone)
|
1439
|
+
def test_main(self, *, time_zone: ZoneInfo, dtype: Datetime) -> None:
|
1440
|
+
name = to_time_zone_name(time_zone)
|
1441
1441
|
expected = dtype.time_zone
|
1442
1442
|
assert name == expected
|
1443
1443
|
|
@@ -9,8 +9,7 @@ from hypothesis.strategies import sampled_from
|
|
9
9
|
from pytest import mark, param
|
10
10
|
|
11
11
|
from utilities.platform import SYSTEM
|
12
|
-
from utilities.types import Dataclass, Number, PathLike
|
13
|
-
from utilities.typing import get_literal_elements
|
12
|
+
from utilities.types import TIME_ZONES, Dataclass, Number, PathLike
|
14
13
|
|
15
14
|
|
16
15
|
class TestDataClassProtocol:
|
@@ -45,7 +44,7 @@ class TestPathLike:
|
|
45
44
|
|
46
45
|
class TestTimeZone:
|
47
46
|
def test_main(self) -> None:
|
48
|
-
result = set(
|
47
|
+
result = set(TIME_ZONES)
|
49
48
|
expected = available_timezones()
|
50
49
|
match SYSTEM:
|
51
50
|
case "windows" | "mac":
|
@@ -8,14 +8,7 @@ from typing import TYPE_CHECKING, Any, ClassVar, Self, cast
|
|
8
8
|
from zoneinfo import ZoneInfo
|
9
9
|
|
10
10
|
from hypothesis import HealthCheck, given, settings
|
11
|
-
from hypothesis.strategies import
|
12
|
-
DataObject,
|
13
|
-
data,
|
14
|
-
integers,
|
15
|
-
none,
|
16
|
-
sampled_from,
|
17
|
-
timezones,
|
18
|
-
)
|
11
|
+
from hypothesis.strategies import DataObject, data, integers, none, sampled_from
|
19
12
|
from pytest import mark, param, raises
|
20
13
|
from whenever import (
|
21
14
|
Date,
|
@@ -24,7 +17,6 @@ from whenever import (
|
|
24
17
|
PlainDateTime,
|
25
18
|
Time,
|
26
19
|
TimeDelta,
|
27
|
-
TimeZoneNotFoundError,
|
28
20
|
Weekday,
|
29
21
|
YearMonth,
|
30
22
|
ZonedDateTime,
|
@@ -41,6 +33,7 @@ from utilities.hypothesis import (
|
|
41
33
|
time_deltas,
|
42
34
|
time_periods,
|
43
35
|
times,
|
36
|
+
zone_infos,
|
44
37
|
zoned_date_time_periods,
|
45
38
|
zoned_date_times,
|
46
39
|
zoned_date_times_2000,
|
@@ -150,7 +143,7 @@ from utilities.whenever import (
|
|
150
143
|
to_zoned_date_time,
|
151
144
|
two_digit_year_month,
|
152
145
|
)
|
153
|
-
from utilities.zoneinfo import UTC
|
146
|
+
from utilities.zoneinfo import UTC
|
154
147
|
|
155
148
|
if TYPE_CHECKING:
|
156
149
|
from collections.abc import Callable
|
@@ -382,7 +375,7 @@ class TestFormatCompact:
|
|
382
375
|
|
383
376
|
class TestFromTimeStamp:
|
384
377
|
@given(
|
385
|
-
datetime=zoned_date_times(time_zone=
|
378
|
+
datetime=zoned_date_times(time_zone=zone_infos()).map(
|
386
379
|
lambda d: d.round("second")
|
387
380
|
)
|
388
381
|
)
|
@@ -392,7 +385,7 @@ class TestFromTimeStamp:
|
|
392
385
|
assert result == datetime
|
393
386
|
|
394
387
|
@given(
|
395
|
-
datetime=zoned_date_times(time_zone=
|
388
|
+
datetime=zoned_date_times(time_zone=zone_infos()).map(
|
396
389
|
lambda d: d.round("millisecond")
|
397
390
|
)
|
398
391
|
)
|
@@ -401,7 +394,7 @@ class TestFromTimeStamp:
|
|
401
394
|
result = from_timestamp_millis(timestamp, time_zone=ZoneInfo(datetime.tz))
|
402
395
|
assert result == datetime
|
403
396
|
|
404
|
-
@given(datetime=zoned_date_times(time_zone=
|
397
|
+
@given(datetime=zoned_date_times(time_zone=zone_infos()))
|
405
398
|
def test_nanos(self, *, datetime: ZonedDateTime) -> None:
|
406
399
|
timestamp = datetime.timestamp_nanos()
|
407
400
|
result = from_timestamp_nanos(timestamp, time_zone=ZoneInfo(datetime.tz))
|
@@ -409,16 +402,16 @@ class TestFromTimeStamp:
|
|
409
402
|
|
410
403
|
|
411
404
|
class TestGetNow:
|
412
|
-
@given(time_zone=
|
405
|
+
@given(time_zone=zone_infos())
|
413
406
|
def test_function(self, *, time_zone: ZoneInfo) -> None:
|
414
|
-
|
415
|
-
now = get_now(time_zone)
|
407
|
+
now = get_now(time_zone)
|
416
408
|
assert isinstance(now, ZonedDateTime)
|
417
409
|
assert now.tz == time_zone.key
|
418
410
|
|
419
411
|
def test_constant(self) -> None:
|
420
412
|
assert isinstance(NOW_UTC, ZonedDateTime)
|
421
|
-
|
413
|
+
expected = UTC.key
|
414
|
+
assert NOW_UTC.tz == expected
|
422
415
|
|
423
416
|
|
424
417
|
class TestGetNowLocal:
|
@@ -435,10 +428,9 @@ class TestGetNowLocal:
|
|
435
428
|
|
436
429
|
|
437
430
|
class TestGetNowPlain:
|
438
|
-
@given(time_zone=
|
431
|
+
@given(time_zone=zone_infos())
|
439
432
|
def test_function(self, *, time_zone: ZoneInfo) -> None:
|
440
|
-
|
441
|
-
now = get_now_plain(time_zone)
|
433
|
+
now = get_now_plain(time_zone)
|
442
434
|
assert isinstance(now, PlainDateTime)
|
443
435
|
|
444
436
|
def test_constant(self) -> None:
|
@@ -1394,32 +1386,50 @@ class TestToZonedDateTime:
|
|
1394
1386
|
def test_default(self) -> None:
|
1395
1387
|
assert abs(to_zoned_date_time() - get_now()) <= SECOND
|
1396
1388
|
|
1397
|
-
@given(date_time=zoned_date_times())
|
1398
|
-
def test_date_time(self, *, date_time: ZonedDateTime) -> None:
|
1399
|
-
|
1389
|
+
@given(date_time=zoned_date_times(), time_zone=zone_infos())
|
1390
|
+
def test_date_time(self, *, date_time: ZonedDateTime, time_zone: ZoneInfo) -> None:
|
1391
|
+
result = to_zoned_date_time(date_time, time_zone=time_zone)
|
1392
|
+
expected = date_time.to_tz(time_zone.key)
|
1393
|
+
assert result.exact_eq(expected)
|
1400
1394
|
|
1401
|
-
@given(date_time=zoned_date_times())
|
1402
|
-
def test_str(self, *, date_time: ZonedDateTime) -> None:
|
1403
|
-
|
1395
|
+
@given(date_time=zoned_date_times(), time_zone=zone_infos())
|
1396
|
+
def test_str(self, *, date_time: ZonedDateTime, time_zone: ZoneInfo) -> None:
|
1397
|
+
result = to_zoned_date_time(date_time.format_common_iso(), time_zone=time_zone)
|
1398
|
+
expected = date_time.to_tz(time_zone.key)
|
1399
|
+
assert result.exact_eq(expected)
|
1404
1400
|
|
1405
|
-
@given(date_time=zoned_date_times_2000)
|
1406
|
-
def test_py_date_time_zone_info(
|
1407
|
-
|
1401
|
+
@given(date_time=zoned_date_times_2000, time_zone=zone_infos())
|
1402
|
+
def test_py_date_time_zone_info(
|
1403
|
+
self, *, date_time: ZonedDateTime, time_zone: ZoneInfo
|
1404
|
+
) -> None:
|
1405
|
+
result = to_zoned_date_time(date_time.py_datetime(), time_zone=time_zone)
|
1406
|
+
expected = date_time.to_tz(time_zone.key)
|
1407
|
+
assert result.exact_eq(expected)
|
1408
1408
|
|
1409
|
-
@given(date_time=zoned_date_times_2000)
|
1410
|
-
def test_py_date_time_dt_utc(
|
1411
|
-
|
1412
|
-
|
1409
|
+
@given(date_time=zoned_date_times_2000, time_zone=zone_infos())
|
1410
|
+
def test_py_date_time_dt_utc(
|
1411
|
+
self, *, date_time: ZonedDateTime, time_zone: ZoneInfo
|
1412
|
+
) -> None:
|
1413
|
+
result = to_zoned_date_time(
|
1414
|
+
date_time.py_datetime().astimezone(dt.UTC), time_zone=time_zone
|
1415
|
+
)
|
1416
|
+
expected = date_time.to_tz(time_zone.key)
|
1417
|
+
assert result.exact_eq(expected)
|
1413
1418
|
|
1414
|
-
@given(date_time=zoned_date_times())
|
1415
|
-
def test_callable(self, *, date_time: ZonedDateTime) -> None:
|
1416
|
-
|
1419
|
+
@given(date_time=zoned_date_times(), time_zone=zone_infos())
|
1420
|
+
def test_callable(self, *, date_time: ZonedDateTime, time_zone: ZoneInfo) -> None:
|
1421
|
+
result = to_zoned_date_time(lambda: date_time, time_zone=time_zone)
|
1422
|
+
expected = date_time.to_tz(time_zone.key)
|
1423
|
+
assert result.exact_eq(expected)
|
1417
1424
|
|
1418
|
-
|
1419
|
-
|
1425
|
+
@given(time_zone=zone_infos())
|
1426
|
+
def test_none(self, *, time_zone: ZoneInfo) -> None:
|
1427
|
+
result = to_zoned_date_time(None, time_zone=time_zone)
|
1428
|
+
assert abs(result - get_now(time_zone)) <= SECOND
|
1420
1429
|
|
1421
|
-
|
1422
|
-
|
1430
|
+
@given(time_zone=zone_infos())
|
1431
|
+
def test_sentinel(self, *, time_zone: ZoneInfo) -> None:
|
1432
|
+
assert to_zoned_date_time(sentinel, time_zone=time_zone) is sentinel
|
1423
1433
|
|
1424
1434
|
@given(date_times=pairs(zoned_date_times()))
|
1425
1435
|
def test_replace_non_sentinel(
|
@@ -1466,12 +1476,6 @@ class TestWheneverLogRecord:
|
|
1466
1476
|
def test_get_length(self) -> None:
|
1467
1477
|
assert isinstance(WheneverLogRecord._get_length(), int)
|
1468
1478
|
|
1469
|
-
def test_get_time_zone(self) -> None:
|
1470
|
-
assert isinstance(WheneverLogRecord._get_time_zone(), ZoneInfo)
|
1471
|
-
|
1472
|
-
def test_get_time_zone_key(self) -> None:
|
1473
|
-
assert isinstance(WheneverLogRecord._get_time_zone_key(), str)
|
1474
|
-
|
1475
1479
|
|
1476
1480
|
class TestZonedDateTimePeriod:
|
1477
1481
|
@given(period=zoned_date_time_periods(), delta=time_deltas())
|
@@ -1669,7 +1673,7 @@ class TestZonedDateTimePeriod:
|
|
1669
1673
|
with assume_does_not_raise(OverflowError, match="date value out of range"):
|
1670
1674
|
result = period.to_tz(UTC)
|
1671
1675
|
assert result.time_zone == UTC
|
1672
|
-
name =
|
1676
|
+
name = UTC.key
|
1673
1677
|
expected = ZonedDateTimePeriod(period.start.to_tz(name), period.end.to_tz(name))
|
1674
1678
|
assert result == expected
|
1675
1679
|
|
@@ -0,0 +1,131 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
3
|
+
import datetime as dt
|
4
|
+
from typing import TYPE_CHECKING, Literal, cast
|
5
|
+
from zoneinfo import ZoneInfo
|
6
|
+
|
7
|
+
from hypothesis import given
|
8
|
+
from hypothesis.strategies import DataObject, data, datetimes, just, sampled_from
|
9
|
+
from pytest import mark, param, raises
|
10
|
+
|
11
|
+
from utilities.hypothesis import zone_infos, zoned_date_times
|
12
|
+
from utilities.tzdata import HongKong, Tokyo
|
13
|
+
from utilities.tzlocal import LOCAL_TIME_ZONE, LOCAL_TIME_ZONE_NAME
|
14
|
+
from utilities.zoneinfo import (
|
15
|
+
UTC,
|
16
|
+
_ToTimeZoneNameInvalidKeyError,
|
17
|
+
_ToTimeZoneNameInvalidTZInfoError,
|
18
|
+
_ToTimeZoneNamePlainDateTimeError,
|
19
|
+
_ToZoneInfoInvalidTZInfoError,
|
20
|
+
_ToZoneInfoPlainDateTimeError,
|
21
|
+
to_time_zone_name,
|
22
|
+
to_zone_info,
|
23
|
+
)
|
24
|
+
|
25
|
+
if TYPE_CHECKING:
|
26
|
+
from utilities.types import TimeZoneLike
|
27
|
+
|
28
|
+
|
29
|
+
class TestToZoneInfo:
|
30
|
+
@given(time_zone=zone_infos())
|
31
|
+
def test_zone_info(self, *, time_zone: ZoneInfo) -> None:
|
32
|
+
result = to_zone_info(time_zone)
|
33
|
+
assert result is time_zone
|
34
|
+
|
35
|
+
@given(data=data(), time_zone=zone_infos())
|
36
|
+
def test_zoned_date_time(self, *, data: DataObject, time_zone: ZoneInfo) -> None:
|
37
|
+
date_time = data.draw(zoned_date_times(time_zone=time_zone))
|
38
|
+
result = to_zone_info(date_time)
|
39
|
+
assert result is time_zone
|
40
|
+
|
41
|
+
@mark.parametrize("time_zone", [param("local"), param("localtime")])
|
42
|
+
def test_local(self, *, time_zone: Literal["local", "localtime"]) -> None:
|
43
|
+
result = to_zone_info(time_zone)
|
44
|
+
assert result is LOCAL_TIME_ZONE
|
45
|
+
|
46
|
+
@given(time_zone=zone_infos())
|
47
|
+
def test_str(self, *, time_zone: ZoneInfo) -> None:
|
48
|
+
result = to_zone_info(cast("TimeZoneLike", time_zone.key))
|
49
|
+
assert result is time_zone
|
50
|
+
|
51
|
+
def test_tz_info(self) -> None:
|
52
|
+
result = to_zone_info(dt.UTC)
|
53
|
+
assert result is UTC
|
54
|
+
|
55
|
+
@given(data=data(), time_zone=zone_infos())
|
56
|
+
def test_py_zoned_date_time(self, *, data: DataObject, time_zone: ZoneInfo) -> None:
|
57
|
+
date_time = data.draw(datetimes(timezones=just(time_zone)))
|
58
|
+
result = to_zone_info(date_time)
|
59
|
+
assert result is time_zone
|
60
|
+
|
61
|
+
def test_error_invalid_tz_info(self) -> None:
|
62
|
+
time_zone = dt.timezone(dt.timedelta(hours=12))
|
63
|
+
with raises(
|
64
|
+
_ToZoneInfoInvalidTZInfoError, match=r"Invalid time-zone: UTC\+12:00"
|
65
|
+
):
|
66
|
+
_ = to_zone_info(time_zone)
|
67
|
+
|
68
|
+
@given(date_time=datetimes())
|
69
|
+
def test_error_plain_date_time(self, *, date_time: dt.datetime) -> None:
|
70
|
+
with raises(_ToZoneInfoPlainDateTimeError, match="Plain date-time: .*"):
|
71
|
+
_ = to_zone_info(date_time)
|
72
|
+
|
73
|
+
|
74
|
+
class TestToTimeZoneName:
|
75
|
+
@given(time_zone=zone_infos())
|
76
|
+
def test_zone_info(self, *, time_zone: ZoneInfo) -> None:
|
77
|
+
result = to_time_zone_name(time_zone)
|
78
|
+
expected = time_zone.key
|
79
|
+
assert result == expected
|
80
|
+
|
81
|
+
@given(data=data(), time_zone=zone_infos())
|
82
|
+
def test_zoned_date_time(self, *, data: DataObject, time_zone: ZoneInfo) -> None:
|
83
|
+
date_time = data.draw(zoned_date_times(time_zone=time_zone))
|
84
|
+
result = to_time_zone_name(date_time)
|
85
|
+
expected = time_zone.key
|
86
|
+
assert result == expected
|
87
|
+
|
88
|
+
@mark.parametrize("time_zone", [param("local"), param("localtime")])
|
89
|
+
def test_local(self, *, time_zone: Literal["local", "localtime"]) -> None:
|
90
|
+
result = to_time_zone_name(time_zone)
|
91
|
+
assert result == LOCAL_TIME_ZONE_NAME
|
92
|
+
|
93
|
+
@given(time_zone=zone_infos())
|
94
|
+
def test_str(self, *, time_zone: ZoneInfo) -> None:
|
95
|
+
result = to_time_zone_name(cast("TimeZoneLike", time_zone.key))
|
96
|
+
expected = time_zone.key
|
97
|
+
assert result == expected
|
98
|
+
|
99
|
+
def test_tz_info(self) -> None:
|
100
|
+
result = to_time_zone_name(dt.UTC)
|
101
|
+
expected = UTC.key
|
102
|
+
assert result == expected
|
103
|
+
|
104
|
+
@given(data=data(), time_zone=zone_infos())
|
105
|
+
def test_py_zoned_date_time(self, *, data: DataObject, time_zone: ZoneInfo) -> None:
|
106
|
+
date_time = data.draw(datetimes(timezones=just(time_zone)))
|
107
|
+
result = to_time_zone_name(date_time)
|
108
|
+
expected = time_zone.key
|
109
|
+
assert result == expected
|
110
|
+
|
111
|
+
def test_error_invalid_key(self) -> None:
|
112
|
+
with raises(
|
113
|
+
_ToTimeZoneNameInvalidKeyError, match="Invalid time-zone: 'invalid'"
|
114
|
+
):
|
115
|
+
_ = to_time_zone_name(cast("TimeZoneLike", "invalid"))
|
116
|
+
|
117
|
+
def test_error_invalid_tz_info(self) -> None:
|
118
|
+
time_zone = dt.timezone(dt.timedelta(hours=12))
|
119
|
+
with raises(_ToTimeZoneNameInvalidTZInfoError, match="Invalid time-zone: .*"):
|
120
|
+
_ = to_time_zone_name(time_zone)
|
121
|
+
|
122
|
+
@given(date_time=datetimes())
|
123
|
+
def test_error_plain_date_time(self, *, date_time: dt.datetime) -> None:
|
124
|
+
with raises(_ToTimeZoneNamePlainDateTimeError, match="Plain date-time: .*"):
|
125
|
+
_ = to_time_zone_name(date_time)
|
126
|
+
|
127
|
+
|
128
|
+
class TestTimeZones:
|
129
|
+
@given(time_zone=sampled_from([HongKong, Tokyo, UTC]))
|
130
|
+
def test_main(self, *, time_zone: ZoneInfo) -> None:
|
131
|
+
assert isinstance(time_zone, ZoneInfo)
|
@@ -32,6 +32,7 @@ from hypothesis.strategies import (
|
|
32
32
|
sampled_from,
|
33
33
|
sets,
|
34
34
|
text,
|
35
|
+
timezones,
|
35
36
|
uuids,
|
36
37
|
)
|
37
38
|
from hypothesis.utils.conventions import not_set
|
@@ -97,14 +98,16 @@ from utilities.whenever import (
|
|
97
98
|
DatePeriod,
|
98
99
|
TimePeriod,
|
99
100
|
ZonedDateTimePeriod,
|
101
|
+
get_now,
|
100
102
|
to_date_time_delta,
|
101
103
|
to_days,
|
102
104
|
to_nanoseconds,
|
103
105
|
)
|
104
|
-
from utilities.zoneinfo import UTC,
|
106
|
+
from utilities.zoneinfo import UTC, to_zone_info
|
105
107
|
|
106
108
|
if TYPE_CHECKING:
|
107
109
|
from collections.abc import Collection, Hashable, Iterable, Iterator
|
110
|
+
from zoneinfo import ZoneInfo
|
108
111
|
|
109
112
|
from hypothesis.database import ExampleDatabase
|
110
113
|
from libcst import Import, ImportFrom
|
@@ -835,7 +838,7 @@ def paths(
|
|
835
838
|
@composite
|
836
839
|
def _path_parts(draw: DrawFn, /) -> str:
|
837
840
|
part = draw(text_ascii(min_size=1, max_size=10))
|
838
|
-
reserved = {"AUX", "NUL", "nuL"}
|
841
|
+
reserved = {"AUX", "NUL", "nuL", "pRn"}
|
839
842
|
_ = assume(part not in reserved)
|
840
843
|
return part
|
841
844
|
|
@@ -1476,6 +1479,19 @@ def year_months(
|
|
1476
1479
|
##
|
1477
1480
|
|
1478
1481
|
|
1482
|
+
@composite
|
1483
|
+
def zone_infos(draw: DrawFn, /) -> ZoneInfo:
|
1484
|
+
"""Strategy for generating time-zones."""
|
1485
|
+
time_zone = draw(timezones())
|
1486
|
+
_ = assume(time_zone.key not in {"Etc/UTC", "localtime"})
|
1487
|
+
with assume_does_not_raise(TimeZoneNotFoundError):
|
1488
|
+
_ = get_now(time_zone)
|
1489
|
+
return time_zone
|
1490
|
+
|
1491
|
+
|
1492
|
+
##
|
1493
|
+
|
1494
|
+
|
1479
1495
|
@composite
|
1480
1496
|
def zoned_date_time_periods(
|
1481
1497
|
draw: DrawFn,
|
@@ -1509,7 +1525,7 @@ def zoned_date_times(
|
|
1509
1525
|
) -> ZonedDateTime:
|
1510
1526
|
"""Strategy for generating zoned date-times."""
|
1511
1527
|
min_value_, max_value_ = [draw2(draw, v) for v in [min_value, max_value]]
|
1512
|
-
time_zone_ =
|
1528
|
+
time_zone_ = to_zone_info(draw2(draw, time_zone))
|
1513
1529
|
match min_value_:
|
1514
1530
|
case None | PlainDateTime():
|
1515
1531
|
...
|
@@ -1530,7 +1546,6 @@ def zoned_date_times(
|
|
1530
1546
|
with (
|
1531
1547
|
assume_does_not_raise(RepeatedTime),
|
1532
1548
|
assume_does_not_raise(SkippedTime),
|
1533
|
-
assume_does_not_raise(TimeZoneNotFoundError),
|
1534
1549
|
assume_does_not_raise(ValueError, match="Resulting datetime is out of range"),
|
1535
1550
|
):
|
1536
1551
|
zoned = plain.assume_tz(time_zone_.key, disambiguate="raise")
|
@@ -1602,6 +1617,7 @@ __all__ = [
|
|
1602
1617
|
"urls",
|
1603
1618
|
"versions",
|
1604
1619
|
"year_months",
|
1620
|
+
"zone_infos",
|
1605
1621
|
"zoned_date_time_periods",
|
1606
1622
|
"zoned_date_times",
|
1607
1623
|
"zoned_date_times_2000",
|
@@ -104,7 +104,7 @@ from utilities.whenever import (
|
|
104
104
|
ZonedDateTimePeriod,
|
105
105
|
to_py_time_delta,
|
106
106
|
)
|
107
|
-
from utilities.zoneinfo import UTC,
|
107
|
+
from utilities.zoneinfo import UTC, to_time_zone_name
|
108
108
|
|
109
109
|
if TYPE_CHECKING:
|
110
110
|
from collections.abc import Callable, Iterable, Iterator, Mapping, Sequence
|
@@ -834,7 +834,7 @@ def convert_time_zone(
|
|
834
834
|
|
835
835
|
def _convert_time_zone_one(sr: Series, /, *, time_zone: TimeZoneLike = UTC) -> Series:
|
836
836
|
if isinstance(sr.dtype, Datetime):
|
837
|
-
return sr.dt.convert_time_zone(
|
837
|
+
return sr.dt.convert_time_zone(to_time_zone_name(time_zone))
|
838
838
|
return sr
|
839
839
|
|
840
840
|
|
@@ -2110,7 +2110,7 @@ def period_range(
|
|
2110
2110
|
eager: bool = False,
|
2111
2111
|
) -> Series | Expr:
|
2112
2112
|
"""Construct a period range."""
|
2113
|
-
time_zone_use = None if time_zone is None else
|
2113
|
+
time_zone_use = None if time_zone is None else to_time_zone_name(time_zone)
|
2114
2114
|
match end_or_length:
|
2115
2115
|
case ZonedDateTime() as end:
|
2116
2116
|
...
|
@@ -2127,7 +2127,7 @@ def period_range(
|
|
2127
2127
|
time_zone=time_zone_use,
|
2128
2128
|
eager=eager,
|
2129
2129
|
).alias("start")
|
2130
|
-
ends =
|
2130
|
+
ends = starts.dt.offset_by(interval).alias("end")
|
2131
2131
|
period = struct(starts, ends)
|
2132
2132
|
return try_reify_expr(period, starts, ends)
|
2133
2133
|
|
@@ -2220,7 +2220,7 @@ def _replace_time_zone_one(
|
|
2220
2220
|
sr: Series, /, *, time_zone: TimeZoneLike | None = UTC
|
2221
2221
|
) -> Series:
|
2222
2222
|
if isinstance(sr.dtype, Datetime):
|
2223
|
-
time_zone_use = None if time_zone is None else
|
2223
|
+
time_zone_use = None if time_zone is None else to_time_zone_name(time_zone)
|
2224
2224
|
return sr.dt.replace_time_zone(time_zone_use)
|
2225
2225
|
return sr
|
2226
2226
|
|
@@ -2611,7 +2611,7 @@ def zoned_date_time_dtype(
|
|
2611
2611
|
*, time_unit: TimeUnit = "us", time_zone: TimeZoneLike = UTC
|
2612
2612
|
) -> Datetime:
|
2613
2613
|
"""Create a zoned date-time data type."""
|
2614
|
-
return Datetime(time_unit=time_unit, time_zone=
|
2614
|
+
return Datetime(time_unit=time_unit, time_zone=to_time_zone_name(time_zone))
|
2615
2615
|
|
2616
2616
|
|
2617
2617
|
def zoned_date_time_period_dtype(
|