dycw-utilities 0.108.4__tar.gz → 0.109.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.108.4 → dycw_utilities-0.109.1}/PKG-INFO +1 -1
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/pyproject.toml +2 -2
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_dataclasses.py +210 -107
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_operator.py +22 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_orjson.py +20 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_parse.py +10 -1
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_polars.py +0 -184
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_python_dotenv.py +4 -20
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_typing.py +27 -13
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_typing_funcs/no_future.py +4 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_typing_funcs/with_future.py +24 -12
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/utilities/__init__.py +1 -1
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/utilities/dataclasses.py +202 -104
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/utilities/parse.py +2 -2
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/utilities/polars.py +0 -99
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/utilities/python_dotenv.py +24 -43
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/.gitignore +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/LICENSE +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/README.md +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/__init__.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/conftest.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/modules/__init__.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/modules/package_missing/__init__.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/modules/package_missing/module.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/modules/package_with/__init__.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/modules/package_with/outer_1.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/modules/package_with/outer_2.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/modules/package_with/subpackage/__init__.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/modules/package_with/subpackage/inner_1.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/modules/package_with/subpackage/inner_2.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/modules/package_with/subpackage/inner_3.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/modules/package_without/__init__.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/modules/package_without/module_1.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/modules/package_without/module_2.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/modules/standalone.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/modules/with_imports.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/regressions/test_pytest_regressions/TestMultipleRegressionFixtures__test_main__obj.json +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/regressions/test_pytest_regressions/TestMultipleRegressionFixtures__test_main__series.json +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_int.json +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_literal__false.json +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_literal__true.json +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_nested.json +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/regressions/test_pytest_regressions/TestPolarsRegressionFixture__test_dataframe.json +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/regressions/test_pytest_regressions/TestPolarsRegressionFixture__test_series.json +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/scripts/__init__.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/scripts/test_async_service/__init__.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/scripts/test_async_service/__main__.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/scripts/test_async_service/run.sh +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/scripts/test_queue_processor/__init__.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/scripts/test_queue_processor/__main__.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/scripts/test_queue_processor/run.sh +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_altair.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_astor.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_asyncio.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_atomicwrites.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_atools.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_cachetools.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_click.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_concurrent.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_contextlib.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_contextvars.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_cryptography.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_cvxpy.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_datetime.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_enum.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_errors.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_eventkit.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_fastapi.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_fpdf2.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_functions.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_functools.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_getpass.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_git.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_hashlib.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_http.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_hypothesis.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_ipython.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_iterables.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_jupyter.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_logging.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_loguru.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_luigi.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_math.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_memory_profiler.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_modules.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_more_itertools.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_numpy.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_optuna.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_os.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_pathlib.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_period.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_pickle.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_platform.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_pqdm.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_pydantic.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_pyinstrument.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_pyrsistent.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_pytest.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_pytest_regressions.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_random.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_re.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_redis.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_reprlib.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_rich.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_scipy.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_sentinel.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_shelve.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_slack_sdk.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_socket.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_sqlalchemy.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_sqlalchemy_polars.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_streamlit.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_sys.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_tempfile.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_tenacity.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_text.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_threading.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_timer.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_traceback.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_traceback_funcs/__init__.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_traceback_funcs/chain.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_traceback_funcs/decorated_async.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_traceback_funcs/decorated_sync.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_traceback_funcs/error_bind.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_traceback_funcs/many.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_traceback_funcs/one.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_traceback_funcs/recursive.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_traceback_funcs/task_group_one.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_traceback_funcs/task_group_two.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_traceback_funcs/two.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_traceback_funcs/untraced.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_types.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_typing_funcs/__init__.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_tzdata.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_tzlocal.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_uuid.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_version.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_warnings.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_whenever.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_zipfile.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/tests/test_zoneinfo.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/utilities/altair.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/utilities/astor.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/utilities/asyncio.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/utilities/atomicwrites.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/utilities/atools.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/utilities/cachetools.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/utilities/click.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/utilities/concurrent.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/utilities/contextlib.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/utilities/contextvars.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/utilities/cryptography.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/utilities/cvxpy.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/utilities/datetime.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/utilities/enum.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/utilities/errors.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/utilities/eventkit.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/utilities/fastapi.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/utilities/fpdf2.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/utilities/functions.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/utilities/functools.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/utilities/getpass.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/utilities/git.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/utilities/hashlib.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/utilities/http.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/utilities/hypothesis.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/utilities/ipython.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/utilities/iterables.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/utilities/jupyter.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/utilities/logging.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/utilities/loguru.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/utilities/luigi.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/utilities/math.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/utilities/memory_profiler.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/utilities/modules.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/utilities/more_itertools.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/utilities/numpy.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/utilities/operator.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/utilities/optuna.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/utilities/orjson.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/utilities/os.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/utilities/pathlib.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/utilities/period.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/utilities/pickle.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/utilities/platform.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/utilities/pqdm.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/utilities/py.typed +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/utilities/pydantic.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/utilities/pyinstrument.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/utilities/pyrsistent.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/utilities/pytest.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/utilities/pytest_regressions.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/utilities/random.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/utilities/re.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/utilities/redis.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/utilities/reprlib.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/utilities/rich.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/utilities/scipy.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/utilities/sentinel.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/utilities/shelve.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/utilities/slack_sdk.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/utilities/socket.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/utilities/sqlalchemy.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/utilities/sqlalchemy_polars.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/utilities/streamlit.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/utilities/sys.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/utilities/tempfile.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/utilities/tenacity.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/utilities/text.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/utilities/threading.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/utilities/timer.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/utilities/traceback.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/utilities/types.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/utilities/typing.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/utilities/tzdata.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/utilities/tzlocal.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/utilities/uuid.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/utilities/version.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/utilities/warnings.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/utilities/whenever.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/utilities/zipfile.py +0 -0
- {dycw_utilities-0.108.4 → dycw_utilities-0.109.1}/src/utilities/zoneinfo.py +0 -0
@@ -89,7 +89,7 @@ dependencies = [
|
|
89
89
|
name = "dycw-utilities"
|
90
90
|
readme = "README.md"
|
91
91
|
requires-python = ">= 3.12"
|
92
|
-
version = "0.
|
92
|
+
version = "0.109.1"
|
93
93
|
|
94
94
|
[project.optional-dependencies]
|
95
95
|
test = [
|
@@ -332,7 +332,7 @@ zzz-test-zoneinfo = [
|
|
332
332
|
# bump-my-version
|
333
333
|
[tool.bumpversion]
|
334
334
|
allow_dirty = true
|
335
|
-
current_version = "0.
|
335
|
+
current_version = "0.109.1"
|
336
336
|
|
337
337
|
[[tool.bumpversion.files]]
|
338
338
|
filename = "src/utilities/__init__.py"
|
@@ -1,22 +1,12 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
|
-
import re
|
4
3
|
from dataclasses import dataclass, field
|
5
4
|
from pathlib import Path
|
6
|
-
from re import DOTALL
|
7
5
|
from types import NoneType
|
8
|
-
from typing import Any,
|
6
|
+
from typing import Any, cast, override
|
9
7
|
|
10
8
|
from hypothesis import given
|
11
|
-
from hypothesis.strategies import
|
12
|
-
DataObject,
|
13
|
-
booleans,
|
14
|
-
data,
|
15
|
-
integers,
|
16
|
-
lists,
|
17
|
-
none,
|
18
|
-
sampled_from,
|
19
|
-
)
|
9
|
+
from hypothesis.strategies import booleans, integers, lists, sampled_from
|
20
10
|
from polars import DataFrame
|
21
11
|
from pytest import raises
|
22
12
|
|
@@ -27,7 +17,8 @@ from tests.test_typing_funcs.no_future import (
|
|
27
17
|
from tests.test_typing_funcs.with_future import (
|
28
18
|
DataClassFutureInt,
|
29
19
|
DataClassFutureIntDefault,
|
30
|
-
|
20
|
+
DataClassFutureIntLowerAndUpper,
|
21
|
+
DataClassFutureIntOneAndTwo,
|
31
22
|
DataClassFutureListInts,
|
32
23
|
DataClassFutureListIntsDefault,
|
33
24
|
DataClassFutureLiteral,
|
@@ -36,17 +27,17 @@ from tests.test_typing_funcs.with_future import (
|
|
36
27
|
DataClassFutureNestedOuterFirstOuter,
|
37
28
|
DataClassFutureNone,
|
38
29
|
DataClassFutureNoneDefault,
|
39
|
-
DataClassFuturePath,
|
40
|
-
DataClassFutureStr,
|
41
30
|
DataClassFutureTypeLiteral,
|
42
31
|
DataClassFutureTypeLiteralNullable,
|
32
|
+
TrueOrFalseFutureLit,
|
33
|
+
TrueOrFalseFutureTypeLit,
|
43
34
|
)
|
44
35
|
from utilities.dataclasses import (
|
36
|
+
MappingToDataclassError,
|
37
|
+
OneFieldEmptyError,
|
38
|
+
OneFieldNonUniqueError,
|
39
|
+
StrMappingToFieldMappingError,
|
45
40
|
YieldFieldsError,
|
46
|
-
_MappingToDataclassCaseInsensitiveNonUniqueError,
|
47
|
-
_MappingToDataclassEmptyError,
|
48
|
-
_TextToDataClassGetFieldEmptyError,
|
49
|
-
_TextToDataClassGetFieldNonUniqueError,
|
50
41
|
_TextToDataClassParseValueError,
|
51
42
|
_TextToDataClassSplitKeyValuePairError,
|
52
43
|
_YieldFieldsClass,
|
@@ -54,12 +45,13 @@ from utilities.dataclasses import (
|
|
54
45
|
dataclass_repr,
|
55
46
|
dataclass_to_dict,
|
56
47
|
mapping_to_dataclass,
|
48
|
+
one_field,
|
57
49
|
replace_non_sentinel,
|
50
|
+
str_mapping_to_field_mapping,
|
58
51
|
text_to_dataclass,
|
59
52
|
yield_fields,
|
60
53
|
)
|
61
54
|
from utilities.functions import get_class_name
|
62
|
-
from utilities.hypothesis import paths, text_ascii
|
63
55
|
from utilities.iterables import one
|
64
56
|
from utilities.orjson import OrjsonLogRecord
|
65
57
|
from utilities.polars import are_frames_equal
|
@@ -67,8 +59,6 @@ from utilities.sentinel import sentinel
|
|
67
59
|
from utilities.types import Dataclass, StrMapping
|
68
60
|
from utilities.typing import get_args, is_list_type, is_literal_type, is_optional_type
|
69
61
|
|
70
|
-
TruthLit = Literal["true", "false"] # in 3.12, use type TruthLit = ...
|
71
|
-
|
72
62
|
|
73
63
|
class TestDataClassRepr:
|
74
64
|
def test_overriding_repr(self) -> None:
|
@@ -273,82 +263,102 @@ class TestDataclassToDictAndDataclassRepr:
|
|
273
263
|
|
274
264
|
|
275
265
|
class TestMappingToDataclass:
|
276
|
-
@given(int_=integers())
|
277
|
-
def test_int_case_sensitive(self, *, int_: int) -> None:
|
278
|
-
obj = mapping_to_dataclass(DataClassFutureInt, {"int_": int_})
|
279
|
-
expected = DataClassFutureInt(int_=int_)
|
280
|
-
assert obj == expected
|
281
|
-
|
282
266
|
@given(key=sampled_from(["int_", "INT_"]), int_=integers())
|
283
|
-
def
|
267
|
+
def test_exact_match_case_insensitive(self, *, key: str, int_: int) -> None:
|
284
268
|
obj = mapping_to_dataclass(DataClassFutureInt, {key: int_})
|
285
269
|
expected = DataClassFutureInt(int_=int_)
|
286
270
|
assert obj == expected
|
287
271
|
|
288
|
-
@given(
|
289
|
-
def
|
290
|
-
|
291
|
-
|
292
|
-
else:
|
293
|
-
mapping = {"int_": int_}
|
294
|
-
obj = mapping_to_dataclass(DataClassFutureIntNullable, mapping)
|
295
|
-
expected = DataClassFutureIntNullable(int_=int_)
|
272
|
+
@given(key=sampled_from(["in", "IN"]), int_=integers())
|
273
|
+
def test_head_case_insensitive(self, *, key: str, int_: int) -> None:
|
274
|
+
obj = mapping_to_dataclass(DataClassFutureInt, {key: int_}, head=True)
|
275
|
+
expected = DataClassFutureInt(int_=int_)
|
296
276
|
assert obj == expected
|
297
277
|
|
298
|
-
@given(
|
299
|
-
def
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
obj = mapping_to_dataclass(DataClassFutureListIntsDefault, mapping)
|
305
|
-
expected = DataClassFutureListIntsDefault(ints=ints)
|
278
|
+
@given(int_=integers())
|
279
|
+
def test_exact_match_case_sensitive(self, *, int_: int) -> None:
|
280
|
+
obj = mapping_to_dataclass(
|
281
|
+
DataClassFutureInt, {"int_": int_}, case_sensitive=True
|
282
|
+
)
|
283
|
+
expected = DataClassFutureInt(int_=int_)
|
306
284
|
assert obj == expected
|
307
285
|
|
308
|
-
@given(
|
309
|
-
def
|
310
|
-
obj = mapping_to_dataclass(
|
311
|
-
|
286
|
+
@given(int_=integers())
|
287
|
+
def test_head_case_sensitive(self, *, int_: int) -> None:
|
288
|
+
obj = mapping_to_dataclass(
|
289
|
+
DataClassFutureInt, {"int": int_}, head=True, case_sensitive=True
|
290
|
+
)
|
291
|
+
expected = DataClassFutureInt(int_=int_)
|
312
292
|
assert obj == expected
|
313
293
|
|
314
|
-
@given(
|
315
|
-
def
|
294
|
+
@given(int_=integers())
|
295
|
+
def test_extra_key(self, *, int_: int) -> None:
|
316
296
|
obj = mapping_to_dataclass(
|
317
|
-
|
297
|
+
DataClassFutureInt, {"int_": int_, "extra": int_}, allow_extra=True
|
318
298
|
)
|
319
|
-
expected =
|
299
|
+
expected = DataClassFutureInt(int_=int_)
|
320
300
|
assert obj == expected
|
321
301
|
|
322
|
-
|
323
|
-
|
302
|
+
def test_error(self) -> None:
|
303
|
+
with raises(
|
304
|
+
MappingToDataclassError,
|
305
|
+
match="Unable to construct 'DataClassFutureInt'; missing values for 'int_'",
|
306
|
+
):
|
307
|
+
_ = mapping_to_dataclass(DataClassFutureInt, {})
|
308
|
+
|
309
|
+
|
310
|
+
class TestOneField:
|
311
|
+
def test_error_exact_match_case_insensitive_empty_error(self) -> None:
|
324
312
|
with raises(
|
325
|
-
|
313
|
+
OneFieldEmptyError,
|
314
|
+
match=r"Dataclass 'DataClassFutureInt' does not contain a field 'invalid' \(modulo case\)",
|
326
315
|
):
|
327
|
-
_ =
|
328
|
-
DataClassFutureInt, {"INT_": value}, case_sensitive=True
|
329
|
-
)
|
316
|
+
_ = one_field(DataClassFutureInt, "invalid")
|
330
317
|
|
331
|
-
|
332
|
-
def test_error_case_insensitive_empty_error(self, *, value: int) -> None:
|
318
|
+
def test_error_exact_match_case_insensitive_non_unique_error(self) -> None:
|
333
319
|
with raises(
|
334
|
-
|
335
|
-
match=r"
|
320
|
+
OneFieldNonUniqueError,
|
321
|
+
match=r"Dataclass 'DataClassFutureIntLowerAndUpper' must contain field 'int_' exactly once \(modulo case\); got 'int_', 'INT_' and perhaps more",
|
336
322
|
):
|
337
|
-
_ =
|
323
|
+
_ = one_field(DataClassFutureIntLowerAndUpper, "int_")
|
338
324
|
|
339
|
-
|
340
|
-
def test_error_case_insensitive_non_unique_error(
|
341
|
-
self, *, value1: int, value2: int
|
342
|
-
) -> None:
|
325
|
+
def test_error_head_case_insensitive_empty_error(self) -> None:
|
343
326
|
with raises(
|
344
|
-
|
345
|
-
match=
|
346
|
-
r"Mapping .* must contain 'int_' exactly once \(modulo case\); got 'int_', 'INT_' and perhaps more",
|
347
|
-
flags=DOTALL,
|
348
|
-
),
|
327
|
+
OneFieldEmptyError,
|
328
|
+
match=r"Dataclass 'DataClassFutureInt' does not contain any field starting with 'invalid' \(modulo case\)",
|
349
329
|
):
|
350
|
-
_ =
|
351
|
-
|
330
|
+
_ = one_field(DataClassFutureInt, "invalid", head=True)
|
331
|
+
|
332
|
+
def test_error_head_case_insensitive_non_unique_error(self) -> None:
|
333
|
+
with raises(
|
334
|
+
OneFieldNonUniqueError,
|
335
|
+
match=r"Dataclass 'DataClassFutureIntOneAndTwo' must contain exactly one field starting with 'int' \(modulo case\); got 'int1', 'int2' and perhaps more",
|
336
|
+
):
|
337
|
+
_ = one_field(DataClassFutureIntOneAndTwo, "int", head=True)
|
338
|
+
|
339
|
+
def test_error_exact_match_case_sensitive_empty_error(self) -> None:
|
340
|
+
with raises(
|
341
|
+
OneFieldEmptyError,
|
342
|
+
match=r"Dataclass 'DataClassFutureInt' does not contain a field 'INT_'",
|
343
|
+
):
|
344
|
+
_ = one_field(DataClassFutureInt, "INT_", case_sensitive=True)
|
345
|
+
|
346
|
+
# there is no head=False, case_sensitive=True, non-unique case
|
347
|
+
|
348
|
+
def test_error_head_case_sensitive_empty_error(self) -> None:
|
349
|
+
with raises(
|
350
|
+
OneFieldEmptyError,
|
351
|
+
match=r"Dataclass 'DataClassFutureInt' does not contain any field starting with 'INT_'",
|
352
|
+
):
|
353
|
+
_ = one_field(DataClassFutureInt, "INT_", head=True, case_sensitive=True)
|
354
|
+
|
355
|
+
def test_error_head_case_sensitive_non_unique_error(self) -> None:
|
356
|
+
with raises(
|
357
|
+
OneFieldNonUniqueError,
|
358
|
+
match=r"Dataclass 'DataClassFutureIntOneAndTwo' must contain exactly one field starting with 'int'; got 'int1', 'int2' and perhaps more",
|
359
|
+
):
|
360
|
+
_ = one_field(
|
361
|
+
DataClassFutureIntOneAndTwo, "int", head=True, case_sensitive=True
|
352
362
|
)
|
353
363
|
|
354
364
|
|
@@ -370,16 +380,117 @@ class TestReplaceNonSentinel:
|
|
370
380
|
assert obj.int_ == 1
|
371
381
|
|
372
382
|
|
383
|
+
class TestStrMappingToFieldMapping:
|
384
|
+
@given(key=sampled_from(["int_", "INT_"]), int_=integers())
|
385
|
+
def test_main_text_case_insensitive(self, *, key: str, int_: int) -> None:
|
386
|
+
result = str_mapping_to_field_mapping(DataClassFutureInt, {key: int_})
|
387
|
+
assert len(result) == 1
|
388
|
+
assert one(result) == one(yield_fields(DataClassFutureInt))
|
389
|
+
assert one(result.values()) == int_
|
390
|
+
|
391
|
+
@given(key=sampled_from(["in", "IN"]), int_=integers())
|
392
|
+
def test_head_case_insensitive(self, *, key: str, int_: int) -> None:
|
393
|
+
result = str_mapping_to_field_mapping(
|
394
|
+
DataClassFutureInt, {key: int_}, head=True
|
395
|
+
)
|
396
|
+
assert len(result) == 1
|
397
|
+
assert one(result) == one(yield_fields(DataClassFutureInt))
|
398
|
+
assert one(result.values()) == int_
|
399
|
+
|
400
|
+
@given(int_=integers())
|
401
|
+
def test_exact_match_case_sensitive(self, *, int_: int) -> None:
|
402
|
+
result = str_mapping_to_field_mapping(
|
403
|
+
DataClassFutureInt, {"int_": int_}, case_sensitive=True
|
404
|
+
)
|
405
|
+
assert len(result) == 1
|
406
|
+
assert one(result) == one(yield_fields(DataClassFutureInt))
|
407
|
+
assert one(result.values()) == int_
|
408
|
+
|
409
|
+
@given(int_=integers())
|
410
|
+
def test_head_case_sensitive(self, *, int_: int) -> None:
|
411
|
+
result = str_mapping_to_field_mapping(
|
412
|
+
DataClassFutureInt, {"int": int_}, head=True, case_sensitive=True
|
413
|
+
)
|
414
|
+
assert len(result) == 1
|
415
|
+
assert one(result) == one(yield_fields(DataClassFutureInt))
|
416
|
+
assert one(result.values()) == int_
|
417
|
+
|
418
|
+
@given(int_=integers())
|
419
|
+
def test_extra_key(self, *, int_: int) -> None:
|
420
|
+
result = str_mapping_to_field_mapping(
|
421
|
+
DataClassFutureInt, {"int_": int_, "extra": int_}, allow_extra=True
|
422
|
+
)
|
423
|
+
assert len(result) == 1
|
424
|
+
assert one(result) == one(yield_fields(DataClassFutureInt))
|
425
|
+
assert one(result.values()) == int_
|
426
|
+
|
427
|
+
@given(int_=integers())
|
428
|
+
def test_error_exact_match_case_insensitive(self, *, int_: int) -> None:
|
429
|
+
with raises(
|
430
|
+
StrMappingToFieldMappingError,
|
431
|
+
match=r"Dataclass 'DataClassFutureInt' does not contain a field 'invalid' \(modulo case\)",
|
432
|
+
):
|
433
|
+
_ = str_mapping_to_field_mapping(
|
434
|
+
DataClassFutureInt, {"int_": int_, "invalid": int_}
|
435
|
+
)
|
436
|
+
|
437
|
+
@given(int_=integers())
|
438
|
+
def test_error_exact_match_case_sensitive(self, *, int_: int) -> None:
|
439
|
+
with raises(
|
440
|
+
StrMappingToFieldMappingError,
|
441
|
+
match=r"Dataclass 'DataClassFutureInt' does not contain a field 'extra'",
|
442
|
+
):
|
443
|
+
_ = str_mapping_to_field_mapping(
|
444
|
+
DataClassFutureInt, {"int_": int_, "extra": int_}, case_sensitive=True
|
445
|
+
)
|
446
|
+
|
447
|
+
@given(int_=integers())
|
448
|
+
def test_error_head_case_insensitive(self, *, int_: int) -> None:
|
449
|
+
with raises(
|
450
|
+
StrMappingToFieldMappingError,
|
451
|
+
match=r"Dataclass .* does not contain any field starting with 'invalid' \(modulo case\)",
|
452
|
+
):
|
453
|
+
_ = str_mapping_to_field_mapping(
|
454
|
+
DataClassFutureInt, {"invalid": int_}, head=True
|
455
|
+
)
|
456
|
+
|
457
|
+
@given(int_=integers())
|
458
|
+
def test_error_head_case_sensitive(self, *, int_: int) -> None:
|
459
|
+
with raises(
|
460
|
+
StrMappingToFieldMappingError,
|
461
|
+
match=r"Dataclass .* does not contain any field starting with 'invalid'",
|
462
|
+
):
|
463
|
+
_ = str_mapping_to_field_mapping(
|
464
|
+
DataClassFutureInt, {"invalid": int_}, head=True, case_sensitive=True
|
465
|
+
)
|
466
|
+
|
467
|
+
|
373
468
|
class TestTextToDataClass:
|
469
|
+
@given(key=sampled_from(["int_", "INT_"]), int_=integers())
|
470
|
+
def test_main_text_case_insensitive(self, *, key: str, int_: int) -> None:
|
471
|
+
result = text_to_dataclass(f"{key}={int_}", DataClassFutureInt)
|
472
|
+
expected = DataClassFutureInt(int_=int_)
|
473
|
+
assert result == expected
|
474
|
+
|
374
475
|
@given(int_=integers())
|
375
|
-
def
|
376
|
-
result = text_to_dataclass(
|
476
|
+
def test_main_text_case_sensitive(self, *, int_: int) -> None:
|
477
|
+
result = text_to_dataclass(
|
478
|
+
f"int_={int_}", DataClassFutureInt, case_sensitive=True
|
479
|
+
)
|
480
|
+
expected = DataClassFutureInt(int_=int_)
|
481
|
+
assert result == expected
|
482
|
+
|
483
|
+
@given(key=sampled_from(["int_", "INT_"]), int_=integers())
|
484
|
+
def test_main_mapping_case_insensitive(self, *, key: str, int_: int) -> None:
|
485
|
+
result = text_to_dataclass({key: str(int_)}, DataClassFutureInt)
|
377
486
|
expected = DataClassFutureInt(int_=int_)
|
378
487
|
assert result == expected
|
379
488
|
|
380
489
|
@given(int_=integers())
|
381
|
-
def
|
382
|
-
result = text_to_dataclass(
|
490
|
+
def test_main_mapping_case_sensitive(self, *, int_: int) -> None:
|
491
|
+
result = text_to_dataclass(
|
492
|
+
{"int_": str(int_)}, DataClassFutureInt, case_sensitive=True
|
493
|
+
)
|
383
494
|
expected = DataClassFutureInt(int_=int_)
|
384
495
|
assert result == expected
|
385
496
|
|
@@ -390,25 +501,6 @@ class TestTextToDataClass:
|
|
390
501
|
):
|
391
502
|
_ = text_to_dataclass("keyvalue", DataClassFutureInt)
|
392
503
|
|
393
|
-
def test_error_get_field_empty(self) -> None:
|
394
|
-
with raises(
|
395
|
-
_TextToDataClassGetFieldEmptyError,
|
396
|
-
match=r"Dataclass 'DataClassFutureInt' does not contain any field starting with 'k' \(modulo case\)",
|
397
|
-
):
|
398
|
-
_ = text_to_dataclass("k=value", DataClassFutureInt)
|
399
|
-
|
400
|
-
def test_error_get_field_non_unique(self) -> None:
|
401
|
-
@dataclass(order=True, unsafe_hash=True, kw_only=True)
|
402
|
-
class Example:
|
403
|
-
int1: int
|
404
|
-
int2: int
|
405
|
-
|
406
|
-
with raises(
|
407
|
-
_TextToDataClassGetFieldNonUniqueError,
|
408
|
-
match=r"Dataclass 'Example' must contain exactly one field starting with 'int' \(modulo case\); got 'int1', 'int2' and perhaps more",
|
409
|
-
):
|
410
|
-
_ = text_to_dataclass("int=value", Example)
|
411
|
-
|
412
504
|
def test_error_parse_value(self) -> None:
|
413
505
|
with raises(
|
414
506
|
_TextToDataClassParseValueError,
|
@@ -462,21 +554,23 @@ class TestYieldFields:
|
|
462
554
|
assert get_args(result.type_) == (int,)
|
463
555
|
|
464
556
|
def test_class_future_literal(self) -> None:
|
465
|
-
result = one(yield_fields(DataClassFutureLiteral))
|
466
|
-
expected = _YieldFieldsClass(
|
557
|
+
result = one(yield_fields(DataClassFutureLiteral, globalns=globals()))
|
558
|
+
expected = _YieldFieldsClass(
|
559
|
+
name="truth", type_=TrueOrFalseFutureLit, kw_only=True
|
560
|
+
)
|
467
561
|
assert result == expected
|
468
562
|
assert is_literal_type(result.type_)
|
469
563
|
assert get_args(result.type_) == ("true", "false")
|
470
564
|
|
471
565
|
def test_class_future_literal_nullable(self) -> None:
|
472
|
-
result = one(yield_fields(DataClassFutureLiteralNullable))
|
566
|
+
result = one(yield_fields(DataClassFutureLiteralNullable, globalns=globals()))
|
473
567
|
expected = _YieldFieldsClass(
|
474
|
-
name="truth", type_=
|
568
|
+
name="truth", type_=TrueOrFalseFutureLit | None, default=None, kw_only=True
|
475
569
|
)
|
476
570
|
assert result == expected
|
477
571
|
assert is_optional_type(result.type_)
|
478
572
|
args = get_args(result.type_)
|
479
|
-
assert args == (
|
573
|
+
assert args == (TrueOrFalseFutureLit,)
|
480
574
|
arg = one(args)
|
481
575
|
assert get_args(arg) == ("true", "false")
|
482
576
|
|
@@ -491,8 +585,14 @@ class TestYieldFields:
|
|
491
585
|
assert result.type_ is DataClassFutureNestedOuterFirstInner
|
492
586
|
|
493
587
|
def test_class_future_type_literal(self) -> None:
|
494
|
-
result = one(
|
495
|
-
|
588
|
+
result = one(
|
589
|
+
yield_fields(
|
590
|
+
DataClassFutureTypeLiteral, globalns=globals(), localns=locals()
|
591
|
+
)
|
592
|
+
)
|
593
|
+
expected = _YieldFieldsClass(
|
594
|
+
name="truth", type_=TrueOrFalseFutureTypeLit, kw_only=True
|
595
|
+
)
|
496
596
|
assert result == expected
|
497
597
|
assert is_literal_type(result.type_)
|
498
598
|
assert get_args(result.type_) == ("true", "false")
|
@@ -502,12 +602,15 @@ class TestYieldFields:
|
|
502
602
|
yield_fields(DataClassFutureTypeLiteralNullable, globalns=globals())
|
503
603
|
)
|
504
604
|
expected = _YieldFieldsClass(
|
505
|
-
name="truth",
|
605
|
+
name="truth",
|
606
|
+
type_=TrueOrFalseFutureTypeLit | None,
|
607
|
+
default=None,
|
608
|
+
kw_only=True,
|
506
609
|
)
|
507
610
|
assert result == expected
|
508
611
|
assert is_optional_type(result.type_)
|
509
612
|
args = get_args(result.type_)
|
510
|
-
assert args == (
|
613
|
+
assert args == (TrueOrFalseFutureTypeLit,)
|
511
614
|
arg = one(args)
|
512
615
|
assert get_args(arg) == ("true", "false")
|
513
616
|
|
@@ -43,6 +43,8 @@ from tests.test_typing_funcs.with_future import (
|
|
43
43
|
DataClassFutureNestedInnerFirstOuter,
|
44
44
|
DataClassFutureNestedOuterFirstOuter,
|
45
45
|
DataClassFutureNone,
|
46
|
+
DataClassFutureTypeLiteral,
|
47
|
+
DataClassFutureTypeLiteralNullable,
|
46
48
|
)
|
47
49
|
from utilities.hypothesis import (
|
48
50
|
assume_does_not_raise,
|
@@ -76,6 +78,8 @@ def base_objects(
|
|
76
78
|
dataclass_literal_nullable: bool = False,
|
77
79
|
dataclass_nested: bool = False,
|
78
80
|
dataclass_none: bool = False,
|
81
|
+
dataclass_type_literal: bool = False,
|
82
|
+
dataclass_type_literal_nullable: bool = False,
|
79
83
|
enum: bool = False,
|
80
84
|
exception_class: bool = False,
|
81
85
|
exception_instance: bool = False,
|
@@ -132,6 +136,15 @@ def base_objects(
|
|
132
136
|
)
|
133
137
|
if dataclass_none:
|
134
138
|
base |= builds(DataClassFutureNone)
|
139
|
+
if dataclass_type_literal:
|
140
|
+
base |= builds(
|
141
|
+
DataClassFutureTypeLiteral, truth=sampled_from(["true", "false"])
|
142
|
+
)
|
143
|
+
if dataclass_type_literal_nullable:
|
144
|
+
base |= builds(
|
145
|
+
DataClassFutureTypeLiteralNullable,
|
146
|
+
truth=sampled_from(["true", "false"]) | none(),
|
147
|
+
)
|
135
148
|
if enum:
|
136
149
|
base |= sampled_from(TruthEnum)
|
137
150
|
if exception_class:
|
@@ -151,6 +164,8 @@ def make_objects(
|
|
151
164
|
dataclass_literal_nullable: bool = False,
|
152
165
|
dataclass_nested: bool = False,
|
153
166
|
dataclass_none: bool = False,
|
167
|
+
dataclass_type_literal: bool = False,
|
168
|
+
dataclass_type_literal_nullable: bool = False,
|
154
169
|
enum: bool = False,
|
155
170
|
exception_class: bool = False,
|
156
171
|
exception_instance: bool = False,
|
@@ -173,6 +188,8 @@ def make_objects(
|
|
173
188
|
dataclass_literal_nullable=dataclass_literal_nullable,
|
174
189
|
dataclass_nested=dataclass_nested,
|
175
190
|
dataclass_none=dataclass_none,
|
191
|
+
dataclass_type_literal=dataclass_type_literal,
|
192
|
+
dataclass_type_literal_nullable=dataclass_type_literal_nullable,
|
176
193
|
enum=enum,
|
177
194
|
exception_class=exception_class,
|
178
195
|
exception_instance=exception_instance,
|
@@ -272,6 +289,8 @@ class TestIsEqual:
|
|
272
289
|
dataclass_literal_nullable=True,
|
273
290
|
dataclass_nested=True,
|
274
291
|
dataclass_none=True,
|
292
|
+
dataclass_type_literal=True,
|
293
|
+
dataclass_type_literal_nullable=True,
|
275
294
|
enum=True,
|
276
295
|
sub_frozenset=True,
|
277
296
|
sub_list=True,
|
@@ -287,12 +306,15 @@ class TestIsEqual:
|
|
287
306
|
objs=pairs(
|
288
307
|
make_objects(
|
289
308
|
dataclass_custom_equality=True,
|
309
|
+
dataclass_default_in_init_child=True,
|
290
310
|
dataclass_int=True,
|
291
311
|
dataclass_int_default=True,
|
292
312
|
dataclass_literal=True,
|
293
313
|
dataclass_literal_nullable=True,
|
294
314
|
dataclass_nested=True,
|
295
315
|
dataclass_none=True,
|
316
|
+
dataclass_type_literal=True,
|
317
|
+
dataclass_type_literal_nullable=True,
|
296
318
|
enum=True,
|
297
319
|
sub_frozenset=True,
|
298
320
|
sub_list=True,
|
@@ -48,6 +48,8 @@ from tests.test_typing_funcs.with_future import (
|
|
48
48
|
DataClassFutureNestedOuterFirstInner,
|
49
49
|
DataClassFutureNestedOuterFirstOuter,
|
50
50
|
DataClassFutureNone,
|
51
|
+
DataClassFutureTypeLiteral,
|
52
|
+
DataClassFutureTypeLiteralNullable,
|
51
53
|
)
|
52
54
|
from utilities.datetime import MINUTE, SECOND, get_now, get_now_local
|
53
55
|
from utilities.functions import is_sequence_of
|
@@ -435,12 +437,15 @@ class TestSerializeAndDeserialize:
|
|
435
437
|
@given(
|
436
438
|
obj=make_objects(
|
437
439
|
dataclass_custom_equality=True,
|
440
|
+
dataclass_default_in_init_child=False,
|
438
441
|
dataclass_int=True,
|
439
442
|
dataclass_int_default=True,
|
440
443
|
dataclass_literal=True,
|
441
444
|
dataclass_literal_nullable=True,
|
442
445
|
dataclass_nested=True,
|
443
446
|
dataclass_none=True,
|
447
|
+
dataclass_type_literal=True,
|
448
|
+
dataclass_type_literal_nullable=True,
|
444
449
|
enum=True,
|
445
450
|
exception_class=True,
|
446
451
|
exception_instance=True,
|
@@ -467,6 +472,8 @@ class TestSerializeAndDeserialize:
|
|
467
472
|
DataClassFutureNestedOuterFirstInner,
|
468
473
|
DataClassFutureNestedOuterFirstOuter,
|
469
474
|
DataClassFutureNone,
|
475
|
+
DataClassFutureTypeLiteral,
|
476
|
+
DataClassFutureTypeLiteralNullable,
|
470
477
|
SubFrozenSet,
|
471
478
|
SubList,
|
472
479
|
SubSet,
|
@@ -559,6 +566,19 @@ class TestSerializeAndDeserialize:
|
|
559
566
|
result = deserialize(ser, objects={DataClassFutureNone})
|
560
567
|
assert is_equal(result, obj)
|
561
568
|
|
569
|
+
@given(obj=make_objects(dataclass_type_literal=True))
|
570
|
+
def test_dataclass_type_literal(self, *, obj: Any) -> None:
|
571
|
+
result = deserialize(serialize(obj), objects={DataClassFutureTypeLiteral})
|
572
|
+
assert is_equal(result, obj)
|
573
|
+
|
574
|
+
@given(obj=make_objects(dataclass_type_literal_nullable=True))
|
575
|
+
def test_dataclass_type_literal_nullable(self, *, obj: Any) -> None:
|
576
|
+
result = deserialize(
|
577
|
+
serialize(obj), objects={DataClassFutureTypeLiteralNullable}
|
578
|
+
)
|
579
|
+
with assume_does_not_raise(IsEqualError):
|
580
|
+
assert is_equal(result, obj)
|
581
|
+
|
562
582
|
@given(obj=builds(DataClassFutureNone))
|
563
583
|
def test_dataclass_no_objects_error(self, *, obj: DataClassFutureNone) -> None:
|
564
584
|
ser = serialize(obj)
|
@@ -12,6 +12,10 @@ from hypothesis.strategies import booleans, dates, floats, integers, sampled_fro
|
|
12
12
|
from pytest import raises
|
13
13
|
|
14
14
|
from tests.test_operator import TruthEnum
|
15
|
+
from tests.test_typing_funcs.with_future import (
|
16
|
+
TrueOrFalseFutureLit,
|
17
|
+
TrueOrFalseFutureTypeLit,
|
18
|
+
)
|
15
19
|
from utilities.functions import ensure_path
|
16
20
|
from utilities.hypothesis import (
|
17
21
|
local_datetimes,
|
@@ -72,7 +76,7 @@ class TestParseText:
|
|
72
76
|
|
73
77
|
@given(truth=sampled_from(["true", "false"]))
|
74
78
|
def test_literal(self, *, truth: Literal["true", "false"]) -> None:
|
75
|
-
result = parse_text(
|
79
|
+
result = parse_text(TrueOrFalseFutureLit, truth)
|
76
80
|
assert result == truth
|
77
81
|
|
78
82
|
def test_nullable_int_none(self) -> None:
|
@@ -131,6 +135,11 @@ class TestParseText:
|
|
131
135
|
result = parse_text(dt.timedelta, text)
|
132
136
|
assert result == timedelta
|
133
137
|
|
138
|
+
@given(truth=sampled_from(["true", "false"]))
|
139
|
+
def test_type_literal(self, *, truth: Literal["true", "false"]) -> None:
|
140
|
+
result = parse_text(TrueOrFalseFutureTypeLit, truth)
|
141
|
+
assert result == truth
|
142
|
+
|
134
143
|
@given(version=versions())
|
135
144
|
def test_version(self, *, version: Version) -> None:
|
136
145
|
text = str(version)
|