dycw-utilities 0.110.1__tar.gz → 0.110.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.110.1 → dycw_utilities-0.110.2}/PKG-INFO +1 -1
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/pyproject.toml +2 -2
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_text.py +54 -5
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/utilities/__init__.py +1 -1
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/utilities/text.py +132 -11
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/.gitignore +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/LICENSE +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/README.md +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/__init__.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/conftest.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/modules/__init__.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/modules/package_missing/__init__.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/modules/package_missing/module.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/modules/package_with/__init__.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/modules/package_with/outer_1.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/modules/package_with/outer_2.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/modules/package_with/subpackage/__init__.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/modules/package_with/subpackage/inner_1.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/modules/package_with/subpackage/inner_2.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/modules/package_with/subpackage/inner_3.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/modules/package_without/__init__.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/modules/package_without/module_1.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/modules/package_without/module_2.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/modules/standalone.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/modules/with_imports.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/regressions/test_pytest_regressions/TestMultipleRegressionFixtures__test_main__obj.json +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/regressions/test_pytest_regressions/TestMultipleRegressionFixtures__test_main__series.json +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_int.json +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_literal__false.json +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_literal__true.json +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_nested.json +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/regressions/test_pytest_regressions/TestPolarsRegressionFixture__test_dataframe.json +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/regressions/test_pytest_regressions/TestPolarsRegressionFixture__test_series.json +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/scripts/__init__.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/scripts/test_async_service/__init__.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/scripts/test_async_service/__main__.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/scripts/test_async_service/run.sh +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/scripts/test_queue_processor/__init__.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/scripts/test_queue_processor/__main__.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/scripts/test_queue_processor/run.sh +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_altair.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_astor.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_asyncio.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_atomicwrites.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_atools.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_cachetools.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_click.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_concurrent.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_contextlib.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_contextvars.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_cryptography.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_cvxpy.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_dataclasses.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_datetime.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_enum.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_errors.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_eventkit.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_fastapi.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_fpdf2.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_functions.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_functools.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_getpass.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_git.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_hashlib.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_http.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_hypothesis.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_ipython.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_iterables.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_jupyter.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_lightweight_charts.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_logging.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_loguru.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_luigi.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_math.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_memory_profiler.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_modules.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_more_itertools.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_numpy.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_operator.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_optuna.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_orjson.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_os.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_parse.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_pathlib.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_period.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_pickle.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_platform.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_polars.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_polars_ols.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_pqdm.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_pydantic.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_pyinstrument.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_pyrsistent.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_pytest.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_pytest_regressions.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_python_dotenv.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_random.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_re.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_redis.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_reprlib.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_rich.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_scipy.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_sentinel.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_shelve.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_slack_sdk.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_socket.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_sqlalchemy.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_sqlalchemy_polars.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_statsmodel.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_streamlit.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_sys.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_tempfile.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_tenacity.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_threading.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_timer.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_traceback.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_traceback_funcs/__init__.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_traceback_funcs/chain.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_traceback_funcs/decorated_async.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_traceback_funcs/decorated_sync.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_traceback_funcs/error_bind.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_traceback_funcs/many.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_traceback_funcs/one.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_traceback_funcs/recursive.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_traceback_funcs/task_group_one.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_traceback_funcs/task_group_two.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_traceback_funcs/two.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_traceback_funcs/untraced.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_types.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_typing.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_typing_funcs/__init__.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_typing_funcs/no_future.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_typing_funcs/with_future.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_tzdata.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_tzlocal.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_uuid.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_version.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_warnings.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_whenever.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_zipfile.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_zoneinfo.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/utilities/altair.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/utilities/astor.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/utilities/asyncio.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/utilities/atomicwrites.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/utilities/atools.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/utilities/cachetools.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/utilities/click.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/utilities/concurrent.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/utilities/contextlib.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/utilities/contextvars.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/utilities/cryptography.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/utilities/cvxpy.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/utilities/dataclasses.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/utilities/datetime.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/utilities/enum.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/utilities/errors.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/utilities/eventkit.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/utilities/fastapi.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/utilities/fpdf2.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/utilities/functions.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/utilities/functools.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/utilities/getpass.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/utilities/git.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/utilities/hashlib.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/utilities/http.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/utilities/hypothesis.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/utilities/ipython.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/utilities/iterables.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/utilities/jupyter.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/utilities/lightweight_charts.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/utilities/logging.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/utilities/loguru.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/utilities/luigi.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/utilities/math.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/utilities/memory_profiler.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/utilities/modules.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/utilities/more_itertools.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/utilities/numpy.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/utilities/operator.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/utilities/optuna.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/utilities/orjson.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/utilities/os.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/utilities/parse.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/utilities/pathlib.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/utilities/period.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/utilities/pickle.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/utilities/platform.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/utilities/polars.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/utilities/polars_ols.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/utilities/pqdm.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/utilities/py.typed +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/utilities/pydantic.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/utilities/pyinstrument.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/utilities/pyrsistent.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/utilities/pytest.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/utilities/pytest_regressions.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/utilities/python_dotenv.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/utilities/random.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/utilities/re.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/utilities/redis.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/utilities/reprlib.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/utilities/rich.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/utilities/scipy.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/utilities/sentinel.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/utilities/shelve.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/utilities/slack_sdk.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/utilities/socket.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/utilities/sqlalchemy.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/utilities/sqlalchemy_polars.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/utilities/statsmodels.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/utilities/streamlit.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/utilities/sys.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/utilities/tempfile.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/utilities/tenacity.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/utilities/threading.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/utilities/timer.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/utilities/traceback.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/utilities/types.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/utilities/typing.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/utilities/tzdata.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/utilities/tzlocal.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/utilities/uuid.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/utilities/version.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/utilities/warnings.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/utilities/whenever.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/utilities/zipfile.py +0 -0
- {dycw_utilities-0.110.1 → dycw_utilities-0.110.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.110.
|
97
|
+
version = "0.110.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.110.
|
340
|
+
current_version = "0.110.2"
|
341
341
|
|
342
342
|
[[tool.bumpversion.files]]
|
343
343
|
filename = "src/utilities/__init__.py"
|
@@ -20,9 +20,12 @@ from utilities.hypothesis import text_ascii
|
|
20
20
|
from utilities.text import (
|
21
21
|
ParseBoolError,
|
22
22
|
ParseNoneError,
|
23
|
-
SplitStrError,
|
24
23
|
_SplitKeyValuePairsDuplicateKeysError,
|
25
24
|
_SplitKeyValuePairsSplitError,
|
25
|
+
_SplitStrClosingBracketMismatchedError,
|
26
|
+
_SplitStrClosingBracketUnmatchedError,
|
27
|
+
_SplitStrCountError,
|
28
|
+
_SplitStrOpeningBracketUnmatchedError,
|
26
29
|
join_strs,
|
27
30
|
parse_bool,
|
28
31
|
parse_none,
|
@@ -114,7 +117,7 @@ class TestSplitKeyValuePairs:
|
|
114
117
|
_ = split_key_value_pairs("a=1,a=22,a=333", mapping=True)
|
115
118
|
|
116
119
|
|
117
|
-
class
|
120
|
+
class TestSplitAndJoinStr:
|
118
121
|
@given(
|
119
122
|
data=data(),
|
120
123
|
case=sampled_from([
|
@@ -126,9 +129,10 @@ class TestSplitStrAndJoinStr:
|
|
126
129
|
("1,22", 2, ["1", "22"]),
|
127
130
|
("1,22,333", 3, ["1", "22", "333"]),
|
128
131
|
("1,,333", 3, ["1", "", "333"]),
|
132
|
+
("1,(22,22,22),333", 5, ["1", "(22", "22", "22)", "333"]),
|
129
133
|
]),
|
130
134
|
)
|
131
|
-
def test_main(self, *, case: tuple[str, int, list[str]]
|
135
|
+
def test_main(self, *, data: DataObject, case: tuple[str, int, list[str]]) -> None:
|
132
136
|
text, n, expected = case
|
133
137
|
n_use = data.draw(just(n) | none())
|
134
138
|
result = split_str(text, n=n_use)
|
@@ -138,6 +142,29 @@ class TestSplitStrAndJoinStr:
|
|
138
142
|
assert result == tuple(expected)
|
139
143
|
assert join_strs(result) == text
|
140
144
|
|
145
|
+
@given(
|
146
|
+
data=data(),
|
147
|
+
case=sampled_from([
|
148
|
+
("1", 1, ["1"]),
|
149
|
+
("1,22", 2, ["1", "22"]),
|
150
|
+
("1,22,333", 3, ["1", "22", "333"]),
|
151
|
+
("1,(22),333", 3, ["1", "(22)", "333"]),
|
152
|
+
("1,(22,22),333", 3, ["1", "(22,22)", "333"]),
|
153
|
+
("1,(22,22,22),333", 3, ["1", "(22,22,22)", "333"]),
|
154
|
+
]),
|
155
|
+
)
|
156
|
+
def test_brackets(
|
157
|
+
self, *, data: DataObject, case: tuple[str, int, list[str]]
|
158
|
+
) -> None:
|
159
|
+
text, n, expected = case
|
160
|
+
n_use = data.draw(just(n) | none())
|
161
|
+
result = split_str(text, brackets=[("(", ")")], n=n_use)
|
162
|
+
if n_use is None:
|
163
|
+
assert result == expected
|
164
|
+
else:
|
165
|
+
assert result == tuple(expected)
|
166
|
+
assert join_strs(result) == text
|
167
|
+
|
141
168
|
@given(texts=lists(text_ascii()))
|
142
169
|
def test_generic(self, *, texts: list[str]) -> None:
|
143
170
|
assert split_str(join_strs(texts)) == texts
|
@@ -146,12 +173,34 @@ class TestSplitStrAndJoinStr:
|
|
146
173
|
def test_sort(self, *, texts: set[str]) -> None:
|
147
174
|
assert split_str(join_strs(texts, sort=True)) == sorted(texts)
|
148
175
|
|
149
|
-
def
|
176
|
+
def test_error_closing_bracket_mismatched(self) -> None:
|
177
|
+
with raises(
|
178
|
+
_SplitStrClosingBracketMismatchedError,
|
179
|
+
match=r"Unable to split '1,\(22\},333'; got mismatched '\(' at position 2 and '}' at position 5",
|
180
|
+
):
|
181
|
+
_ = split_str("1,(22},333", brackets=[("(", ")"), ("{", "}")])
|
182
|
+
|
183
|
+
def test_error_closing_bracket_unmatched(self) -> None:
|
150
184
|
with raises(
|
151
|
-
|
185
|
+
_SplitStrClosingBracketUnmatchedError,
|
186
|
+
match=r"Unable to split '1,22\),333'; got unmatched '\)' at position 4",
|
187
|
+
):
|
188
|
+
_ = split_str("1,22),333", brackets=[("(", ")")])
|
189
|
+
|
190
|
+
def test_error_count(self) -> None:
|
191
|
+
with raises(
|
192
|
+
_SplitStrCountError,
|
193
|
+
match=r"Unable to split '1,22,333' into 4 part\(s\); got 3",
|
152
194
|
):
|
153
195
|
_ = split_str("1,22,333", n=4)
|
154
196
|
|
197
|
+
def test_error_opening_bracket(self) -> None:
|
198
|
+
with raises(
|
199
|
+
_SplitStrOpeningBracketUnmatchedError,
|
200
|
+
match=r"Unable to split '1,\(22,333'; got unmatched '\(' at position 2",
|
201
|
+
):
|
202
|
+
_ = split_str("1,(22,333", brackets=[("(", ")")])
|
203
|
+
|
155
204
|
|
156
205
|
class TestSnakeCase:
|
157
206
|
@given(
|
@@ -1,12 +1,14 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
3
|
import re
|
4
|
+
from collections import deque
|
4
5
|
from dataclasses import dataclass
|
5
|
-
from
|
6
|
+
from itertools import chain
|
7
|
+
from re import IGNORECASE, Match, escape, search
|
6
8
|
from textwrap import dedent
|
7
9
|
from typing import TYPE_CHECKING, Any, Literal, overload, override
|
8
10
|
|
9
|
-
from utilities.iterables import CheckDuplicatesError, check_duplicates
|
11
|
+
from utilities.iterables import CheckDuplicatesError, check_duplicates, transpose
|
10
12
|
from utilities.reprlib import get_repr
|
11
13
|
|
12
14
|
if TYPE_CHECKING:
|
@@ -167,47 +169,134 @@ class _SplitKeyValuePairsDuplicateKeysError(SplitKeyValuePairsError):
|
|
167
169
|
|
168
170
|
|
169
171
|
@overload
|
170
|
-
def split_str(
|
172
|
+
def split_str(
|
173
|
+
text: str,
|
174
|
+
/,
|
175
|
+
*,
|
176
|
+
separator: str = ",",
|
177
|
+
brackets: Iterable[tuple[str, str]] | None = None,
|
178
|
+
n: Literal[1],
|
179
|
+
) -> tuple[str]: ...
|
171
180
|
@overload
|
172
181
|
def split_str(
|
173
|
-
text: str,
|
182
|
+
text: str,
|
183
|
+
/,
|
184
|
+
*,
|
185
|
+
separator: str = ",",
|
186
|
+
brackets: Iterable[tuple[str, str]] | None = None,
|
187
|
+
n: Literal[2],
|
174
188
|
) -> tuple[str, str]: ...
|
175
189
|
@overload
|
176
190
|
def split_str(
|
177
|
-
text: str,
|
191
|
+
text: str,
|
192
|
+
/,
|
193
|
+
*,
|
194
|
+
separator: str = ",",
|
195
|
+
brackets: Iterable[tuple[str, str]] | None = None,
|
196
|
+
n: Literal[3],
|
178
197
|
) -> tuple[str, str, str]: ...
|
179
198
|
@overload
|
180
199
|
def split_str(
|
181
|
-
text: str,
|
200
|
+
text: str,
|
201
|
+
/,
|
202
|
+
*,
|
203
|
+
separator: str = ",",
|
204
|
+
brackets: Iterable[tuple[str, str]] | None = None,
|
205
|
+
n: Literal[4],
|
182
206
|
) -> tuple[str, str, str, str]: ...
|
183
207
|
@overload
|
184
208
|
def split_str(
|
185
|
-
text: str,
|
209
|
+
text: str,
|
210
|
+
/,
|
211
|
+
*,
|
212
|
+
separator: str = ",",
|
213
|
+
brackets: Iterable[tuple[str, str]] | None = None,
|
214
|
+
n: Literal[5],
|
186
215
|
) -> tuple[str, str, str, str, str]: ...
|
187
216
|
@overload
|
188
217
|
def split_str(
|
189
|
-
text: str,
|
218
|
+
text: str,
|
219
|
+
/,
|
220
|
+
*,
|
221
|
+
separator: str = ",",
|
222
|
+
brackets: Iterable[tuple[str, str]] | None = None,
|
223
|
+
n: int | None = None,
|
190
224
|
) -> Sequence[str]: ...
|
191
225
|
def split_str(
|
192
|
-
text: str,
|
226
|
+
text: str,
|
227
|
+
/,
|
228
|
+
*,
|
229
|
+
separator: str = ",",
|
230
|
+
brackets: Iterable[tuple[str, str]] | None = None,
|
231
|
+
n: int | None = None,
|
193
232
|
) -> Sequence[str]:
|
194
233
|
"""Split a string, with a special provision for the empty string."""
|
195
234
|
if text == "":
|
196
235
|
texts = []
|
197
236
|
elif text == _escape_separator(separator=separator):
|
198
237
|
texts = [""]
|
199
|
-
|
238
|
+
elif brackets is None:
|
200
239
|
texts = text.split(separator)
|
240
|
+
else:
|
241
|
+
texts = _split_str_brackets(text, brackets, separator=separator)
|
201
242
|
if n is None:
|
202
243
|
return texts
|
203
244
|
if len(texts) != n:
|
204
|
-
raise
|
245
|
+
raise _SplitStrCountError(text=text, n=n, texts=texts)
|
205
246
|
return tuple(texts)
|
206
247
|
|
207
248
|
|
249
|
+
def _split_str_brackets(
|
250
|
+
text: str, brackets: Iterable[tuple[str, str]], /, *, separator: str = ","
|
251
|
+
) -> Sequence[str]:
|
252
|
+
brackets = list(brackets)
|
253
|
+
opens, closes = transpose(brackets)
|
254
|
+
close_to_open = {close: open_ for open_, close in brackets}
|
255
|
+
|
256
|
+
escapes = map(escape, chain(chain.from_iterable(brackets), [separator]))
|
257
|
+
pattern = re.compile("|".join(escapes))
|
258
|
+
|
259
|
+
results: Sequence[str] = []
|
260
|
+
stack: deque[tuple[str, int]] = deque()
|
261
|
+
last = 0
|
262
|
+
|
263
|
+
for match in pattern.finditer(text):
|
264
|
+
token, position = match.group(), match.start()
|
265
|
+
if token in opens:
|
266
|
+
stack.append((token, position))
|
267
|
+
elif token in closes:
|
268
|
+
if len(stack) == 0:
|
269
|
+
raise _SplitStrClosingBracketUnmatchedError(
|
270
|
+
text=text, token=token, position=position
|
271
|
+
)
|
272
|
+
open_token, open_position = stack.pop()
|
273
|
+
if open_token != close_to_open[token]:
|
274
|
+
raise _SplitStrClosingBracketMismatchedError(
|
275
|
+
text=text,
|
276
|
+
opening_token=open_token,
|
277
|
+
opening_position=open_position,
|
278
|
+
closing_token=token,
|
279
|
+
closing_position=position,
|
280
|
+
)
|
281
|
+
elif (token == separator) and (len(stack) == 0):
|
282
|
+
results.append(text[last:position].strip())
|
283
|
+
last = position + 1
|
284
|
+
results.append(text[last:].strip())
|
285
|
+
if len(stack) >= 1:
|
286
|
+
token, position = stack.pop()
|
287
|
+
raise _SplitStrOpeningBracketUnmatchedError(
|
288
|
+
text=text, token=token, position=position
|
289
|
+
)
|
290
|
+
return results
|
291
|
+
|
292
|
+
|
208
293
|
@dataclass(kw_only=True, slots=True)
|
209
294
|
class SplitStrError(Exception):
|
210
295
|
text: str
|
296
|
+
|
297
|
+
|
298
|
+
@dataclass(kw_only=True, slots=True)
|
299
|
+
class _SplitStrCountError(SplitStrError):
|
211
300
|
n: int
|
212
301
|
texts: Sequence[str]
|
213
302
|
|
@@ -216,6 +305,38 @@ class SplitStrError(Exception):
|
|
216
305
|
return f"Unable to split {self.text!r} into {self.n} part(s); got {len(self.texts)}"
|
217
306
|
|
218
307
|
|
308
|
+
@dataclass(kw_only=True, slots=True)
|
309
|
+
class _SplitStrClosingBracketMismatchedError(SplitStrError):
|
310
|
+
opening_token: str
|
311
|
+
opening_position: int
|
312
|
+
closing_token: str
|
313
|
+
closing_position: int
|
314
|
+
|
315
|
+
@override
|
316
|
+
def __str__(self) -> str:
|
317
|
+
return f"Unable to split {self.text!r}; got mismatched {self.opening_token!r} at position {self.opening_position} and {self.closing_token!r} at position {self.closing_position}"
|
318
|
+
|
319
|
+
|
320
|
+
@dataclass(kw_only=True, slots=True)
|
321
|
+
class _SplitStrClosingBracketUnmatchedError(SplitStrError):
|
322
|
+
token: str
|
323
|
+
position: int
|
324
|
+
|
325
|
+
@override
|
326
|
+
def __str__(self) -> str:
|
327
|
+
return f"Unable to split {self.text!r}; got unmatched {self.token!r} at position {self.position}"
|
328
|
+
|
329
|
+
|
330
|
+
@dataclass(kw_only=True, slots=True)
|
331
|
+
class _SplitStrOpeningBracketUnmatchedError(SplitStrError):
|
332
|
+
token: str
|
333
|
+
position: int
|
334
|
+
|
335
|
+
@override
|
336
|
+
def __str__(self) -> str:
|
337
|
+
return f"Unable to split {self.text!r}; got unmatched {self.token!r} at position {self.position}"
|
338
|
+
|
339
|
+
|
219
340
|
def join_strs(
|
220
341
|
texts: Iterable[str], /, *, sort: bool = False, separator: str = ","
|
221
342
|
) -> str:
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/modules/package_missing/__init__.py
RENAMED
File without changes
|
{dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/modules/package_missing/module.py
RENAMED
File without changes
|
{dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/modules/package_with/__init__.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/modules/package_without/__init__.py
RENAMED
File without changes
|
{dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/modules/package_without/module_1.py
RENAMED
File without changes
|
{dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/modules/package_without/module_2.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/scripts/test_async_service/__init__.py
RENAMED
File without changes
|
{dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/scripts/test_async_service/__main__.py
RENAMED
File without changes
|
{dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/scripts/test_async_service/run.sh
RENAMED
File without changes
|
{dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/scripts/test_queue_processor/__init__.py
RENAMED
File without changes
|
{dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/scripts/test_queue_processor/__main__.py
RENAMED
File without changes
|
{dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/scripts/test_queue_processor/run.sh
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_traceback_funcs/__init__.py
RENAMED
File without changes
|
File without changes
|
{dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_traceback_funcs/decorated_async.py
RENAMED
File without changes
|
{dycw_utilities-0.110.1 → dycw_utilities-0.110.2}/src/tests/test_traceback_funcs/decorated_sync.py
RENAMED
File without changes
|