dycw-utilities 0.112.0__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.0 → dycw_utilities-0.112.2}/PKG-INFO +1 -1
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/pyproject.toml +2 -2
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_dataclasses.py +17 -8
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_parse.py +43 -23
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_sentinel.py +4 -3
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_text.py +8 -8
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_typing.py +154 -101
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/utilities/__init__.py +1 -1
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/utilities/parse.py +3 -2
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/utilities/polars.py +7 -6
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/utilities/sentinel.py +1 -1
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/utilities/text.py +3 -3
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/utilities/typing.py +59 -11
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/.gitignore +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/LICENSE +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/README.md +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/__init__.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/conftest.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/modules/__init__.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/modules/package_missing/__init__.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/modules/package_missing/module.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/modules/package_with/__init__.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/modules/package_with/outer_1.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/modules/package_with/outer_2.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/modules/package_with/subpackage/__init__.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/modules/package_with/subpackage/inner_1.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/modules/package_with/subpackage/inner_2.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/modules/package_with/subpackage/inner_3.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/modules/package_without/__init__.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/modules/package_without/module_1.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/modules/package_without/module_2.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/modules/standalone.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/modules/with_imports.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/regressions/test_pytest_regressions/TestMultipleRegressionFixtures__test_main__obj.json +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/regressions/test_pytest_regressions/TestMultipleRegressionFixtures__test_main__series.json +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_int.json +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_literal__false.json +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_literal__true.json +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_nested.json +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/regressions/test_pytest_regressions/TestPolarsRegressionFixture__test_dataframe.json +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/regressions/test_pytest_regressions/TestPolarsRegressionFixture__test_series.json +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/scripts/__init__.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/scripts/test_async_service/__init__.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/scripts/test_async_service/__main__.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/scripts/test_async_service/run.sh +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/scripts/test_queue_processor/__init__.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/scripts/test_queue_processor/__main__.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/scripts/test_queue_processor/run.sh +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_altair.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_astor.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_asyncio.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_atomicwrites.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_atools.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_cachetools.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_click.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_concurrent.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_contextlib.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_contextvars.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_cryptography.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_cvxpy.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_datetime.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_enum.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_errors.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_eventkit.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_fastapi.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_fpdf2.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_functions.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_functools.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_getpass.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_git.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_hashlib.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_http.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_hypothesis.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_ipython.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_iterables.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_jupyter.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_lightweight_charts.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_logging.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_loguru.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_luigi.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_math.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_memory_profiler.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_modules.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_more_itertools.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_numpy.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_operator.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_optuna.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_orjson.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_os.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_pathlib.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_period.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_pickle.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_platform.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_polars.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_polars_ols.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_pqdm.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_pydantic.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_pyinstrument.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_pyrsistent.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_pytest.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_pytest_regressions.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_python_dotenv.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_random.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_re.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_redis.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_reprlib.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_rich.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_scipy.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_shelve.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_slack_sdk.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_socket.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_sqlalchemy.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_sqlalchemy_polars.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_statsmodel.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_streamlit.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_sys.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_tempfile.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_tenacity.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_threading.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_timer.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_traceback.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_traceback_funcs/__init__.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_traceback_funcs/chain.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_traceback_funcs/decorated_async.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_traceback_funcs/decorated_sync.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_traceback_funcs/error_bind.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_traceback_funcs/many.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_traceback_funcs/one.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_traceback_funcs/recursive.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_traceback_funcs/task_group_one.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_traceback_funcs/task_group_two.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_traceback_funcs/two.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_traceback_funcs/untraced.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_types.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_typing_funcs/__init__.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_typing_funcs/no_future.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_typing_funcs/with_future.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_tzdata.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_tzlocal.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_uuid.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_version.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_warnings.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_whenever.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_zipfile.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/tests/test_zoneinfo.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/utilities/altair.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/utilities/astor.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/utilities/asyncio.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/utilities/atomicwrites.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/utilities/atools.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/utilities/cachetools.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/utilities/click.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/utilities/concurrent.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/utilities/contextlib.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/utilities/contextvars.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/utilities/cryptography.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/utilities/cvxpy.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/utilities/dataclasses.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/utilities/datetime.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/utilities/enum.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/utilities/errors.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/utilities/eventkit.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/utilities/fastapi.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/utilities/fpdf2.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/utilities/functions.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/utilities/functools.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/utilities/getpass.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/utilities/git.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/utilities/hashlib.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/utilities/http.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/utilities/hypothesis.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/utilities/ipython.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/utilities/iterables.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/utilities/jupyter.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/utilities/lightweight_charts.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/utilities/logging.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/utilities/loguru.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/utilities/luigi.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/utilities/math.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/utilities/memory_profiler.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/utilities/modules.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/utilities/more_itertools.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/utilities/numpy.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/utilities/operator.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/utilities/optuna.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/utilities/orjson.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/utilities/os.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/utilities/pathlib.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/utilities/period.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/utilities/pickle.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/utilities/platform.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/utilities/polars_ols.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/utilities/pqdm.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/utilities/py.typed +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/utilities/pydantic.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/utilities/pyinstrument.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/utilities/pyrsistent.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/utilities/pytest.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/utilities/pytest_regressions.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/utilities/python_dotenv.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/utilities/random.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/utilities/re.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/utilities/redis.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/utilities/reprlib.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/utilities/rich.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/utilities/scipy.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/utilities/shelve.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/utilities/slack_sdk.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/utilities/socket.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/utilities/sqlalchemy.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/utilities/sqlalchemy_polars.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/utilities/statsmodels.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/utilities/streamlit.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/utilities/sys.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/utilities/tempfile.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/utilities/tenacity.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/utilities/threading.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/utilities/timer.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/utilities/traceback.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/utilities/types.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/utilities/tzdata.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/utilities/tzlocal.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/utilities/uuid.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/utilities/version.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/utilities/warnings.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/utilities/whenever.py +0 -0
- {dycw_utilities-0.112.0 → dycw_utilities-0.112.2}/src/utilities/zipfile.py +0 -0
- {dycw_utilities-0.112.0 → 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()))
|
@@ -15,6 +15,7 @@ from hypothesis.strategies import (
|
|
15
15
|
frozensets,
|
16
16
|
integers,
|
17
17
|
lists,
|
18
|
+
none,
|
18
19
|
sampled_from,
|
19
20
|
sets,
|
20
21
|
times,
|
@@ -56,6 +57,7 @@ from utilities.parse import (
|
|
56
57
|
serialize_object,
|
57
58
|
)
|
58
59
|
from utilities.sentinel import Sentinel, sentinel
|
60
|
+
from utilities.text import parse_bool
|
59
61
|
from utilities.types import Duration, Number
|
60
62
|
from utilities.version import Version
|
61
63
|
|
@@ -97,28 +99,17 @@ class TestSerializeAndParseObject:
|
|
97
99
|
result = parse_object(TruthEnum, serialized)
|
98
100
|
assert result is truth
|
99
101
|
|
100
|
-
@given(int_=integers())
|
101
|
-
def test_extra_type(self, *, int_: int) -> None:
|
102
|
-
serialized = serialize_object(int_)
|
103
|
-
result = parse_object(
|
104
|
-
DataClassFutureInt,
|
105
|
-
serialized,
|
106
|
-
extra={DataClassFutureInt: lambda text: DataClassFutureInt(int_=int(text))},
|
107
|
-
)
|
108
|
-
expected = DataClassFutureInt(int_=int_)
|
109
|
-
assert result == expected
|
110
|
-
|
111
102
|
@given(float_=floats())
|
112
103
|
def test_float(self, *, float_: float) -> None:
|
113
104
|
serialized = serialize_object(float_)
|
114
105
|
result = parse_object(float, serialized)
|
115
106
|
assert is_equal(result, float_)
|
116
107
|
|
117
|
-
@given(
|
118
|
-
def test_frozenset(self, *,
|
119
|
-
serialized = serialize_object(
|
108
|
+
@given(dates=frozensets(dates()))
|
109
|
+
def test_frozenset(self, *, dates: frozenset[dt.date]) -> None:
|
110
|
+
serialized = serialize_object(dates)
|
120
111
|
result = parse_object(frozenset[dt.date], serialized)
|
121
|
-
assert result ==
|
112
|
+
assert result == dates
|
122
113
|
|
123
114
|
@given(int_=integers())
|
124
115
|
def test_int(self, *, int_: int) -> None:
|
@@ -126,11 +117,17 @@ class TestSerializeAndParseObject:
|
|
126
117
|
result = parse_object(int, serialized)
|
127
118
|
assert result == int_
|
128
119
|
|
129
|
-
@given(
|
130
|
-
def test_list(self, *,
|
131
|
-
serialized = serialize_object(
|
120
|
+
@given(dates=lists(dates()))
|
121
|
+
def test_list(self, *, dates: list[dt.date]) -> None:
|
122
|
+
serialized = serialize_object(dates)
|
132
123
|
result = parse_object(list[dt.date], serialized)
|
133
|
-
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_
|
134
131
|
|
135
132
|
@given(truth=sampled_from(["true", "false"]))
|
136
133
|
def test_literal(self, *, truth: Literal["true", "false"]) -> None:
|
@@ -204,11 +201,11 @@ class TestSerializeAndParseObject:
|
|
204
201
|
result = parse_object(Sentinel, serialized)
|
205
202
|
assert result is sentinel
|
206
203
|
|
207
|
-
@given(
|
208
|
-
def test_set(self, *,
|
209
|
-
serialized = serialize_object(
|
204
|
+
@given(dates=sets(dates()))
|
205
|
+
def test_set(self, *, dates: set[dt.date]) -> None:
|
206
|
+
serialized = serialize_object(dates)
|
210
207
|
result = parse_object(set[dt.date], serialized)
|
211
|
-
assert result ==
|
208
|
+
assert result == dates
|
212
209
|
|
213
210
|
@given(serialized=text_ascii())
|
214
211
|
def test_to_serialized(self, *, serialized: str) -> None:
|
@@ -233,6 +230,17 @@ class TestSerializeAndParseObject:
|
|
233
230
|
result = parse_object(tuple[int, int], serialized)
|
234
231
|
assert result == (x, y)
|
235
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
|
+
|
236
244
|
@given(truth=sampled_from(["true", "false"]))
|
237
245
|
def test_type_literal(self, *, truth: Literal["true", "false"]) -> None:
|
238
246
|
result = parse_object(TrueOrFalseFutureTypeLit, truth)
|
@@ -337,6 +345,18 @@ class TestParseObject:
|
|
337
345
|
):
|
338
346
|
_ = parse_object(bool, text, extra={int: parser})
|
339
347
|
|
348
|
+
@given(value=text_ascii(min_size=10) | none())
|
349
|
+
def test_optional_type_with_union_extra_not_used(
|
350
|
+
self, *, value: str | None
|
351
|
+
) -> None:
|
352
|
+
text = serialize_object(value)
|
353
|
+
|
354
|
+
def parser(text: str, /) -> Number:
|
355
|
+
return int(text)
|
356
|
+
|
357
|
+
result = parse_object(str | None, text, extra={Number: parser})
|
358
|
+
assert result == value
|
359
|
+
|
340
360
|
def test_error_bool(self) -> None:
|
341
361
|
with raises(
|
342
362
|
_ParseObjectParseError,
|
@@ -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)
|
@@ -61,7 +61,8 @@ def parse_object(
|
|
61
61
|
) -> Any:
|
62
62
|
"""Parse text."""
|
63
63
|
if extra is not None:
|
64
|
-
|
64
|
+
with suppress(_ParseObjectParseError):
|
65
|
+
return _parse_object_extra(type_, text, extra)
|
65
66
|
if type_ is None:
|
66
67
|
try:
|
67
68
|
return parse_none(text)
|
@@ -285,7 +286,7 @@ def _parse_object_extra(cls: Any, text: str, extra: ParseObjectExtra, /) -> Any:
|
|
285
286
|
parser = one(
|
286
287
|
p for c, p in extra.items() if (cls is c) or is_subclass_gen(cls, c)
|
287
288
|
)
|
288
|
-
except OneEmptyError:
|
289
|
+
except (OneEmptyError, TypeError):
|
289
290
|
raise _ParseObjectParseError(type_=cls, text=text) from None
|
290
291
|
except OneNonUniqueError as error:
|
291
292
|
raise _ParseObjectExtraNonUniqueError(
|
@@ -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
|
|