dycw-utilities 0.112.1__tar.gz → 0.112.2__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.112.1 → dycw_utilities-0.112.2}/PKG-INFO +1 -1
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/pyproject.toml +2 -2
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_dataclasses.py +17 -8
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_parse.py +30 -23
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_sentinel.py +4 -3
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_text.py +8 -8
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_typing.py +154 -101
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/utilities/__init__.py +1 -1
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/utilities/polars.py +7 -6
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/utilities/sentinel.py +1 -1
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/utilities/text.py +3 -3
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/utilities/typing.py +59 -11
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/.gitignore +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/LICENSE +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/README.md +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/__init__.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/conftest.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/modules/__init__.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/modules/package_missing/__init__.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/modules/package_missing/module.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/modules/package_with/__init__.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/modules/package_with/outer_1.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/modules/package_with/outer_2.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/modules/package_with/subpackage/__init__.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/modules/package_with/subpackage/inner_1.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/modules/package_with/subpackage/inner_2.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/modules/package_with/subpackage/inner_3.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/modules/package_without/__init__.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/modules/package_without/module_1.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/modules/package_without/module_2.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/modules/standalone.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/modules/with_imports.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/regressions/test_pytest_regressions/TestMultipleRegressionFixtures__test_main__obj.json +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/regressions/test_pytest_regressions/TestMultipleRegressionFixtures__test_main__series.json +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_int.json +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_literal__false.json +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_literal__true.json +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_nested.json +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/regressions/test_pytest_regressions/TestPolarsRegressionFixture__test_dataframe.json +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/regressions/test_pytest_regressions/TestPolarsRegressionFixture__test_series.json +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/scripts/__init__.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/scripts/test_async_service/__init__.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/scripts/test_async_service/__main__.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/scripts/test_async_service/run.sh +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/scripts/test_queue_processor/__init__.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/scripts/test_queue_processor/__main__.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/scripts/test_queue_processor/run.sh +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_altair.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_astor.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_asyncio.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_atomicwrites.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_atools.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_cachetools.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_click.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_concurrent.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_contextlib.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_contextvars.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_cryptography.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_cvxpy.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_datetime.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_enum.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_errors.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_eventkit.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_fastapi.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_fpdf2.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_functions.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_functools.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_getpass.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_git.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_hashlib.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_http.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_hypothesis.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_ipython.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_iterables.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_jupyter.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_lightweight_charts.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_logging.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_loguru.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_luigi.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_math.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_memory_profiler.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_modules.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_more_itertools.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_numpy.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_operator.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_optuna.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_orjson.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_os.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_pathlib.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_period.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_pickle.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_platform.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_polars.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_polars_ols.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_pqdm.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_pydantic.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_pyinstrument.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_pyrsistent.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_pytest.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_pytest_regressions.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_python_dotenv.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_random.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_re.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_redis.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_reprlib.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_rich.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_scipy.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_shelve.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_slack_sdk.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_socket.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_sqlalchemy.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_sqlalchemy_polars.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_statsmodel.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_streamlit.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_sys.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_tempfile.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_tenacity.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_threading.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_timer.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_traceback.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_traceback_funcs/__init__.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_traceback_funcs/chain.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_traceback_funcs/decorated_async.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_traceback_funcs/decorated_sync.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_traceback_funcs/error_bind.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_traceback_funcs/many.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_traceback_funcs/one.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_traceback_funcs/recursive.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_traceback_funcs/task_group_one.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_traceback_funcs/task_group_two.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_traceback_funcs/two.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_traceback_funcs/untraced.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_types.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_typing_funcs/__init__.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_typing_funcs/no_future.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_typing_funcs/with_future.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_tzdata.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_tzlocal.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_uuid.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_version.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_warnings.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_whenever.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_zipfile.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/tests/test_zoneinfo.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/utilities/altair.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/utilities/astor.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/utilities/asyncio.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/utilities/atomicwrites.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/utilities/atools.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/utilities/cachetools.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/utilities/click.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/utilities/concurrent.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/utilities/contextlib.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/utilities/contextvars.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/utilities/cryptography.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/utilities/cvxpy.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/utilities/dataclasses.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/utilities/datetime.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/utilities/enum.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/utilities/errors.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/utilities/eventkit.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/utilities/fastapi.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/utilities/fpdf2.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/utilities/functions.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/utilities/functools.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/utilities/getpass.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/utilities/git.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/utilities/hashlib.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/utilities/http.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/utilities/hypothesis.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/utilities/ipython.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/utilities/iterables.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/utilities/jupyter.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/utilities/lightweight_charts.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/utilities/logging.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/utilities/loguru.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/utilities/luigi.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/utilities/math.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/utilities/memory_profiler.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/utilities/modules.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/utilities/more_itertools.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/utilities/numpy.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/utilities/operator.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/utilities/optuna.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/utilities/orjson.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/utilities/os.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/utilities/parse.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/utilities/pathlib.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/utilities/period.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/utilities/pickle.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/utilities/platform.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/utilities/polars_ols.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/utilities/pqdm.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/utilities/py.typed +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/utilities/pydantic.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/utilities/pyinstrument.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/utilities/pyrsistent.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/utilities/pytest.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/utilities/pytest_regressions.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/utilities/python_dotenv.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/utilities/random.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/utilities/re.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/utilities/redis.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/utilities/reprlib.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/utilities/rich.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/utilities/scipy.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/utilities/shelve.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/utilities/slack_sdk.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/utilities/socket.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/utilities/sqlalchemy.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/utilities/sqlalchemy_polars.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/utilities/statsmodels.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/utilities/streamlit.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/utilities/sys.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/utilities/tempfile.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/utilities/tenacity.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/utilities/threading.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/utilities/timer.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/utilities/traceback.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/utilities/types.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/utilities/tzdata.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/utilities/tzlocal.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/utilities/uuid.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/utilities/version.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/utilities/warnings.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/utilities/whenever.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/utilities/zipfile.py +0 -0
- {dycw_utilities-0.112.1 → dycw_utilities-0.112.2}/src/utilities/zoneinfo.py +0 -0
@@ -94,7 +94,7 @@ dependencies = [
|
|
94
94
|
name = "dycw-utilities"
|
95
95
|
readme = "README.md"
|
96
96
|
requires-python = ">= 3.12"
|
97
|
-
version = "0.112.
|
97
|
+
version = "0.112.2"
|
98
98
|
|
99
99
|
[project.optional-dependencies]
|
100
100
|
test = [
|
@@ -337,7 +337,7 @@ zzz-test-zoneinfo = [
|
|
337
337
|
# bump-my-version
|
338
338
|
[tool.bumpversion]
|
339
339
|
allow_dirty = true
|
340
|
-
current_version = "0.112.
|
340
|
+
current_version = "0.112.2"
|
341
341
|
|
342
342
|
[[tool.bumpversion.files]]
|
343
343
|
filename = "src/utilities/__init__.py"
|
@@ -3,7 +3,7 @@ from __future__ import annotations
|
|
3
3
|
from dataclasses import dataclass, field
|
4
4
|
from pathlib import Path
|
5
5
|
from types import NoneType
|
6
|
-
from typing import Any, cast, override
|
6
|
+
from typing import Any, Literal, cast, override
|
7
7
|
|
8
8
|
from hypothesis import given
|
9
9
|
from hypothesis.strategies import booleans, integers, lists, sampled_from
|
@@ -406,7 +406,18 @@ class TestSerializeAndParseDataClass:
|
|
406
406
|
assert result == obj
|
407
407
|
|
408
408
|
@given(int_=integers())
|
409
|
-
def
|
409
|
+
def test_literal_type(self, *, int_: int) -> None:
|
410
|
+
obj = DataClassFutureInt(int_=int_)
|
411
|
+
serialized = serialize_dataclass(obj)
|
412
|
+
result = parse_dataclass(
|
413
|
+
serialized,
|
414
|
+
DataClassFutureInt,
|
415
|
+
extra_parsers={Literal["lit"]: NotImplementedError},
|
416
|
+
)
|
417
|
+
assert result == obj
|
418
|
+
|
419
|
+
@given(int_=integers())
|
420
|
+
def test_type_extra(self, *, int_: int) -> None:
|
410
421
|
obj = DataClassFutureNestedOuterFirstOuter(
|
411
422
|
inner=DataClassFutureNestedOuterFirstInner(int_=int_)
|
412
423
|
)
|
@@ -625,9 +636,8 @@ class TestYieldFields:
|
|
625
636
|
assert result == expected
|
626
637
|
assert is_optional_type(result.type_)
|
627
638
|
args = get_args(result.type_)
|
628
|
-
assert args == (TrueOrFalseFutureLit,)
|
629
|
-
|
630
|
-
assert get_args(arg) == ("true", "false")
|
639
|
+
assert args == (TrueOrFalseFutureLit, NoneType)
|
640
|
+
assert get_args(args[0]) == ("true", "false")
|
631
641
|
|
632
642
|
def test_class_future_nested(self) -> None:
|
633
643
|
result = one(
|
@@ -665,9 +675,8 @@ class TestYieldFields:
|
|
665
675
|
assert result == expected
|
666
676
|
assert is_optional_type(result.type_)
|
667
677
|
args = get_args(result.type_)
|
668
|
-
assert args == (TrueOrFalseFutureTypeLit,)
|
669
|
-
|
670
|
-
assert get_args(arg) == ("true", "false")
|
678
|
+
assert args == (TrueOrFalseFutureTypeLit, NoneType)
|
679
|
+
assert get_args(args[0]) == ("true", "false")
|
671
680
|
|
672
681
|
def test_class_orjson_log_record(self) -> None:
|
673
682
|
result = list(yield_fields(OrjsonLogRecord, globalns=globals()))
|
@@ -57,6 +57,7 @@ from utilities.parse import (
|
|
57
57
|
serialize_object,
|
58
58
|
)
|
59
59
|
from utilities.sentinel import Sentinel, sentinel
|
60
|
+
from utilities.text import parse_bool
|
60
61
|
from utilities.types import Duration, Number
|
61
62
|
from utilities.version import Version
|
62
63
|
|
@@ -98,28 +99,17 @@ class TestSerializeAndParseObject:
|
|
98
99
|
result = parse_object(TruthEnum, serialized)
|
99
100
|
assert result is truth
|
100
101
|
|
101
|
-
@given(int_=integers())
|
102
|
-
def test_extra_type(self, *, int_: int) -> None:
|
103
|
-
serialized = serialize_object(int_)
|
104
|
-
result = parse_object(
|
105
|
-
DataClassFutureInt,
|
106
|
-
serialized,
|
107
|
-
extra={DataClassFutureInt: lambda text: DataClassFutureInt(int_=int(text))},
|
108
|
-
)
|
109
|
-
expected = DataClassFutureInt(int_=int_)
|
110
|
-
assert result == expected
|
111
|
-
|
112
102
|
@given(float_=floats())
|
113
103
|
def test_float(self, *, float_: float) -> None:
|
114
104
|
serialized = serialize_object(float_)
|
115
105
|
result = parse_object(float, serialized)
|
116
106
|
assert is_equal(result, float_)
|
117
107
|
|
118
|
-
@given(
|
119
|
-
def test_frozenset(self, *,
|
120
|
-
serialized = serialize_object(
|
108
|
+
@given(dates=frozensets(dates()))
|
109
|
+
def test_frozenset(self, *, dates: frozenset[dt.date]) -> None:
|
110
|
+
serialized = serialize_object(dates)
|
121
111
|
result = parse_object(frozenset[dt.date], serialized)
|
122
|
-
assert result ==
|
112
|
+
assert result == dates
|
123
113
|
|
124
114
|
@given(int_=integers())
|
125
115
|
def test_int(self, *, int_: int) -> None:
|
@@ -127,11 +117,17 @@ class TestSerializeAndParseObject:
|
|
127
117
|
result = parse_object(int, serialized)
|
128
118
|
assert result == int_
|
129
119
|
|
130
|
-
@given(
|
131
|
-
def test_list(self, *,
|
132
|
-
serialized = serialize_object(
|
120
|
+
@given(dates=lists(dates()))
|
121
|
+
def test_list(self, *, dates: list[dt.date]) -> None:
|
122
|
+
serialized = serialize_object(dates)
|
133
123
|
result = parse_object(list[dt.date], serialized)
|
134
|
-
assert result ==
|
124
|
+
assert result == dates
|
125
|
+
|
126
|
+
@given(bool_=booleans())
|
127
|
+
def test_literal_extra(self, *, bool_: bool) -> None:
|
128
|
+
text = serialize_object(bool_)
|
129
|
+
result = parse_object(bool, text, extra={Literal["lit"]: parse_bool})
|
130
|
+
assert result is bool_
|
135
131
|
|
136
132
|
@given(truth=sampled_from(["true", "false"]))
|
137
133
|
def test_literal(self, *, truth: Literal["true", "false"]) -> None:
|
@@ -205,11 +201,11 @@ class TestSerializeAndParseObject:
|
|
205
201
|
result = parse_object(Sentinel, serialized)
|
206
202
|
assert result is sentinel
|
207
203
|
|
208
|
-
@given(
|
209
|
-
def test_set(self, *,
|
210
|
-
serialized = serialize_object(
|
204
|
+
@given(dates=sets(dates()))
|
205
|
+
def test_set(self, *, dates: set[dt.date]) -> None:
|
206
|
+
serialized = serialize_object(dates)
|
211
207
|
result = parse_object(set[dt.date], serialized)
|
212
|
-
assert result ==
|
208
|
+
assert result == dates
|
213
209
|
|
214
210
|
@given(serialized=text_ascii())
|
215
211
|
def test_to_serialized(self, *, serialized: str) -> None:
|
@@ -234,6 +230,17 @@ class TestSerializeAndParseObject:
|
|
234
230
|
result = parse_object(tuple[int, int], serialized)
|
235
231
|
assert result == (x, y)
|
236
232
|
|
233
|
+
@given(int_=integers())
|
234
|
+
def test_type_extra(self, *, int_: int) -> None:
|
235
|
+
serialized = serialize_object(int_)
|
236
|
+
result = parse_object(
|
237
|
+
DataClassFutureInt,
|
238
|
+
serialized,
|
239
|
+
extra={DataClassFutureInt: lambda text: DataClassFutureInt(int_=int(text))},
|
240
|
+
)
|
241
|
+
expected = DataClassFutureInt(int_=int_)
|
242
|
+
assert result == expected
|
243
|
+
|
237
244
|
@given(truth=sampled_from(["true", "false"]))
|
238
245
|
def test_type_literal(self, *, truth: Literal["true", "false"]) -> None:
|
239
246
|
result = parse_object(TrueOrFalseFutureTypeLit, truth)
|
@@ -26,11 +26,12 @@ class TestParseSentinel:
|
|
26
26
|
result = parse_sentinel(text_use)
|
27
27
|
assert result is sentinel
|
28
28
|
|
29
|
-
|
29
|
+
@given(text=sampled_from(["invalid", "ssentinell"]))
|
30
|
+
def test_error(self, *, text: str) -> None:
|
30
31
|
with raises(
|
31
|
-
ParseSentinelError, match="Unable to parse sentinel value; got '
|
32
|
+
ParseSentinelError, match="Unable to parse sentinel value; got '.*'"
|
32
33
|
):
|
33
|
-
_ = parse_sentinel(
|
34
|
+
_ = parse_sentinel(text)
|
34
35
|
|
35
36
|
|
36
37
|
class TestSentinel:
|
@@ -51,11 +51,10 @@ class TestParseBool:
|
|
51
51
|
result = parse_bool(text_use)
|
52
52
|
assert result is value
|
53
53
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
_ = parse_bool("invalid")
|
54
|
+
@given(text=sampled_from(["invalid", "11", "00", "ttruee", "ffalsee"]))
|
55
|
+
def test_error(self, *, text: str) -> None:
|
56
|
+
with raises(ParseBoolError, match="Unable to parse boolean value; got '.*'"):
|
57
|
+
_ = parse_bool(text)
|
59
58
|
|
60
59
|
|
61
60
|
class TestParseNone:
|
@@ -66,9 +65,10 @@ class TestParseNone:
|
|
66
65
|
result = parse_none(text_use)
|
67
66
|
assert result is None
|
68
67
|
|
69
|
-
|
70
|
-
|
71
|
-
|
68
|
+
@given(text=sampled_from(["invalid", "nnonee"]))
|
69
|
+
def test_error(self, *, text: str) -> None:
|
70
|
+
with raises(ParseNoneError, match="Unable to parse null value; got '.*'"):
|
71
|
+
_ = parse_none(text)
|
72
72
|
|
73
73
|
|
74
74
|
class TestReprEncode:
|
@@ -22,8 +22,10 @@ from hypothesis.strategies import (
|
|
22
22
|
just,
|
23
23
|
none,
|
24
24
|
sampled_from,
|
25
|
+
sets,
|
26
|
+
tuples,
|
25
27
|
)
|
26
|
-
from pytest import
|
28
|
+
from pytest import raises
|
27
29
|
|
28
30
|
from tests.test_typing_funcs.no_future import (
|
29
31
|
DataClassNoFutureNestedInnerFirstInner,
|
@@ -54,6 +56,7 @@ from tests.test_typing_funcs.with_future import (
|
|
54
56
|
from utilities.sentinel import Sentinel
|
55
57
|
from utilities.types import Duration, LogLevel, Number, Parallelism, Seed
|
56
58
|
from utilities.typing import (
|
59
|
+
IsSubclassGenError,
|
57
60
|
_GetTypeClassesTupleError,
|
58
61
|
_GetTypeClassesTypeError,
|
59
62
|
_GetUnionTypeClassesInternalTypeError,
|
@@ -85,32 +88,40 @@ if TYPE_CHECKING:
|
|
85
88
|
|
86
89
|
|
87
90
|
class TestContainsSelf:
|
88
|
-
@
|
91
|
+
@given(obj=sampled_from([Self, Self | None]))
|
89
92
|
def test_main(self, *, obj: Any) -> None:
|
90
93
|
assert contains_self(obj)
|
91
94
|
|
92
95
|
|
93
96
|
class TestGetArgs:
|
94
|
-
@
|
95
|
-
(
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
],
|
97
|
+
@given(
|
98
|
+
case=sampled_from([
|
99
|
+
(dict[int, int], (int, int)),
|
100
|
+
(frozenset[int], (int,)),
|
101
|
+
(int | None, (int, NoneType)),
|
102
|
+
(int | str, (int, str)),
|
103
|
+
(list[int], (int,)),
|
104
|
+
(Literal["a", "b", "c"], ("a", "b", "c")),
|
105
|
+
(Mapping[int, int], (int, int)),
|
106
|
+
(Sequence[int], (int,)),
|
107
|
+
(set[int], (int,)),
|
108
|
+
(LogLevel, ("DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL")),
|
109
|
+
(Parallelism, ("processes", "threads")),
|
110
|
+
])
|
109
111
|
)
|
110
|
-
def test_main(self, *,
|
112
|
+
def test_main(self, *, case: tuple[Any, tuple[Any, ...]]) -> None:
|
113
|
+
obj, expected = case
|
111
114
|
result = get_args(obj)
|
112
115
|
assert result == expected
|
113
116
|
|
117
|
+
@given(case=sampled_from([(int | None, (int,)), (int | str | None, (int, str))]))
|
118
|
+
def test_optional_drop_none(
|
119
|
+
self, *, case: tuple[Any, tuple[type[Any], ...]]
|
120
|
+
) -> None:
|
121
|
+
obj, expected = case
|
122
|
+
result = get_args(obj, optional_drop_none=True)
|
123
|
+
assert result == expected
|
124
|
+
|
114
125
|
|
115
126
|
type _PlusOrMinusOneLit = Literal[1, -1]
|
116
127
|
type _TruthLit = Literal["true", "false"]
|
@@ -417,73 +428,71 @@ class TestGetUnionTypeClasses:
|
|
417
428
|
|
418
429
|
|
419
430
|
class TestIsAnnotationOfType:
|
420
|
-
@
|
421
|
-
(
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
],
|
431
|
+
@given(
|
432
|
+
case=sampled_from([
|
433
|
+
(is_dict_type, Mapping[int, int], False),
|
434
|
+
(is_dict_type, Sequence[int], False),
|
435
|
+
(is_dict_type, dict[int, int], True),
|
436
|
+
(is_dict_type, frozenset[int], False),
|
437
|
+
(is_dict_type, list[int], False),
|
438
|
+
(is_dict_type, set[int], False),
|
439
|
+
(is_dict_type, tuple[int, int], False),
|
440
|
+
(is_frozenset_type, Mapping[int, int], False),
|
441
|
+
(is_frozenset_type, Sequence[int], False),
|
442
|
+
(is_frozenset_type, dict[int, int], False),
|
443
|
+
(is_frozenset_type, frozenset[int], True),
|
444
|
+
(is_frozenset_type, list[int], False),
|
445
|
+
(is_frozenset_type, set[int], False),
|
446
|
+
(is_frozenset_type, tuple[int, int], False),
|
447
|
+
(is_list_type, Mapping[int, int], False),
|
448
|
+
(is_list_type, Sequence[int], False),
|
449
|
+
(is_list_type, dict[int, int], False),
|
450
|
+
(is_list_type, frozenset[int], False),
|
451
|
+
(is_list_type, list[int], True),
|
452
|
+
(is_list_type, set[int], False),
|
453
|
+
(is_list_type, tuple[int, int], False),
|
454
|
+
(is_literal_type, Literal["a", "b", "c"], True),
|
455
|
+
(is_literal_type, list[int], False),
|
456
|
+
(is_mapping_type, Mapping[int, int], True),
|
457
|
+
(is_mapping_type, Sequence[int], False),
|
458
|
+
(is_mapping_type, dict[int, int], False),
|
459
|
+
(is_mapping_type, frozenset[int], False),
|
460
|
+
(is_mapping_type, list[int], False),
|
461
|
+
(is_mapping_type, set[int], False),
|
462
|
+
(is_mapping_type, tuple[int, int], False),
|
463
|
+
(is_optional_type, Literal["a", "b", "c"] | None, True),
|
464
|
+
(is_optional_type, Literal["a", "b", "c"], False),
|
465
|
+
(is_optional_type, int | None, True),
|
466
|
+
(is_optional_type, int | str, False),
|
467
|
+
(is_optional_type, list[int] | None, True),
|
468
|
+
(is_optional_type, list[int], False),
|
469
|
+
(is_sequence_type, Mapping[int, int], False),
|
470
|
+
(is_sequence_type, Sequence[int], True),
|
471
|
+
(is_sequence_type, dict[int, int], False),
|
472
|
+
(is_sequence_type, frozenset[int], False),
|
473
|
+
(is_sequence_type, list[int], False),
|
474
|
+
(is_sequence_type, set[int], False),
|
475
|
+
(is_sequence_type, tuple[int, int], False),
|
476
|
+
(is_set_type, Mapping[int, int], False),
|
477
|
+
(is_set_type, Sequence[int], False),
|
478
|
+
(is_set_type, dict[int, int], False),
|
479
|
+
(is_set_type, frozenset[int], False),
|
480
|
+
(is_set_type, list[int], False),
|
481
|
+
(is_set_type, set[int], True),
|
482
|
+
(is_set_type, tuple[int, int], False),
|
483
|
+
(is_tuple_type, Mapping[int, int], False),
|
484
|
+
(is_tuple_type, Sequence[int], False),
|
485
|
+
(is_tuple_type, dict[int, int], False),
|
486
|
+
(is_tuple_type, frozenset[int], False),
|
487
|
+
(is_tuple_type, list[int], False),
|
488
|
+
(is_tuple_type, set[int], False),
|
489
|
+
(is_tuple_type, tuple[int, int], True),
|
490
|
+
(is_union_type, int | str, True),
|
491
|
+
(is_union_type, list[int], False),
|
492
|
+
])
|
483
493
|
)
|
484
|
-
def test_main(
|
485
|
-
|
486
|
-
) -> None:
|
494
|
+
def test_main(self, *, case: tuple[Callable[[Any], bool], Any, bool]) -> None:
|
495
|
+
func, obj, expected = case
|
487
496
|
assert func(obj) is expected
|
488
497
|
|
489
498
|
|
@@ -491,27 +500,52 @@ class TestIsInstanceGen:
|
|
491
500
|
@given(
|
492
501
|
data=data(),
|
493
502
|
case=sampled_from([
|
494
|
-
(booleans(), bool, True),
|
495
|
-
(booleans(), int, False),
|
496
|
-
(integers(), bool, False),
|
497
|
-
(integers(), int, True),
|
498
|
-
(booleans(), (bool, int), True),
|
499
|
-
(integers(), (bool, int), True),
|
500
|
-
(dates(), dt.date, True),
|
501
|
-
(dates(), dt.datetime, False),
|
502
|
-
(datetimes(), dt.date, False),
|
503
|
-
(datetimes(), dt.datetime, True),
|
504
|
-
(booleans(), Number, False),
|
505
|
-
(integers(), Number, True),
|
506
|
-
(floats(), Number, True),
|
503
|
+
(booleans(), bool, None, True),
|
504
|
+
(booleans(), int, None, False),
|
505
|
+
(integers(), bool, None, False),
|
506
|
+
(integers(), int, None, True),
|
507
|
+
(booleans(), (bool, int), None, True),
|
508
|
+
(integers(), (bool, int), None, True),
|
509
|
+
(dates(), dt.date, None, True),
|
510
|
+
(dates(), dt.datetime, None, False),
|
511
|
+
(datetimes(), dt.date, None, False),
|
512
|
+
(datetimes(), dt.datetime, None, True),
|
513
|
+
(booleans(), Number, None, False),
|
514
|
+
(integers(), Number, None, True),
|
515
|
+
(floats(), Number, None, True),
|
516
|
+
(tuples(booleans()), (bool,), None, True),
|
517
|
+
(tuples(booleans()), (int,), None, False),
|
518
|
+
(tuples(integers()), (bool,), None, False),
|
519
|
+
(tuples(integers()), (int,), None, True),
|
520
|
+
(tuples(integers()), (int, int), None, False),
|
521
|
+
(integers(), int | None, None, True),
|
522
|
+
(integers() | none(), int, None, False),
|
523
|
+
(integers() | none(), int | None, None, True),
|
524
|
+
(sampled_from([1, 2]), Literal[1, 2, 3], 2, True),
|
525
|
+
(sampled_from([1, 2, 3]), Literal[1, 2, 3], 3, True),
|
526
|
+
(sampled_from([1, 2, 3]), Literal[1, 2], 3, False),
|
527
|
+
(booleans(), Literal[1, 2, 3], None, False),
|
528
|
+
(sampled_from([1, 2, 3]), bool, 3, False),
|
529
|
+
(tuples(booleans()), Literal[1, 2, 3], None, False),
|
530
|
+
(sampled_from([1, 2, 3]), (bool,), 3, False),
|
507
531
|
]),
|
508
532
|
)
|
509
533
|
def test_main(
|
510
|
-
self,
|
534
|
+
self,
|
535
|
+
*,
|
536
|
+
data: DataObject,
|
537
|
+
case: tuple[SearchStrategy[Any], Any, int | None, bool],
|
511
538
|
) -> None:
|
512
|
-
strategy, type_, expected = case
|
513
|
-
|
514
|
-
|
539
|
+
strategy, type_, min_size, expected = case
|
540
|
+
match expected:
|
541
|
+
case True:
|
542
|
+
value = data.draw(strategy)
|
543
|
+
assert is_instance_gen(value, type_)
|
544
|
+
case False:
|
545
|
+
values = data.draw(
|
546
|
+
sets(strategy, min_size=100 if min_size is None else min_size)
|
547
|
+
)
|
548
|
+
assert not all(is_instance_gen(v, type_) for v in values)
|
515
549
|
|
516
550
|
@given(bool_=booleans())
|
517
551
|
def test_bool_value_vs_custom_int(self, *, bool_: bool) -> None:
|
@@ -560,6 +594,21 @@ class TestIsSubclassGen:
|
|
560
594
|
(bool, Number, False),
|
561
595
|
(int, Number, True),
|
562
596
|
(float, Number, True),
|
597
|
+
((bool,), (bool,), True),
|
598
|
+
((bool,), (int,), False),
|
599
|
+
((int,), (bool,), False),
|
600
|
+
((int,), (int,), True),
|
601
|
+
((int,), (int, int), False),
|
602
|
+
(int, int | None, True),
|
603
|
+
(int | None, int, False),
|
604
|
+
(int | None, int | None, True),
|
605
|
+
(Literal[1, 2], Literal[1, 2, 3], True),
|
606
|
+
(Literal[1, 2, 3], Literal[1, 2, 3], True),
|
607
|
+
(Literal[1, 2, 3], Literal[1, 2], False),
|
608
|
+
(bool, Literal[1, 2, 3], False),
|
609
|
+
(Literal[1, 2, 3], bool, False),
|
610
|
+
((bool,), Literal[1, 2, 3], False),
|
611
|
+
(Literal[1, 2, 3], (bool,), False),
|
563
612
|
])
|
564
613
|
)
|
565
614
|
def test_main(self, *, case: tuple[type[Any], Any, bool]) -> None:
|
@@ -574,3 +623,7 @@ class TestIsSubclassGen:
|
|
574
623
|
assert not is_subclass_gen(int, MyInt)
|
575
624
|
assert is_subclass_gen(MyInt, int)
|
576
625
|
assert is_subclass_gen(MyInt, MyInt)
|
626
|
+
|
627
|
+
def test_error(self) -> None:
|
628
|
+
with raises(IsSubclassGenError, match="Argument must be a class; got None"):
|
629
|
+
_ = is_subclass_gen(None, NoneType)
|
@@ -941,10 +941,9 @@ def dataclass_to_schema(
|
|
941
941
|
dtype = struct_dtype(**dtypes)
|
942
942
|
elif field.type_ is dt.datetime:
|
943
943
|
dtype = _dataclass_to_schema_datetime(field)
|
944
|
-
elif is_union_type(field.type_) and set(
|
945
|
-
|
946
|
-
|
947
|
-
}:
|
944
|
+
elif is_union_type(field.type_) and set(
|
945
|
+
get_args(field.type_, optional_drop_none=True)
|
946
|
+
) == {dt.date, dt.datetime}:
|
948
947
|
if is_instance_gen(field.value, dt.date):
|
949
948
|
dtype = Date
|
950
949
|
else:
|
@@ -1002,7 +1001,7 @@ def _dataclass_to_schema_one(
|
|
1002
1001
|
if is_literal_type(obj):
|
1003
1002
|
return pl.Enum(get_args(obj))
|
1004
1003
|
if is_optional_type(obj):
|
1005
|
-
inner_type = one(get_args(obj))
|
1004
|
+
inner_type = one(get_args(obj, optional_drop_none=True))
|
1006
1005
|
return _dataclass_to_schema_one(inner_type, globalns=globalns, localns=localns)
|
1007
1006
|
msg = f"{obj=}"
|
1008
1007
|
raise NotImplementedError(msg)
|
@@ -1732,7 +1731,9 @@ def _struct_from_dataclass_one(
|
|
1732
1731
|
):
|
1733
1732
|
return String
|
1734
1733
|
if is_optional_type(ann):
|
1735
|
-
return _struct_from_dataclass_one(
|
1734
|
+
return _struct_from_dataclass_one(
|
1735
|
+
one(get_args(ann, optional_drop_none=True)), time_zone=time_zone
|
1736
|
+
)
|
1736
1737
|
if is_frozenset_type(ann) or is_list_type(ann) or is_set_type(ann):
|
1737
1738
|
return List(_struct_from_dataclass_one(one(get_args(ann)), time_zone=time_zone))
|
1738
1739
|
raise _StructFromDataClassTypeError(ann=ann)
|
@@ -40,7 +40,7 @@ sentinel = Sentinel()
|
|
40
40
|
|
41
41
|
def parse_sentinel(text: str, /) -> Sentinel:
|
42
42
|
"""Parse text into the Sentinel value."""
|
43
|
-
if
|
43
|
+
if search("^(|sentinel|<sentinel>)$", text, flags=IGNORECASE):
|
44
44
|
return sentinel
|
45
45
|
raise ParseSentinelError(text=text)
|
46
46
|
|
@@ -25,9 +25,9 @@ DEFAULT_SEPARATOR = ","
|
|
25
25
|
|
26
26
|
def parse_bool(text: str, /) -> bool:
|
27
27
|
"""Parse text into a boolean value."""
|
28
|
-
if
|
28
|
+
if search(r"^(0|False)$", text, flags=IGNORECASE):
|
29
29
|
return False
|
30
|
-
if
|
30
|
+
if search(r"^(1|True)$", text, flags=IGNORECASE):
|
31
31
|
return True
|
32
32
|
raise ParseBoolError(text=text)
|
33
33
|
|
@@ -46,7 +46,7 @@ class ParseBoolError(Exception):
|
|
46
46
|
|
47
47
|
def parse_none(text: str, /) -> None:
|
48
48
|
"""Parse text into the None value."""
|
49
|
-
if
|
49
|
+
if search(r"^(|None)$", text, flags=IGNORECASE):
|
50
50
|
return
|
51
51
|
raise ParseNoneError(text=text)
|
52
52
|
|