dycw-utilities 0.125.3__tar.gz → 0.125.5__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.125.3 → dycw_utilities-0.125.5}/PKG-INFO +6 -6
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/pyproject.toml +14 -11
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_iterables.py +2 -165
- dycw_utilities-0.125.5/src/tests/test_libcst.py +158 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_loguru.py +1 -6
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_polars.py +2 -9
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_pytest.py +1 -1
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_sqlalchemy_polars.py +1 -3
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/__init__.py +1 -1
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/iterables.py +1 -53
- dycw_utilities-0.125.5/src/utilities/libcst.py +176 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/lightweight_charts.py +1 -1
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/polars.py +8 -8
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/polars_ols.py +1 -3
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/pyrsistent.py +5 -5
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/pytest.py +3 -5
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/sqlalchemy_polars.py +1 -4
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/.gitignore +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/LICENSE +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/README.md +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/__init__.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/conftest.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/modules/__init__.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/modules/package_missing/__init__.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/modules/package_missing/module.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/modules/package_with/__init__.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/modules/package_with/outer_1.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/modules/package_with/outer_2.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/modules/package_with/subpackage/__init__.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/modules/package_with/subpackage/inner_1.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/modules/package_with/subpackage/inner_2.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/modules/package_with/subpackage/inner_3.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/modules/package_without/__init__.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/modules/package_without/module_1.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/modules/package_without/module_2.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/modules/standalone.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/modules/with_imports.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/regressions/test_pytest_regressions/TestMultipleRegressionFixtures__test_main__obj.json +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/regressions/test_pytest_regressions/TestMultipleRegressionFixtures__test_main__series.json +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_int.json +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_literal__false.json +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_literal__true.json +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_nested.json +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/regressions/test_pytest_regressions/TestPolarsRegressionFixture__test_dataframe.json +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/regressions/test_pytest_regressions/TestPolarsRegressionFixture__test_series.json +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_altair.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_asyncio.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_atomicwrites.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_atools.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_cachetools.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_click.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_concurrent.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_contextlib.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_contextvars.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_cryptography.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_cvxpy.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_dataclasses.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_datetime.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_enum.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_errors.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_eventkit.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_fastapi.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_fpdf2.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_functions.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_functools.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_getpass.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_git.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_hashlib.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_http.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_hypothesis.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_importlib.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_ipython.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_jupyter.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_lightweight_charts.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_logging.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_luigi.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_math.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_memory_profiler.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_modules.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_more_itertools.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_numpy.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_operator.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_optuna.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_orjson.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_os.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_parse.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_pathlib.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_period.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_pickle.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_platform.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_polars_ols.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_pqdm.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_pydantic.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_pyinstrument.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_pyrsistent.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_pytest_regressions.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_python_dotenv.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_random.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_re.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_redis.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_reprlib.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_rich.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_scipy.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_sentinel.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_shelve.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_slack_sdk.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_socket.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_sqlalchemy.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_statsmodel.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_streamlit.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_sys.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_tempfile.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_tenacity.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_text.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_threading.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_timer.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_traceback.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_traceback_funcs/__init__.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_traceback_funcs/chain.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_traceback_funcs/decorated_async.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_traceback_funcs/decorated_sync.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_traceback_funcs/error_bind.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_traceback_funcs/many.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_traceback_funcs/one.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_traceback_funcs/recursive.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_traceback_funcs/task_group_one.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_traceback_funcs/task_group_two.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_traceback_funcs/two.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_traceback_funcs/untraced.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_types.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_typing.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_typing_funcs/__init__.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_typing_funcs/no_future.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_typing_funcs/with_future.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_tzdata.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_tzlocal.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_uuid.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_version.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_warnings.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_whenever.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_zipfile.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_zoneinfo.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/altair.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/asyncio.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/atomicwrites.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/atools.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/cachetools.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/click.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/concurrent.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/contextlib.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/contextvars.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/cryptography.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/cvxpy.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/dataclasses.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/datetime.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/enum.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/errors.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/eventkit.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/fastapi.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/fpdf2.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/functions.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/functools.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/getpass.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/git.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/hashlib.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/http.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/hypothesis.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/importlib.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/ipython.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/jupyter.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/logging.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/loguru.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/luigi.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/math.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/memory_profiler.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/modules.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/more_itertools.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/numpy.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/operator.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/optuna.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/orjson.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/os.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/parse.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/pathlib.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/period.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/pickle.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/platform.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/pqdm.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/py.typed +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/pydantic.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/pyinstrument.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/pytest_regressions.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/python_dotenv.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/random.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/re.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/redis.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/reprlib.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/rich.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/scipy.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/sentinel.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/shelve.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/slack_sdk.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/socket.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/sqlalchemy.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/statsmodels.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/streamlit.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/sys.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/tempfile.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/tenacity.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/text.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/threading.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/timer.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/traceback.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/types.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/typing.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/tzdata.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/tzlocal.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/uuid.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/version.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/warnings.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/whenever.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/zipfile.py +0 -0
- {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/zoneinfo.py +0 -0
@@ -1,16 +1,16 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: dycw-utilities
|
3
|
-
Version: 0.125.
|
3
|
+
Version: 0.125.5
|
4
4
|
Author-email: Derek Wan <d.wan@icloud.com>
|
5
5
|
License-File: LICENSE
|
6
6
|
Requires-Python: >=3.12
|
7
7
|
Requires-Dist: typing-extensions<4.14,>=4.13.1
|
8
8
|
Provides-Extra: test
|
9
|
-
Requires-Dist: hypothesis<6.132,>=6.131.
|
9
|
+
Requires-Dist: hypothesis<6.132,>=6.131.28; extra == 'test'
|
10
10
|
Requires-Dist: pytest-asyncio<0.27,>=0.26.0; extra == 'test'
|
11
11
|
Requires-Dist: pytest-cov<6.2,>=6.1.1; extra == 'test'
|
12
12
|
Requires-Dist: pytest-instafail<0.6,>=0.5.0; extra == 'test'
|
13
|
-
Requires-Dist: pytest-lazy-fixtures<1.2,>=1.1.
|
13
|
+
Requires-Dist: pytest-lazy-fixtures<1.2,>=1.1.3; extra == 'test'
|
14
14
|
Requires-Dist: pytest-only<2.2,>=2.1.2; extra == 'test'
|
15
15
|
Requires-Dist: pytest-randomly<3.17,>=3.16.0; extra == 'test'
|
16
16
|
Requires-Dist: pytest-regressions<2.8,>=2.7.0; extra == 'test'
|
@@ -41,7 +41,7 @@ Requires-Dist: whenever<0.9,>=0.8.2; extra == 'zzz-test-click'
|
|
41
41
|
Provides-Extra: zzz-test-contextlib
|
42
42
|
Provides-Extra: zzz-test-contextvars
|
43
43
|
Provides-Extra: zzz-test-cryptography
|
44
|
-
Requires-Dist: cryptography<45.1,>=45.0.
|
44
|
+
Requires-Dist: cryptography<45.1,>=45.0.3; extra == 'zzz-test-cryptography'
|
45
45
|
Provides-Extra: zzz-test-cvxpy
|
46
46
|
Requires-Dist: cvxpy<1.7,>=1.6.5; extra == 'zzz-test-cvxpy'
|
47
47
|
Provides-Extra: zzz-test-dataclasses
|
@@ -78,7 +78,7 @@ Provides-Extra: zzz-test-hypothesis
|
|
78
78
|
Requires-Dist: aiosqlite<0.22,>=0.21.0; extra == 'zzz-test-hypothesis'
|
79
79
|
Requires-Dist: asyncpg<0.31,>=0.30.0; extra == 'zzz-test-hypothesis'
|
80
80
|
Requires-Dist: greenlet<3.3,>=3.2.0; extra == 'zzz-test-hypothesis'
|
81
|
-
Requires-Dist: hypothesis<6.132,>=6.131.
|
81
|
+
Requires-Dist: hypothesis<6.132,>=6.131.28; extra == 'zzz-test-hypothesis'
|
82
82
|
Requires-Dist: luigi<3.7,>=3.6.0; extra == 'zzz-test-hypothesis'
|
83
83
|
Requires-Dist: numpy<2.3,>=2.2.6; extra == 'zzz-test-hypothesis'
|
84
84
|
Requires-Dist: pathvalidate<3.3,>=3.2.3; extra == 'zzz-test-hypothesis'
|
@@ -174,7 +174,7 @@ Requires-Dist: scipy<1.16,>=1.15.3; extra == 'zzz-test-scipy'
|
|
174
174
|
Provides-Extra: zzz-test-sentinel
|
175
175
|
Provides-Extra: zzz-test-shelve
|
176
176
|
Provides-Extra: zzz-test-slack-sdk
|
177
|
-
Requires-Dist: aiohttp<3.
|
177
|
+
Requires-Dist: aiohttp<3.13,>=3.12.0; extra == 'zzz-test-slack-sdk'
|
178
178
|
Requires-Dist: slack-sdk<3.36,>=3.35.0; extra == 'zzz-test-slack-sdk'
|
179
179
|
Provides-Extra: zzz-test-socket
|
180
180
|
Provides-Extra: zzz-test-sqlalchemy
|
@@ -8,7 +8,7 @@ requires = ["hatchling"]
|
|
8
8
|
# dependency groups
|
9
9
|
[dependency-groups]
|
10
10
|
dev = [
|
11
|
-
"aiohttp >= 3.
|
11
|
+
"aiohttp >= 3.12.0, < 3.13", # for slack
|
12
12
|
"aiosqlite >= 0.21.0, < 0.22",
|
13
13
|
"altair >= 5.5.0, < 5.6",
|
14
14
|
"asyncpg >= 0.30.0, < 0.31", # for sqlalchemy async
|
@@ -18,14 +18,14 @@ dev = [
|
|
18
18
|
"click >= 8.2.1, < 8.3",
|
19
19
|
"coloredlogs >= 15.0.1, < 15.1",
|
20
20
|
"concurrent-log-handler >= 0.9.26, < 0.10",
|
21
|
-
"cryptography >= 45.0.
|
21
|
+
"cryptography >= 45.0.3, < 45.1",
|
22
22
|
"cvxpy >= 1.6.5, < 1.7",
|
23
23
|
"eventkit >= 1.0.3, < 1.1",
|
24
24
|
"fastapi >= 0.115.11, < 0.116",
|
25
25
|
"fpdf2 >= 2.8.3, < 2.9",
|
26
26
|
"greenlet >= 3.2.0, < 3.3", # for sqlalchemy async
|
27
27
|
"httpx >= 0.28.1, < 0.29", # for fastapi
|
28
|
-
"hypothesis >= 6.131.
|
28
|
+
"hypothesis >= 6.131.28, < 6.132",
|
29
29
|
"img2pdf >= 0.6.0, < 0.7",
|
30
30
|
"lightweight-charts >= 2.1, < 2.2",
|
31
31
|
"loguru >= 0.7.3, < 0.8",
|
@@ -35,6 +35,7 @@ dev = [
|
|
35
35
|
"nest-asyncio >= 1.6.0, < 1.7", # for sqlalchemy async
|
36
36
|
"nox >= 2025.2.9, < 2025.3",
|
37
37
|
"numpy >= 2.2.6, < 2.3",
|
38
|
+
"libcst >= 1.7.0, < 1.8",
|
38
39
|
"optuna >= 4.3.0, < 4.4",
|
39
40
|
"orjson >= 3.10.18, < 3.11",
|
40
41
|
"pathvalidate >= 3.2.3, < 3.3",
|
@@ -44,6 +45,7 @@ dev = [
|
|
44
45
|
"psycopg2-binary >= 2.9.10, < 2.10", # for sqlalchemy
|
45
46
|
"pydantic >= 2.11.4, < 2.12",
|
46
47
|
"pyinstrument >= 5.0.2, < 5.1",
|
48
|
+
"pyright[nodejs] >= 1.1.401, < 1.2",
|
47
49
|
"pyrsistent >= 0.20.0, < 0.21",
|
48
50
|
"pytest >= 8.3.5, < 8.4",
|
49
51
|
"pytest-regressions >= 2.7.0, < 2.8",
|
@@ -70,7 +72,7 @@ dev = [
|
|
70
72
|
"pytest-asyncio >= 0.26.0, < 0.27",
|
71
73
|
"pytest-cov >= 6.1.1, < 6.2",
|
72
74
|
"pytest-instafail >= 0.5.0, < 0.6",
|
73
|
-
"pytest-lazy-fixtures >= 1.1.
|
75
|
+
"pytest-lazy-fixtures >= 1.1.3, < 1.2",
|
74
76
|
"pytest-only >= 2.1.2, < 2.2",
|
75
77
|
"pytest-randomly >= 3.16.0, < 3.17",
|
76
78
|
"pytest-rerunfailures >= 15.1, < 16",
|
@@ -91,16 +93,16 @@ dependencies = [
|
|
91
93
|
name = "dycw-utilities"
|
92
94
|
readme = "README.md"
|
93
95
|
requires-python = ">= 3.12"
|
94
|
-
version = "0.125.
|
96
|
+
version = "0.125.5"
|
95
97
|
|
96
98
|
[project.optional-dependencies]
|
97
99
|
test = [
|
98
|
-
"hypothesis >= 6.131.
|
100
|
+
"hypothesis >= 6.131.28, < 6.132",
|
99
101
|
"pytest >= 8.3.5, < 8.4",
|
100
102
|
"pytest-asyncio >= 0.26.0, < 0.27",
|
101
103
|
"pytest-cov >= 6.1.1, < 6.2",
|
102
104
|
"pytest-instafail >= 0.5.0, < 0.6",
|
103
|
-
"pytest-lazy-fixtures >= 1.1.
|
105
|
+
"pytest-lazy-fixtures >= 1.1.3, < 1.2",
|
104
106
|
"pytest-only >= 2.1.2, < 2.2",
|
105
107
|
"pytest-randomly >= 3.16.0, < 3.17",
|
106
108
|
"pytest-regressions >= 2.7.0, < 2.8",
|
@@ -131,7 +133,7 @@ zzz-test-click = [
|
|
131
133
|
]
|
132
134
|
zzz-test-contextlib = []
|
133
135
|
zzz-test-contextvars = []
|
134
|
-
zzz-test-cryptography = ["cryptography >= 45.0.
|
136
|
+
zzz-test-cryptography = ["cryptography >= 45.0.3, < 45.1"]
|
135
137
|
zzz-test-cvxpy = ["cvxpy >= 1.6.5, < 1.7"]
|
136
138
|
zzz-test-dataclasses = [
|
137
139
|
"orjson >= 3.10.15, < 3.11",
|
@@ -172,7 +174,7 @@ zzz-test-hypothesis = [
|
|
172
174
|
"aiosqlite >= 0.21.0, < 0.22",
|
173
175
|
"asyncpg >= 0.30.0, < 0.31", # for sqlalchemy async
|
174
176
|
"greenlet >= 3.2.0, < 3.3", # for sqlalchemy async
|
175
|
-
"hypothesis >= 6.131.
|
177
|
+
"hypothesis >= 6.131.28, < 6.132",
|
176
178
|
"luigi >= 3.6.0, < 3.7",
|
177
179
|
"numpy >= 2.2.6, < 2.3",
|
178
180
|
"pathvalidate >= 3.2.3, < 3.3",
|
@@ -268,7 +270,7 @@ zzz-test-scipy = ["scipy >= 1.15.3, < 1.16"]
|
|
268
270
|
zzz-test-sentinel = []
|
269
271
|
zzz-test-shelve = []
|
270
272
|
zzz-test-slack-sdk = [
|
271
|
-
"aiohttp >= 3.
|
273
|
+
"aiohttp >= 3.12.0, < 3.13", # for slack
|
272
274
|
"slack-sdk >= 3.35.0, < 3.36",
|
273
275
|
]
|
274
276
|
zzz-test-socket = []
|
@@ -332,7 +334,7 @@ zzz-test-zoneinfo = [
|
|
332
334
|
# bump-my-version
|
333
335
|
[tool.bumpversion]
|
334
336
|
allow_dirty = true
|
335
|
-
current_version = "0.125.
|
337
|
+
current_version = "0.125.5"
|
336
338
|
|
337
339
|
[[tool.bumpversion.files]]
|
338
340
|
filename = "src/utilities/__init__.py"
|
@@ -394,6 +396,7 @@ style = [
|
|
394
396
|
[tool.pyright]
|
395
397
|
deprecateTypingAliases = true
|
396
398
|
enableReachabilityAnalysis = false
|
399
|
+
ignore = ["**/_typeshed/**"]
|
397
400
|
pythonVersion = "3.12"
|
398
401
|
reportAny = false
|
399
402
|
reportCallInDefaultInitializer = true
|
@@ -1,14 +1,14 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
3
|
import re
|
4
|
-
from dataclasses import dataclass
|
4
|
+
from dataclasses import dataclass
|
5
5
|
from enum import Enum, auto
|
6
6
|
from functools import cmp_to_key
|
7
7
|
from itertools import chain, repeat
|
8
8
|
from math import isfinite, isinf, isnan, nan
|
9
9
|
from operator import add, neg, sub
|
10
10
|
from re import DOTALL
|
11
|
-
from typing import TYPE_CHECKING, Any, ClassVar
|
11
|
+
from typing import TYPE_CHECKING, Any, ClassVar
|
12
12
|
|
13
13
|
from hypothesis import given
|
14
14
|
from hypothesis.strategies import (
|
@@ -52,7 +52,6 @@ from utilities.iterables import (
|
|
52
52
|
CheckSubSetError,
|
53
53
|
CheckSuperMappingError,
|
54
54
|
CheckSuperSetError,
|
55
|
-
Collection,
|
56
55
|
EnsureIterableError,
|
57
56
|
EnsureIterableNotStrError,
|
58
57
|
MergeStrMappingsError,
|
@@ -637,168 +636,6 @@ class TestCmpNullable:
|
|
637
636
|
assert result == expected
|
638
637
|
|
639
638
|
|
640
|
-
@dataclass(unsafe_hash=True, slots=True)
|
641
|
-
class _Item:
|
642
|
-
n: int
|
643
|
-
|
644
|
-
|
645
|
-
class TestCollection:
|
646
|
-
def test_and_singleton(self) -> None:
|
647
|
-
collection = Collection(map(_Item, range(3)))
|
648
|
-
result = collection & _Item(1)
|
649
|
-
assert isinstance(result, Collection)
|
650
|
-
expected = Collection(_Item(1))
|
651
|
-
assert result == expected
|
652
|
-
|
653
|
-
def test_and_collection(self) -> None:
|
654
|
-
collection = Collection(map(_Item, range(3)))
|
655
|
-
result = collection & Collection(_Item(1))
|
656
|
-
assert isinstance(result, Collection)
|
657
|
-
expected = Collection(_Item(1))
|
658
|
-
assert result == expected
|
659
|
-
|
660
|
-
def test_and_iterable(self) -> None:
|
661
|
-
collection = Collection(map(_Item, range(3)))
|
662
|
-
result = collection & [_Item(1)]
|
663
|
-
assert isinstance(result, Collection)
|
664
|
-
expected = Collection(_Item(1))
|
665
|
-
assert result == expected
|
666
|
-
|
667
|
-
def test_filter(self) -> None:
|
668
|
-
collection = Collection(map(_Item, range(4)))
|
669
|
-
result = collection.filter(lambda item: item.n % 2 == 0)
|
670
|
-
assert isinstance(result, Collection)
|
671
|
-
expected = Collection(_Item(0), _Item(2))
|
672
|
-
assert result == expected
|
673
|
-
|
674
|
-
def test_hash(self) -> None:
|
675
|
-
collection = Collection(map(_Item, range(3)))
|
676
|
-
_ = hash(collection)
|
677
|
-
|
678
|
-
def test_init(self) -> None:
|
679
|
-
class SubCollection(Collection[_Item]):
|
680
|
-
@override
|
681
|
-
def __init__(self, *item_or_items: MaybeIterable[_Item]) -> None:
|
682
|
-
super().__init__(*item_or_items)
|
683
|
-
if any(item.n >= 1 for item in self):
|
684
|
-
msg = "n >= 1 is not permitted"
|
685
|
-
raise ValueError(msg)
|
686
|
-
|
687
|
-
with raises(ValueError, match="n >= 1 is not permitted"):
|
688
|
-
_ = SubCollection(map(_Item, range(3)))
|
689
|
-
|
690
|
-
def test_map_return_same_type(self) -> None:
|
691
|
-
collection = Collection(map(_Item, range(3)))
|
692
|
-
result = collection.map(lambda item: replace(item, n=item.n + 1))
|
693
|
-
assert isinstance(result, Collection)
|
694
|
-
expected = Collection(map(_Item, range(1, 4)))
|
695
|
-
assert result == expected
|
696
|
-
|
697
|
-
def test_map_return_different_type(self) -> None:
|
698
|
-
collection = Collection(map(_Item, range(3)))
|
699
|
-
result = collection.map(lambda item: item.n)
|
700
|
-
assert isinstance(result, Collection)
|
701
|
-
expected = Collection(range(3))
|
702
|
-
assert result == expected
|
703
|
-
|
704
|
-
def test_new_one_singleton(self) -> None:
|
705
|
-
collection = Collection(_Item(1))
|
706
|
-
assert isinstance(collection, Collection)
|
707
|
-
assert len(collection) == 1
|
708
|
-
assert one(collection) == _Item(1)
|
709
|
-
|
710
|
-
def test_new_one_iterable(self) -> None:
|
711
|
-
collection = Collection(map(_Item, range(3)))
|
712
|
-
assert isinstance(collection, Collection)
|
713
|
-
assert len(collection) == 3
|
714
|
-
|
715
|
-
def test_new_many_singletons(self) -> None:
|
716
|
-
collection = Collection(_Item(1), _Item(2), _Item(3))
|
717
|
-
assert isinstance(collection, Collection)
|
718
|
-
assert len(collection) == 3
|
719
|
-
|
720
|
-
def test_new_many_iterables(self) -> None:
|
721
|
-
collection = Collection(map(_Item, range(3)), map(_Item, range(3)))
|
722
|
-
assert isinstance(collection, Collection)
|
723
|
-
assert len(collection) == 3
|
724
|
-
|
725
|
-
def test_new_check_items(self) -> None:
|
726
|
-
class SubCollection(Collection[_Item]):
|
727
|
-
@classmethod
|
728
|
-
@override
|
729
|
-
def check_items(cls, items: Iterable[_Item]) -> None:
|
730
|
-
if any(item.n >= 1 for item in items):
|
731
|
-
msg = "n >= 1 is not permitted"
|
732
|
-
raise ValueError(msg)
|
733
|
-
|
734
|
-
with raises(ValueError, match="n >= 1 is not permitted"):
|
735
|
-
_ = SubCollection(map(_Item, range(3)))
|
736
|
-
|
737
|
-
def test_or_singleton(self) -> None:
|
738
|
-
collection = Collection(map(_Item, range(3)))
|
739
|
-
result = collection | _Item(3)
|
740
|
-
assert isinstance(result, Collection)
|
741
|
-
expected = Collection(map(_Item, range(4)))
|
742
|
-
assert result == expected
|
743
|
-
|
744
|
-
def test_or_collection(self) -> None:
|
745
|
-
collection = Collection(map(_Item, range(3)))
|
746
|
-
result = collection | Collection(map(_Item, range(1, 4)))
|
747
|
-
assert isinstance(result, Collection)
|
748
|
-
expected = Collection(map(_Item, range(4)))
|
749
|
-
assert result == expected
|
750
|
-
|
751
|
-
def test_or_iterable(self) -> None:
|
752
|
-
collection = Collection(map(_Item, range(3)))
|
753
|
-
result = collection | map(_Item, range(1, 4))
|
754
|
-
assert isinstance(result, Collection)
|
755
|
-
expected = Collection(map(_Item, range(4)))
|
756
|
-
assert result == expected
|
757
|
-
|
758
|
-
def test_partition(self) -> None:
|
759
|
-
collection = Collection(map(_Item, range(4)))
|
760
|
-
result_false, result_true = collection.partition(lambda item: item.n % 2 == 0)
|
761
|
-
assert isinstance(result_false, Collection)
|
762
|
-
expected_false = Collection(_Item(1), _Item(3))
|
763
|
-
assert result_false == expected_false
|
764
|
-
assert isinstance(result_true, Collection)
|
765
|
-
expected_true = Collection(_Item(0), _Item(2))
|
766
|
-
assert result_true == expected_true
|
767
|
-
|
768
|
-
def test_repr(self) -> None:
|
769
|
-
collection = Collection(map(_Item, range(3)))
|
770
|
-
result = repr(collection)
|
771
|
-
expected = "Collection({_Item(n=0), _Item(n=1), _Item(n=2)})"
|
772
|
-
assert result == expected
|
773
|
-
|
774
|
-
def test_str(self) -> None:
|
775
|
-
collection = Collection(map(_Item, range(3)))
|
776
|
-
result = str(collection)
|
777
|
-
expected = "Collection({_Item(n=0), _Item(n=1), _Item(n=2)})"
|
778
|
-
assert result == expected
|
779
|
-
|
780
|
-
def test_sub_single_item(self) -> None:
|
781
|
-
collection = Collection(map(_Item, range(3)))
|
782
|
-
result = collection - _Item(1)
|
783
|
-
assert isinstance(result, Collection)
|
784
|
-
expected = Collection(_Item(0), _Item(2))
|
785
|
-
assert result == expected
|
786
|
-
|
787
|
-
def test_sub_collection(self) -> None:
|
788
|
-
collection = Collection(map(_Item, range(3)))
|
789
|
-
result = collection - Collection(_Item(1))
|
790
|
-
assert isinstance(result, Collection)
|
791
|
-
expected = Collection(_Item(0), _Item(2))
|
792
|
-
assert result == expected
|
793
|
-
|
794
|
-
def test_sub_iterable(self) -> None:
|
795
|
-
collection = Collection(map(_Item, range(3)))
|
796
|
-
result = collection - [_Item(1)]
|
797
|
-
assert isinstance(result, Collection)
|
798
|
-
expected = Collection(_Item(0), _Item(2))
|
799
|
-
assert result == expected
|
800
|
-
|
801
|
-
|
802
639
|
class TestEnsureHashables:
|
803
640
|
def test_main(self) -> None:
|
804
641
|
assert ensure_hashables(1, 2, a=3, b=4) == ([1, 2], {"a": 3, "b": 4})
|
@@ -0,0 +1,158 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
3
|
+
import re
|
4
|
+
from re import DOTALL
|
5
|
+
|
6
|
+
from hypothesis import given
|
7
|
+
from hypothesis.strategies import sampled_from
|
8
|
+
from libcst import (
|
9
|
+
Attribute,
|
10
|
+
Dot,
|
11
|
+
Expr,
|
12
|
+
Import,
|
13
|
+
ImportAlias,
|
14
|
+
ImportFrom,
|
15
|
+
ImportStar,
|
16
|
+
Module,
|
17
|
+
Name,
|
18
|
+
SimpleStatementLine,
|
19
|
+
)
|
20
|
+
from pytest import raises
|
21
|
+
|
22
|
+
from tests.conftest import SKIPIF_CI
|
23
|
+
from utilities.iterables import one
|
24
|
+
from utilities.libcst import (
|
25
|
+
_ParseImportAliasError,
|
26
|
+
_ParseImportEmptyModuleError,
|
27
|
+
generate_f_string,
|
28
|
+
generate_from_import,
|
29
|
+
generate_import,
|
30
|
+
join_dotted_str,
|
31
|
+
parse_import,
|
32
|
+
render_module,
|
33
|
+
split_dotted_str,
|
34
|
+
)
|
35
|
+
|
36
|
+
|
37
|
+
class TestGenerateFString:
|
38
|
+
def test_main(self) -> None:
|
39
|
+
string = generate_f_string("foo", "bar")
|
40
|
+
result = Module([SimpleStatementLine([Expr(string)])]).code.strip("\n")
|
41
|
+
expected = 'f"{foo}bar"'
|
42
|
+
assert result == expected
|
43
|
+
|
44
|
+
|
45
|
+
class TestGenerateFromImport:
|
46
|
+
@given(
|
47
|
+
case=sampled_from([
|
48
|
+
("foo", "bar", None, "from foo import bar"),
|
49
|
+
("foo", "bar", "bar2", "from foo import bar as bar2"),
|
50
|
+
("foo.bar", "baz", None, "from foo.bar import baz"),
|
51
|
+
("foo.bar", "baz", "baz2", "from foo.bar import baz as baz2"),
|
52
|
+
])
|
53
|
+
)
|
54
|
+
def test_main(self, *, case: tuple[str, str, str | None, str]) -> None:
|
55
|
+
module, name, asname, expected = case
|
56
|
+
imp = generate_from_import(module, name, asname=asname)
|
57
|
+
result = Module([SimpleStatementLine([imp])]).code.strip("\n")
|
58
|
+
assert result == expected
|
59
|
+
|
60
|
+
|
61
|
+
class TestGenerateImport:
|
62
|
+
@given(
|
63
|
+
case=sampled_from([
|
64
|
+
("foo", None, "import foo"),
|
65
|
+
("foo", "foo2", "import foo as foo2"),
|
66
|
+
("foo.bar", None, "import foo.bar"),
|
67
|
+
("foo.bar", "bar2", "import foo.bar as bar2"),
|
68
|
+
])
|
69
|
+
)
|
70
|
+
def test_main(self, *, case: tuple[str, str | None, str]) -> None:
|
71
|
+
module, asname, expected = case
|
72
|
+
imp = generate_import(module, asname=asname)
|
73
|
+
result = Module([SimpleStatementLine([imp])]).code.strip("\n")
|
74
|
+
assert result == expected
|
75
|
+
|
76
|
+
|
77
|
+
class TestParseImport:
|
78
|
+
def test_import_one_name(self) -> None:
|
79
|
+
imp = Import(names=[ImportAlias(Name("foo"))])
|
80
|
+
parsed = one(parse_import(imp))
|
81
|
+
assert parsed.module == "foo"
|
82
|
+
assert parsed.name is None
|
83
|
+
|
84
|
+
def test_import_one_attr(self) -> None:
|
85
|
+
imp = Import(names=[ImportAlias(Attribute(Name("foo"), Name("bar")))])
|
86
|
+
parsed = one(parse_import(imp))
|
87
|
+
assert parsed.module == "foo.bar"
|
88
|
+
assert parsed.name is None
|
89
|
+
|
90
|
+
def test_import_many(self) -> None:
|
91
|
+
imp = Import(names=[ImportAlias(Name("foo")), ImportAlias(Name("bar"))])
|
92
|
+
result = parse_import(imp)
|
93
|
+
assert len(result) == 2
|
94
|
+
first, second = result
|
95
|
+
assert first.module == "foo"
|
96
|
+
assert first.name is None
|
97
|
+
assert second.module == "bar"
|
98
|
+
assert second.name is None
|
99
|
+
|
100
|
+
def test_from_import_one(self) -> None:
|
101
|
+
imp = ImportFrom(module=Name("foo"), names=[ImportAlias(Name("bar"))])
|
102
|
+
result = one(parse_import(imp))
|
103
|
+
assert result.module == "foo"
|
104
|
+
assert result.name == "bar"
|
105
|
+
|
106
|
+
def test_from_import_many(self) -> None:
|
107
|
+
imp = ImportFrom(
|
108
|
+
module=Name("foo"),
|
109
|
+
names=[ImportAlias(Name("bar")), ImportAlias(Name("baz"))],
|
110
|
+
)
|
111
|
+
result = parse_import(imp)
|
112
|
+
first, second = result
|
113
|
+
assert first.module == "foo"
|
114
|
+
assert first.name == "bar"
|
115
|
+
assert second.module == "foo"
|
116
|
+
assert second.name == "baz"
|
117
|
+
|
118
|
+
def test_from_import_star(self) -> None:
|
119
|
+
imp = ImportFrom(module=Name("foo"), names=ImportStar())
|
120
|
+
result = one(parse_import(imp))
|
121
|
+
assert result.module == "foo"
|
122
|
+
assert result.name == "*"
|
123
|
+
|
124
|
+
def test_error_empty_module(self) -> None:
|
125
|
+
alias = ImportAlias(name=Name("foo"))
|
126
|
+
imp = ImportFrom(module=None, names=[alias], relative=[Dot()])
|
127
|
+
with raises(
|
128
|
+
_ParseImportEmptyModuleError, match="Module must not be None; got .*"
|
129
|
+
):
|
130
|
+
_ = parse_import(imp)
|
131
|
+
|
132
|
+
def test_error_alias(self) -> None:
|
133
|
+
alias = ImportAlias(name=Attribute(Name("foo"), Name("bar")))
|
134
|
+
imp = ImportFrom(module=Name("baz"), names=[alias])
|
135
|
+
with raises(
|
136
|
+
_ParseImportAliasError,
|
137
|
+
match=re.compile(
|
138
|
+
r"Invalid alias name; got module 'baz' and attribute 'Name\(.*\)'",
|
139
|
+
flags=DOTALL,
|
140
|
+
),
|
141
|
+
):
|
142
|
+
_ = parse_import(imp)
|
143
|
+
|
144
|
+
|
145
|
+
class TestRenderModule:
|
146
|
+
@SKIPIF_CI
|
147
|
+
def test_main(self) -> None:
|
148
|
+
module = Module([SimpleStatementLine([generate_import("foo")])])
|
149
|
+
result = render_module(module)
|
150
|
+
expected = "import foo\n"
|
151
|
+
assert result == expected
|
152
|
+
|
153
|
+
|
154
|
+
class TestSplitAndJoinDottedStr:
|
155
|
+
@given(text=sampled_from(["foo", "foo.bar", "foo.bar.baz"]))
|
156
|
+
def test_main(self, *, text: str) -> None:
|
157
|
+
result = join_dotted_str(split_dotted_str(text))
|
158
|
+
assert result == text
|
@@ -6,12 +6,7 @@ from re import search
|
|
6
6
|
from typing import TYPE_CHECKING, Any, cast
|
7
7
|
|
8
8
|
from loguru import logger
|
9
|
-
from loguru._recattrs import
|
10
|
-
RecordFile, # pyright: ignore[reportPrivateImportUsage]
|
11
|
-
RecordLevel, # pyright: ignore[reportPrivateImportUsage]
|
12
|
-
RecordProcess, # pyright: ignore[reportPrivateImportUsage]
|
13
|
-
RecordThread, # pyright: ignore[reportPrivateImportUsage]
|
14
|
-
)
|
9
|
+
from loguru._recattrs import RecordFile, RecordLevel, RecordProcess, RecordThread
|
15
10
|
from pytest import CaptureFixture, fixture, mark, param, raises
|
16
11
|
|
17
12
|
from utilities.loguru import (
|
@@ -51,10 +51,7 @@ from polars import (
|
|
51
51
|
lit,
|
52
52
|
struct,
|
53
53
|
)
|
54
|
-
from polars._typing import
|
55
|
-
IntoExprColumn, # pyright: ignore[reportPrivateImportUsage]
|
56
|
-
SchemaDict, # pyright: ignore[reportPrivateImportUsage]
|
57
|
-
)
|
54
|
+
from polars._typing import IntoExprColumn, SchemaDict
|
58
55
|
from polars.exceptions import ComputeError
|
59
56
|
from polars.testing import assert_frame_equal, assert_series_equal
|
60
57
|
from pytest import raises
|
@@ -177,11 +174,7 @@ if TYPE_CHECKING:
|
|
177
174
|
from collections.abc import Callable, Iterable, Mapping, Sequence
|
178
175
|
from zoneinfo import ZoneInfo
|
179
176
|
|
180
|
-
from polars._typing import
|
181
|
-
IntoExprColumn, # pyright: ignore[reportPrivateImportUsage]
|
182
|
-
PolarsDataType, # pyright: ignore[reportPrivateImportUsage]
|
183
|
-
SchemaDict, # pyright: ignore[reportPrivateImportUsage]
|
184
|
-
)
|
177
|
+
from polars._typing import IntoExprColumn, PolarsDataType, SchemaDict
|
185
178
|
from polars.datatypes import DataTypeClass
|
186
179
|
|
187
180
|
from utilities.types import MaybeType, StrMapping, WeekDay
|
@@ -111,9 +111,7 @@ from utilities.sqlalchemy_polars import (
|
|
111
111
|
if TYPE_CHECKING:
|
112
112
|
from collections.abc import Callable, Iterable, Sequence
|
113
113
|
|
114
|
-
from polars._typing import
|
115
|
-
PolarsDataType, # pyright: ignore[reportPrivateImportUsage]
|
116
|
-
)
|
114
|
+
from polars._typing import PolarsDataType
|
117
115
|
from polars.datatypes import DataTypeClass
|
118
116
|
from sqlalchemy.ext.asyncio import AsyncEngine
|
119
117
|
|
@@ -25,7 +25,6 @@ from typing import (
|
|
25
25
|
Any,
|
26
26
|
Generic,
|
27
27
|
Literal,
|
28
|
-
Self,
|
29
28
|
TypeGuard,
|
30
29
|
TypeVar,
|
31
30
|
assert_never,
|
@@ -45,7 +44,7 @@ from utilities.math import (
|
|
45
44
|
)
|
46
45
|
from utilities.reprlib import get_repr
|
47
46
|
from utilities.sentinel import Sentinel, sentinel
|
48
|
-
from utilities.types import Sign, THashable,
|
47
|
+
from utilities.types import Sign, THashable, TSupportsAdd, TSupportsLT
|
49
48
|
from utilities.zoneinfo import UTC
|
50
49
|
|
51
50
|
if TYPE_CHECKING:
|
@@ -722,57 +721,6 @@ def chunked(iterable: Iterable[_T], n: int, /) -> Iterator[Sequence[_T]]:
|
|
722
721
|
##
|
723
722
|
|
724
723
|
|
725
|
-
class Collection(frozenset[THashable]):
|
726
|
-
"""A collection of hashable, sortable items."""
|
727
|
-
|
728
|
-
def __new__(cls, *item_or_items: MaybeIterable[THashable]) -> Self:
|
729
|
-
items = list(chain(*map(always_iterable, item_or_items)))
|
730
|
-
cls.check_items(items)
|
731
|
-
return super().__new__(cls, items)
|
732
|
-
|
733
|
-
def __init__(self, *item_or_items: MaybeIterable[THashable]) -> None:
|
734
|
-
super().__init__()
|
735
|
-
_ = item_or_items
|
736
|
-
|
737
|
-
@override
|
738
|
-
def __and__(self, other: MaybeIterable[THashable], /) -> Self:
|
739
|
-
if isinstance(other, type(self)):
|
740
|
-
return type(self)(super().__and__(other))
|
741
|
-
return self.__and__(type(self)(other))
|
742
|
-
|
743
|
-
@override
|
744
|
-
def __or__(self, other: MaybeIterable[THashable], /) -> Self:
|
745
|
-
if isinstance(other, type(self)):
|
746
|
-
return type(self)(super().__or__(other))
|
747
|
-
return self.__or__(type(self)(other))
|
748
|
-
|
749
|
-
@override
|
750
|
-
def __sub__(self, other: MaybeIterable[THashable], /) -> Self:
|
751
|
-
if isinstance(other, type(self)):
|
752
|
-
return type(self)(super().__sub__(other))
|
753
|
-
return self.__sub__(type(self)(other))
|
754
|
-
|
755
|
-
@classmethod
|
756
|
-
def check_items(cls, items: Iterable[THashable], /) -> None:
|
757
|
-
_ = items
|
758
|
-
|
759
|
-
def filter(self, func: Callable[[THashable], bool], /) -> Self:
|
760
|
-
return type(self)(filter(func, self))
|
761
|
-
|
762
|
-
def map(self, func: Callable[[THashable], THashable2], /) -> Collection[THashable2]:
|
763
|
-
values = cast("Any", map(func, self))
|
764
|
-
return cast("Any", type(self)(values))
|
765
|
-
|
766
|
-
def partition(self, func: Callable[[THashable], bool], /) -> tuple[Self, Self]:
|
767
|
-
from more_itertools import partition
|
768
|
-
|
769
|
-
is_false, is_true = partition(func, self)
|
770
|
-
return type(self)(is_false), type(self)(is_true)
|
771
|
-
|
772
|
-
|
773
|
-
##
|
774
|
-
|
775
|
-
|
776
724
|
def ensure_hashables(
|
777
725
|
*args: Any, **kwargs: Any
|
778
726
|
) -> tuple[list[Hashable], dict[str, Hashable]]:
|