dycw-utilities 0.151.12__tar.gz → 0.153.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.151.12 → dycw_utilities-0.153.0}/PKG-INFO +2 -2
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/pyproject.toml +4 -4
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/test_functions.py +1 -13
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/test_iterables.py +0 -22
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/test_logging.py +18 -20
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/test_pathlib.py +55 -50
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/test_polars.py +5 -5
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/test_postgres.py +2 -4
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/test_pottery.py +3 -3
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/test_pyinstrument.py +1 -1
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/test_random.py +1 -1
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/test_text.py +18 -1
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/test_traceback.py +3 -9
- dycw_utilities-0.153.0/src/tests/test_uuid.py +89 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/test_version.py +19 -19
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/test_whenever.py +571 -38
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/utilities/__init__.py +1 -1
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/utilities/asyncio.py +12 -11
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/utilities/cryptography.py +3 -3
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/utilities/eventkit.py +8 -8
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/utilities/functions.py +1 -33
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/utilities/iterables.py +1 -12
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/utilities/logging.py +23 -24
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/utilities/pathlib.py +34 -34
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/utilities/postgres.py +12 -12
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/utilities/pottery.py +5 -5
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/utilities/pyinstrument.py +3 -3
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/utilities/pytest.py +8 -8
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/utilities/pytest_plugins/pytest_randomly.py +1 -1
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/utilities/pytest_plugins/pytest_regressions.py +1 -1
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/utilities/random.py +8 -6
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/utilities/redis.py +2 -2
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/utilities/text.py +37 -2
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/utilities/traceback.py +15 -18
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/utilities/typed_settings.py +3 -3
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/utilities/types.py +29 -35
- dycw_utilities-0.153.0/src/utilities/uuid.py +61 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/utilities/version.py +27 -26
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/utilities/whenever.py +431 -37
- dycw_utilities-0.151.12/src/tests/test_period.py +0 -531
- dycw_utilities-0.151.12/src/tests/test_uuid.py +0 -37
- dycw_utilities-0.151.12/src/utilities/period.py +0 -370
- dycw_utilities-0.151.12/src/utilities/uuid.py +0 -24
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/.gitignore +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/LICENSE +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/README.md +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/__init__.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/conftest.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/modules/__init__.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/modules/package_missing/__init__.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/modules/package_missing/module.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/modules/package_with/__init__.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/modules/package_with/outer_1.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/modules/package_with/outer_2.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/modules/package_with/subpackage/__init__.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/modules/package_with/subpackage/inner_1.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/modules/package_with/subpackage/inner_2.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/modules/package_with/subpackage/inner_3.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/modules/package_without/__init__.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/modules/package_without/module_1.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/modules/package_without/module_2.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/modules/standalone.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/modules/with_imports.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/regressions/test_pytest_regressions/TestMultipleRegressionFixtures__test_main__obj.json +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/regressions/test_pytest_regressions/TestMultipleRegressionFixtures__test_main__series.json +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_int.json +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_literal__false.json +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_literal__true.json +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_nested.json +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/regressions/test_pytest_regressions/TestPolarsRegressionFixture__test_dataframe.json +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/regressions/test_pytest_regressions/TestPolarsRegressionFixture__test_series.json +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/test_altair.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/test_asyncio.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/test_atomicwrites.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/test_atools.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/test_cachetools.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/test_click.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/test_concurrent.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/test_contextlib.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/test_contextvars.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/test_cryptography.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/test_cvxpy.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/test_dataclasses.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/test_enum.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/test_errors.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/test_eventkit.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/test_fastapi.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/test_fpdf2.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/test_functools.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/test_getpass.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/test_gzip.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/test_hashlib.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/test_http.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/test_hypothesis.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/test_importlib.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/test_inflect.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/test_ipython.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/test_json.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/test_jupyter.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/test_libcst.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/test_lightweight_charts.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/test_math.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/test_memory_profiler.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/test_modules.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/test_more_itertools.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/test_numpy.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/test_objects/__init__.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/test_objects/objects.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/test_operator.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/test_optuna.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/test_orjson.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/test_os.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/test_parse.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/test_pickle.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/test_platform.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/test_polars_ols.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/test_pqdm.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/test_psutil.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/test_pytest.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/test_pytest_randomly.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/test_pytest_regressions.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/test_re.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/test_redis.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/test_reprlib.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/test_scipy.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/test_sentinel.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/test_shelve.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/test_slack_sdk.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/test_socket.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/test_sqlalchemy.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/test_sqlalchemy_polars.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/test_statsmodels.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/test_string.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/test_tempfile.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/test_threading.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/test_timer.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/test_typed_settings.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/test_types.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/test_typing.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/test_typing_funcs/__init__.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/test_typing_funcs/no_future.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/test_typing_funcs/with_future.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/test_tzdata.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/test_tzlocal.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/test_warnings.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/test_yield_access/__init__.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/test_yield_access/script.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/test_yield_access/script.sh +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/test_zipfile.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/tests/test_zoneinfo.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/utilities/altair.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/utilities/atomicwrites.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/utilities/atools.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/utilities/cachetools.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/utilities/click.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/utilities/concurrent.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/utilities/contextlib.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/utilities/contextvars.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/utilities/cvxpy.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/utilities/dataclasses.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/utilities/enum.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/utilities/errors.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/utilities/fastapi.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/utilities/fpdf2.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/utilities/functools.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/utilities/getpass.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/utilities/gzip.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/utilities/hashlib.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/utilities/http.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/utilities/hypothesis.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/utilities/importlib.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/utilities/inflect.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/utilities/ipython.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/utilities/json.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/utilities/jupyter.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/utilities/libcst.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/utilities/lightweight_charts.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/utilities/math.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/utilities/memory_profiler.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/utilities/modules.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/utilities/more_itertools.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/utilities/numpy.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/utilities/operator.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/utilities/optuna.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/utilities/orjson.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/utilities/os.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/utilities/parse.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/utilities/pickle.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/utilities/platform.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/utilities/polars.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/utilities/polars_ols.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/utilities/pqdm.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/utilities/psutil.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/utilities/py.typed +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/utilities/pytest_plugins/__init__.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/utilities/pytest_regressions.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/utilities/re.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/utilities/reprlib.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/utilities/scipy.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/utilities/sentinel.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/utilities/shelve.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/utilities/slack_sdk.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/utilities/socket.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/utilities/sqlalchemy.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/utilities/sqlalchemy_polars.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/utilities/statsmodels.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/utilities/string.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/utilities/tempfile.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/utilities/threading.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/utilities/timer.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/utilities/typing.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/utilities/tzdata.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/utilities/tzlocal.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/utilities/warnings.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/utilities/zipfile.py +0 -0
- {dycw_utilities-0.151.12 → dycw_utilities-0.153.0}/src/utilities/zoneinfo.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: dycw-utilities
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.153.0
|
4
4
|
Author-email: Derek Wan <d.wan@icloud.com>
|
5
5
|
License-File: LICENSE
|
6
6
|
Requires-Python: >=3.12
|
@@ -12,7 +12,7 @@ Provides-Extra: logging
|
|
12
12
|
Requires-Dist: coloredlogs<15.1,>=15.0.1; extra == 'logging'
|
13
13
|
Provides-Extra: test
|
14
14
|
Requires-Dist: dycw-pytest-only<2.2,>=2.1.1; extra == 'test'
|
15
|
-
Requires-Dist: hypothesis<6.137,>=6.136.
|
15
|
+
Requires-Dist: hypothesis<6.137,>=6.136.6; extra == 'test'
|
16
16
|
Requires-Dist: pudb<2025.2,>=2025.1; extra == 'test'
|
17
17
|
Requires-Dist: pytest-asyncio<1.2,>=1.1.0; extra == 'test'
|
18
18
|
Requires-Dist: pytest-cov<6.3,>=6.2.1; extra == 'test'
|
@@ -69,7 +69,7 @@ http-test = [
|
|
69
69
|
"orjson",
|
70
70
|
]
|
71
71
|
hypothesis = [
|
72
|
-
"hypothesis >=6.136.
|
72
|
+
"hypothesis >=6.136.6, <6.137",
|
73
73
|
]
|
74
74
|
hypothesis-test = [
|
75
75
|
"libcst",
|
@@ -229,7 +229,7 @@ dependencies = [
|
|
229
229
|
name = "dycw-utilities"
|
230
230
|
readme = "README.md"
|
231
231
|
requires-python = ">= 3.12"
|
232
|
-
version = "0.
|
232
|
+
version = "0.153.0"
|
233
233
|
|
234
234
|
[project.entry-points.pytest11]
|
235
235
|
pytest-randomly = "utilities.pytest_plugins.pytest_randomly"
|
@@ -241,7 +241,7 @@ logging = [
|
|
241
241
|
]
|
242
242
|
test = [
|
243
243
|
"dycw-pytest-only >=2.1.1, <2.2",
|
244
|
-
"hypothesis >=6.136.
|
244
|
+
"hypothesis >=6.136.6, <6.137",
|
245
245
|
"pudb >=2025.1, <2025.2",
|
246
246
|
"pytest >=8.4.1, <8.5",
|
247
247
|
"pytest-asyncio >=1.1.0, <1.2",
|
@@ -262,7 +262,7 @@ test = [
|
|
262
262
|
# bump-my-version
|
263
263
|
[tool.bumpversion]
|
264
264
|
allow_dirty = true
|
265
|
-
current_version = "0.
|
265
|
+
current_version = "0.153.0"
|
266
266
|
|
267
267
|
[[tool.bumpversion.files]]
|
268
268
|
filename = "src/utilities/__init__.py"
|
@@ -90,13 +90,11 @@ from utilities.functions import (
|
|
90
90
|
min_nullable,
|
91
91
|
not_func,
|
92
92
|
second,
|
93
|
-
to_bool,
|
94
93
|
yield_object_attributes,
|
95
94
|
yield_object_cached_properties,
|
96
95
|
yield_object_properties,
|
97
96
|
)
|
98
|
-
from utilities.
|
99
|
-
from utilities.sentinel import Sentinel, sentinel
|
97
|
+
from utilities.sentinel import sentinel
|
100
98
|
from utilities.whenever import NOW_UTC, ZERO_TIME, get_now, get_today
|
101
99
|
|
102
100
|
if TYPE_CHECKING:
|
@@ -917,16 +915,6 @@ class TestSecond:
|
|
917
915
|
assert second(pair) == y
|
918
916
|
|
919
917
|
|
920
|
-
class TestToBool:
|
921
|
-
@given(bool_=booleans() | none() | sentinels())
|
922
|
-
def test_bool_none_or_sentinel(self, *, bool_: bool | None | Sentinel) -> None:
|
923
|
-
assert to_bool(bool_=bool_) is bool_
|
924
|
-
|
925
|
-
@given(bool_=booleans())
|
926
|
-
def test_callable(self, *, bool_: bool) -> None:
|
927
|
-
assert to_bool(bool_=lambda: bool_) is bool_
|
928
|
-
|
929
|
-
|
930
918
|
class TestYieldObjectAttributes:
|
931
919
|
@given(n=integers())
|
932
920
|
def test_main(self, *, n: int) -> None:
|
@@ -68,7 +68,6 @@ from utilities.iterables import (
|
|
68
68
|
_RangePartitionsTotalError,
|
69
69
|
_sort_iterable_cmp_floats,
|
70
70
|
always_iterable,
|
71
|
-
always_iterable_hashable,
|
72
71
|
apply_bijection,
|
73
72
|
apply_to_tuple,
|
74
73
|
apply_to_varargs,
|
@@ -166,27 +165,6 @@ class TestAlwaysIterable:
|
|
166
165
|
assert list(always_iterable(yield_ints())) == [0, 1]
|
167
166
|
|
168
167
|
|
169
|
-
class TestAlwaysIterableHashable:
|
170
|
-
def test_none(self) -> None:
|
171
|
-
assert always_iterable_hashable(None) is None
|
172
|
-
|
173
|
-
@given(x=integers())
|
174
|
-
def test_integer(self, *, x: int) -> None:
|
175
|
-
assert always_iterable_hashable(x) == (x,)
|
176
|
-
|
177
|
-
@given(x=text())
|
178
|
-
def test_string(self, *, x: str) -> None:
|
179
|
-
assert always_iterable_hashable(x) == (x,)
|
180
|
-
|
181
|
-
@given(x=lists(integers()))
|
182
|
-
def test_list_of_integers(self, *, x: list[int]) -> None:
|
183
|
-
assert always_iterable_hashable(x) == tuple(x)
|
184
|
-
|
185
|
-
@given(x=lists(text()))
|
186
|
-
def test_list_of_strings(self, *, x: list[str]) -> None:
|
187
|
-
assert always_iterable_hashable(x) == tuple(x)
|
188
|
-
|
189
|
-
|
190
168
|
class TestApplyBijection:
|
191
169
|
@given(text=text_ascii())
|
192
170
|
def test_main(self, *, text: str) -> None:
|
@@ -2,7 +2,7 @@ from __future__ import annotations
|
|
2
2
|
|
3
3
|
from asyncio import sleep
|
4
4
|
from io import StringIO
|
5
|
-
from logging import Formatter,
|
5
|
+
from logging import Formatter, StreamHandler, getLogger
|
6
6
|
from pathlib import Path
|
7
7
|
from re import search
|
8
8
|
from typing import TYPE_CHECKING, Any, cast
|
@@ -32,9 +32,9 @@ from utilities.logging import (
|
|
32
32
|
filter_for_key,
|
33
33
|
get_format_str,
|
34
34
|
get_formatter,
|
35
|
-
get_logger,
|
36
35
|
get_logging_level_number,
|
37
36
|
setup_logging,
|
37
|
+
to_logger,
|
38
38
|
)
|
39
39
|
from utilities.text import unique_str
|
40
40
|
from utilities.types import LogLevel
|
@@ -261,24 +261,6 @@ class TestGetFormatter:
|
|
261
261
|
assert isinstance(formatter, Formatter)
|
262
262
|
|
263
263
|
|
264
|
-
class TestGetLogger:
|
265
|
-
def test_logger(self) -> None:
|
266
|
-
logger = getLogger(unique_str())
|
267
|
-
result = get_logger(logger=logger)
|
268
|
-
assert result is logger
|
269
|
-
|
270
|
-
def test_str(self) -> None:
|
271
|
-
name = unique_str()
|
272
|
-
logger = getLogger(name)
|
273
|
-
assert isinstance(logger, Logger)
|
274
|
-
assert logger.name == name
|
275
|
-
|
276
|
-
def test_none(self) -> None:
|
277
|
-
result = get_logger()
|
278
|
-
assert isinstance(result, Logger)
|
279
|
-
assert result.name == "root"
|
280
|
-
|
281
|
-
|
282
264
|
class TestGetLoggingLevelNumber:
|
283
265
|
@mark.parametrize(
|
284
266
|
("level", "expected"),
|
@@ -576,3 +558,19 @@ class TestSizeAndTimeRotatingFileHandler:
|
|
576
558
|
record = one(r for r in caplog.records if r.name == name)
|
577
559
|
path.unlink()
|
578
560
|
assert not handler._should_rollover(record)
|
561
|
+
|
562
|
+
|
563
|
+
class TestToLogger:
|
564
|
+
def test_default(self) -> None:
|
565
|
+
assert to_logger().name == "root"
|
566
|
+
|
567
|
+
@given(name=text_ascii(min_size=1))
|
568
|
+
def test_logger(self, *, name: str) -> None:
|
569
|
+
assert to_logger(getLogger(name)).name == name
|
570
|
+
|
571
|
+
@given(name=text_ascii(min_size=1))
|
572
|
+
def test_str(self, *, name: str) -> None:
|
573
|
+
assert to_logger(name).name == name
|
574
|
+
|
575
|
+
def test_none(self) -> None:
|
576
|
+
assert to_logger(None).name == "root"
|
@@ -11,7 +11,7 @@ from pytest import mark, param, raises
|
|
11
11
|
|
12
12
|
from tests.conftest import SKIPIF_CI_AND_WINDOWS
|
13
13
|
from utilities.dataclasses import replace_non_sentinel
|
14
|
-
from utilities.hypothesis import git_repos, paths, temp_paths
|
14
|
+
from utilities.hypothesis import git_repos, pairs, paths, temp_paths
|
15
15
|
from utilities.pathlib import (
|
16
16
|
GetPackageRootError,
|
17
17
|
GetRepoRootError,
|
@@ -23,7 +23,6 @@ from utilities.pathlib import (
|
|
23
23
|
ensure_suffix,
|
24
24
|
expand_path,
|
25
25
|
get_package_root,
|
26
|
-
get_path,
|
27
26
|
get_repo_root,
|
28
27
|
get_root,
|
29
28
|
get_tail,
|
@@ -31,6 +30,7 @@ from utilities.pathlib import (
|
|
31
30
|
list_dir,
|
32
31
|
module_path,
|
33
32
|
temp_cwd,
|
33
|
+
to_path,
|
34
34
|
)
|
35
35
|
from utilities.sentinel import Sentinel, sentinel
|
36
36
|
from utilities.tempfile import TemporaryDirectory
|
@@ -77,42 +77,6 @@ class TestExpandPath:
|
|
77
77
|
assert result == expected
|
78
78
|
|
79
79
|
|
80
|
-
class TestGetPath:
|
81
|
-
@given(path=paths())
|
82
|
-
def test_path(self, *, path: Path) -> None:
|
83
|
-
assert get_path(path=path) == path
|
84
|
-
|
85
|
-
@given(path=paths())
|
86
|
-
def test_str(self, *, path: Path) -> None:
|
87
|
-
assert get_path(path=str(path)) == path
|
88
|
-
|
89
|
-
def test_none(self) -> None:
|
90
|
-
assert get_path(path=None) == Path.cwd()
|
91
|
-
|
92
|
-
def test_sentinel(self) -> None:
|
93
|
-
assert get_path(path=sentinel) is sentinel
|
94
|
-
|
95
|
-
@given(path1=paths(), path2=paths())
|
96
|
-
def test_replace_non_sentinel(self, *, path1: Path, path2: Path) -> None:
|
97
|
-
@dataclass(kw_only=True, slots=True)
|
98
|
-
class Example:
|
99
|
-
path: Path = field(default_factory=Path.cwd)
|
100
|
-
|
101
|
-
def replace(
|
102
|
-
self, *, path: MaybeCallablePathLike | Sentinel = sentinel
|
103
|
-
) -> Self:
|
104
|
-
return replace_non_sentinel(self, path=get_path(path=path))
|
105
|
-
|
106
|
-
obj = Example(path=path1)
|
107
|
-
assert obj.path == path1
|
108
|
-
assert obj.replace().path == path1
|
109
|
-
assert obj.replace(path=path2).path == path2
|
110
|
-
|
111
|
-
@given(path=paths())
|
112
|
-
def test_callable(self, *, path: Path) -> None:
|
113
|
-
assert get_path(path=lambda: path) == path
|
114
|
-
|
115
|
-
|
116
80
|
class TestGetPackageRoot:
|
117
81
|
@given(tail=paths())
|
118
82
|
@settings(
|
@@ -121,7 +85,7 @@ class TestGetPackageRoot:
|
|
121
85
|
def test_dir(self, *, tmp_path: Path, tail: Path) -> None:
|
122
86
|
tmp_path.joinpath("pyproject.toml").touch()
|
123
87
|
path = tmp_path.joinpath(tail)
|
124
|
-
result = get_package_root(path
|
88
|
+
result = get_package_root(path)
|
125
89
|
expected = tmp_path.resolve()
|
126
90
|
assert result == expected
|
127
91
|
|
@@ -133,20 +97,20 @@ class TestGetPackageRoot:
|
|
133
97
|
tmp_path.joinpath("pyproject.toml").touch()
|
134
98
|
path = tmp_path.joinpath(tail)
|
135
99
|
path.touch()
|
136
|
-
root = get_package_root(path
|
100
|
+
root = get_package_root(path)
|
137
101
|
expected = tmp_path.resolve()
|
138
102
|
assert root == expected
|
139
103
|
|
140
104
|
def test_error(self, *, tmp_path: Path) -> None:
|
141
105
|
with raises(GetPackageRootError, match="Path is not part of a package: .*"):
|
142
|
-
_ = get_package_root(
|
106
|
+
_ = get_package_root(tmp_path)
|
143
107
|
|
144
108
|
|
145
109
|
class TestGetRepoRoot:
|
146
110
|
@given(repo=git_repos(), tail=paths())
|
147
111
|
@settings(max_examples=1)
|
148
112
|
def test_dir(self, *, repo: Path, tail: Path) -> None:
|
149
|
-
root = get_repo_root(
|
113
|
+
root = get_repo_root(repo.joinpath(tail))
|
150
114
|
expected = repo.resolve()
|
151
115
|
assert root == expected
|
152
116
|
|
@@ -155,7 +119,7 @@ class TestGetRepoRoot:
|
|
155
119
|
def test_file(self, *, repo: Path, tail: Path) -> None:
|
156
120
|
path = repo.joinpath(tail)
|
157
121
|
path.touch()
|
158
|
-
root = get_repo_root(path
|
122
|
+
root = get_repo_root(path)
|
159
123
|
expected = repo.resolve()
|
160
124
|
assert root == expected
|
161
125
|
|
@@ -163,14 +127,14 @@ class TestGetRepoRoot:
|
|
163
127
|
with raises(
|
164
128
|
GetRepoRootError, match="Path is not part of a `git` repository: .*"
|
165
129
|
):
|
166
|
-
_ = get_repo_root(
|
130
|
+
_ = get_repo_root(tmp_path)
|
167
131
|
|
168
132
|
|
169
133
|
class TestGetRoot:
|
170
134
|
@given(repo=git_repos(), tail=paths())
|
171
135
|
@settings(max_examples=1)
|
172
136
|
def test_repo_only(self, *, repo: Path, tail: Path) -> None:
|
173
|
-
root = get_root(
|
137
|
+
root = get_root(repo.joinpath(tail))
|
174
138
|
expected = repo.resolve()
|
175
139
|
assert root == expected
|
176
140
|
|
@@ -181,7 +145,7 @@ class TestGetRoot:
|
|
181
145
|
def test_package_only(self, *, tmp_path: Path, tail: Path) -> None:
|
182
146
|
tmp_path.joinpath("pyproject.toml").touch()
|
183
147
|
path = tmp_path.joinpath(tail)
|
184
|
-
result = get_root(path
|
148
|
+
result = get_root(path)
|
185
149
|
expected = tmp_path.resolve()
|
186
150
|
assert result == expected
|
187
151
|
|
@@ -192,7 +156,7 @@ class TestGetRoot:
|
|
192
156
|
def test_repo_and_package(self, *, repo: Path, tail: Path) -> None:
|
193
157
|
repo.joinpath("pyproject.toml").touch()
|
194
158
|
path = repo.joinpath(tail)
|
195
|
-
root = get_root(path
|
159
|
+
root = get_root(path)
|
196
160
|
expected = repo.resolve()
|
197
161
|
assert root == expected
|
198
162
|
|
@@ -204,7 +168,7 @@ class TestGetRoot:
|
|
204
168
|
path = repo.joinpath(tail)
|
205
169
|
path.mkdir(parents=True)
|
206
170
|
path.joinpath("pyproject.toml").touch()
|
207
|
-
root = get_root(path
|
171
|
+
root = get_root(path)
|
208
172
|
expected = path.resolve()
|
209
173
|
assert root == expected
|
210
174
|
|
@@ -217,13 +181,13 @@ class TestGetRoot:
|
|
217
181
|
temp.joinpath("pyproject.toml").touch()
|
218
182
|
path = temp.joinpath(tail)
|
219
183
|
_ = copytree(repo, path)
|
220
|
-
root = get_root(path
|
184
|
+
root = get_root(path)
|
221
185
|
expected = path.resolve()
|
222
186
|
assert root == expected
|
223
187
|
|
224
188
|
def test_error(self, *, tmp_path: Path) -> None:
|
225
189
|
with raises(GetRootError, match="Unable to determine root from '.*'"):
|
226
|
-
_ = get_root(
|
190
|
+
_ = get_root(tmp_path)
|
227
191
|
|
228
192
|
|
229
193
|
class TestGetTail:
|
@@ -317,3 +281,44 @@ class TestTempCWD:
|
|
317
281
|
with temp_cwd(tmp_path):
|
318
282
|
assert Path.cwd() == tmp_path
|
319
283
|
assert Path.cwd() != tmp_path
|
284
|
+
|
285
|
+
|
286
|
+
class TestToPath:
|
287
|
+
def test_default(self) -> None:
|
288
|
+
assert to_path() == Path.cwd()
|
289
|
+
|
290
|
+
@given(path=paths())
|
291
|
+
def test_path(self, *, path: Path) -> None:
|
292
|
+
assert to_path(path) == path
|
293
|
+
|
294
|
+
@given(path=paths())
|
295
|
+
def test_str(self, *, path: Path) -> None:
|
296
|
+
assert to_path(str(path)) == path
|
297
|
+
|
298
|
+
@given(path=paths())
|
299
|
+
def test_callable(self, *, path: Path) -> None:
|
300
|
+
assert to_path(lambda: path) == path
|
301
|
+
|
302
|
+
def test_none(self) -> None:
|
303
|
+
assert to_path(None) == Path.cwd()
|
304
|
+
|
305
|
+
def test_sentinel(self) -> None:
|
306
|
+
assert to_path(sentinel) is sentinel
|
307
|
+
|
308
|
+
@given(paths=pairs(paths()))
|
309
|
+
def test_replace_non_sentinel(self, *, paths: tuple[Path, Path]) -> None:
|
310
|
+
path1, path2 = paths
|
311
|
+
|
312
|
+
@dataclass(kw_only=True, slots=True)
|
313
|
+
class Example:
|
314
|
+
path: Path = field(default_factory=Path.cwd)
|
315
|
+
|
316
|
+
def replace(
|
317
|
+
self, *, path: MaybeCallablePathLike | Sentinel = sentinel
|
318
|
+
) -> Self:
|
319
|
+
return replace_non_sentinel(self, path=to_path(path))
|
320
|
+
|
321
|
+
obj = Example(path=path1)
|
322
|
+
assert obj.path == path1
|
323
|
+
assert obj.replace().path == path1
|
324
|
+
assert obj.replace(path=path2).path == path2
|
@@ -1115,7 +1115,7 @@ class TestDataClassToSchema:
|
|
1115
1115
|
@given(time_zone=timezones())
|
1116
1116
|
def test_date_or_datetime_as_zoned_datetime(self, *, time_zone: ZoneInfo) -> None:
|
1117
1117
|
with assume_does_not_raise(TimeZoneNotFoundError):
|
1118
|
-
now = get_now(time_zone
|
1118
|
+
now = get_now(time_zone).py_datetime()
|
1119
1119
|
|
1120
1120
|
@dataclass(kw_only=True, slots=True)
|
1121
1121
|
class Example:
|
@@ -1247,7 +1247,7 @@ class TestDataClassToSchema:
|
|
1247
1247
|
@given(time_zone=timezones())
|
1248
1248
|
def test_zoned_datetime(self, *, time_zone: ZoneInfo) -> None:
|
1249
1249
|
with assume_does_not_raise(TimeZoneNotFoundError):
|
1250
|
-
now = get_now(time_zone
|
1250
|
+
now = get_now(time_zone).py_datetime()
|
1251
1251
|
|
1252
1252
|
@dataclass(kw_only=True, slots=True)
|
1253
1253
|
class Example:
|
@@ -1261,8 +1261,8 @@ class TestDataClassToSchema:
|
|
1261
1261
|
@given(start=timezones(), end=timezones())
|
1262
1262
|
def test_zoned_datetime_nested(self, *, start: ZoneInfo, end: ZoneInfo) -> None:
|
1263
1263
|
with assume_does_not_raise(TimeZoneNotFoundError):
|
1264
|
-
now_start = get_now(
|
1265
|
-
now_end = get_now(
|
1264
|
+
now_start = get_now(start).py_datetime()
|
1265
|
+
now_end = get_now(end).py_datetime()
|
1266
1266
|
|
1267
1267
|
@dataclass(kw_only=True, slots=True)
|
1268
1268
|
class Inner:
|
@@ -1410,7 +1410,7 @@ class TestFiniteEWMMean:
|
|
1410
1410
|
)
|
1411
1411
|
def test_main(self, *, case: tuple[float, float, list[float], list[float]]) -> None:
|
1412
1412
|
alpha, min_weight, exp_base, exp_result = case
|
1413
|
-
state = get_state(
|
1413
|
+
state = get_state(0)
|
1414
1414
|
series = Series(values=[state.randint(-10, 10) for _ in range(100)])
|
1415
1415
|
base = series.ewm_mean(alpha=alpha)
|
1416
1416
|
exp_base_sr = Series(values=exp_base, dtype=Float64)
|
@@ -23,8 +23,6 @@ from utilities.typing import get_literal_elements
|
|
23
23
|
if TYPE_CHECKING:
|
24
24
|
from pathlib import Path
|
25
25
|
|
26
|
-
from utilities.types import MaybeListStr
|
27
|
-
|
28
26
|
|
29
27
|
@composite
|
30
28
|
def tables(draw: DrawFn, /) -> list[Table | str]:
|
@@ -68,8 +66,8 @@ class TestPGDump:
|
|
68
66
|
format_: _PGDumpFormat,
|
69
67
|
jobs: int | None,
|
70
68
|
create: bool,
|
71
|
-
extension:
|
72
|
-
extension_exc:
|
69
|
+
extension: list[str] | None,
|
70
|
+
extension_exc: list[str] | None,
|
73
71
|
schema: list[str] | None,
|
74
72
|
schema_exc: list[str] | None,
|
75
73
|
table: list[Table | str] | None,
|
@@ -23,7 +23,7 @@ if TYPE_CHECKING:
|
|
23
23
|
from redis.asyncio import Redis
|
24
24
|
from whenever import TimeDelta
|
25
25
|
|
26
|
-
from utilities.types import
|
26
|
+
from utilities.types import LoggerLike
|
27
27
|
|
28
28
|
|
29
29
|
class TestExtendLock:
|
@@ -79,7 +79,7 @@ class TestTryYieldCoroutineLooper:
|
|
79
79
|
lst: list[None],
|
80
80
|
/,
|
81
81
|
*,
|
82
|
-
logger:
|
82
|
+
logger: LoggerLike | None = None,
|
83
83
|
context: ContextVar[bool] | None = None,
|
84
84
|
) -> None:
|
85
85
|
async with try_yield_coroutine_looper(
|
@@ -95,7 +95,7 @@ class TestTryYieldCoroutineLooper:
|
|
95
95
|
lst: list[None],
|
96
96
|
/,
|
97
97
|
*,
|
98
|
-
logger:
|
98
|
+
logger: LoggerLike | None = None,
|
99
99
|
context: ContextVar[bool] | None = None,
|
100
100
|
) -> None:
|
101
101
|
await sleep_td(self.delta)
|
@@ -17,7 +17,7 @@ from hypothesis.strategies import (
|
|
17
17
|
)
|
18
18
|
from pytest import mark, param, raises
|
19
19
|
|
20
|
-
from utilities.hypothesis import text_ascii
|
20
|
+
from utilities.hypothesis import sentinels, text_ascii
|
21
21
|
from utilities.text import (
|
22
22
|
ParseBoolError,
|
23
23
|
ParseNoneError,
|
@@ -37,12 +37,15 @@ from utilities.text import (
|
|
37
37
|
split_str,
|
38
38
|
str_encode,
|
39
39
|
strip_and_dedent,
|
40
|
+
to_bool,
|
40
41
|
unique_str,
|
41
42
|
)
|
42
43
|
|
43
44
|
if TYPE_CHECKING:
|
44
45
|
from collections.abc import Sequence
|
45
46
|
|
47
|
+
from utilities.sentinel import Sentinel
|
48
|
+
|
46
49
|
|
47
50
|
class TestParseBool:
|
48
51
|
@given(data=data(), value=booleans())
|
@@ -323,6 +326,20 @@ class TestStripAndDedent:
|
|
323
326
|
assert result == expected
|
324
327
|
|
325
328
|
|
329
|
+
class TestToBool:
|
330
|
+
@given(bool_=booleans() | none() | sentinels())
|
331
|
+
def test_bool_none_or_sentinel(self, *, bool_: bool | None | Sentinel) -> None:
|
332
|
+
assert to_bool(bool_) is bool_
|
333
|
+
|
334
|
+
@given(bool_=booleans())
|
335
|
+
def test_str(self, *, bool_: bool) -> None:
|
336
|
+
assert to_bool(str(bool_)) is bool_
|
337
|
+
|
338
|
+
@given(bool_=booleans())
|
339
|
+
def test_callable(self, *, bool_: bool) -> None:
|
340
|
+
assert to_bool(lambda: bool_) is bool_
|
341
|
+
|
342
|
+
|
326
343
|
class TestUniqueStrs:
|
327
344
|
def test_main(self) -> None:
|
328
345
|
first, second = [unique_str() for _ in range(2)]
|
@@ -8,7 +8,7 @@ from typing import TYPE_CHECKING
|
|
8
8
|
|
9
9
|
from hypothesis import given
|
10
10
|
from hypothesis.strategies import sampled_from
|
11
|
-
from pytest import CaptureFixture,
|
11
|
+
from pytest import CaptureFixture, raises
|
12
12
|
|
13
13
|
from utilities.iterables import one
|
14
14
|
from utilities.traceback import (
|
@@ -18,13 +18,10 @@ from utilities.traceback import (
|
|
18
18
|
make_except_hook,
|
19
19
|
)
|
20
20
|
from utilities.tzlocal import LOCAL_TIME_ZONE_NAME
|
21
|
-
from utilities.whenever import get_now
|
22
21
|
|
23
22
|
if TYPE_CHECKING:
|
24
23
|
from collections.abc import Iterable
|
25
24
|
|
26
|
-
from utilities.types import MaybeCallableZonedDateTime
|
27
|
-
|
28
25
|
|
29
26
|
class TestFormatExceptionStack:
|
30
27
|
@classmethod
|
@@ -45,14 +42,11 @@ class TestFormatExceptionStack:
|
|
45
42
|
result = format_exception_stack(error).splitlines()
|
46
43
|
self._assert_lines(result)
|
47
44
|
|
48
|
-
|
49
|
-
def test_header(self, *, start: MaybeCallableZonedDateTime) -> None:
|
45
|
+
def test_header(self) -> None:
|
50
46
|
try:
|
51
47
|
_ = self.func(1, 2, 3, 4, c=5, d=6, e=7)
|
52
48
|
except AssertionError as error:
|
53
|
-
result = format_exception_stack(
|
54
|
-
error, header=True, start=start
|
55
|
-
).splitlines()
|
49
|
+
result = format_exception_stack(error, header=True).splitlines()
|
56
50
|
patterns = [
|
57
51
|
rf"^Date/time \| \d{{8}}T\d{{6}}\[{LOCAL_TIME_ZONE_NAME}\]$",
|
58
52
|
rf"^Started \| (\d{{8}}T\d{{6}}\[{LOCAL_TIME_ZONE_NAME}\]|)$",
|
@@ -0,0 +1,89 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
3
|
+
from dataclasses import dataclass, field
|
4
|
+
from re import search
|
5
|
+
from typing import TYPE_CHECKING, Self
|
6
|
+
from uuid import UUID
|
7
|
+
|
8
|
+
from hypothesis import given
|
9
|
+
from hypothesis.strategies import integers, none, randoms, uuids
|
10
|
+
|
11
|
+
from utilities.dataclasses import replace_non_sentinel
|
12
|
+
from utilities.hypothesis import pairs
|
13
|
+
from utilities.sentinel import Sentinel, sentinel
|
14
|
+
from utilities.uuid import UUID_EXACT_PATTERN, UUID_PATTERN, get_uuid, to_uuid
|
15
|
+
|
16
|
+
if TYPE_CHECKING:
|
17
|
+
from random import Random
|
18
|
+
|
19
|
+
from utilities.sentinel import Sentinel
|
20
|
+
from utilities.types import MaybeCallableUUIDLike
|
21
|
+
|
22
|
+
|
23
|
+
class TestGetUUID:
|
24
|
+
@given(seed=randoms() | none())
|
25
|
+
def test_main(self, *, seed: Random | None) -> None:
|
26
|
+
assert isinstance(get_uuid(seed), UUID)
|
27
|
+
|
28
|
+
@given(seed=integers())
|
29
|
+
def test_deterministic(self, *, seed: int) -> None:
|
30
|
+
uuid1, uuid2 = [get_uuid(seed) for _ in range(2)]
|
31
|
+
assert uuid1 == uuid2
|
32
|
+
|
33
|
+
|
34
|
+
class TestToUUID:
|
35
|
+
def test_default(self) -> None:
|
36
|
+
assert isinstance(to_uuid(), UUID)
|
37
|
+
|
38
|
+
@given(uuid=uuids())
|
39
|
+
def test_uuid(self, *, uuid: UUID) -> None:
|
40
|
+
assert to_uuid(uuid) == uuid
|
41
|
+
|
42
|
+
@given(uuid=uuids())
|
43
|
+
def test_str(self, *, uuid: UUID) -> None:
|
44
|
+
assert to_uuid(str(uuid)) == uuid
|
45
|
+
|
46
|
+
@given(seed=randoms())
|
47
|
+
def test_seed(self, *, seed: Random) -> None:
|
48
|
+
assert isinstance(to_uuid(seed), UUID)
|
49
|
+
|
50
|
+
@given(uuid=uuids())
|
51
|
+
def test_callable(self, *, uuid: UUID) -> None:
|
52
|
+
assert to_uuid(lambda: uuid) == uuid
|
53
|
+
|
54
|
+
def test_none(self) -> None:
|
55
|
+
assert isinstance(to_uuid(None), UUID)
|
56
|
+
|
57
|
+
def test_sentinel(self) -> None:
|
58
|
+
assert to_uuid(sentinel) is sentinel
|
59
|
+
|
60
|
+
@given(uuids=pairs(uuids()))
|
61
|
+
def test_replace_non_sentinel(self, *, uuids: tuple[UUID, UUID]) -> None:
|
62
|
+
uuid1, uuid2 = uuids
|
63
|
+
|
64
|
+
@dataclass(kw_only=True, slots=True)
|
65
|
+
class Example:
|
66
|
+
uuid: UUID = field(default_factory=get_uuid)
|
67
|
+
|
68
|
+
def replace(
|
69
|
+
self, *, uuid: MaybeCallableUUIDLike | Sentinel = sentinel
|
70
|
+
) -> Self:
|
71
|
+
return replace_non_sentinel(self, uuid=to_uuid(uuid))
|
72
|
+
|
73
|
+
obj = Example(uuid=uuid1)
|
74
|
+
assert obj.uuid == uuid1
|
75
|
+
assert obj.replace().uuid == uuid1
|
76
|
+
assert obj.replace(uuid=uuid2).uuid == uuid2
|
77
|
+
assert isinstance(obj.replace(uuid=get_uuid).uuid, UUID)
|
78
|
+
|
79
|
+
|
80
|
+
class TestUUIDPattern:
|
81
|
+
@given(uuid=uuids())
|
82
|
+
def test_main(self, *, uuid: UUID) -> None:
|
83
|
+
assert search(UUID_PATTERN, str(uuid))
|
84
|
+
|
85
|
+
@given(uuid=uuids())
|
86
|
+
def test_exact(self, *, uuid: UUID) -> None:
|
87
|
+
text = f".{uuid}."
|
88
|
+
assert search(UUID_PATTERN, text)
|
89
|
+
assert not search(UUID_EXACT_PATTERN, text)
|