dycw-utilities 0.168.1__tar.gz → 0.168.3__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.168.1 → dycw_utilities-0.168.3}/PKG-INFO +1 -1
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/pyproject.toml +2 -2
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_logging.py +2 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_pydantic_settings.py +125 -4
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/__init__.py +1 -1
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/pydantic_settings.py +77 -7
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/.gitignore +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/LICENSE +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/README.md +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/__init__.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/conftest.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/modules/__init__.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/modules/package_missing/__init__.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/modules/package_missing/module.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/modules/package_with/__init__.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/modules/package_with/outer_1.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/modules/package_with/outer_2.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/modules/package_with/subpackage/__init__.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/modules/package_with/subpackage/inner_1.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/modules/package_with/subpackage/inner_2.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/modules/package_with/subpackage/inner_3.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/modules/package_without/__init__.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/modules/package_without/module_1.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/modules/package_without/module_2.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/modules/standalone.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/modules/with_imports.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/regressions/test_pytest_regressions/TestMultipleRegressionFixtures__test_main__obj.json +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/regressions/test_pytest_regressions/TestMultipleRegressionFixtures__test_main__series.json +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_int.json +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_literal__false.json +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_literal__true.json +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_nested.json +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/regressions/test_pytest_regressions/TestPolarsRegressionFixture__test_dataframe.json +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/regressions/test_pytest_regressions/TestPolarsRegressionFixture__test_series.json +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_aeventkit.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_altair.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_asyncio.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_atomicwrites.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_atools.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_cachetools.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_click.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_concurrent.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_contextlib.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_contextvars.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_cryptography.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_cvxpy.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_dataclasses.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_docker.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_enum.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_errors.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_fastapi.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_fpdf2.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_functions.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_functools.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_getpass.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_git.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_gzip.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_hashlib.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_http.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_hypothesis.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_importlib.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_inflect.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_ipython.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_iterables.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_jinja2.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_json.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_jupyter.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_libcst.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_lightweight_charts.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_math.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_memory_profiler.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_modules.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_more_itertools.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_numpy.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_objects/__init__.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_objects/objects.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_operator.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_optuna.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_orjson.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_os.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_parse.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_pathlib.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_pickle.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_platform.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_polars.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_polars_ols.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_postgres.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_pottery.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_pqdm.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_psutil.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_pydantic_settings_sops.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_pyinstrument.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_pytest.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_pytest_randomly.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_pytest_regressions.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_random.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_re.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_redis.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_reprlib.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_scipy.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_sentinel.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_shelve.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_slack_sdk.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_socket.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_sqlalchemy.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_sqlalchemy_polars.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_statsmodels.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_string.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_tempfile.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_testbook.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_text.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_threading.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_timer.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_traceback.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_typed_settings.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_types.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_typing.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_typing_funcs/__init__.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_typing_funcs/no_future.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_typing_funcs/with_future.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_tzdata.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_tzlocal.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_uuid.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_version.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_warnings.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_whenever.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_zipfile.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_zoneinfo.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/aeventkit.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/altair.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/asyncio.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/atomicwrites.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/atools.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/cachetools.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/click.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/concurrent.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/contextlib.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/contextvars.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/cryptography.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/cvxpy.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/dataclasses.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/docker.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/enum.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/errors.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/fastapi.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/fpdf2.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/functions.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/functools.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/getpass.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/git.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/gzip.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/hashlib.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/http.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/hypothesis.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/importlib.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/inflect.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/ipython.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/iterables.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/jinja2.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/json.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/jupyter.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/libcst.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/lightweight_charts.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/logging.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/math.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/memory_profiler.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/modules.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/more_itertools.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/numpy.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/operator.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/optuna.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/orjson.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/os.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/parse.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/pathlib.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/pickle.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/platform.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/polars.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/polars_ols.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/postgres.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/pottery.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/pqdm.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/psutil.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/py.typed +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/pydantic_settings_sops.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/pyinstrument.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/pytest.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/pytest_plugins/__init__.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/pytest_plugins/pytest_randomly.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/pytest_plugins/pytest_regressions.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/pytest_regressions.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/random.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/re.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/redis.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/reprlib.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/scipy.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/sentinel.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/shelve.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/slack_sdk.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/socket.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/sqlalchemy.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/sqlalchemy_polars.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/statsmodels.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/string.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/tempfile.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/testbook.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/text.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/threading.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/timer.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/traceback.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/typed_settings.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/types.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/typing.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/tzdata.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/tzlocal.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/uuid.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/version.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/warnings.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/whenever.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/zipfile.py +0 -0
- {dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/utilities/zoneinfo.py +0 -0
|
@@ -249,7 +249,7 @@ dependencies = [
|
|
|
249
249
|
name = "dycw-utilities"
|
|
250
250
|
readme = "README.md"
|
|
251
251
|
requires-python = ">= 3.12"
|
|
252
|
-
version = "0.168.
|
|
252
|
+
version = "0.168.3"
|
|
253
253
|
|
|
254
254
|
[project.entry-points.pytest11]
|
|
255
255
|
pytest-randomly = "utilities.pytest_plugins.pytest_randomly"
|
|
@@ -282,7 +282,7 @@ test = [
|
|
|
282
282
|
# bump-my-version
|
|
283
283
|
[tool.bumpversion]
|
|
284
284
|
allow_dirty = true
|
|
285
|
-
current_version = "0.168.
|
|
285
|
+
current_version = "0.168.3"
|
|
286
286
|
|
|
287
287
|
[[tool.bumpversion.files]]
|
|
288
288
|
filename = "src/utilities/__init__.py"
|
|
@@ -449,10 +449,12 @@ class TestSizeAndTimeRotatingFileHandler:
|
|
|
449
449
|
)
|
|
450
450
|
)
|
|
451
451
|
|
|
452
|
+
await sleep(0.1)
|
|
452
453
|
files = list(tmp_path.iterdir())
|
|
453
454
|
assert len(files) == 1
|
|
454
455
|
assert any(p for p in files if search(r"^log\.txt$", p.name))
|
|
455
456
|
|
|
457
|
+
await sleep(0.1)
|
|
456
458
|
logger.warning("message 1")
|
|
457
459
|
files = list(tmp_path.iterdir())
|
|
458
460
|
assert len(files) == 1
|
|
@@ -1,15 +1,20 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import json
|
|
4
|
+
from stat import S_IXUSR
|
|
5
|
+
from subprocess import STDOUT, CalledProcessError, check_output
|
|
4
6
|
from typing import TYPE_CHECKING, ClassVar
|
|
5
7
|
|
|
6
8
|
import tomlkit
|
|
7
9
|
import yaml
|
|
8
10
|
from pydantic_settings import BaseSettings, SettingsConfigDict
|
|
11
|
+
from pytest import mark, param
|
|
9
12
|
|
|
13
|
+
from tests.conftest import SKIPIF_CI_AND_WINDOWS
|
|
10
14
|
from utilities.os import temp_environ
|
|
11
15
|
from utilities.pydantic_settings import (
|
|
12
16
|
CustomBaseSettings,
|
|
17
|
+
HashableBaseSettings,
|
|
13
18
|
PathLikeOrWithSection,
|
|
14
19
|
load_settings,
|
|
15
20
|
)
|
|
@@ -101,11 +106,12 @@ class TestCustomBaseSettings:
|
|
|
101
106
|
settings = load_settings(Settings)
|
|
102
107
|
assert settings.x == 1
|
|
103
108
|
|
|
104
|
-
|
|
109
|
+
@mark.parametrize("inner_cls", [param(BaseSettings), param(HashableBaseSettings)])
|
|
110
|
+
def test_env_var_with_nested(self, *, inner_cls: type[BaseSettings]) -> None:
|
|
105
111
|
class Settings(CustomBaseSettings):
|
|
106
112
|
inner: Inner
|
|
107
113
|
|
|
108
|
-
class Inner(
|
|
114
|
+
class Inner(inner_cls):
|
|
109
115
|
x: int
|
|
110
116
|
|
|
111
117
|
_ = Settings.model_rebuild()
|
|
@@ -114,12 +120,15 @@ class TestCustomBaseSettings:
|
|
|
114
120
|
settings = load_settings(Settings)
|
|
115
121
|
assert settings.inner.x == 1
|
|
116
122
|
|
|
117
|
-
|
|
123
|
+
@mark.parametrize("inner_cls", [param(BaseSettings), param(HashableBaseSettings)])
|
|
124
|
+
def test_env_var_with_prefix_and_nested(
|
|
125
|
+
self, *, inner_cls: type[BaseSettings]
|
|
126
|
+
) -> None:
|
|
118
127
|
class Settings(CustomBaseSettings):
|
|
119
128
|
model_config = SettingsConfigDict(env_prefix="test__")
|
|
120
129
|
inner: Inner
|
|
121
130
|
|
|
122
|
-
class Inner(
|
|
131
|
+
class Inner(inner_cls):
|
|
123
132
|
x: int
|
|
124
133
|
|
|
125
134
|
_ = Settings.model_rebuild()
|
|
@@ -131,3 +140,115 @@ class TestCustomBaseSettings:
|
|
|
131
140
|
class Settings(CustomBaseSettings): ...
|
|
132
141
|
|
|
133
142
|
_ = load_settings(Settings)
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
class TestHashableBaseSettings:
|
|
146
|
+
def test_hashable(self) -> None:
|
|
147
|
+
class Settings(HashableBaseSettings):
|
|
148
|
+
x: int = 1
|
|
149
|
+
|
|
150
|
+
settings = load_settings(Settings)
|
|
151
|
+
_ = hash(settings)
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
class TestLoadSettings:
|
|
155
|
+
@mark.parametrize(
|
|
156
|
+
("args", "expected"),
|
|
157
|
+
[
|
|
158
|
+
param([], "settings=_Settings(a=1, b=2, inner=_Inner(c=3, d=4))"),
|
|
159
|
+
param(["-a", "5"], "settings=_Settings(a=5, b=2, inner=_Inner(c=3, d=4))"),
|
|
160
|
+
param(
|
|
161
|
+
["--inner.c", "5"],
|
|
162
|
+
"settings=_Settings(a=1, b=2, inner=_Inner(c=5, d=4))",
|
|
163
|
+
),
|
|
164
|
+
param(
|
|
165
|
+
["-h"],
|
|
166
|
+
"""
|
|
167
|
+
usage: script.py [-h] [-a int] [-b int] [--inner [JSON]] [--inner.c int]
|
|
168
|
+
[--inner.d int]
|
|
169
|
+
|
|
170
|
+
options:
|
|
171
|
+
-h, --help show this help message and exit
|
|
172
|
+
-a int (default: 1)
|
|
173
|
+
-b int (default: 2)
|
|
174
|
+
|
|
175
|
+
inner options:
|
|
176
|
+
--inner [JSON] set inner from JSON string (default: {})
|
|
177
|
+
--inner.c int (default: 3)
|
|
178
|
+
--inner.d int (default: 4)
|
|
179
|
+
""",
|
|
180
|
+
),
|
|
181
|
+
],
|
|
182
|
+
)
|
|
183
|
+
@SKIPIF_CI_AND_WINDOWS
|
|
184
|
+
def test_cli(self, *, tmp_path: Path, args: list[str], expected: str) -> None:
|
|
185
|
+
script = tmp_path.joinpath("script.py")
|
|
186
|
+
_ = script.write_text("""\
|
|
187
|
+
#!/usr/bin/env python3
|
|
188
|
+
from __future__ import annotations
|
|
189
|
+
|
|
190
|
+
from collections.abc import Sequence
|
|
191
|
+
from pathlib import Path
|
|
192
|
+
from typing import ClassVar
|
|
193
|
+
|
|
194
|
+
from pydantic_settings import BaseSettings
|
|
195
|
+
|
|
196
|
+
from utilities.pydantic_settings import CustomBaseSettings, PathLikeOrWithSection, load_settings
|
|
197
|
+
|
|
198
|
+
class _Settings(CustomBaseSettings):
|
|
199
|
+
toml_files: ClassVar[Sequence[PathLikeOrWithSection]] = [
|
|
200
|
+
Path(__file__).parent.joinpath("config.toml")
|
|
201
|
+
]
|
|
202
|
+
|
|
203
|
+
a: int
|
|
204
|
+
b: int
|
|
205
|
+
inner: _Inner
|
|
206
|
+
|
|
207
|
+
class _Inner(BaseSettings):
|
|
208
|
+
c: int
|
|
209
|
+
d: int
|
|
210
|
+
|
|
211
|
+
def main() -> None:
|
|
212
|
+
settings = load_settings(_Settings, cli=True)
|
|
213
|
+
print(f"{settings=}")
|
|
214
|
+
|
|
215
|
+
if __name__ == "__main__":
|
|
216
|
+
main()
|
|
217
|
+
""")
|
|
218
|
+
script.chmod(script.stat().st_mode | S_IXUSR)
|
|
219
|
+
config = tmp_path.joinpath("config.toml")
|
|
220
|
+
_ = config.write_text(
|
|
221
|
+
"""\
|
|
222
|
+
a = 1
|
|
223
|
+
b = 2
|
|
224
|
+
|
|
225
|
+
[inner]
|
|
226
|
+
c = 3
|
|
227
|
+
d = 4
|
|
228
|
+
"""
|
|
229
|
+
)
|
|
230
|
+
try:
|
|
231
|
+
result = check_output([script, *args], stderr=STDOUT, text=True).strip("\n")
|
|
232
|
+
except CalledProcessError as error:
|
|
233
|
+
raise RuntimeError(error.stdout) from None
|
|
234
|
+
assert result == expected.strip("\n")
|
|
235
|
+
|
|
236
|
+
def test_cli_coverage(self, *, tmp_path: Path) -> None:
|
|
237
|
+
config = tmp_path.joinpath("config.toml")
|
|
238
|
+
_ = config.write_text("""
|
|
239
|
+
a = 1
|
|
240
|
+
|
|
241
|
+
[inner]
|
|
242
|
+
b = 2""")
|
|
243
|
+
|
|
244
|
+
class Example(CustomBaseSettings):
|
|
245
|
+
toml_files: ClassVar[Sequence[PathLikeOrWithSection]] = [config]
|
|
246
|
+
|
|
247
|
+
a: int
|
|
248
|
+
inner: _Inner
|
|
249
|
+
|
|
250
|
+
class _Inner(BaseSettings):
|
|
251
|
+
b: int
|
|
252
|
+
|
|
253
|
+
_ = Example.model_rebuild()
|
|
254
|
+
_ = load_settings(Example, cli=True)
|
|
@@ -2,10 +2,12 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
from functools import reduce
|
|
4
4
|
from pathlib import Path
|
|
5
|
-
from typing import TYPE_CHECKING, Any, ClassVar, assert_never, override
|
|
5
|
+
from typing import TYPE_CHECKING, Any, ClassVar, assert_never, cast, override
|
|
6
6
|
|
|
7
|
+
from pydantic import Field, create_model
|
|
7
8
|
from pydantic_settings import (
|
|
8
9
|
BaseSettings,
|
|
10
|
+
CliSettingsSource,
|
|
9
11
|
JsonConfigSettingsSource,
|
|
10
12
|
PydanticBaseSettingsSource,
|
|
11
13
|
SettingsConfigDict,
|
|
@@ -14,6 +16,7 @@ from pydantic_settings import (
|
|
|
14
16
|
)
|
|
15
17
|
from pydantic_settings.sources import DEFAULT_PATH
|
|
16
18
|
|
|
19
|
+
from utilities.errors import ImpossibleCaseError
|
|
17
20
|
from utilities.iterables import always_iterable
|
|
18
21
|
|
|
19
22
|
if TYPE_CHECKING:
|
|
@@ -29,7 +32,7 @@ type PathLikeOrWithSection = PathLike | PathLikeWithSection
|
|
|
29
32
|
|
|
30
33
|
|
|
31
34
|
class CustomBaseSettings(BaseSettings):
|
|
32
|
-
"""Base settings for loading JSON files."""
|
|
35
|
+
"""Base settings for loading JSON/TOML/YAML files."""
|
|
33
36
|
|
|
34
37
|
# paths
|
|
35
38
|
json_files: ClassVar[Sequence[PathLikeOrWithSection]] = []
|
|
@@ -76,11 +79,6 @@ class CustomBaseSettings(BaseSettings):
|
|
|
76
79
|
)
|
|
77
80
|
|
|
78
81
|
|
|
79
|
-
def load_settings[T: BaseSettings](cls: type[T], /) -> T:
|
|
80
|
-
"""Load a set of settings."""
|
|
81
|
-
return cls()
|
|
82
|
-
|
|
83
|
-
|
|
84
82
|
class JsonConfigSectionSettingsSource(JsonConfigSettingsSource):
|
|
85
83
|
@override
|
|
86
84
|
def __init__(
|
|
@@ -158,8 +156,80 @@ def _get_section(
|
|
|
158
156
|
return reduce(lambda acc, el: acc.get(el, {}), always_iterable(section), mapping)
|
|
159
157
|
|
|
160
158
|
|
|
159
|
+
##
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
class HashableBaseSettings(BaseSettings):
|
|
163
|
+
"""Base settings for loading JSON files."""
|
|
164
|
+
|
|
165
|
+
# config
|
|
166
|
+
model_config: ClassVar[SettingsConfigDict] = SettingsConfigDict(frozen=True)
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
##
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
def load_settings[T: BaseSettings](cls: type[T], /, *, cli: bool = False) -> T:
|
|
173
|
+
"""Load a set of settings."""
|
|
174
|
+
_ = cls.model_rebuild()
|
|
175
|
+
if cli:
|
|
176
|
+
cls_with_defaults = _load_settings_create_model(cls)
|
|
177
|
+
|
|
178
|
+
@classmethod
|
|
179
|
+
def settings_customise_sources(
|
|
180
|
+
cls: type[BaseSettings],
|
|
181
|
+
settings_cls: type[BaseSettings],
|
|
182
|
+
init_settings: PydanticBaseSettingsSource,
|
|
183
|
+
env_settings: PydanticBaseSettingsSource,
|
|
184
|
+
dotenv_settings: PydanticBaseSettingsSource,
|
|
185
|
+
file_secret_settings: PydanticBaseSettingsSource,
|
|
186
|
+
) -> tuple[PydanticBaseSettingsSource, ...]:
|
|
187
|
+
parent = cast(
|
|
188
|
+
"Any", super(cls_with_defaults, cls)
|
|
189
|
+
).settings_customise_sources(
|
|
190
|
+
settings_cls=settings_cls,
|
|
191
|
+
init_settings=init_settings,
|
|
192
|
+
env_settings=env_settings,
|
|
193
|
+
dotenv_settings=dotenv_settings,
|
|
194
|
+
file_secret_settings=file_secret_settings,
|
|
195
|
+
)
|
|
196
|
+
return (
|
|
197
|
+
CliSettingsSource(
|
|
198
|
+
settings_cls, cli_parse_args=True, case_sensitive=False
|
|
199
|
+
),
|
|
200
|
+
*parent,
|
|
201
|
+
)
|
|
202
|
+
|
|
203
|
+
cls_use = type(
|
|
204
|
+
cls.__name__,
|
|
205
|
+
(cls_with_defaults,),
|
|
206
|
+
{"settings_customise_sources": settings_customise_sources},
|
|
207
|
+
)
|
|
208
|
+
cls_use = cast("type[T]", cls_use)
|
|
209
|
+
else:
|
|
210
|
+
cls_use = cls
|
|
211
|
+
return cls_use()
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
def _load_settings_create_model[T: BaseSettings](
|
|
215
|
+
cls: type[T], /, *, values: T | None = None
|
|
216
|
+
) -> type[T]:
|
|
217
|
+
values_use = cls() if values is None else values
|
|
218
|
+
kwargs: dict[str, Any] = {}
|
|
219
|
+
for name, field in cls.model_fields.items():
|
|
220
|
+
if (ann := field.annotation) is None:
|
|
221
|
+
raise ImpossibleCaseError(case=[f"{ann=}"]) # pragma: no cover
|
|
222
|
+
value = getattr(values_use, name)
|
|
223
|
+
if issubclass(ann, BaseSettings):
|
|
224
|
+
kwargs[name] = _load_settings_create_model(ann, values=value)
|
|
225
|
+
else:
|
|
226
|
+
kwargs[name] = (field.annotation, Field(default=value))
|
|
227
|
+
return create_model(cls.__name__, __base__=cls, **kwargs)
|
|
228
|
+
|
|
229
|
+
|
|
161
230
|
__all__ = [
|
|
162
231
|
"CustomBaseSettings",
|
|
232
|
+
"HashableBaseSettings",
|
|
163
233
|
"JsonConfigSectionSettingsSource",
|
|
164
234
|
"TomlConfigSectionSettingsSource",
|
|
165
235
|
"YamlConfigSectionSettingsSource",
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/modules/package_missing/__init__.py
RENAMED
|
File without changes
|
{dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/modules/package_missing/module.py
RENAMED
|
File without changes
|
{dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/modules/package_with/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/modules/package_without/__init__.py
RENAMED
|
File without changes
|
{dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/modules/package_without/module_1.py
RENAMED
|
File without changes
|
{dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/modules/package_without/module_2.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dycw_utilities-0.168.1 → dycw_utilities-0.168.3}/src/tests/test_typing_funcs/with_future.py
RENAMED
|
File without changes
|
|
File without changes
|